Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 04 Nov 2013 16:33:35 -0500
changeset 153429 94a672274c2b319732713e02527a542e6b63ae1b
parent 153391 311650f884516d100d36e4d61fedbffe2ca18704 (current diff)
parent 153428 7d298c4380ad7e0f65c421a7ae6345bfb7a3f3f5 (diff)
child 153430 a8131d677d9b5d640e18cb3cab06f669a2175050
push id3331
push userryanvm@gmail.com
push dateMon, 04 Nov 2013 21:33:50 +0000
treeherderfx-team@94a672274c2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
Merge m-c to fx-team.
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "17d3c31fb43696cda00ae13b79b8f2053fa12e11", 
+    "revision": "00ceae21c52602059b7614b661bc39a3c73c84de", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/components/migration/src/SafariProfileMigrator.js
+++ b/browser/components/migration/src/SafariProfileMigrator.js
@@ -337,39 +337,16 @@ Preferences.prototype = {
         // Firefox has an elaborate set of Image preferences. The correlation is:
         // Mode:                            Safari    Firefox
         // Blocked                          FALSE     2
         // Allowed                          TRUE      1
         // Allowed, originating site only   --        3
         this._set("WebKitDisplayImagesKey", "permissions.default.image",
                   function(webkitVal) webkitVal ? 1 : 2);
 
-        // Default charset migration
-        this._set("WebKitDefaultTextEncodingName", "intl.charset.default",
-          function(webkitCharset) {
-            // We don't support x-mac-korean (see bug 713516), but it mostly matches
-            // EUC-KR.
-            if (webkitCharset == "x-mac-korean")
-              return "EUC-KR";
-
-            // getCharsetAlias throws if an invalid value is passed in.
-            try {
-              return Cc["@mozilla.org/charset-converter-manager;1"].
-                     getService(Ci.nsICharsetConverterManager).
-                     getCharsetAlias(webkitCharset);
-            }
-            catch(ex) {
-              Cu.reportError("Could not convert webkit charset '" + webkitCharset +
-                             "' to a supported charset");
-            }
-            // Don't set the preference if we could not get the corresponding
-            // charset.
-            return undefined;
-          });
-
 #ifdef XP_WIN
         // Cookie-accept policy.
         // For the OS X version, see WebFoundationCookieBehavior.
         // Setting                    Safari          Firefox
         // Always Accept              0               0
         // Accept from Originating    2               1
         // Never Accept               1               2
         this._set("WebKitCookieStorageAcceptPolicy",
--- a/browser/components/preferences/fonts.js
+++ b/browser/components/preferences/fonts.js
@@ -93,28 +93,16 @@ var gFontsDialog = {
       if (fontItems.length)
         break;
     }
     if (fontItems.length)
       return fontItems[0].getAttribute("value");
     return defaultValue;
   },
   
-  _charsetMenuInitialized: false,
-  readDefaultCharset: function ()
-  {
-    if (!this._charsetMenuInitialized) {
-      var os = Components.classes["@mozilla.org/observer-service;1"]
-                         .getService(Components.interfaces.nsIObserverService);
-      os.notifyObservers(null, "charsetmenu-selected", "other");
-      this._charsetMenuInitialized = true;
-    }
-    return undefined;
-  },
-  
   readUseDocumentFonts: function ()
   {
     var preference = document.getElementById("browser.display.use_document_fonts");
     return preference.value == 1;
   },
   
   writeUseDocumentFonts: function ()
   {
--- a/browser/components/preferences/fonts.xul
+++ b/browser/components/preferences/fonts.xul
@@ -32,17 +32,17 @@
   <prefpane id="FontsDialogPane"
             helpTopic="prefs-fonts-and-colors">
   
     <preferences id="fontPreferences">
       <preference id="font.language.group"  name="font.language.group"  type="wstring"/>
       <preference id="browser.display.use_document_fonts"
                   name="browser.display.use_document_fonts"
                   type="int"/>
-      <preference id="intl.charset.default" name="intl.charset.default" type="wstring"/>
+      <preference id="intl.charset.fallback.override" name="intl.charset.fallback.override" type="string"/>
     </preferences>
     
     <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
     <script type="application/javascript" src="chrome://mozapps/content/preferences/fontbuilder.js"/>
     <script type="application/javascript" src="chrome://browser/content/preferences/fonts.js"/>
 
     <!-- Fonts for: [ Language ] -->
     <groupbox>
@@ -257,21 +257,32 @@
     <!-- Character Encoding -->
     <groupbox>
       <caption label="&languages.customize.Fallback.grouplabel;"/>
       <description>&languages.customize.Fallback.desc;</description>
       <hbox align="center">
         <label value="&languages.customize.Fallback.label;"
                accesskey="&languages.customize.Fallback.accesskey;"
                control="DefaultCharsetList"/>
-        <menulist id="DefaultCharsetList" ref="NC:DecodersRoot" datasources="rdf:charset-menu"
-                  preference="intl.charset.default" 
-                  onsyncfrompreference="return gFontsDialog.readDefaultCharset();">
-          <template>
-            <menupopup>
-              <menuitem label="rdf:http://home.netscape.com/NC-rdf#Name" value="..." uri="..."/>
-            </menupopup>
-          </template>
+        <menulist id="DefaultCharsetList" preference="intl.charset.fallback.override">
+          <menupopup>
+            <menuitem label="&languages.customize.Fallback.auto;"        value=""/>
+            <menuitem label="&languages.customize.Fallback.arabic;"      value="windows-1256"/>
+            <menuitem label="&languages.customize.Fallback.baltic;"      value="windows-1257"/>
+            <menuitem label="&languages.customize.Fallback.ceiso;"       value="ISO-8859-2"/>
+            <menuitem label="&languages.customize.Fallback.cewindows;"   value="windows-1250"/>
+            <menuitem label="&languages.customize.Fallback.simplified;"  value="gbk"/>
+            <menuitem label="&languages.customize.Fallback.traditional;" value="Big5"/>
+            <menuitem label="&languages.customize.Fallback.cyrillic;"    value="windows-1251"/>
+            <menuitem label="&languages.customize.Fallback.greek;"       value="ISO-8859-7"/>
+            <menuitem label="&languages.customize.Fallback.hebrew;"      value="windows-1255"/>
+            <menuitem label="&languages.customize.Fallback.japanese;"    value="Shift_JIS"/>
+            <menuitem label="&languages.customize.Fallback.korean;"      value="EUC-KR"/>
+            <menuitem label="&languages.customize.Fallback.thai;"        value="windows-874"/>
+            <menuitem label="&languages.customize.Fallback.turkish;"     value="windows-1254"/>
+            <menuitem label="&languages.customize.Fallback.vietnamese;"  value="windows-1258"/>
+            <menuitem label="&languages.customize.Fallback.other;"       value="windows-1252"/>
+          </menupopup>
         </menulist>
       </hbox>
     </groupbox>
   </prefpane>
 </prefwindow>
--- a/browser/locales/en-US/chrome/browser/preferences/fonts.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/fonts.dtd
@@ -67,8 +67,45 @@
 
 <!ENTITY  allowPagesToUse.label                   "Allow pages to choose their own fonts, instead of my selections above">
 <!ENTITY  allowPagesToUse.accesskey               "A">
 
 <!ENTITY languages.customize.Fallback.grouplabel  "Character Encoding for Legacy Content">
 <!ENTITY languages.customize.Fallback.label       "Fallback Character Encoding:">
 <!ENTITY languages.customize.Fallback.accesskey   "C">
 <!ENTITY languages.customize.Fallback.desc        "This character encoding is used for legacy content that fails to declare its encoding.">
+
+<!ENTITY languages.customize.Fallback.auto        "Default for Current Locale">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.arabic):
+     Translate "Arabic" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.arabic      "Arabic">
+<!ENTITY languages.customize.Fallback.baltic      "Baltic">
+<!ENTITY languages.customize.Fallback.ceiso       "Central European, ISO">
+<!ENTITY languages.customize.Fallback.cewindows   "Central European, Microsoft">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.simplified):
+     Translate "Chinese" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.simplified  "Chinese, Simplified">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.traditional):
+     Translate "Chinese" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.traditional "Chinese, Traditional">
+<!ENTITY languages.customize.Fallback.cyrillic    "Cyrillic">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.greek):
+     Translate "Greek" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.greek       "Greek">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.hebrew):
+     Translate "Hebrew" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.hebrew      "Hebrew">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.japanese):
+     Translate "Japanese" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.japanese    "Japanese">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.korean):
+     Translate "Korean" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.korean      "Korean">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.thai):
+     Translate "Thai" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.thai        "Thai">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.turkish):
+     Translate "Turkish" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.turkish     "Turkish">
+<!-- LOCALIZATION NOTE (languages.customize.Fallback.vietnamese):
+     Translate "Vietnamese" as an adjective for an encoding, not as the name of the language. -->
+<!ENTITY languages.customize.Fallback.vietnamese  "Vietnamese">
+<!ENTITY languages.customize.Fallback.other       "Other (incl. Western European)">
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -78,16 +78,17 @@
 #include "nsArrayUtils.h"
 #include "nsIEffectiveTLDService.h"
 
 #include "nsIPrompt.h"
 //AHMED 12-2
 #include "nsBidiUtils.h"
 
 #include "mozilla/dom/EncodingUtils.h"
+#include "mozilla/dom/FallbackEncoding.h"
 #include "nsIEditingSession.h"
 #include "nsIEditor.h"
 #include "nsNodeInfoManager.h"
 #include "nsIPlaintextEditor.h"
 #include "nsIHTMLEditor.h"
 #include "nsIEditorStyleSheets.h"
 #include "nsIInlineSpellChecker.h"
 #include "nsRange.h"
@@ -440,36 +441,23 @@ nsHTMLDocument::TryParentCharset(nsIDocS
     }
 
     aCharset.Assign(parentCharset);
     aCharsetSource = kCharsetFromParentFrame;
   }
 }
 
 void
-nsHTMLDocument::TryWeakDocTypeDefault(int32_t& aCharsetSource,
-                                      nsACString& aCharset)
+nsHTMLDocument::TryFallback(int32_t& aCharsetSource, nsACString& aCharset)
 {
-  if (kCharsetFromWeakDocTypeDefault <= aCharsetSource)
+  if (kCharsetFromFallback <= aCharsetSource)
     return;
 
-  const nsAdoptingCString& defCharset =
-    Preferences::GetLocalizedCString("intl.charset.default");
-
-  // Don't let the user break things by setting intl.charset.default to
-  // not a rough ASCII superset
-  nsAutoCString canonical;
-  if (EncodingUtils::FindEncodingForLabel(defCharset, canonical) &&
-      EncodingUtils::IsAsciiCompatible(canonical)) {
-    aCharset = canonical;
-  } else {
-    aCharset.AssignLiteral("windows-1252");
-  }
-  aCharsetSource = kCharsetFromWeakDocTypeDefault;
-  return;
+  aCharsetSource = kCharsetFromFallback;
+  FallbackEncoding::FromLocale(aCharset);
 }
 
 void
 nsHTMLDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
 {
   nsDocument::SetDocumentCharacterSet(aCharSetID);
   // Make sure to stash this charset on our channel as needed if it's a wyciwyg
   // channel.
@@ -637,17 +625,17 @@ nsHTMLDocument::StartDocumentLoad(const 
   
   // For error reporting
   nsHtml5TreeOpExecutor* executor = nullptr;
   if (loadAsHtml5) {
     executor = static_cast<nsHtml5TreeOpExecutor*> (mParser->GetContentSink());
   }
 
   if (!IsHTML() || !docShell) { // no docshell for text/html XHR
-    charsetSource = IsHTML() ? kCharsetFromWeakDocTypeDefault
+    charsetSource = IsHTML() ? kCharsetFromFallback
                              : kCharsetFromDocTypeDefault;
     charset.AssignLiteral("UTF-8");
     TryChannelCharset(aChannel, charsetSource, charset, executor);
     parserCharsetSource = charsetSource;
     parserCharset = charset;
   } else {
     NS_ASSERTION(docShell, "Unexpected null value");
 
@@ -678,17 +666,17 @@ nsHTMLDocument::StartDocumentLoad(const 
 
     TryHintCharset(muCV, charsetSource, charset); // XXX mailnews-only
     TryParentCharset(docShell, charsetSource, charset);
 
     if (cachingChan && !urlSpec.IsEmpty()) {
       TryCacheCharset(cachingChan, charsetSource, charset);
     }
 
-    TryWeakDocTypeDefault(charsetSource, charset);
+    TryFallback(charsetSource, charset);
 
     if (wyciwygChannel) {
       // We know for sure that the parser needs to be using UTF16.
       parserCharset = "UTF-16";
       parserCharsetSource = charsetSource < kCharsetFromChannel ?
         kCharsetFromChannel : charsetSource;
         
       nsAutoCString cachedCharset;
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -308,18 +308,17 @@ protected:
                             nsIDocShell*  aDocShell,
                             int32_t& aCharsetSource,
                             nsACString& aCharset);
   static void TryCacheCharset(nsICachingChannel* aCachingChannel,
                                 int32_t& aCharsetSource,
                                 nsACString& aCharset);
   void TryParentCharset(nsIDocShell*  aDocShell,
                         int32_t& charsetSource, nsACString& aCharset);
-  static void TryWeakDocTypeDefault(int32_t& aCharsetSource,
-                                    nsACString& aCharset);
+  static void TryFallback(int32_t& aCharsetSource, nsACString& aCharset);
 
   // Override so we can munge the charset on our wyciwyg channel as needed.
   virtual void SetDocumentCharacterSet(const nsACString& aCharSetID) MOZ_OVERRIDE;
 
   // Tracks if we are currently processing any document.write calls (either
   // implicit or explicit). Note that if a write call writes out something which
   // would block the parser, then mWriteLevel will be incorrect until the parser
   // finishes processing that script.
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1891,17 +1891,17 @@ nsDocShell::GatherCharsetMenuTelemetry()
   bool isFileURL = false;
   nsIURI* url = doc->GetOriginalURI();
   if (url) {
     url->SchemeIs("file", &isFileURL);
   }
 
   int32_t charsetSource = doc->GetDocumentCharacterSetSource();
   switch (charsetSource) {
-    case kCharsetFromWeakDocTypeDefault:
+    case kCharsetFromFallback:
     case kCharsetFromDocTypeDefault:
     case kCharsetFromCache:
     case kCharsetFromParentFrame:
     case kCharsetFromHintPrevDoc:
       // Changing charset on an unlabeled doc.
       if (isFileURL) {
         Telemetry::Accumulate(Telemetry::CHARSET_OVERRIDE_SITUATION, 0);
       } else {
--- a/dom/bluetooth/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/BluetoothServiceBluedroid.cpp
@@ -56,30 +56,107 @@ public:
 
 private:
   BluetoothSignal mSignal;
 };
 
 /**
  *  Static variables
  */
-
 static bluetooth_device_t* sBtDevice;
 static const bt_interface_t* sBtInterface;
 static bool sIsBtEnabled = false;
 static bool sAdapterDiscoverable = false;
 static nsString sAdapterBdAddress;
 static nsString sAdapterBdName;
 static uint32_t sAdapterDiscoverableTimeout;
+static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeDiscoveryRunnableArray;
 static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray;
 
 /**
  *  Static callback functions
  */
 static void
+ClassToIcon(uint32_t aClass, nsAString& aRetIcon)
+{
+  switch ((aClass & 0x1f00) >> 8) {
+    case 0x01:
+      aRetIcon.AssignLiteral("computer");
+      break;
+    case 0x02:
+      switch ((aClass & 0xfc) >> 2) {
+        case 0x01:
+        case 0x02:
+        case 0x03:
+        case 0x05:
+          aRetIcon.AssignLiteral("phone");
+          break;
+        case 0x04:
+          aRetIcon.AssignLiteral("modem");
+          break;
+      }
+      break;
+    case 0x03:
+      aRetIcon.AssignLiteral("network-wireless");
+      break;
+    case 0x04:
+      switch ((aClass & 0xfc) >> 2) {
+        case 0x01:
+        case 0x02:
+        case 0x06:
+          aRetIcon.AssignLiteral("audio-card");
+          break;
+        case 0x0b:
+        case 0x0c:
+        case 0x0d:
+          aRetIcon.AssignLiteral("camera-video");
+          break;
+        default:
+          aRetIcon.AssignLiteral("audio-card");
+          break;
+      }
+      break;
+    case 0x05:
+      switch ((aClass & 0xc0) >> 6) {
+        case 0x00:
+          switch ((aClass && 0x1e) >> 2) {
+            case 0x01:
+            case 0x02:
+              aRetIcon.AssignLiteral("input-gaming");
+              break;
+          }
+          break;
+        case 0x01:
+          aRetIcon.AssignLiteral("input-keyboard");
+          break;
+        case 0x02:
+          switch ((aClass && 0x1e) >> 2) {
+            case 0x05:
+              aRetIcon.AssignLiteral("input-tablet");
+              break;
+            default:
+              aRetIcon.AssignLiteral("input-mouse");
+              break;
+          }
+      }
+      break;
+    case 0x06:
+      if (aClass & 0x80) {
+        aRetIcon.AssignLiteral("printer");
+        break;
+      }
+      if (aClass & 0x20) {
+        aRetIcon.AssignLiteral("camera-photo");
+        break;
+      }
+      break;
+  }
+}
+
+static void
 AdapterStateChangeCallback(bt_state_t aStatus)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   BT_LOGD("%s, BT_STATE:%d", __FUNCTION__, aStatus);
   nsAutoString signalName;
   if (aStatus == BT_STATE_ON) {
     sIsBtEnabled = true;
@@ -105,16 +182,26 @@ BdAddressTypeToString(bt_bdaddr_t* aBdAd
 
   sprintf((char*)bdstr, "%02x:%02x:%02x:%02x:%02x:%02x",
           (int)addr[0],(int)addr[1],(int)addr[2],
           (int)addr[3],(int)addr[4],(int)addr[5]);
 
   aRetBdAddress = NS_ConvertUTF8toUTF16((char*)bdstr);
 }
 
+static bool
+IsReady()
+{
+  if (!sBtInterface || !sIsBtEnabled) {
+    BT_LOGR("Warning! Bluetooth Service is not ready");
+    return false;
+  }
+  return true;
+}
+
 static void
 AdapterPropertiesChangeCallback(bt_status_t aStatus, int aNumProperties,
                                 bt_property_t *aProperties)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   BluetoothValue propertyValue;
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
@@ -167,20 +254,120 @@ AdapterPropertiesChangeCallback(bt_statu
     if (!sSetPropertyRunnableArray.IsEmpty()) {
       DispatchBluetoothReply(sSetPropertyRunnableArray[0], BluetoothValue(true),
                              EmptyString());
       sSetPropertyRunnableArray.RemoveElementAt(0);
     }
   }
 }
 
-bt_callbacks_t sBluetoothCallbacks = {
+static void
+RemoteDevicePropertiesChangeCallback(bt_status_t aStatus,
+                                     bt_bdaddr_t *aBdAddress,
+                                     int aNumProperties,
+                                     bt_property_t *aProperties)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  // First, get remote device bd_address since it will be the key of
+  // return name value pair.
+  nsString remoteDeviceBdAddress;
+  BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
+
+  InfallibleTArray<BluetoothNamedValue> deviceProperties;
+
+  for (int i = 0; i < aNumProperties; ++i) {
+    bt_property_t p = aProperties[i];
+
+    if (p.type == BT_PROPERTY_BDNAME) {
+      BluetoothValue propertyValue = NS_ConvertUTF8toUTF16((char*)p.val);
+      deviceProperties.AppendElement(
+        BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue));
+    } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) {
+      uint32_t cod = *(uint32_t*)p.val;
+      deviceProperties.AppendElement(
+        BluetoothNamedValue(NS_LITERAL_STRING("Class"), BluetoothValue(cod)));
+      nsString icon;
+      ClassToIcon(cod, icon);
+      deviceProperties.AppendElement(
+        BluetoothNamedValue(NS_LITERAL_STRING("Icon"), BluetoothValue(icon)));
+    } else {
+      BT_LOGR("Other non-handled device properties. Type: %d", p.type);
+    }
+  }
+}
+
+static void
+DeviceFoundCallback(int aNumProperties, bt_property_t *aProperties)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  BluetoothValue propertyValue;
+  InfallibleTArray<BluetoothNamedValue> propertiesArray;
+
+  for (int i = 0; i < aNumProperties; i++) {
+    bt_property_t p = aProperties[i];
+
+    if (p.type == BT_PROPERTY_BDADDR) {
+      nsString remoteDeviceBdAddress;
+      BdAddressTypeToString((bt_bdaddr_t*)p.val, remoteDeviceBdAddress);
+      propertyValue = remoteDeviceBdAddress;
+      propertiesArray.AppendElement(
+          BluetoothNamedValue(NS_LITERAL_STRING("Address"), propertyValue));
+    } else if (p.type == BT_PROPERTY_BDNAME) {
+      propertyValue = NS_ConvertUTF8toUTF16((char*)p.val);
+      propertiesArray.AppendElement(
+        BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue));
+    } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) {
+      uint32_t cod = *(uint32_t*)p.val;
+      propertyValue = cod;
+      propertiesArray.AppendElement(
+        BluetoothNamedValue(NS_LITERAL_STRING("Class"), propertyValue));
+      nsString icon;
+      ClassToIcon(cod, icon);
+      propertyValue = icon;
+      propertiesArray.AppendElement(
+        BluetoothNamedValue(NS_LITERAL_STRING("Icon"), propertyValue));
+    } else {
+      BT_LOGD("Not handled remote device property: %d", p.type);
+    }
+  }
+
+  BluetoothValue value = propertiesArray;
+  BluetoothSignal signal(NS_LITERAL_STRING("DeviceFound"),
+                         NS_LITERAL_STRING(KEY_ADAPTER), value);
+  nsRefPtr<DistributeBluetoothSignalTask>
+    t = new DistributeBluetoothSignalTask(signal);
+  if (NS_FAILED(NS_DispatchToMainThread(t))) {
+    NS_WARNING("Failed to dispatch to main thread!");
+  }
+}
+
+static void
+DiscoveryStateChangedCallback(bt_discovery_state_t aState)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  if (!sChangeDiscoveryRunnableArray.IsEmpty()) {
+    BluetoothValue values(true);
+    DispatchBluetoothReply(sChangeDiscoveryRunnableArray[0],
+                           values, EmptyString());
+
+    sChangeDiscoveryRunnableArray.RemoveElementAt(0);
+  }
+}
+
+bt_callbacks_t sBluetoothCallbacks =
+{
   sizeof(sBluetoothCallbacks),
   AdapterStateChangeCallback,
-  AdapterPropertiesChangeCallback
+  AdapterPropertiesChangeCallback,
+  RemoteDevicePropertiesChangeCallback,
+  DeviceFoundCallback,
+  DiscoveryStateChangedCallback
 };
 
 /**
  *  Static functions
  */
 static bool
 EnsureBluetoothHalLoad()
 {
@@ -330,23 +517,53 @@ BluetoothServiceBluedroid::GetPairedDevi
 {
   return NS_OK;
 }
 
 nsresult
 BluetoothServiceBluedroid::StartDiscoveryInternal(
   BluetoothReplyRunnable* aRunnable)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!IsReady()) {
+    NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
+
+    return NS_OK;
+  }
+  int ret = sBtInterface->start_discovery();
+  if (ret != BT_STATUS_SUCCESS) {
+    ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("StartDiscovery"));
+
+    return NS_OK;
+  }
+
+  sChangeDiscoveryRunnableArray.AppendElement(aRunnable);
   return NS_OK;
 }
 
 nsresult
 BluetoothServiceBluedroid::StopDiscoveryInternal(
   BluetoothReplyRunnable* aRunnable)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!IsReady()) {
+    NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
+    return NS_OK;
+  }
+  int ret = sBtInterface->cancel_discovery();
+  if (ret != BT_STATUS_SUCCESS) {
+    ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("StopDiscovery"));
+    return NS_OK;
+  }
+
+  sChangeDiscoveryRunnableArray.AppendElement(aRunnable);
   return NS_OK;
 }
 
 nsresult
 BluetoothServiceBluedroid::GetDevicePropertiesInternal(
   const BluetoothSignal& aSignal)
 {
   return NS_OK;
@@ -354,16 +571,23 @@ BluetoothServiceBluedroid::GetDeviceProp
 
 nsresult
 BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
                                        const BluetoothNamedValue& aValue,
                                        BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  if (!IsReady()) {
+    NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
+
+    return NS_OK;
+  }
+
   const nsString propName = aValue.name();
   bt_property_t prop;
   nsString str;
 
   // For Bluedroid, it's necessary to check property name for SetProperty
   if (propName.EqualsLiteral("Name")) {
     prop.type = BT_PROPERTY_BDNAME;
   } else if (propName.EqualsLiteral("Discoverable")) {
new file mode 100644
--- /dev/null
+++ b/dom/encoding/FallbackEncoding.cpp
@@ -0,0 +1,137 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/FallbackEncoding.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+#include "nsUConvPropertySearch.h"
+#include "nsIChromeRegistry.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
+
+namespace mozilla {
+namespace dom {
+
+static const char* localesFallbacks[][3] = {
+#include "localesfallbacks.properties.h"
+};
+
+FallbackEncoding* FallbackEncoding::sInstance = nullptr;
+
+FallbackEncoding::FallbackEncoding()
+{
+  MOZ_COUNT_CTOR(FallbackEncoding);
+  MOZ_ASSERT(!FallbackEncoding::sInstance,
+             "Singleton already exists.");
+}
+
+FallbackEncoding::~FallbackEncoding()
+{
+  MOZ_COUNT_DTOR(FallbackEncoding);
+}
+
+void
+FallbackEncoding::Get(nsACString& aFallback)
+{
+  if (!mFallback.IsEmpty()) {
+    aFallback = mFallback;
+    return;
+  }
+
+  const nsAdoptingCString& override =
+    Preferences::GetCString("intl.charset.fallback.override");
+  // Don't let the user break things by setting the override to unreasonable
+  // values via about:config
+  if (!EncodingUtils::FindEncodingForLabel(override, mFallback) ||
+      !EncodingUtils::IsAsciiCompatible(mFallback) ||
+      mFallback.EqualsLiteral("UTF-8")) {
+    mFallback.Truncate();
+  }
+
+  if (!mFallback.IsEmpty()) {
+    aFallback = mFallback;
+    return;
+  }
+
+  nsAutoCString locale;
+  nsCOMPtr<nsIXULChromeRegistry> registry =
+    mozilla::services::GetXULChromeRegistryService();
+  if (registry) {
+    registry->GetSelectedLocale(NS_LITERAL_CSTRING("global"), locale);
+  }
+
+  // Let's lower case the string just in case unofficial language packs
+  // don't stick to conventions.
+  ToLowerCase(locale); // ASCII lowercasing with CString input!
+
+  // Special case Traditional Chinese before throwing away stuff after the
+  // language itself. Today we only ship zh-TW, but be defensive about
+  // possible future values.
+  if (locale.EqualsLiteral("zh-tw") ||
+      locale.EqualsLiteral("zh-hk") ||
+      locale.EqualsLiteral("zh-mo") ||
+      locale.EqualsLiteral("zh-hant")) {
+    mFallback.AssignLiteral("Big5");
+    aFallback = mFallback;
+    return;
+  }
+
+  // Throw away regions and other variants to accommodate weird stuff seen
+  // in telemetry--apparently unofficial language packs.
+  int32_t index = locale.FindChar('-');
+  if (index >= 0) {
+    locale.Truncate(index);
+  }
+
+  if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
+      localesFallbacks, ArrayLength(localesFallbacks), locale, mFallback))) {
+    mFallback.AssignLiteral("windows-1252");
+  }
+
+  aFallback = mFallback;
+}
+
+void
+FallbackEncoding::FromLocale(nsACString& aFallback)
+{
+  MOZ_ASSERT(FallbackEncoding::sInstance,
+             "Using uninitialized fallback cache.");
+  FallbackEncoding::sInstance->Get(aFallback);
+}
+
+// PrefChangedFunc
+int
+FallbackEncoding::PrefChanged(const char*, void*)
+{
+  MOZ_ASSERT(FallbackEncoding::sInstance,
+             "Pref callback called with null fallback cache.");
+  FallbackEncoding::sInstance->Invalidate();
+  return 0;
+}
+
+void
+FallbackEncoding::Initialize()
+{
+  MOZ_ASSERT(!FallbackEncoding::sInstance,
+             "Initializing pre-existing fallback cache.");
+  FallbackEncoding::sInstance = new FallbackEncoding;
+  Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
+                                "intl.charset.fallback.override",
+                                nullptr);
+  Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
+                                "general.useragent.locale",
+                                nullptr);
+}
+
+void
+FallbackEncoding::Shutdown()
+{
+  MOZ_ASSERT(FallbackEncoding::sInstance,
+             "Releasing non-existent fallback cache.");
+  delete FallbackEncoding::sInstance;
+  FallbackEncoding::sInstance = nullptr;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/encoding/FallbackEncoding.h
@@ -0,0 +1,72 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_FallbackEncoding_h_
+#define mozilla_dom_FallbackEncoding_h_
+
+#include "nsString.h"
+
+namespace mozilla {
+namespace dom {
+
+class FallbackEncoding
+{
+public:
+
+  /**
+   * Gets the locale-dependent fallback encoding for legacy HTML and plain
+   * text content.
+   *
+   * @param aFallback the outparam for the fallback encoding
+   */
+  static void FromLocale(nsACString& aFallback);
+
+  // public API ends here!
+
+  /**
+   * Allocate sInstance used by FromLocale().
+   * To be called from nsLayoutStatics only.
+   */
+  static void Initialize();
+
+  /**
+   * Delete sInstance used by FromLocale().
+   * To be called from nsLayoutStatics only.
+   */
+  static void Shutdown();
+
+private:
+
+  /**
+   * The fallback cache.
+   */
+  static FallbackEncoding* sInstance;
+
+  FallbackEncoding();
+  ~FallbackEncoding();
+
+  /**
+   * Invalidates the cache.
+   */
+  void Invalidate()
+  {
+    mFallback.Truncate();
+  }
+
+  static int PrefChanged(const char*, void*);
+
+  /**
+   * Gets the fallback encoding label.
+   * @param aFallback the fallback encoding
+   */
+  void Get(nsACString& aFallback);
+
+  nsCString mFallback;
+};
+
+} // dom
+} // mozilla
+
+#endif // mozilla_dom_FallbackEncoding_h_
+
--- a/dom/encoding/Makefile.in
+++ b/dom/encoding/Makefile.in
@@ -4,16 +4,20 @@
 
 LOCAL_INCLUDES = \
 	-I$(topsrcdir)/intl/locale/src \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 EncodingUtils.$(OBJ_SUFFIX): labelsencodings.properties.h
+FallbackEncoding.$(OBJ_SUFFIX): localesfallbacks.properties.h
 
 PROPS2ARRAYS = $(topsrcdir)/intl/locale/src/props2arrays.py
 labelsencodings.properties.h: $(PROPS2ARRAYS) labelsencodings.properties
 	$(PYTHON) $^ $@
+localesfallbacks.properties.h: $(PROPS2ARRAYS) localesfallbacks.properties
+	$(PYTHON) $^ $@
 
 GARBAGE += \
-	charsetalias.properties.h \
+	labelsencodings.properties.h \
+	localesfallbacks.properties.h \
 	$(NULL)
new file mode 100644
--- /dev/null
+++ b/dom/encoding/localesfallbacks.properties
@@ -0,0 +1,72 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This file contains mappings from languages to legacy encodings for languages
+# that are associated with legacy encoding other than windows-1252 (except
+# Traditional Chinese, which is handled as a special case elsewhere).
+#
+# The keys are language codes without regions. The values are Gecko-canonical
+# encoding labels (not necessarily lower case!).
+#
+# Rules:
+#
+# * Avoid editing this file!
+#
+# * If you do edit this file, be sure to file a spec bug against WHATWG HTML
+#   to keep this file in sync with
+#   http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding
+#
+# * As an exception to the previous rule, gbk is used instead of GB18030 
+#   until/unless work on http://encoding.spec.whatwg.org/ shows that the former
+#   can be treated as an alias of the latter and our decoder implementation 
+#   has been audited to match the spec.
+#
+# * Use only the language code without a hyphen or anything that would come
+#   after the hyphen.
+#
+# * Don't put windows-1252-affiliated languages here.
+#
+# * Don't put Traditional Chinese here.
+
+ar=windows-1256
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+ba=windows-1251
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+be=windows-1251
+bg=windows-1251
+cs=windows-1250
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23090
+el=ISO-8859-7
+et=windows-1257
+fa=windows-1256
+he=windows-1255
+hr=windows-1250
+hu=ISO-8859-2
+ja=Shift_JIS
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+kk=windows-1251
+ko=EUC-KR
+ku=windows-1254
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+ky=windows-1251
+lt=windows-1257
+lv=windows-1257
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+mk=windows-1251
+pl=ISO-8859-2
+ru=windows-1251
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+sah=windows-1251
+sk=windows-1250
+sl=ISO-8859-2
+sr=windows-1251
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+tg=windows-1251
+th=windows-874
+tr=windows-1254
+# https://www.w3.org/Bugs/Public/show_bug.cgi?id=23089
+tt=windows-1251
+uk=windows-1251
+vi=windows-1258
+zh=gbk
--- a/dom/encoding/moz.build
+++ b/dom/encoding/moz.build
@@ -5,22 +5,24 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 TEST_DIRS += ['test']
 
 MODULE = 'dom'
 
 EXPORTS.mozilla.dom += [
     'EncodingUtils.h',
+    'FallbackEncoding.h',
     'TextDecoder.h',
     'TextEncoder.h',
 ]
 
 SOURCES += [
     'EncodingUtils.cpp',
+    'FallbackEncoding.cpp',
     'TextDecoder.cpp',
     'TextEncoder.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -157,16 +157,22 @@ public:
     return mContentParent;
   }
 
   already_AddRefed<IDBObjectStore>
   CreateObjectStoreInternal(IDBTransaction* aTransaction,
                             const ObjectStoreInfoGuts& aInfo,
                             ErrorResult& aRv);
 
+  IDBFactory*
+  Factory() const
+  {
+    return mFactory;
+  }
+
   // nsWrapperCache
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
@@ -217,16 +223,17 @@ public:
     return PersistenceTypeToStorage(mPersistenceType);
   }
 
   already_AddRefed<IDBRequest>
   MozCreateFileHandle(const nsAString& aName, const Optional<nsAString>& aType,
                       ErrorResult& aRv);
 
   virtual void LastRelease() MOZ_OVERRIDE;
+
 private:
   IDBDatabase();
   ~IDBDatabase();
 
   void OnUnlink();
 
   // The factory must be kept alive when IndexedDB is used in multiple
   // processes. If it dies then the entire actor tree will be destroyed with it
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -142,16 +142,22 @@ public:
   }
 
   const nsCString&
   GetASCIIOrigin() const
   {
     return mASCIIOrigin;
   }
 
+  bool
+  FromIPC()
+  {
+    return !!mContentParent;
+  }
+
   // nsWrapperCache
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -61,69 +61,60 @@ IDBRequest::IDBRequest()
 IDBRequest::~IDBRequest()
 {
   mResultVal = JSVAL_VOID;
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 // static
 already_AddRefed<IDBRequest>
-IDBRequest::Create(IDBWrapperCache* aOwnerCache,
+IDBRequest::Create(IDBDatabase* aDatabase,
                    IDBTransaction* aTransaction)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBRequest> request(new IDBRequest());
 
   request->mTransaction = aTransaction;
-  request->BindToOwner(aOwnerCache);
-  request->SetScriptOwner(aOwnerCache->GetScriptOwner());
-  request->CaptureCaller();
+  request->BindToOwner(aDatabase);
+  request->SetScriptOwner(aDatabase->GetScriptOwner());
+
+  if (!aDatabase->Factory()->FromIPC()) {
+    request->CaptureCaller();
+  }
+
 
   return request.forget();
 }
 
 // static
 already_AddRefed<IDBRequest>
 IDBRequest::Create(IDBObjectStore* aSourceAsObjectStore,
-                   IDBWrapperCache* aOwnerCache,
+                   IDBDatabase* aDatabase,
                    IDBTransaction* aTransaction)
 {
-  nsRefPtr<IDBRequest> request = Create(aOwnerCache, aTransaction);
+  nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction);
 
   request->mSourceAsObjectStore = aSourceAsObjectStore;
 
   return request.forget();
 }
 
 // static
 already_AddRefed<IDBRequest>
 IDBRequest::Create(IDBIndex* aSourceAsIndex,
-                   IDBWrapperCache* aOwnerCache,
+                   IDBDatabase* aDatabase,
                    IDBTransaction* aTransaction)
 {
-  nsRefPtr<IDBRequest> request = Create(aOwnerCache, aTransaction);
+  nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction);
 
   request->mSourceAsIndex = aSourceAsIndex;
 
   return request.forget();
 }
 
-// static
-already_AddRefed<IDBRequest>
-IDBRequest::Create(IDBCursor* aSourceAsCursor,
-                   IDBWrapperCache* aOwnerCache,
-                   IDBTransaction* aTransaction)
-{
-  nsRefPtr<IDBRequest> request = Create(aOwnerCache, aTransaction);
-
-  request->mSourceAsCursor = aSourceAsCursor;
-
-  return request.forget();
-}
-
 #ifdef DEBUG
 void
 IDBRequest::AssertSourceIsCorrect() const
 {
   // At most one of mSourceAs* is allowed to be non-null.  Check that by
   // summing the double negation of each one and asserting the sum is at most
   // 1.
 
@@ -282,21 +273,17 @@ IDBRequest::GetJSContext()
 void
 IDBRequest::CaptureCaller()
 {
   AutoJSContext cx;
 
   const char* filename = nullptr;
   uint32_t lineNo = 0;
   if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) {
-    // If our caller is in another process, we won't have a JSContext on the
-    // stack, and AutoJSContext will push the SafeJSContext. But that won't have
-    // any script on it (certainly not after the push), so GetCallingLocation
-    // will fail when it calls JS_DescribeScriptedCaller. That's fine.
-    NS_WARNING("Failed to get caller.");
+    MOZ_CRASH("Failed to get caller.");
     return;
   }
 
   mFilename.Assign(NS_ConvertUTF8toUTF16(filename));
   mLineNo = lineNo;
 }
 
 void
@@ -413,19 +400,22 @@ IDBOpenDBRequest::Create(IDBFactory* aFa
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aFactory, "Null pointer!");
 
   nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest();
 
   request->BindToOwner(aOwner);
   request->SetScriptOwner(aScriptOwner);
-  request->CaptureCaller();
   request->mFactory = aFactory;
 
+  if (!aFactory->FromIPC()) {
+    request->CaptureCaller();
+  }
+
   return request.forget();
 }
 
 void
 IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -41,31 +41,27 @@ class IndexedDBRequestParentBase;
 class IDBRequest : public IDBWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
                                                          IDBWrapperCache)
 
   static
-  already_AddRefed<IDBRequest> Create(IDBWrapperCache* aOwnerCache,
+  already_AddRefed<IDBRequest> Create(IDBDatabase* aDatabase,
                                       IDBTransaction* aTransaction);
 
   static
   already_AddRefed<IDBRequest> Create(IDBObjectStore* aSource,
-                                      IDBWrapperCache* aOwnerCache,
+                                      IDBDatabase* aDatabase,
                                       IDBTransaction* aTransaction);
 
   static
   already_AddRefed<IDBRequest> Create(IDBIndex* aSource,
-                                      IDBWrapperCache* aOwnerCache,
-                                      IDBTransaction* aTransaction);
-  static
-  already_AddRefed<IDBRequest> Create(IDBCursor* aSource,
-                                      IDBWrapperCache* aOwnerCache,
+                                      IDBDatabase* aDatabase,
                                       IDBTransaction* aTransaction);
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
 
   void GetSource(Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const;
 
   void Reset();
--- a/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl
@@ -6,17 +6,17 @@
 
 interface nsIDOMEventListener;
 interface nsIDOMMozSmsFilter;
 interface nsIDOMMozSmsSegmentInfo;
 interface nsIDOMDOMCursor;
 interface nsIDOMDOMRequest;
 interface nsIDOMBlob;
 
-[scriptable, builtinclass, uuid(d1e35354-3d21-11e3-86da-77253f4c5683)]
+[scriptable, builtinclass, uuid(0e4ff35e-ab84-434a-96b4-46807798cc7e)]
 interface nsIDOMMozMobileMessageManager : nsIDOMEventTarget
 {
   nsIDOMDOMRequest getSegmentInfoForText(in DOMString text);
 
 
   /**
    * Function to send SMS.
    *
@@ -52,17 +52,18 @@ interface nsIDOMMozMobileMessageManager 
   nsIDOMDOMRequest getMessage(in long id);
 
   // The parameter can be either a message id or a nsIDOMMoz{Mms,Sms}Message.
   nsIDOMDOMRequest delete(in jsval param);
 
   // Iterates through nsIDOMMoz{Mms,Sms}Message.
   nsIDOMDOMCursor getMessages(in nsIDOMMozSmsFilter filter, in boolean reverse);
 
-  nsIDOMDOMRequest markMessageRead(in long id, in boolean value);
+  nsIDOMDOMRequest markMessageRead(in long id, in boolean value,
+                                   [optional] in boolean aSendReadReport);
 
   // Iterates through nsIDOMMozMobileMessageThread.
   nsIDOMDOMCursor getThreads();
 
   nsIDOMDOMRequest retrieveMMS(in long id);
 
   [implicit_jscontext] attribute jsval onreceived;
   [implicit_jscontext] attribute jsval onretrieving;
--- a/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
@@ -16,17 +16,17 @@ dictionary MmsAttachment
 };
 
 dictionary MmsDeliveryInfo
 {
   DOMString? receiver;
   DOMString? deliveryStatus;
 };
 
-[scriptable, builtinclass, uuid(35d88c5e-2746-11e3-9d7b-83ca2203a291)]
+[scriptable, builtinclass, uuid(85bfc639-0d8f-43fa-8c12-6bd2958bf219)]
 interface nsIDOMMozMmsMessage : nsISupports
 {
   /**
    * |type| is always "mms".
    */
   readonly attribute DOMString type;
 
   readonly attribute long      id;
@@ -62,9 +62,12 @@ interface nsIDOMMozMmsMessage : nsISuppo
 
   [implicit_jscontext]
   readonly attribute jsval     attachments;    // MmsAttachment[]
 
   [implicit_jscontext]
   readonly attribute jsval     expiryDate;     // Date object
                                                // Expiry date for an MMS to be
                                                // manually downloaded.
+
+  // Request read report from sender or not.
+  readonly attribute boolean   isReadReportRequested;
 };
--- a/dom/mobilemessage/interfaces/nsIMmsService.idl
+++ b/dom/mobilemessage/interfaces/nsIMmsService.idl
@@ -7,20 +7,24 @@ interface nsIMobileMessageCallback;
 interface nsIDOMBlob;
 
 %{C++
 #define MMS_SERVICE_CID { 0x06d9124b, 0x80e0, 0x40ed, \
   { 0x98, 0x71, 0x4d, 0x23, 0x4a, 0x0f, 0xd4, 0x31 } }
 #define MMS_SERVICE_CONTRACTID "@mozilla.org/mms/mmsservice;1"
 %}
 
-[scriptable, uuid(544bfa56-3d60-11e3-8b69-2383ccac8c81)]
+[scriptable, uuid(543278b3-d926-4c65-84b8-b49ad7a17d21)]
 interface nsIMmsService : nsISupports
 {
   readonly attribute unsigned long mmsDefaultServiceId;
 
   void send(in unsigned long serviceId,
             in jsval parameters /* MmsParameters */,
             in nsIMobileMessageCallback request);
 
   void retrieve(in long id,
                 in nsIMobileMessageCallback request);
+
+  void sendReadReport(in DOMString messageID,
+                      in DOMString toAddress,
+                      in DOMString iccId);
 };
--- a/dom/mobilemessage/interfaces/nsIMobileMessageDatabaseService.idl
+++ b/dom/mobilemessage/interfaces/nsIMobileMessageDatabaseService.idl
@@ -11,29 +11,30 @@
 #define MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessagedatabaseservice;1"
 %}
 
 interface nsICursorContinueCallback;
 interface nsIDOMMozSmsFilter;
 interface nsIMobileMessageCallback;
 interface nsIMobileMessageCursorCallback;
 
-[scriptable, uuid(ea6f49ae-3a4c-47eb-a489-15578e634100)]
+[scriptable, uuid(8439916f-abc1-4c67-aa45-8a276a0a7855)]
 interface nsIMobileMessageDatabaseService : nsISupports
 {
   [binaryname(GetMessageMoz)]
   void getMessage(in long messageId,
                   in nsIMobileMessageCallback request);
 
   void deleteMessage([array, size_is(count)] in long messageIds,
                      in uint32_t count,
                      in nsIMobileMessageCallback request);
 
   nsICursorContinueCallback createMessageCursor(in nsIDOMMozSmsFilter filter,
                                                 in boolean reverse,
                                                 in nsIMobileMessageCursorCallback callback);
 
   void markMessageRead(in long messageId,
                        in boolean value,
+                       in boolean sendReadReport,
                        in nsIMobileMessageCallback request);
 
   nsICursorContinueCallback createThreadCursor(in nsIMobileMessageCursorCallback callback);
 };
--- a/dom/mobilemessage/interfaces/nsIMobileMessageService.idl
+++ b/dom/mobilemessage/interfaces/nsIMobileMessageService.idl
@@ -9,17 +9,17 @@ interface nsIDOMMozMmsMessage;
 interface nsIDOMMozMobileMessageThread;
 interface nsIDOMMozSmsSegmentInfo;
 
 %{C++
 #define MOBILE_MESSAGE_SERVICE_CID { 0x829c1dd6, 0x0466, 0x4591, { 0x83, 0x6f, 0xb8, 0xf6, 0xfd, 0x1f, 0x7b, 0xa5 } }
 #define MOBILE_MESSAGE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessageservice;1"
 %}
 
-[scriptable, builtinclass, uuid(729b616e-2766-11e3-9c6a-47e6110e44c6)]
+[scriptable, builtinclass, uuid(7a39eeb4-827e-4c70-9804-288f94174ebe)]
 interface nsIMobileMessageService : nsISupports
 {
   [implicit_jscontext]
   nsIDOMMozSmsMessage createSmsMessage(in long      id,
                                        in unsigned long long threadId,
                                        in DOMString iccId,
                                        in DOMString delivery,
                                        in DOMString deliveryStatus,
@@ -39,17 +39,18 @@ interface nsIMobileMessageService : nsIS
                                        in jsval     deliveryInfo,
                                        in DOMString sender,
                                        in jsval     receivers,
                                        in jsval     timestamp,
                                        in boolean   read,
                                        in DOMString subject,
                                        in DOMString smil,
                                        in jsval     attachments,
-                                       in jsval     expiryDate);
+                                       in jsval     expiryDate,
+                                       in boolean   isReadReportRequested);
 
   nsIDOMMozSmsSegmentInfo createSmsSegmentInfo(in long segments,
                                                in long charsPerSegment,
                                                in long charsAvailableInLastSegment);
 
   [implicit_jscontext]
   nsIDOMMozMobileMessageThread createThread(in unsigned long long id,
                                             in jsval              participants,
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -40,45 +40,48 @@ MmsMessage::MmsMessage(int32_t          
                        const nsTArray<MmsDeliveryInfo>& aDeliveryInfo,
                        const nsAString&                 aSender,
                        const nsTArray<nsString>&        aReceivers,
                        uint64_t                         aTimestamp,
                        bool                             aRead,
                        const nsAString&                 aSubject,
                        const nsAString&                 aSmil,
                        const nsTArray<MmsAttachment>&   aAttachments,
-                       uint64_t                         aExpiryDate)
+                       uint64_t                         aExpiryDate,
+                       bool                             aIsReadReportRequested)
   : mId(aId),
     mThreadId(aThreadId),
     mIccId(aIccId),
     mDelivery(aDelivery),
     mDeliveryInfo(aDeliveryInfo),
     mSender(aSender),
     mReceivers(aReceivers),
     mTimestamp(aTimestamp),
     mRead(aRead),
     mSubject(aSubject),
     mSmil(aSmil),
     mAttachments(aAttachments),
-    mExpiryDate(aExpiryDate)
+    mExpiryDate(aExpiryDate),
+    mIsReadReportRequested(aIsReadReportRequested)
 {
 }
 
 MmsMessage::MmsMessage(const mobilemessage::MmsMessageData& aData)
   : mId(aData.id())
   , mThreadId(aData.threadId())
   , mIccId(aData.iccId())
   , mDelivery(aData.delivery())
   , mSender(aData.sender())
   , mReceivers(aData.receivers())
   , mTimestamp(aData.timestamp())
   , mRead(aData.read())
   , mSubject(aData.subject())
   , mSmil(aData.smil())
   , mExpiryDate(aData.expiryDate())
+  , mIsReadReportRequested(aData.isReadReportRequested())
 {
   uint32_t len = aData.attachments().Length();
   mAttachments.SetCapacity(len);
   for (uint32_t i = 0; i < len; i++) {
     MmsAttachment att;
     const MmsAttachmentData &element = aData.attachments()[i];
     att.id = element.id();
     att.location = element.location();
@@ -170,16 +173,17 @@ MmsMessage::Create(int32_t              
                    const nsAString&      aSender,
                    const JS::Value&      aReceivers,
                    const JS::Value&      aTimestamp,
                    bool                  aRead,
                    const nsAString&      aSubject,
                    const nsAString&      aSmil,
                    const JS::Value&      aAttachments,
                    const JS::Value&      aExpiryDate,
+                   bool                  aIsReadReportRequested,
                    JSContext*            aCx,
                    nsIDOMMozMmsMessage** aMessage)
 {
   *aMessage = nullptr;
 
   // Set |delivery|.
   DeliveryState delivery;
   if (aDelivery.Equals(DELIVERY_SENT)) {
@@ -289,17 +293,18 @@ MmsMessage::Create(int32_t              
                                                          deliveryInfo,
                                                          aSender,
                                                          receivers,
                                                          timestamp,
                                                          aRead,
                                                          aSubject,
                                                          aSmil,
                                                          attachments,
-                                                         expiryDate);
+                                                         expiryDate,
+                                                         aIsReadReportRequested);
   message.forget(aMessage);
   return NS_OK;
 }
 
 bool
 MmsMessage::GetData(ContentParent* aParent,
                     mobilemessage::MmsMessageData& aData)
 {
@@ -311,16 +316,17 @@ MmsMessage::GetData(ContentParent* aPare
   aData.delivery() = mDelivery;
   aData.sender().Assign(mSender);
   aData.receivers() = mReceivers;
   aData.timestamp() = mTimestamp;
   aData.read() = mRead;
   aData.subject() = mSubject;
   aData.smil() = mSmil;
   aData.expiryDate() = mExpiryDate;
+  aData.isReadReportRequested() = mIsReadReportRequested;
 
   aData.deliveryInfo().SetCapacity(mDeliveryInfo.Length());
   for (uint32_t i = 0; i < mDeliveryInfo.Length(); i++) {
     MmsDeliveryInfoData infoData;
     const MmsDeliveryInfo &info = mDeliveryInfo[i];
     infoData.receiver().Assign(info.receiver);
 
     DeliveryStatus status;
@@ -609,10 +615,18 @@ MmsMessage::GetExpiryDate(JSContext* cx,
 {
   JSObject *obj = JS_NewDateObjectMsec(cx, mExpiryDate);
   NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
 
   *aDate = OBJECT_TO_JSVAL(obj);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+MmsMessage::GetIsReadReportRequested(bool* aIsReadReportRequested)
+{
+  *aIsReadReportRequested = mIsReadReportRequested;
+  return NS_OK;
+}
+
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/mobilemessage/src/MmsMessage.h
+++ b/dom/mobilemessage/src/MmsMessage.h
@@ -34,33 +34,35 @@ public:
              const nsTArray<idl::MmsDeliveryInfo>& aDeliveryInfo,
              const nsAString&                      aSender,
              const nsTArray<nsString>&             aReceivers,
              uint64_t                              aTimestamp,
              bool                                  aRead,
              const nsAString&                      aSubject,
              const nsAString&                      aSmil,
              const nsTArray<idl::MmsAttachment>&   aAttachments,
-             uint64_t                              aExpiryDate);
+             uint64_t                              aExpiryDate,
+             bool                                  aIsReadReportRequested);
 
   MmsMessage(const mobilemessage::MmsMessageData& aData);
 
   static nsresult Create(int32_t               aId,
                          uint64_t              aThreadId,
                          const nsAString&      aIccId,
                          const nsAString&      aDelivery,
                          const JS::Value&      aDeliveryInfo,
                          const nsAString&      aSender,
                          const JS::Value&      aReceivers,
                          const JS::Value&      aTimestamp,
                          bool                  aRead,
                          const nsAString&      aSubject,
                          const nsAString&      aSmil,
                          const JS::Value&      aAttachments,
                          const JS::Value&      aExpiryDate,
+                         bool                  aIsReadReportRequested,
                          JSContext*            aCx,
                          nsIDOMMozMmsMessage** aMessage);
 
   bool GetData(ContentParent* aParent,
                mobilemessage::MmsMessageData& aData);
 
 private:
 
@@ -72,14 +74,15 @@ private:
   nsString                       mSender;
   nsTArray<nsString>             mReceivers;
   uint64_t                       mTimestamp;
   bool                           mRead;
   nsString                       mSubject;
   nsString                       mSmil;
   nsTArray<idl::MmsAttachment>   mAttachments;
   uint64_t                       mExpiryDate;
+  bool                           mIsReadReportRequested;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_mobilemessage_MmsMessage_h
--- a/dom/mobilemessage/src/MobileMessageManager.cpp
+++ b/dom/mobilemessage/src/MobileMessageManager.cpp
@@ -392,25 +392,28 @@ MobileMessageManager::GetMessages(nsIDOM
   cursorCallback->mDOMCursor = new DOMCursor(GetOwner(), continueCallback);
   NS_ADDREF(*aCursor = cursorCallback->mDOMCursor);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageManager::MarkMessageRead(int32_t aId, bool aValue,
+                                      bool aSendReadReport,
                                       nsIDOMDOMRequest** aRequest)
 {
   nsCOMPtr<nsIMobileMessageDatabaseService> mobileMessageDBService =
     do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(mobileMessageDBService, NS_ERROR_FAILURE);
 
   nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
   nsCOMPtr<nsIMobileMessageCallback> msgCallback = new MobileMessageCallback(request);
-  nsresult rv = mobileMessageDBService->MarkMessageRead(aId, aValue, msgCallback);
+  nsresult rv = mobileMessageDBService->MarkMessageRead(aId, aValue,
+                                                        aSendReadReport,
+                                                        msgCallback);
   NS_ENSURE_SUCCESS(rv, rv);
 
   request.forget(aRequest);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageManager::GetThreads(nsIDOMDOMCursor** aCursor)
--- a/dom/mobilemessage/src/MobileMessageService.cpp
+++ b/dom/mobilemessage/src/MobileMessageService.cpp
@@ -69,32 +69,34 @@ MobileMessageService::CreateMmsMessage(i
                                        const nsAString&      aSender,
                                        const JS::Value&      aReceivers,
                                        const JS::Value&      aTimestamp,
                                        bool                  aRead,
                                        const nsAString&      aSubject,
                                        const nsAString&      aSmil,
                                        const JS::Value&      aAttachments,
                                        const JS::Value&      aExpiryDate,
+                                       bool                  aIsReadReportRequested,
                                        JSContext*            aCx,
                                        nsIDOMMozMmsMessage** aMessage)
 {
   return MmsMessage::Create(aId,
                             aThreadId,
                             aIccId,
                             aDelivery,
                             aDeliveryInfo,
                             aSender,
                             aReceivers,
                             aTimestamp,
                             aRead,
                             aSubject,
                             aSmil,
                             aAttachments,
                             aExpiryDate,
+                            aIsReadReportRequested,
                             aCx,
                             aMessage);
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateSmsSegmentInfo(int32_t aSegments,
                                            int32_t aCharsPerSegment,
                                            int32_t aCharsAvailableInLastSegment,
--- a/dom/mobilemessage/src/android/MmsService.cpp
+++ b/dom/mobilemessage/src/android/MmsService.cpp
@@ -32,11 +32,20 @@ MmsService::Send(uint32_t aServiceid,
 NS_IMETHODIMP
 MmsService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest)
 {
   // TODO: Bug 860174, implement this function.
   NS_NOTYETIMPLEMENTED("Implement me!");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+NS_IMETHODIMP
+MmsService::SendReadReport(const nsAString & messageID,
+                           const nsAString & toAddress,
+                           const nsAString & iccId)
+{
+  NS_NOTYETIMPLEMENTED("Implement me!");
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 } // namespace mobilemessage
 } // namespace dom
 } // namespace mozilla
--- a/dom/mobilemessage/src/android/MobileMessageDatabaseService.cpp
+++ b/dom/mobilemessage/src/android/MobileMessageDatabaseService.cpp
@@ -53,16 +53,17 @@ MobileMessageDatabaseService::CreateMess
                                                   nsICursorContinueCallback** aResult)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId,
                                               bool aValue,
+                                              bool aSendReadReport,
                                               nsIMobileMessageCallback* aRequest)
 {
   // TODO: This would need to be implemented as part of Bug 748391
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback,
--- a/dom/mobilemessage/src/fallback/MmsService.cpp
+++ b/dom/mobilemessage/src/fallback/MmsService.cpp
@@ -30,11 +30,20 @@ MmsService::Send(uint32_t aServiceId,
 
 NS_IMETHODIMP
 MmsService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest)
 {
   NS_NOTYETIMPLEMENTED("Implement me!");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+NS_IMETHODIMP
+MmsService::SendReadReport(const nsAString & messageID,
+                           const nsAString & toAddress,
+                           const nsAString & iccId)
+{
+  NS_NOTYETIMPLEMENTED("Implement me!");
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 } // namespace mobilemessage
 } // namespace dom
 } // namespace mozilla
--- a/dom/mobilemessage/src/fallback/MobileMessageDatabaseService.cpp
+++ b/dom/mobilemessage/src/fallback/MobileMessageDatabaseService.cpp
@@ -36,16 +36,17 @@ MobileMessageDatabaseService::CreateMess
 {
   NS_ERROR("We should not be here!");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId,
                                               bool aValue,
+                                              bool aSendReadReport,
                                               nsIMobileMessageCallback* aRequest)
 {
   NS_ERROR("We should not be here!");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback,
--- a/dom/mobilemessage/src/gonk/MmsPduHelper.jsm
+++ b/dom/mobilemessage/src/gonk/MmsPduHelper.jsm
@@ -1621,16 +1621,22 @@ const MMS_PDU_TYPES = (function () {
                                          "x-mms-mms-version",
                                          "message-id",
                                          "to",
                                          "date",
                                          "x-mms-status"]);
   add(MMS_PDU_TYPE_ACKNOWLEDGE_IND, false, ["x-mms-message-type",
                                             "x-mms-transaction-id",
                                             "x-mms-mms-version"]);
+  add(MMS_PDU_TYPE_READ_REC_IND, false, ["x-mms-message-type",
+                                         "message-id",
+                                         "x-mms-mms-version",
+                                         "to",
+                                         "from",
+                                         "x-mms-read-status"]);
 
   return pdus;
 })();
 
 /**
  * Header field names and assigned numbers.
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.4
@@ -1667,17 +1673,17 @@ const MMS_HEADER_FIELDS = (function () {
   add("x-mms-response-text",                     0x13, ResponseText);
   add("x-mms-sender-visibility",                 0x14, BooleanValue);
   add("x-mms-status",                            0x15, StatusValue);
   add("subject",                                 0x16, EncodedStringValue);
   add("to",                                      0x17, Address);
   add("x-mms-transaction-id",                    0x18, WSP.TextString);
   add("x-mms-retrieve-status",                   0x19, RetrieveStatusValue);
   add("x-mms-retrieve-text",                     0x1A, EncodedStringValue);
-  //add("x-mms-read-status", 0x1B);
+  add("x-mms-read-status",                       0x1B, BooleanValue);
   add("x-mms-reply-charging",                    0x1C, ReplyChargingValue);
   add("x-mms-reply-charging-deadline",           0x1D, ExpiryValue);
   add("x-mms-reply-charging-id",                 0x1E, WSP.TextString);
   add("x-mms-reply-charging-size",               0x1F, WSP.LongInteger);
   add("x-mms-previously-sent-by",                0x20, PreviouslySentByValue);
   add("x-mms-previously-sent-date",              0x21, PreviouslySentDateValue);
   add("x-mms-store",                             0x22, BooleanValue);
   add("x-mms-mm-state",                          0x23, MmStateValue);
--- a/dom/mobilemessage/src/gonk/MmsService.js
+++ b/dom/mobilemessage/src/gonk/MmsService.js
@@ -133,27 +133,29 @@ XPCOMUtils.defineLazyServiceGetter(this,
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "@mozilla.org/mobilemessage/mobilemessageservice;1",
                                    "nsIMobileMessageService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
                                    "@mozilla.org/system-message-internal;1",
                                    "nsISystemMessagesInternal");
 
+XPCOMUtils.defineLazyServiceGetter(this, "gRil",
+                                   "@mozilla.org/ril;1",
+                                   "nsIRadioInterfaceLayer");
+
 XPCOMUtils.defineLazyGetter(this, "MMS", function () {
   let MMS = {};
   Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS);
   return MMS;
 });
 
 function MmsConnection(aServiceId) {
   this.serviceId = aServiceId;
-  let ril = Cc["@mozilla.org/ril;1"]
-              .getService(Ci["nsIRadioInterfaceLayer"]);
-  this.radioInterface = ril.getRadioInterface(aServiceId);
+  this.radioInterface = gRil.getRadioInterface(aServiceId);
 };
 
 MmsConnection.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
   /** MMS proxy settings. */
   mmsc:     "",
   mmsProxy: "",
@@ -1309,16 +1311,57 @@ function getDefaultServiceId() {
   if (id >= numRil || id < 0) {
     id = 0;
   }
 
   return id;
 }
 
 /**
+ * Return M-Read-Rec.ind back to MMSC
+ *
+ * @param messageID
+ *        Message-ID of the message.
+ * @param toAddress
+ *        The address of the recipient of the Read Report, i.e. the originator
+ *        of the original multimedia message.
+ *
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A section 6.7.2
+ */
+function ReadRecTransaction(mmsConnection, messageID, toAddress) {
+  this.mmsConnection = mmsConnection;
+  let headers = {};
+
+  // Mandatory fields
+  headers["x-mms-message-type"] = MMS.MMS_PDU_TYPE_READ_REC_IND;
+  headers["x-mms-mms-version"] = MMS.MMS_VERSION;
+  headers["message-id"] = messageID;
+  let type = MMS.Address.resolveType(toAddress);
+  let to = {address: toAddress,
+            type: type}
+  headers["to"] = to;
+  headers["from"] = null;
+  headers["x-mms-read-status"] = true;
+
+  this.istream = MMS.PduHelper.compose(null, {headers: headers});
+  if (!this.istream) {
+    throw Cr.NS_ERROR_FAILURE;
+  }
+}
+ReadRecTransaction.prototype = {
+  run: function() {
+    gMmsTransactionHelper.sendRequest(this.mmsConnection,
+                                      "POST",
+                                      null,
+                                      this.istream,
+                                      null);
+  }
+};
+
+/**
  * MmsService
  */
 function MmsService() {
   if (DEBUG) {
     let macro = (MMS.MMS_VERSION >> 4) & 0x0f;
     let minor = MMS.MMS_VERSION & 0x0f;
     debug("Running protocol version: " + macro + "." + minor);
   }
@@ -2130,21 +2173,19 @@ MmsService.prototype = {
           if (DEBUG) debug("The message to be retrieved is expired.");
           aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR);
           return;
         }
       }
 
       // Get the RIL service ID based on the saved MMS message record's ICC ID,
       // which could fail when the corresponding SIM card isn't installed.
-      let ril = Cc["@mozilla.org/ril;1"]
-                  .getService(Ci["nsIRadioInterfaceLayer"]);
       let serviceId;
       try {
-        serviceId = ril.getClientIdByIccId(aMessageRecord.iccId);
+        serviceId = gRil.getClientIdByIccId(aMessageRecord.iccId);
       } catch (e) {
         if (DEBUG) debug("RIL service is not available for ICC ID.");
         aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR);
         return;
       }
 
       let mmsConnection = gMmsConnections.getConnByServiceId(serviceId);
 
@@ -2253,16 +2294,42 @@ MmsService.prototype = {
           this.retrieveMessage(mmsConnection,
                                url,
                                responseNotify.bind(this),
                                aDomMessage);
         }).bind(this));
     }).bind(this));
   },
 
+  sendReadReport: function sendReadReport(messageID, toAddress, iccId) {
+    if (DEBUG) {
+      debug("messageID: " + messageID + " toAddress: " +
+            JSON.stringify(toAddress));
+    }
+
+    // Get the RIL service ID based on the saved MMS message record's ICC ID,
+    // which could fail when the corresponding SIM card isn't installed.
+    let serviceId;
+    try {
+      serviceId = gRil.getClientIdByIccId(iccId);
+    } catch (e) {
+      if (DEBUG) debug("RIL service is not available for ICC ID.");
+      return;
+    }
+
+    let mmsConnection = gMmsConnections.getConnByServiceId(serviceId);
+    try {
+      let transaction =
+        new ReadRecTransaction(mmsConnection, messageID, toAddress);
+      transaction.run();
+    } catch (e) {
+      if (DEBUG) debug("sendReadReport fail. e = " + e);
+    }
+  },
+
   // nsIWapPushApplication
 
   receiveWapPush: function receiveWapPush(array, length, offset, options) {
     let data = {array: array, offset: offset};
     let msg = MMS.PduHelper.parse(data, null);
     if (!msg) {
       return false;
     }
--- a/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js
+++ b/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js
@@ -19,17 +19,17 @@ const RIL_GETMESSAGESCURSOR_CID =
 const RIL_GETTHREADSCURSOR_CID =
   Components.ID("{95ee7c3e-d6f2-4ec4-ade5-0c453c036d35}");
 
 const DEBUG = false;
 const DISABLE_MMS_GROUPING_FOR_RECEIVING = true;
 
 
 const DB_NAME = "sms";
-const DB_VERSION = 16;
+const DB_VERSION = 17;
 const MESSAGE_STORE_NAME = "sms";
 const THREAD_STORE_NAME = "thread";
 const PARTICIPANT_STORE_NAME = "participant";
 const MOST_RECENT_STORE_NAME = "most-recent";
 
 const DELIVERY_SENDING = "sending";
 const DELIVERY_SENT = "sent";
 const DELIVERY_RECEIVED = "received";
@@ -60,16 +60,19 @@ const NEXT = "next";
 
 const COLLECT_ID_END = 0;
 const COLLECT_ID_ERROR = -1;
 const COLLECT_TIMESTAMP_UNUSED = 0;
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "@mozilla.org/mobilemessage/mobilemessageservice;1",
                                    "nsIMobileMessageService");
+XPCOMUtils.defineLazyServiceGetter(this, "gMMSService",
+                                   "@mozilla.org/mms/rilmmsservice;1",
+                                   "nsIMmsService");
 
 /**
  * MobileMessageDatabaseService
  */
 function MobileMessageDatabaseService() {
   // Prime the directory service's cache to ensure that the ProfD entry exists
   // by the time IndexedDB queries for it off the main thread. (See bug 743635.)
   Services.dirsvc.get("ProfD", Ci.nsIFile);
@@ -225,20 +228,24 @@ MobileMessageDatabaseService.prototype =
             if (DEBUG) debug("Upgrade to version 14. Fix the wrong participants.");
             self.upgradeSchema13(event.target.transaction, next);
             break;
           case 14:
             if (DEBUG) debug("Upgrade to version 15. Add deliveryTimestamp.");
             self.upgradeSchema14(event.target.transaction, next);
             break;
           case 15:
-            if (DEBUG) debug("Upgrade to version 15. Add ICC ID for each message.");
+            if (DEBUG) debug("Upgrade to version 16. Add ICC ID for each message.");
             self.upgradeSchema15(event.target.transaction, next);
             break;
           case 16:
+            if (DEBUG) debug("Upgrade to version 17. Add isReadReportSent for incoming MMS.");
+            self.upgradeSchema16(event.target.transaction, next);
+            break;
+          case 17:
             // This will need to be moved for each new version
             if (DEBUG) debug("Upgrade finished.");
             break;
           default:
             event.target.transaction.abort();
             callback("Old database version: " + event.oldVersion, null);
             break;
         }
@@ -1067,16 +1074,39 @@ MobileMessageDatabaseService.prototype =
 
       let messageRecord = cursor.value;
       messageRecord.iccId = null;
       cursor.update(messageRecord);
       cursor.continue();
     };
   },
 
+  /**
+   * Add isReadReportSent for incoming MMS.
+   */
+  upgradeSchema16: function upgradeSchema16(transaction, next) {
+    let messageStore = transaction.objectStore(MESSAGE_STORE_NAME);
+
+    // Update type attributes.
+    messageStore.openCursor().onsuccess = function(event) {
+      let cursor = event.target.result;
+      if (!cursor) {
+        next();
+        return;
+      }
+
+      let messageRecord = cursor.value;
+      if (messageRecord.type == "mms") {
+        messageRecord.isReadReportSent = false;
+        cursor.update(messageRecord);
+      }
+      cursor.continue();
+    };
+  },
+
   matchParsedPhoneNumbers: function matchParsedPhoneNumbers(addr1, parsedAddr1,
                                                             addr2, parsedAddr2) {
     if ((parsedAddr1.internationalNumber &&
          parsedAddr1.internationalNumber === parsedAddr2.internationalNumber) ||
         (parsedAddr1.nationalNumber &&
          parsedAddr1.nationalNumber === parsedAddr2.nationalNumber)) {
       return true;
     }
@@ -1176,29 +1206,31 @@ MobileMessageDatabaseService.prototype =
             "content": partContent
           });
         }
       }
       let expiryDate = 0;
       if (headers["x-mms-expiry"] != undefined) {
         expiryDate = aMessageRecord.timestamp + headers["x-mms-expiry"] * 1000;
       }
+      let isReadReportRequested = headers["x-mms-read-report"] || false;
       return gMobileMessageService.createMmsMessage(aMessageRecord.id,
                                                     aMessageRecord.threadId,
                                                     aMessageRecord.iccId,
                                                     aMessageRecord.delivery,
                                                     aMessageRecord.deliveryInfo,
                                                     aMessageRecord.sender,
                                                     aMessageRecord.receivers,
                                                     aMessageRecord.timestamp,
                                                     aMessageRecord.read,
                                                     subject,
                                                     smil,
                                                     attachments,
-                                                    expiryDate);
+                                                    expiryDate,
+                                                    isReadReportRequested);
     }
   },
 
   findParticipantRecordByAddress: function findParticipantRecordByAddress(
       aParticipantStore, aAddress, aCreate, aCallback) {
     if (DEBUG) {
       debug("findParticipantRecordByAddress("
             + JSON.stringify(aAddress) + ", " + aCreate + ")");
@@ -1727,16 +1759,17 @@ MobileMessageDatabaseService.prototype =
 
     // Adding needed indexes and extra attributes for internal use.
     // threadIdIndex & participantIdsIndex are filled in saveRecord().
     aMessage.readIndex = [FILTER_READ_UNREAD, timestamp];
     aMessage.read = FILTER_READ_UNREAD;
 
     if (aMessage.type == "mms") {
       aMessage.transactionIdIndex = aMessage.transactionId;
+      aMessage.isReadReportSent = false;
     }
 
     if (aMessage.type == "sms") {
       aMessage.delivery = DELIVERY_RECEIVED;
       aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS;
 
       // If |deliveryTimestamp| is not specified, use 0 as default.
       if (aMessage.deliveryTimestamp == undefined) {
@@ -2054,54 +2087,72 @@ MobileMessageDatabaseService.prototype =
       let collector = cursor.collector;
       let collect = collector.collect.bind(collector);
       FilterSearcherHelper.transact(self, txn, error, filter, reverse, collect);
     }, [MESSAGE_STORE_NAME, PARTICIPANT_STORE_NAME]);
 
     return cursor;
   },
 
-  markMessageRead: function markMessageRead(messageId, value, aRequest) {
+  markMessageRead: function markMessageRead(messageId, value, aSendReadReport, aRequest) {
     if (DEBUG) debug("Setting message " + messageId + " read to " + value);
     this.newTxn(READ_WRITE, function (error, txn, stores) {
       if (error) {
         if (DEBUG) debug(error);
         aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
         return;
       }
+
       txn.onerror = function onerror(event) {
         if (DEBUG) debug("Caught error on transaction ", event.target.errorCode);
         aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
       };
+
       let messageStore = stores[0];
       let threadStore = stores[1];
       messageStore.get(messageId).onsuccess = function onsuccess(event) {
         let messageRecord = event.target.result;
         if (!messageRecord) {
           if (DEBUG) debug("Message ID " + messageId + " not found");
           aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR);
           return;
         }
+
         if (messageRecord.id != messageId) {
           if (DEBUG) {
             debug("Retrieve message ID (" + messageId + ") is " +
                   "different from the one we got");
           }
           aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.UNKNOWN_ERROR);
           return;
         }
+
         // If the value to be set is the same as the current message `read`
         // value, we just notify successfully.
         if (messageRecord.read == value) {
           if (DEBUG) debug("The value of messageRecord.read is already " + value);
           aRequest.notifyMessageMarkedRead(messageRecord.read);
           return;
         }
+
         messageRecord.read = value ? FILTER_READ_READ : FILTER_READ_UNREAD;
         messageRecord.readIndex = [messageRecord.read, messageRecord.timestamp];
+        let readReportMessageId, readReportTo;
+        if (aSendReadReport &&
+            messageRecord.type == "mms" &&
+            messageRecord.delivery == DELIVERY_RECEIVED &&
+            messageRecord.read == FILTER_READ_READ &&
+            !messageRecord.isReadReportSent) {
+          messageRecord.isReadReportSent = true;
+
+          let from = messageRecord.headers["from"];
+          readReportTo = from && from.address;
+          readReportMessageId = messageRecord.headers["message-id"];
+        }
+
         if (DEBUG) debug("Message.read set to: " + value);
         messageStore.put(messageRecord).onsuccess = function onsuccess(event) {
           if (DEBUG) {
             debug("Update successfully completed. Message: " +
                   JSON.stringify(event.target.result));
           }
 
           // Now update the unread count.
@@ -2113,16 +2164,21 @@ MobileMessageDatabaseService.prototype =
             if (DEBUG) {
               debug("Updating unreadCount for thread id " + threadId + ": " +
                     (value ?
                      threadRecord.unreadCount + 1 :
                      threadRecord.unreadCount - 1) +
                      " -> " + threadRecord.unreadCount);
             }
             threadStore.put(threadRecord).onsuccess = function(event) {
+              if(readReportMessageId && readReportTo) {
+                gMMSService.sendReadReport(readReportMessageId,
+                                           readReportTo,
+                                           messageRecord.iccId);
+              }
               aRequest.notifyMessageMarkedRead(messageRecord.read);
             };
           };
         };
       };
     }, [MESSAGE_STORE_NAME, THREAD_STORE_NAME]);
   },
 
--- a/dom/mobilemessage/src/ipc/PSms.ipdl
+++ b/dom/mobilemessage/src/ipc/PSms.ipdl
@@ -57,16 +57,17 @@ struct CreateMessageCursorRequest
   SmsFilterData filter;
   bool reverse;
 };
 
 struct MarkMessageReadRequest
 {
   int32_t messageId;
   bool value;
+  bool sendReadReport;
 };
 
 struct GetSegmentInfoForTextRequest
 {
   nsString text;
 };
 
 struct CreateThreadCursorRequest
--- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp
+++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp
@@ -238,19 +238,20 @@ SmsIPCService::CreateMessageCursor(nsIDO
 
   return SendCursorRequest(CreateMessageCursorRequest(data, aReverse),
                            aCursorCallback, aResult);
 }
 
 NS_IMETHODIMP
 SmsIPCService::MarkMessageRead(int32_t aMessageId,
                                bool aValue,
+                               bool aSendReadReport,
                                nsIMobileMessageCallback* aRequest)
 {
-  return SendRequest(MarkMessageReadRequest(aMessageId, aValue), aRequest);
+  return SendRequest(MarkMessageReadRequest(aMessageId, aValue, aSendReadReport), aRequest);
 }
 
 NS_IMETHODIMP
 SmsIPCService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCursorCallback,
                                   nsICursorContinueCallback** aResult)
 {
   return SendCursorRequest(CreateThreadCursorRequest(), aCursorCallback,
                            aResult);
@@ -328,8 +329,17 @@ SmsIPCService::Send(uint32_t aServiceId,
   return SendRequest(SendMessageRequest(req), aRequest);
 }
 
 NS_IMETHODIMP
 SmsIPCService::Retrieve(int32_t aId, nsIMobileMessageCallback *aRequest)
 {
   return SendRequest(RetrieveMessageRequest(aId), aRequest);
 }
+
+NS_IMETHODIMP
+SmsIPCService::SendReadReport(const nsAString & messageID,
+                              const nsAString & toAddress,
+                              const nsAString & iccId)
+{
+  NS_ERROR("We should not be here!");
+  return NS_OK;
+}
--- a/dom/mobilemessage/src/ipc/SmsParent.cpp
+++ b/dom/mobilemessage/src/ipc/SmsParent.cpp
@@ -537,17 +537,17 @@ bool
 SmsRequestParent::DoRequest(const MarkMessageReadRequest& aRequest)
 {
   nsresult rv = NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
     do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
   if (dbService) {
     rv = dbService->MarkMessageRead(aRequest.messageId(), aRequest.value(),
-                                    this);
+                                    aRequest.sendReadReport(), this);
   }
 
   if (NS_FAILED(rv)) {
     return NS_SUCCEEDED(NotifyMarkMessageReadFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
   }
 
   return true;
 }
--- a/dom/mobilemessage/src/ipc/SmsTypes.ipdlh
+++ b/dom/mobilemessage/src/ipc/SmsTypes.ipdlh
@@ -62,16 +62,17 @@ struct MmsMessageData
   nsString              sender;
   nsString[]            receivers;
   uint64_t              timestamp;
   bool                  read;
   nsString              subject;
   nsString              smil;
   MmsAttachmentData[]   attachments;
   uint64_t              expiryDate;
+  bool                  isReadReportRequested;
 };
 
 union MobileMessageData
 {
   MmsMessageData;
   SmsMessageData;
 };
 
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -519,17 +519,17 @@ nsJSObjWrapper::NP_Deallocate(NPObject *
 // static
 void
 nsJSObjWrapper::NP_Invalidate(NPObject *npobj)
 {
   nsJSObjWrapper *jsnpobj = (nsJSObjWrapper *)npobj;
 
   if (jsnpobj && jsnpobj->mJSObj) {
     // Unroot the object's JSObject
-    js_RemoveRoot(sJSRuntime, &jsnpobj->mJSObj);
+    JS_RemoveObjectRootRT(sJSRuntime, &jsnpobj->mJSObj);
 
     if (sJSObjWrappers.ops) {
       // Remove the wrapper from the hash
 
       nsJSObjWrapperKey key(jsnpobj->mJSObj, jsnpobj->mNpp);
       PL_DHashTableOperate(&sJSObjWrappers, &key, PL_DHASH_REMOVE);
     }
 
--- a/extensions/universalchardet/tests/CharsetDetectionTests.js
+++ b/extensions/universalchardet/tests/CharsetDetectionTests.js
@@ -40,27 +40,19 @@ function InitDetectorTests()
     } catch (e) {
         gOldPref = "";
     }
     SetDetectorPref(gDetectorList[0]);
     gTestIndex = 0;
     $("testframe").onload = DoDetectionTest;
 
     if (gExpectedCharset == "default") {
-        try {
-            gExpectedCharset = prefService
-                .getComplexValue("intl.charset.default",
-                                 Ci.nsIPrefLocalizedString)
-                .data;
-            if (gExpectedCharset == "ISO-8859-1") {
-                gExpectedCharset = "windows-1252";
-            }
-        } catch (e) {
-            gExpectedCharset = "windows-1252";
-        }
+        // No point trying to be generic here, because we have plenty of other
+        // unit tests that fail if run using a non-windows-1252 locale.
+        gExpectedCharset = "windows-1252";
     }
 
     // Get the local directory. This needs to be a file: URI because chrome:
     // URIs are always UTF-8 (bug 617339) and we are testing decoding from other
     // charsets.
     var jar = getJar(getRootDirectory(window.location.href));
     var dir = jar ?
                 extractJarToTmp(jar) :
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -380,20 +380,20 @@ frontend::CompileScript(ExclusiveContext
      * header) override any source map urls passed as comment pragmas.
      */
     if (options.sourceMapURL) {
         if (!ss->setSourceMapURL(cx, options.sourceMapURL))
             return nullptr;
     }
 
     /*
-     * Nowadays the threaded interpreter needs a stop instruction, so we
+     * Nowadays the threaded interpreter needs a last return instruction, so we
      * do have to emit that here.
      */
-    if (Emit1(cx, &bce, JSOP_STOP) < 0)
+    if (Emit1(cx, &bce, JSOP_RETRVAL) < 0)
         return nullptr;
 
     if (!JSScript::fullyInitFromEmitter(cx, script, &bce))
         return nullptr;
 
     bce.tellDebuggerAboutCompiledScript(cx);
 
     if (sct && !extraSct && !sct->complete())
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1135,27 +1135,16 @@ TryConvertFreeName(BytecodeEmitter *bce,
     }
 
     /*
      * When parsing inner functions lazily, parse nodes for outer functions no
      * longer exist and only the function's scope chain is available for
      * resolving upvar accesses within the inner function.
      */
     if (bce->emitterMode == BytecodeEmitter::LazyFunction) {
-        // The only statements within a lazy function which can push lexical
-        // scopes are try/catch blocks. Use generic ops in this case.
-        for (StmtInfoBCE *stmt = bce->topStmt; stmt; stmt = stmt->down) {
-            switch (stmt->type) {
-              case STMT_TRY:
-              case STMT_FINALLY:
-                return true;
-              default:;
-            }
-        }
-
         size_t hops = 0;
         FunctionBox *funbox = bce->sc->asFunctionBox();
         if (funbox->hasExtensibleScope())
             return false;
         if (funbox->function()->isNamedLambda() && funbox->function()->atom() == pn->pn_atom)
             return false;
         if (funbox->isHeavyweight()) {
             hops++;
@@ -2695,20 +2684,20 @@ frontend::EmitFunctionScript(ExclusiveCo
             return false;
 
         // No need to check for finally blocks, etc as in EmitReturn.
         if (Emit1(cx, bce, JSOP_RETURN) < 0)
             return false;
     }
 
     /*
-     * Always end the script with a JSOP_STOP. Some other parts of the codebase
+     * Always end the script with a JSOP_RETRVAL. Some other parts of the codebase
      * depend on this opcode, e.g. js_InternalInterpret.
      */
-    if (Emit1(cx, bce, JSOP_STOP) < 0)
+    if (Emit1(cx, bce, JSOP_RETRVAL) < 0)
         return false;
 
     if (!JSScript::fullyInitFromEmitter(cx, bce->script, bce))
         return false;
 
     /*
      * If this function is only expected to run once, mark the script so that
      * initializers created within it may be given more precise types.
@@ -3157,17 +3146,17 @@ enum GroupOption { GroupIsDecl, GroupIsN
  * we set *pop to JSOP_NOP so callers can veto emitting pn followed by a pop.
  */
 static bool
 MaybeEmitGroupAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn,
                          GroupOption groupOption, JSOp *pop)
 {
     JS_ASSERT(pn->isKind(PNK_ASSIGN));
     JS_ASSERT(pn->isOp(JSOP_NOP));
-    JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_POPV);
+    JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_SETRVAL);
 
     ParseNode *lhs = pn->pn_left;
     ParseNode *rhs = pn->pn_right;
     if (lhs->isKind(PNK_ARRAY) && rhs->isKind(PNK_ARRAY) &&
         !(rhs->pn_xflags & PNX_SPECIALARRAYINIT) &&
         lhs->pn_count <= rhs->pn_count)
     {
         if (groupOption == GroupIsDecl && !EmitDestructuringDecls(cx, bce, prologOp, lhs))
@@ -3189,17 +3178,17 @@ MaybeEmitGroupAssignment(ExclusiveContex
  * decompile so we restrict the ourselves to cases where the lhs and rhs are in
  * 1:1 correspondence and lhs elements are simple names.
  */
 static bool
 MaybeEmitLetGroupDecl(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp *pop)
 {
     JS_ASSERT(pn->isKind(PNK_ASSIGN));
     JS_ASSERT(pn->isOp(JSOP_NOP));
-    JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_POPV);
+    JS_ASSERT(*pop == JSOP_POP || *pop == JSOP_SETRVAL);
 
     ParseNode *lhs = pn->pn_left;
     ParseNode *rhs = pn->pn_right;
     if (lhs->isKind(PNK_ARRAY) && rhs->isKind(PNK_ARRAY) &&
         !(rhs->pn_xflags & PNX_SPECIALARRAYINIT) &&
         !(lhs->pn_xflags & PNX_SPECIALARRAYINIT) &&
         lhs->pn_count == rhs->pn_count)
     {
@@ -5304,17 +5293,17 @@ EmitStatement(ExclusiveContext *cx, Byte
 
     /*
      * Top-level or called-from-a-native JS_Execute/EvaluateScript,
      * debugger, and eval frames may need the value of the ultimate
      * expression statement as the script's result, despite the fact
      * that it appears useless to the compiler.
      *
      * API users may also set the JSOPTION_NO_SCRIPT_RVAL option when
-     * calling JS_Compile* to suppress JSOP_POPV.
+     * calling JS_Compile* to suppress JSOP_SETRVAL.
      */
     bool wantval = false;
     bool useful = false;
     if (bce->sc->isFunctionBox()) {
         JS_ASSERT(!bce->script->noScriptRval);
     } else {
         useful = wantval = !bce->script->noScriptRval;
     }
@@ -5334,17 +5323,17 @@ EmitStatement(ExclusiveContext *cx, Byte
             bce->topStmt->type == STMT_LABEL &&
             bce->topStmt->update >= bce->offset())
         {
             useful = true;
         }
     }
 
     if (useful) {
-        JSOp op = wantval ? JSOP_POPV : JSOP_POP;
+        JSOp op = wantval ? JSOP_SETRVAL : JSOP_POP;
         JS_ASSERT_IF(pn2->isKind(PNK_ASSIGN), pn2->isOp(JSOP_NOP));
 #if JS_HAS_DESTRUCTURING
         if (!wantval &&
             pn2->isKind(PNK_ASSIGN) &&
             !MaybeEmitGroupAssignment(cx, bce, op, pn2, GroupIsNotDecl, &op))
         {
             return false;
         }
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -265,57 +265,37 @@ HashTableWriteBarrierPost(JSRuntime *rt,
 #ifdef JSGC_GENERATIONAL
     if (key && IsInsideNursery(rt, key)) {
         JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
         shadowRuntime->gcStoreBufferPtr()->putGeneric(gc::HashKeyRef<Map, Key>(map, key));
     }
 #endif
 }
 
+/*
+ * Base class for barriered pointer types.
+ */
 template<class T, typename Unioned = uintptr_t>
-class EncapsulatedPtr
+class BarrieredPtr
 {
   protected:
     union {
         T *value;
         Unioned other;
     };
 
+    BarrieredPtr(T *v) : value(v) {}
+    ~BarrieredPtr() { pre(); }
+
   public:
-    EncapsulatedPtr() : value(nullptr) {}
-    EncapsulatedPtr(T *v) : value(v) {}
-    explicit EncapsulatedPtr(const EncapsulatedPtr<T> &v) : value(v.value) {}
-
-    ~EncapsulatedPtr() { pre(); }
-
     void init(T *v) {
         JS_ASSERT(!IsPoisonedPtr<T>(v));
         this->value = v;
     }
 
-    /* Use to set the pointer to nullptr. */
-    void clear() {
-        pre();
-        value = nullptr;
-    }
-
-    EncapsulatedPtr<T, Unioned> &operator=(T *v) {
-        pre();
-        JS_ASSERT(!IsPoisonedPtr<T>(v));
-        value = v;
-        return *this;
-    }
-
-    EncapsulatedPtr<T, Unioned> &operator=(const EncapsulatedPtr<T> &v) {
-        pre();
-        JS_ASSERT(!IsPoisonedPtr<T>(v.value));
-        value = v.value;
-        return *this;
-    }
-
     /* Use this if the automatic coercion to T* isn't working. */
     T *get() const { return value; }
 
     /*
      * Use these if you want to change the value without invoking the barrier.
      * Obviously this is dangerous unless you know the barrier is not needed.
      */
     T **unsafeGet() { return &value; }
@@ -327,29 +307,58 @@ class EncapsulatedPtr
     T *operator->() const { return value; }
 
     operator T*() const { return value; }
 
   protected:
     void pre() { T::writeBarrierPre(value); }
 };
 
+template<class T, typename Unioned = uintptr_t>
+class EncapsulatedPtr : public BarrieredPtr<T, Unioned>
+{
+  public:
+    EncapsulatedPtr() : BarrieredPtr<T, Unioned>(nullptr) {}
+    EncapsulatedPtr(T *v) : BarrieredPtr<T, Unioned>(v) {}
+    explicit EncapsulatedPtr(const EncapsulatedPtr<T, Unioned> &v)
+      : BarrieredPtr<T, Unioned>(v.value) {}
+
+    /* Use to set the pointer to nullptr. */
+    void clear() {
+        this->pre();
+        this->value = nullptr;
+    }
+
+    EncapsulatedPtr<T, Unioned> &operator=(T *v) {
+        this->pre();
+        JS_ASSERT(!IsPoisonedPtr<T>(v));
+        this->value = v;
+        return *this;
+    }
+
+    EncapsulatedPtr<T, Unioned> &operator=(const EncapsulatedPtr<T> &v) {
+        this->pre();
+        JS_ASSERT(!IsPoisonedPtr<T>(v.value));
+        this->value = v.value;
+        return *this;
+    }
+};
+
 /*
  * A pre- and post-barriered heap pointer, for use inside the JS engine.
  *
  * Not to be confused with JS::Heap<T>.
  */
 template <class T, class Unioned = uintptr_t>
-class HeapPtr : public EncapsulatedPtr<T, Unioned>
+class HeapPtr : public BarrieredPtr<T, Unioned>
 {
   public:
-    HeapPtr() : EncapsulatedPtr<T>(nullptr) {}
-    explicit HeapPtr(T *v) : EncapsulatedPtr<T>(v) { post(); }
-    explicit HeapPtr(const HeapPtr<T> &v)
-      : EncapsulatedPtr<T>(v) { post(); }
+    HeapPtr() : BarrieredPtr<T, Unioned>(nullptr) {}
+    explicit HeapPtr(T *v) : BarrieredPtr<T, Unioned>(v) { post(); }
+    explicit HeapPtr(const HeapPtr<T> &v) : BarrieredPtr<T, Unioned>(v) { post(); }
 
     void init(T *v) {
         JS_ASSERT(!IsPoisonedPtr<T>(v));
         this->value = v;
         post();
     }
 
     HeapPtr<T, Unioned> &operator=(T *v) {
@@ -405,25 +414,25 @@ class FixedHeapPtr
     }
 
     void init(T *ptr) {
         value = ptr;
     }
 };
 
 template <class T>
-class RelocatablePtr : public EncapsulatedPtr<T>
+class RelocatablePtr : public BarrieredPtr<T>
 {
   public:
-    RelocatablePtr() : EncapsulatedPtr<T>(nullptr) {}
-    explicit RelocatablePtr(T *v) : EncapsulatedPtr<T>(v) {
+    RelocatablePtr() : BarrieredPtr<T>(nullptr) {}
+    explicit RelocatablePtr(T *v) : BarrieredPtr<T>(v) {
         if (v)
             post();
     }
-    RelocatablePtr(const RelocatablePtr<T> &v) : EncapsulatedPtr<T>(v) {
+    RelocatablePtr(const RelocatablePtr<T> &v) : BarrieredPtr<T>(v) {
         if (this->value)
             post();
     }
 
     ~RelocatablePtr() {
         if (this->value)
             relocate(this->value->runtimeFromAnyThread());
     }
@@ -490,16 +499,19 @@ BarrieredSetPair(Zone *zone,
     v1.post();
     v2.post();
 }
 
 class Shape;
 class BaseShape;
 namespace types { struct TypeObject; }
 
+typedef BarrieredPtr<JSObject> BarrieredPtrObject;
+typedef BarrieredPtr<JSScript> BarrieredPtrScript;
+
 typedef EncapsulatedPtr<JSObject> EncapsulatedPtrObject;
 typedef EncapsulatedPtr<JSScript> EncapsulatedPtrScript;
 
 typedef RelocatablePtr<JSObject> RelocatablePtrObject;
 typedef RelocatablePtr<JSScript> RelocatablePtrScript;
 
 typedef HeapPtr<JSObject> HeapPtrObject;
 typedef HeapPtr<JSFunction> HeapPtrFunction;
@@ -535,64 +547,50 @@ struct EncapsulatedPtrHasher
     static HashNumber hash(Lookup obj) { return DefaultHasher<T *>::hash(obj); }
     static bool match(const Key &k, Lookup l) { return k.get() == l; }
     static void rekey(Key &k, const Key& newKey) { k.unsafeSet(newKey); }
 };
 
 template <class T>
 struct DefaultHasher< EncapsulatedPtr<T> > : EncapsulatedPtrHasher<T> { };
 
-class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
+/*
+ * Base class for barriered value types.
+ */
+class BarrieredValue : public ValueOperations<BarrieredValue>
 {
   protected:
     Value value;
 
     /*
      * Ensure that EncapsulatedValue is not constructable, except by our
      * implementations.
      */
-    EncapsulatedValue() MOZ_DELETE;
+    BarrieredValue() MOZ_DELETE;
 
-  public:
-    EncapsulatedValue(const Value &v) : value(v) {
-        JS_ASSERT(!IsPoisonedValue(v));
-    }
-    EncapsulatedValue(const EncapsulatedValue &v) : value(v) {
+    BarrieredValue(const Value &v) : value(v) {
         JS_ASSERT(!IsPoisonedValue(v));
     }
 
-    ~EncapsulatedValue() {
+    ~BarrieredValue() {
         pre();
     }
 
+  public:
     void init(const Value &v) {
         JS_ASSERT(!IsPoisonedValue(v));
         value = v;
     }
     void init(JSRuntime *rt, const Value &v) {
         JS_ASSERT(!IsPoisonedValue(v));
         value = v;
     }
 
-    EncapsulatedValue &operator=(const Value &v) {
-        pre();
-        JS_ASSERT(!IsPoisonedValue(v));
-        value = v;
-        return *this;
-    }
-
-    EncapsulatedValue &operator=(const EncapsulatedValue &v) {
-        pre();
-        JS_ASSERT(!IsPoisonedValue(v));
-        value = v.get();
-        return *this;
-    }
-
-    bool operator==(const EncapsulatedValue &v) const { return value == v.value; }
-    bool operator!=(const EncapsulatedValue &v) const { return value != v.value; }
+    bool operator==(const BarrieredValue &v) const { return value == v.value; }
+    bool operator!=(const BarrieredValue &v) const { return value != v.value; }
 
     const Value &get() const { return value; }
     Value *unsafeGet() { return &value; }
     operator const Value &() const { return value; }
 
     JSGCTraceKind gcKind() const { return value.gcKind(); }
 
     uint64_t asRawBits() const { return value.asRawBits(); }
@@ -631,43 +629,64 @@ class EncapsulatedValue : public ValueOp
     static JS::shadow::Runtime *shadowRuntimeFromMainThread(const Value &v) {
         return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromMainThread(v));
     }
     static JS::shadow::Runtime *shadowRuntimeFromAnyThread(const Value &v) {
         return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(v));
     }
 
   private:
-    friend class ValueOperations<EncapsulatedValue>;
+    friend class ValueOperations<BarrieredValue>;
     const Value * extract() const { return &value; }
 };
 
+class EncapsulatedValue : public BarrieredValue
+{
+  public:
+    EncapsulatedValue(const Value &v) : BarrieredValue(v) {}
+    EncapsulatedValue(const EncapsulatedValue &v) : BarrieredValue(v) {}
+
+    EncapsulatedValue &operator=(const Value &v) {
+        pre();
+        JS_ASSERT(!IsPoisonedValue(v));
+        value = v;
+        return *this;
+    }
+
+    EncapsulatedValue &operator=(const EncapsulatedValue &v) {
+        pre();
+        JS_ASSERT(!IsPoisonedValue(v));
+        value = v.get();
+        return *this;
+    }
+};
+
 /*
  * A pre- and post-barriered heap JS::Value, for use inside the JS engine.
  *
  * Not to be confused with JS::Heap<JS::Value>.
  */
-class HeapValue : public EncapsulatedValue
+class HeapValue : public BarrieredValue
 {
   public:
     explicit HeapValue()
-      : EncapsulatedValue(UndefinedValue())
+      : BarrieredValue(UndefinedValue())
     {
         post();
     }
 
     explicit HeapValue(const Value &v)
-      : EncapsulatedValue(v)
+      : BarrieredValue(v)
     {
         JS_ASSERT(!IsPoisonedValue(v));
         post();
     }
 
     explicit HeapValue(const HeapValue &v)
-      : EncapsulatedValue(v.value)
+      : BarrieredValue(v.value)
     {
         JS_ASSERT(!IsPoisonedValue(v.value));
         post();
     }
 
     ~HeapValue() {
         pre();
     }
@@ -740,33 +759,30 @@ class HeapValue : public EncapsulatedVal
         writeBarrierPost(value, &value);
     }
 
     void post(JSRuntime *rt) {
         writeBarrierPost(rt, value, &value);
     }
 };
 
-class RelocatableValue : public EncapsulatedValue
+class RelocatableValue : public BarrieredValue
 {
   public:
-    explicit RelocatableValue()
-      : EncapsulatedValue(UndefinedValue())
-    {}
+    explicit RelocatableValue() : BarrieredValue(UndefinedValue()) {}
 
     explicit RelocatableValue(const Value &v)
-      : EncapsulatedValue(v)
+      : BarrieredValue(v)
     {
-        JS_ASSERT(!IsPoisonedValue(v));
         if (v.isMarkable())
             post();
     }
 
     RelocatableValue(const RelocatableValue &v)
-      : EncapsulatedValue(v.value)
+      : BarrieredValue(v.value)
     {
         JS_ASSERT(!IsPoisonedValue(v.value));
         if (v.value.isMarkable())
             post();
     }
 
     ~RelocatableValue()
     {
@@ -817,43 +833,35 @@ class RelocatableValue : public Encapsul
     void relocate(JSRuntime *rt) {
 #ifdef JSGC_GENERATIONAL
         JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
         shadowRuntime->gcStoreBufferPtr()->removeRelocatableValue(&value);
 #endif
     }
 };
 
-class HeapSlot : public EncapsulatedValue
+class HeapSlot : public BarrieredValue
 {
-    /*
-     * Operator= is not valid for HeapSlot because is must take the object and
-     * slot offset to provide to the post/generational barrier.
-     */
-    inline HeapSlot &operator=(const Value &v) MOZ_DELETE;
-    inline HeapSlot &operator=(const HeapValue &v) MOZ_DELETE;
-    inline HeapSlot &operator=(const HeapSlot &v) MOZ_DELETE;
-
   public:
     enum Kind {
         Slot,
         Element
     };
 
     explicit HeapSlot() MOZ_DELETE;
 
     explicit HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
-      : EncapsulatedValue(v)
+      : BarrieredValue(v)
     {
         JS_ASSERT(!IsPoisonedValue(v));
         post(obj, kind, slot, v);
     }
 
     explicit HeapSlot(JSObject *obj, Kind kind, uint32_t slot, const HeapSlot &s)
-      : EncapsulatedValue(s.value)
+      : BarrieredValue(s.value)
     {
         JS_ASSERT(!IsPoisonedValue(s.value));
         post(obj, kind, slot, s);
     }
 
     ~HeapSlot() {
         pre();
     }
@@ -920,17 +928,17 @@ class HeapSlot : public EncapsulatedValu
     }
 
     void post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, Value target) {
         HeapSlot::writeBarrierPost(rt, owner, kind, slot, target);
     }
 };
 
 static inline const Value *
-Valueify(const EncapsulatedValue *array)
+Valueify(const BarrieredValue *array)
 {
     JS_STATIC_ASSERT(sizeof(HeapValue) == sizeof(Value));
     JS_STATIC_ASSERT(sizeof(HeapSlot) == sizeof(Value));
     return (const Value *)array;
 }
 
 static inline HeapValue *
 HeapValueify(Value *v)
@@ -949,37 +957,32 @@ class HeapSlotArray
 
     operator const Value *() const { return Valueify(array); }
     operator HeapSlot *() const { return array; }
 
     HeapSlotArray operator +(int offset) const { return HeapSlotArray(array + offset); }
     HeapSlotArray operator +(uint32_t offset) const { return HeapSlotArray(array + offset); }
 };
 
-class EncapsulatedId
+/*
+ * Base class for barriered jsid types.
+ */
+class BarrieredId
 {
   protected:
     jsid value;
 
   private:
-    EncapsulatedId(const EncapsulatedId &v) MOZ_DELETE;
+    BarrieredId(const BarrieredId &v) MOZ_DELETE;
+
+  protected:
+    explicit BarrieredId(jsid id) : value(id) {}
+    ~BarrieredId() { pre(); }
 
   public:
-    explicit EncapsulatedId() : value(JSID_VOID) {}
-    explicit EncapsulatedId(jsid id) : value(id) {}
-    ~EncapsulatedId() { pre(); }
-
-    EncapsulatedId &operator=(const EncapsulatedId &v) {
-        if (v.value != value)
-            pre();
-        JS_ASSERT(!IsPoisonedId(v.value));
-        value = v.value;
-        return *this;
-    }
-
     bool operator==(jsid id) const { return value == id; }
     bool operator!=(jsid id) const { return value != id; }
 
     jsid get() const { return value; }
     jsid *unsafeGet() { return &value; }
     void unsafeSet(jsid newId) { value = newId; }
     operator jsid() const { return value; }
 
@@ -1000,23 +1003,46 @@ class EncapsulatedId
                 js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &str, "write barrier");
                 JS_ASSERT(str == JSID_TO_STRING(value));
             }
         }
 #endif
     }
 };
 
-class RelocatableId : public EncapsulatedId
+class EncapsulatedId : public BarrieredId
 {
   public:
-    explicit RelocatableId() : EncapsulatedId() {}
-    explicit inline RelocatableId(jsid id) : EncapsulatedId(id) {}
+    explicit EncapsulatedId(jsid id) : BarrieredId(id) {}
+    explicit EncapsulatedId() : BarrieredId(JSID_VOID) {}
+
+    EncapsulatedId &operator=(const EncapsulatedId &v) {
+        if (v.value != value)
+            pre();
+        JS_ASSERT(!IsPoisonedId(v.value));
+        value = v.value;
+        return *this;
+    }
+};
+
+class RelocatableId : public BarrieredId
+{
+  public:
+    explicit RelocatableId() : BarrieredId(JSID_VOID) {}
+    explicit inline RelocatableId(jsid id) : BarrieredId(id) {}
     ~RelocatableId() { pre(); }
 
+    bool operator==(jsid id) const { return value == id; }
+    bool operator!=(jsid id) const { return value != id; }
+
+    jsid get() const { return value; }
+    operator jsid() const { return value; }
+
+    jsid *unsafeGet() { return &value; }
+
     RelocatableId &operator=(jsid id) {
         if (id != value)
             pre();
         JS_ASSERT(!IsPoisonedId(id));
         value = id;
         return *this;
     }
 
@@ -1029,23 +1055,23 @@ class RelocatableId : public Encapsulate
     }
 };
 
 /*
  * A pre- and post-barriered heap jsid, for use inside the JS engine.
  *
  * Not to be confused with JS::Heap<jsid>.
  */
-class HeapId : public EncapsulatedId
+class HeapId : public BarrieredId
 {
   public:
-    explicit HeapId() : EncapsulatedId() {}
+    explicit HeapId() : BarrieredId(JSID_VOID) {}
 
     explicit HeapId(jsid id)
-      : EncapsulatedId(id)
+      : BarrieredId(id)
     {
         JS_ASSERT(!IsPoisonedId(id));
         post();
     }
 
     ~HeapId() { pre(); }
 
     void init(jsid id) {
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -214,17 +214,17 @@ void
 MarkUnbarriered(JSTracer *trc, T **thingp, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkInternal(trc, thingp);
 }
 
 template <typename T>
 static void
-Mark(JSTracer *trc, EncapsulatedPtr<T> *thing, const char *name)
+Mark(JSTracer *trc, BarrieredPtr<T> *thing, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkInternal(trc, thing->unsafeGet());
 }
 
 } /* namespace gc */
 } /* namespace js */
 
@@ -306,17 +306,17 @@ IsAboutToBeFinalized(T **thingp)
      */
     JS_ASSERT(!(*thingp)->arenaHeader()->allocatedDuringIncremental);
 
     return !(*thingp)->isMarked();
 }
 
 #define DeclMarkerImpl(base, type)                                                                \
 void                                                                                              \
-Mark##base(JSTracer *trc, EncapsulatedPtr<type> *thing, const char *name)                         \
+Mark##base(JSTracer *trc, BarrieredPtr<type> *thing, const char *name)                         \
 {                                                                                                 \
     Mark<type>(trc, thing, name);                                                                 \
 }                                                                                                 \
                                                                                                   \
 void                                                                                              \
 Mark##base##Root(JSTracer *trc, type **thingp, const char *name)                                  \
 {                                                                                                 \
     MarkRoot<type>(trc, thingp, name);                                                            \
@@ -347,29 +347,29 @@ Mark##base##RootRange(JSTracer *trc, siz
                                                                                                   \
 bool                                                                                              \
 Is##base##Marked(type **thingp)                                                                   \
 {                                                                                                 \
     return IsMarked<type>(thingp);                                                                \
 }                                                                                                 \
                                                                                                   \
 bool                                                                                              \
-Is##base##Marked(EncapsulatedPtr<type> *thingp)                                                   \
+Is##base##Marked(BarrieredPtr<type> *thingp)                                                   \
 {                                                                                                 \
     return IsMarked<type>(thingp->unsafeGet());                                                   \
 }                                                                                                 \
                                                                                                   \
 bool                                                                                              \
 Is##base##AboutToBeFinalized(type **thingp)                                                       \
 {                                                                                                 \
     return IsAboutToBeFinalized<type>(thingp);                                                    \
 }                                                                                                 \
                                                                                                   \
 bool                                                                                              \
-Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp)                                       \
+Is##base##AboutToBeFinalized(BarrieredPtr<type> *thingp)                                       \
 {                                                                                                 \
     return IsAboutToBeFinalized<type>(thingp->unsafeGet());                                       \
 }
 
 DeclMarkerImpl(BaseShape, BaseShape)
 DeclMarkerImpl(BaseShape, UnownedBaseShape)
 DeclMarkerImpl(IonCode, jit::IonCode)
 DeclMarkerImpl(Object, ArgumentsObject)
@@ -471,17 +471,17 @@ MarkIdInternal(JSTracer *trc, jsid *id)
         *id = OBJECT_TO_JSID(obj);
     } else {
         /* Unset realLocation manually if we do not call MarkInternal. */
         JS_UNSET_TRACING_LOCATION(trc);
     }
 }
 
 void
-gc::MarkId(JSTracer *trc, EncapsulatedId *id, const char *name)
+gc::MarkId(JSTracer *trc, BarrieredId *id, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkIdInternal(trc, id->unsafeGet());
 }
 
 void
 gc::MarkIdRoot(JSTracer *trc, jsid *id, const char *name)
 {
@@ -532,17 +532,17 @@ MarkValueInternal(JSTracer *trc, Value *
             v->setObjectOrNull((JSObject *)thing);
     } else {
         /* Unset realLocation manually if we do not call MarkInternal. */
         JS_UNSET_TRACING_LOCATION(trc);
     }
 }
 
 void
-gc::MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name)
+gc::MarkValue(JSTracer *trc, BarrieredValue *v, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkValueInternal(trc, v->unsafeGet());
 }
 
 void
 gc::MarkValueRoot(JSTracer *trc, Value *v, const char *name)
 {
@@ -563,17 +563,17 @@ gc::MarkTypeRoot(JSTracer *trc, types::T
     } else if (v->isTypeObject()) {
         types::TypeObject *typeObj = v->typeObject();
         MarkInternal(trc, &typeObj);
         *v = types::Type::ObjectType(typeObj);
     }
 }
 
 void
-gc::MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name)
+gc::MarkValueRange(JSTracer *trc, size_t len, BarrieredValue *vec, const char *name)
 {
     for (size_t i = 0; i < len; ++i) {
         JS_SET_TRACING_INDEX(trc, name, i);
         MarkValueInternal(trc, vec[i].unsafeGet());
     }
 }
 
 void
@@ -872,17 +872,17 @@ PushMarkStack(GCMarker *gcmarker, BaseSh
 }
 
 static void
 ScanShape(GCMarker *gcmarker, Shape *shape)
 {
   restart:
     PushMarkStack(gcmarker, shape->base());
 
-    const EncapsulatedId &id = shape->propidRef();
+    const BarrieredId &id = shape->propidRef();
     if (JSID_IS_STRING(id))
         PushMarkStack(gcmarker, JSID_TO_STRING(id));
     else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
         PushMarkStack(gcmarker, JSID_TO_OBJECT(id));
 
     shape = shape->previous();
     if (shape && shape->markIfUnmarked(gcmarker->getMarkColor()))
         goto restart;
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -76,25 +76,25 @@ namespace gc {
  *     object not in the group of compartments currently being swept, as even if
  *     it is unmarked it may still become marked before it is swept.
  *
  * IsObjectMarked(JSObject **thing);
  *     This function is indended to be used in rare cases in code used to mark
  *     GC things.  It indicates whether the object is currently marked.
  */
 #define DeclMarker(base, type)                                                                    \
-void Mark##base(JSTracer *trc, EncapsulatedPtr<type> *thing, const char *name);                   \
+void Mark##base(JSTracer *trc, BarrieredPtr<type> *thing, const char *name);                   \
 void Mark##base##Root(JSTracer *trc, type **thingp, const char *name);                            \
 void Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name);                     \
 void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *thing, const char *name);        \
 void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name);            \
 bool Is##base##Marked(type **thingp);                                                             \
-bool Is##base##Marked(EncapsulatedPtr<type> *thingp);                                             \
+bool Is##base##Marked(BarrieredPtr<type> *thingp);                                             \
 bool Is##base##AboutToBeFinalized(type **thingp);                                                 \
-bool Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp);
+bool Is##base##AboutToBeFinalized(BarrieredPtr<type> *thingp);                                 \
 
 DeclMarker(BaseShape, BaseShape)
 DeclMarker(BaseShape, UnownedBaseShape)
 DeclMarker(IonCode, jit::IonCode)
 DeclMarker(Object, ArgumentsObject)
 DeclMarker(Object, ArrayBufferObject)
 DeclMarker(Object, ArrayBufferViewObject)
 DeclMarker(Object, DebugScopeObject)
@@ -137,37 +137,37 @@ void
 MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name);
 
 void
 MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name);
 
 /*** ID Marking ***/
 
 void
-MarkId(JSTracer *trc, EncapsulatedId *id, const char *name);
+MarkId(JSTracer *trc, BarrieredId *id, const char *name);
 
 void
 MarkIdRoot(JSTracer *trc, jsid *id, const char *name);
 
 void
 MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name);
 
 void
 MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name);
 
 void
 MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
 
 /*** Value Marking ***/
 
 void
-MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name);
+MarkValue(JSTracer *trc, BarrieredValue *v, const char *name);
 
 void
-MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name);
+MarkValueRange(JSTracer *trc, size_t len, BarrieredValue *vec, const char *name);
 
 inline void
 MarkValueRange(JSTracer *trc, HeapValue *begin, HeapValue *end, const char *name)
 {
     return MarkValueRange(trc, end - begin, begin, name);
 }
 
 void
@@ -254,29 +254,29 @@ PushArena(GCMarker *gcmarker, ArenaHeade
 /*** Generic ***/
 
 /*
  * The Mark() functions interface should only be used by code that must be
  * templated.  Other uses should use the more specific, type-named functions.
  */
 
 inline void
-Mark(JSTracer *trc, EncapsulatedValue *v, const char *name)
+Mark(JSTracer *trc, BarrieredValue *v, const char *name)
 {
     MarkValue(trc, v, name);
 }
 
 inline void
-Mark(JSTracer *trc, EncapsulatedPtrObject *o, const char *name)
+Mark(JSTracer *trc, BarrieredPtrObject *o, const char *name)
 {
     MarkObject(trc, o, name);
 }
 
 inline void
-Mark(JSTracer *trc, EncapsulatedPtrScript *o, const char *name)
+Mark(JSTracer *trc, BarrieredPtrScript *o, const char *name)
 {
     MarkScript(trc, o, name);
 }
 
 inline void
 Mark(JSTracer *trc, HeapPtr<jit::IonCode> *code, const char *name)
 {
     MarkIonCode(trc, code, name);
@@ -298,51 +298,51 @@ Mark(JSTracer *trc, ScopeObject **obj, c
 
 bool
 IsCellMarked(Cell **thingp);
 
 bool
 IsCellAboutToBeFinalized(Cell **thing);
 
 inline bool
-IsMarked(EncapsulatedValue *v)
+IsMarked(BarrieredValue *v)
 {
     if (!v->isMarkable())
         return true;
     return IsValueMarked(v->unsafeGet());
 }
 
 inline bool
-IsMarked(EncapsulatedPtrObject *objp)
+IsMarked(BarrieredPtrObject *objp)
 {
     return IsObjectMarked(objp);
 }
 
 inline bool
-IsMarked(EncapsulatedPtrScript *scriptp)
+IsMarked(BarrieredPtrScript *scriptp)
 {
     return IsScriptMarked(scriptp);
 }
 
 inline bool
-IsAboutToBeFinalized(EncapsulatedValue *v)
+IsAboutToBeFinalized(BarrieredValue *v)
 {
     if (!v->isMarkable())
         return false;
     return IsValueAboutToBeFinalized(v->unsafeGet());
 }
 
 inline bool
-IsAboutToBeFinalized(EncapsulatedPtrObject *objp)
+IsAboutToBeFinalized(BarrieredPtrObject *objp)
 {
     return IsObjectAboutToBeFinalized(objp);
 }
 
 inline bool
-IsAboutToBeFinalized(EncapsulatedPtrScript *scriptp)
+IsAboutToBeFinalized(BarrieredPtrScript *scriptp)
 {
     return IsScriptAboutToBeFinalized(scriptp);
 }
 
 #ifdef JS_ION
 /* Nonsense to get WeakCache to work with new Marking semantics. */
 
 inline bool
--- a/js/src/jit-test/jit_test.py
+++ b/js/src/jit-test/jit_test.py
@@ -191,17 +191,16 @@ def main(argv):
                 job_list.append(new_test)
 
     prefix = [os.path.abspath(args[0])] + shlex.split(options.shell_args)
     prolog = os.path.join(jittests.LIB_DIR, 'prolog.js')
     if options.remote:
         prolog = posixpath.join(options.remote_test_root, 'jit-tests', 'jit-tests', 'lib', 'prolog.js')
 
     prefix += ['-f', prolog]
-    prefix += ['--js-cache', jittests.JS_CACHE_DIR]
 
     # Avoid racing on the cache by having the js shell create a new cache
     # subdir for each process. The js shell takes care of deleting these
     # subdirs when the process exits.
     if options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING:
         prefix += ['--js-cache-per-process']
 
     # Clean up any remnants from previous crashes etc
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -363,24 +363,27 @@ BacktrackingAllocator::groupAndQueueRegi
 
         BacktrackingVirtualRegister &reg = vregs[i];
         JS_ASSERT(reg.numIntervals() <= 2);
         JS_ASSERT(!reg.canonicalSpill());
 
         if (!reg.numIntervals())
             continue;
 
+        // Disable this for now; see bugs 906858, 931487, and 932465.
+#if 0
         // Eagerly set the canonical spill slot for registers which are preset
         // for that slot, and reuse it for other registers in the group.
         LDefinition *def = reg.def();
         if (def->policy() == LDefinition::PRESET && !def->output()->isRegister()) {
             reg.setCanonicalSpill(*def->output());
             if (reg.group() && reg.group()->spill.isUse())
                 reg.group()->spill = *def->output();
         }
+#endif
 
         // Place all intervals for this register on the allocation queue.
         // During initial queueing use single queue items for groups of
         // registers, so that they will be allocated together and reduce the
         // risk of unnecessary conflicts. This is in keeping with the idea that
         // register groups are effectively single registers whose value changes
         // during execution. If any intervals in the group are evicted later
         // then they will be reallocated individually.
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -723,30 +723,34 @@ BaselineCompiler::emitSPSPop()
 
 MethodStatus
 BaselineCompiler::emitBody()
 {
     JS_ASSERT(pc == script->code);
 
     bool lastOpUnreachable = false;
     uint32_t emittedOps = 0;
+    mozilla::DebugOnly<jsbytecode *> prevpc = pc;
 
     while (true) {
         JSOp op = JSOp(*pc);
         IonSpew(IonSpew_BaselineOp, "Compiling op @ %d: %s",
                 int(pc - script->code), js_CodeName[op]);
 
         BytecodeInfo *info = analysis_.maybeInfo(pc);
 
         // Skip unreachable ops.
         if (!info) {
-            if (op == JSOP_STOP)
+            // Test if last instructions and stop emitting in that case.
+            pc += GetBytecodeLength(pc);
+            if (pc >= script->code + script->length)
                 break;
-            pc += GetBytecodeLength(pc);
+
             lastOpUnreachable = true;
+            prevpc = pc;
             continue;
         }
 
         // Fully sync the stack if there are incoming jumps.
         if (info->jumpTarget) {
             frame.syncStack(0);
             frame.setStackDepth(info->stackDepth);
         }
@@ -786,25 +790,29 @@ BaselineCompiler::emitBody()
           case OP:                             \
             if (!this->emit_##OP())            \
                 return Method_Error;           \
             break;
 OPCODE_LIST(EMIT_OP)
 #undef EMIT_OP
         }
 
-        if (op == JSOP_STOP)
+        // Test if last instructions and stop emitting in that case.
+        pc += GetBytecodeLength(pc);
+        if (pc >= script->code + script->length)
             break;
 
-        pc += GetBytecodeLength(pc);
         emittedOps++;
         lastOpUnreachable = false;
+#ifdef DEBUG
+        prevpc = pc;
+#endif
     }
 
-    JS_ASSERT(JSOp(*pc) == JSOP_STOP);
+    JS_ASSERT(JSOp(*prevpc) == JSOP_RETRVAL);
     return Method_Compiled;
 }
 
 bool
 BaselineCompiler::emit_JSOP_NOP()
 {
     return true;
 }
@@ -2687,36 +2695,36 @@ BaselineCompiler::emitReturn()
         pushArg(Imm32(1));
         pushArg(R0.scratchReg());
         if (!callVM(DebugEpilogueInfo))
             return false;
 
         masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
     }
 
-    if (JSOp(*pc) != JSOP_STOP) {
-        // JSOP_STOP is immediately followed by the return label, so we don't
-        // need a jump.
+    // Only emit the jump if this JSOP_RETRVAL is not the last instruction.
+    // Not needed for last instruction, because last instruction flows
+    // into return label.
+    if (pc + GetBytecodeLength(pc) < script->code + script->length)
         masm.jump(&return_);
-    }
 
     return true;
 }
 
 bool
 BaselineCompiler::emit_JSOP_RETURN()
 {
     JS_ASSERT(frame.stackDepth() == 1);
 
     frame.popValue(JSReturnOperand);
     return emitReturn();
 }
 
 bool
-BaselineCompiler::emit_JSOP_STOP()
+BaselineCompiler::emit_JSOP_RETRVAL()
 {
     JS_ASSERT(frame.stackDepth() == 0);
 
     masm.moveValue(UndefinedValue(), JSReturnOperand);
 
     if (!script->noScriptRval) {
         // Return the value in the return value slot, if any.
         Label done;
@@ -2724,22 +2732,16 @@ BaselineCompiler::emit_JSOP_STOP()
         masm.branchTest32(Assembler::Zero, flags, Imm32(BaselineFrame::HAS_RVAL), &done);
         masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
         masm.bind(&done);
     }
 
     return emitReturn();
 }
 
-bool
-BaselineCompiler::emit_JSOP_RETRVAL()
-{
-    return emit_JSOP_STOP();
-}
-
 typedef bool (*ToIdFn)(JSContext *, HandleScript, jsbytecode *, HandleValue, HandleValue,
                        MutableHandleValue);
 static const VMFunction ToIdInfo = FunctionInfo<ToIdFn>(js::ToIdOperation);
 
 bool
 BaselineCompiler::emit_JSOP_TOID()
 {
     // Load index in R0, but keep values on the stack for the decompiler.
@@ -2844,22 +2846,16 @@ BaselineCompiler::emit_JSOP_CALLEE()
     JS_ASSERT(function());
     frame.syncStack(0);
     masm.loadPtr(frame.addressOfCallee(), R0.scratchReg());
     masm.tagValue(JSVAL_TYPE_OBJECT, R0.scratchReg(), R0);
     frame.push(R0);
     return true;
 }
 
-bool
-BaselineCompiler::emit_JSOP_POPV()
-{
-    return emit_JSOP_SETRVAL();
-}
-
 typedef bool (*NewArgumentsObjectFn)(JSContext *, BaselineFrame *, MutableHandleValue);
 static const VMFunction NewArgumentsObjectInfo =
     FunctionInfo<NewArgumentsObjectFn>(jit::NewArgumentsObject);
 
 bool
 BaselineCompiler::emit_JSOP_ARGUMENTS()
 {
     frame.syncStack(0);
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -159,21 +159,19 @@ namespace jit {
     _(JSOP_REST)               \
     _(JSOP_TOID)               \
     _(JSOP_TABLESWITCH)        \
     _(JSOP_ITER)               \
     _(JSOP_MOREITER)           \
     _(JSOP_ITERNEXT)           \
     _(JSOP_ENDITER)            \
     _(JSOP_CALLEE)             \
-    _(JSOP_POPV)               \
     _(JSOP_SETRVAL)            \
-    _(JSOP_RETURN)             \
-    _(JSOP_STOP)               \
-    _(JSOP_RETRVAL)
+    _(JSOP_RETRVAL)            \
+    _(JSOP_RETURN)
 
 class BaselineCompiler : public BaselineCompilerSpecific
 {
     FixedList<Label>            labels_;
     NonAssertingLabel           return_;
 #ifdef JSGC_GENERATIONAL
     NonAssertingLabel           postBarrierSlot_;
 #endif
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1217,17 +1217,16 @@ IonBuilder::traverseBytecode()
               case JSOP_POPN:
               case JSOP_DUP:
               case JSOP_DUP2:
               case JSOP_PICK:
               case JSOP_SWAP:
               case JSOP_SETARG:
               case JSOP_SETLOCAL:
               case JSOP_SETRVAL:
-              case JSOP_POPV:
               case JSOP_VOID:
                 // Don't require SSA uses for values popped by these ops.
                 break;
 
               case JSOP_POS:
               case JSOP_TOID:
                 // These ops may leave their input on the stack without setting
                 // the Folded flag. If this value will be popped immediately,
@@ -1266,17 +1265,16 @@ IonBuilder::snoopControlFlow(JSOp op)
     switch (op) {
       case JSOP_NOP:
         return maybeLoop(op, info().getNote(gsn, pc));
 
       case JSOP_POP:
         return maybeLoop(op, info().getNote(gsn, pc));
 
       case JSOP_RETURN:
-      case JSOP_STOP:
       case JSOP_RETRVAL:
         return processReturn(op);
 
       case JSOP_THROW:
         return processThrow();
 
       case JSOP_GOTO:
       {
@@ -1673,17 +1671,16 @@ IonBuilder::inspectOpcode(JSOp op)
 
       case JSOP_ENDITER:
         return jsop_iterend();
 
       case JSOP_IN:
         return jsop_in();
 
       case JSOP_SETRVAL:
-      case JSOP_POPV:
         JS_ASSERT(!script()->noScriptRval);
         current->setSlot(info().returnValueSlot(), current->pop());
         return true;
 
       case JSOP_INSTANCEOF:
         return jsop_instanceof();
 
       default:
@@ -3473,28 +3470,25 @@ IonBuilder::processReturn(JSOp op)
 {
     MDefinition *def;
     switch (op) {
       case JSOP_RETURN:
         // Return the last instruction.
         def = current->pop();
         break;
 
-      case JSOP_STOP:
+      case JSOP_RETRVAL:
         // Return undefined eagerly if script doesn't use return value.
         if (script()->noScriptRval) {
             MInstruction *ins = MConstant::New(UndefinedValue());
             current->add(ins);
             def = ins;
             break;
         }
 
-        // Fall through
-      case JSOP_RETRVAL:
-        // Return the value in the return value slot.
         def = current->getSlot(info().returnValueSlot());
         break;
 
       default:
         def = nullptr;
         MOZ_ASSUME_UNREACHABLE("unknown return op");
     }
 
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -222,17 +222,17 @@ ScriptAnalysis::analyzeBytecode(JSContex
 
         JS_ASSERT(stackDepth >= nuses);
         stackDepth -= nuses;
         stackDepth += ndefs;
 
         switch (op) {
 
           case JSOP_RETURN:
-          case JSOP_STOP:
+          case JSOP_RETRVAL:
             numReturnSites_++;
             break;
 
           case JSOP_NAME:
           case JSOP_CALLNAME:
           case JSOP_BINDNAME:
           case JSOP_SETNAME:
           case JSOP_DELNAME:
@@ -1216,17 +1216,16 @@ ScriptAnalysis::analyzeSSA(JSContext *cx
                     }
                 }
             }
             break;
           }
 
           case JSOP_THROW:
           case JSOP_RETURN:
-          case JSOP_STOP:
           case JSOP_RETRVAL:
             mergeAllExceptionTargets(cx, values, exceptionTargets);
             break;
 
           default:;
         }
 
         if (IsJumpOpcode(op)) {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1649,62 +1649,62 @@ JS_AddNamedScriptRoot(JSContext *cx, JSS
 }
 
 /* We allow unrooting from finalizers within the GC */
 
 JS_PUBLIC_API(void)
 JS_RemoveValueRoot(JSContext *cx, jsval *vp)
 {
     CHECK_REQUEST(cx);
-    js_RemoveRoot(cx->runtime(), (void *)vp);
+    RemoveRoot(cx->runtime(), (void *)vp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveStringRoot(JSContext *cx, JSString **rp)
 {
     CHECK_REQUEST(cx);
-    js_RemoveRoot(cx->runtime(), (void *)rp);
+    RemoveRoot(cx->runtime(), (void *)rp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveObjectRoot(JSContext *cx, JSObject **rp)
 {
     CHECK_REQUEST(cx);
-    js_RemoveRoot(cx->runtime(), (void *)rp);
+    RemoveRoot(cx->runtime(), (void *)rp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveScriptRoot(JSContext *cx, JSScript **rp)
 {
     CHECK_REQUEST(cx);
-    js_RemoveRoot(cx->runtime(), (void *)rp);
+    RemoveRoot(cx->runtime(), (void *)rp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveValueRootRT(JSRuntime *rt, jsval *vp)
 {
-    js_RemoveRoot(rt, (void *)vp);
+    RemoveRoot(rt, (void *)vp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveStringRootRT(JSRuntime *rt, JSString **rp)
 {
-    js_RemoveRoot(rt, (void *)rp);
+    RemoveRoot(rt, (void *)rp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveObjectRootRT(JSRuntime *rt, JSObject **rp)
 {
-    js_RemoveRoot(rt, (void *)rp);
+    RemoveRoot(rt, (void *)rp);
 }
 
 JS_PUBLIC_API(void)
 JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp)
 {
-    js_RemoveRoot(rt, (void *)rp);
+    RemoveRoot(rt, (void *)rp);
 }
 
 JS_NEVER_INLINE JS_PUBLIC_API(void)
 JS_AnchorPtr(void *p)
 {
 }
 
 JS_PUBLIC_API(bool)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1975,21 +1975,16 @@ extern JS_PUBLIC_API(void)
 JS_RemoveStringRootRT(JSRuntime *rt, JSString **rp);
 
 extern JS_PUBLIC_API(void)
 JS_RemoveObjectRootRT(JSRuntime *rt, JSObject **rp);
 
 extern JS_PUBLIC_API(void)
 JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp);
 
-/* TODO: remove these APIs */
-
-extern JS_FRIEND_API(void)
-js_RemoveRoot(JSRuntime *rt, void *rp);
-
 /*
  * C-compatible version of the Anchor class. It should be called after the last
  * use of the variable it protects.
  */
 extern JS_NEVER_INLINE JS_PUBLIC_API(void)
 JS_AnchorPtr(void *p);
 
 /*
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -1195,17 +1195,17 @@ array_join(JSContext *cx, unsigned argc,
 }
 
 static inline bool
 InitArrayTypes(JSContext *cx, TypeObject *type, const Value *vector, unsigned count)
 {
     if (cx->typeInferenceEnabled() && !type->unknownProperties()) {
         AutoEnterAnalysis enter(cx);
 
-        TypeSet *types = type->getProperty(cx, JSID_VOID);
+        HeapTypeSet *types = type->getProperty(cx, JSID_VOID);
         if (!types)
             return false;
 
         for (unsigned i = 0; i < count; i++) {
             if (vector[i].isMagic(JS_ELEMENTS_HOLE))
                 continue;
             Type valtype = GetValueType(vector[i]);
             types->addType(cx, valtype);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1099,21 +1099,21 @@ extern JS_FRIEND_API(bool)
 js_AddObjectRoot(JSRuntime *rt, JSObject **objp)
 {
     return AddRoot(rt, objp, nullptr, JS_GC_ROOT_OBJECT_PTR);
 }
 
 extern JS_FRIEND_API(void)
 js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp)
 {
-    js_RemoveRoot(rt, objp);
-}
-
-JS_FRIEND_API(void)
-js_RemoveRoot(JSRuntime *rt, void *rp)
+    RemoveRoot(rt, objp);
+}
+
+void
+js::RemoveRoot(JSRuntime *rt, void *rp)
 {
     rt->gcRootsHash.remove(rp);
     rt->gcPoke = true;
 }
 
 typedef RootedValueMap::Range RootRange;
 typedef RootedValueMap::Entry RootEntry;
 typedef RootedValueMap::Enum RootEnum;
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -663,16 +663,19 @@ extern bool
 AddObjectRoot(JSContext *cx, JSObject **rp, const char *name);
 
 extern bool
 AddObjectRoot(JSRuntime *rt, JSObject **rp, const char *name);
 
 extern bool
 AddScriptRoot(JSContext *cx, JSScript **rp, const char *name);
 
+extern void
+RemoveRoot(JSRuntime *rt, void *rp);
+
 } /* namespace js */
 
 extern bool
 js_InitGC(JSRuntime *rt, uint32_t maxbytes);
 
 extern void
 js_FinishGC(JSRuntime *rt);
 
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -392,20 +392,18 @@ TypeSet::addTypesToConstraint(JSContext 
     if (!enumerateTypes(&types))
         cx->compartment()->types.setPendingNukeTypes(cx);
 
     for (unsigned i = 0; i < types.length(); i++)
         constraint->newType(cx, this, types[i]);
 }
 
 void
-TypeSet::add(JSContext *cx, TypeConstraint *constraint, bool callExisting)
+ConstraintTypeSet::add(JSContext *cx, TypeConstraint *constraint, bool callExisting)
 {
-    JS_ASSERT(isStackSet() || isHeapSet());
-
     if (!constraint) {
         /* OOM failure while constructing the constraint. */
         cx->compartment()->types.setPendingNukeTypes(cx);
         return;
     }
 
     JS_ASSERT(cx->compartment()->activeAnalysis);
 
@@ -480,19 +478,17 @@ TypeSet::clone(LifoAlloc *alloc, Tempora
     TypeObjectKey **newSet;
     if (capacity) {
         newSet = alloc->newArray<TypeObjectKey*>(capacity);
         if (!newSet)
             return false;
         PodCopy(newSet, objectSet, capacity);
     }
 
-    uint32_t newFlags = flags & ~(TYPE_FLAG_STACK_SET | TYPE_FLAG_HEAP_SET);
-
-    new(result) TemporaryTypeSet(newFlags, capacity ? newSet : objectSet);
+    new(result) TemporaryTypeSet(flags, capacity ? newSet : objectSet);
     return true;
 }
 
 TemporaryTypeSet *
 TypeSet::clone(LifoAlloc *alloc) const
 {
     TemporaryTypeSet *res = alloc->new_<TemporaryTypeSet>();
     if (!res || !clone(alloc, res))
@@ -1347,17 +1343,17 @@ TypeObjectKey::watchStateChangeForTypedA
 
 static void
 ObjectStateChange(ExclusiveContext *cxArg, TypeObject *object, bool markingUnknown)
 {
     if (object->unknownProperties())
         return;
 
     /* All constraints listening to state changes are on the empty id. */
-    TypeSet *types = object->maybeGetProperty(JSID_EMPTY);
+    HeapTypeSet *types = object->maybeGetProperty(JSID_EMPTY);
 
     /* Mark as unknown after getting the types, to avoid assertion. */
     if (markingUnknown)
         object->flags |= OBJECT_FLAG_DYNAMIC_MASK | OBJECT_FLAG_UNKNOWN_PROPERTIES;
 
     if (types) {
         if (JSContext *cx = cxArg->maybeJSContext()) {
             TypeConstraint *constraint = types->constraintList;
@@ -2167,17 +2163,17 @@ TypeCompartment::markSetsUnknown(JSConte
      * a generic object type. It is not sufficient to mark just the persistent
      * sets, as analysis of individual opcodes can pull type objects from
      * static information (like initializer objects at various offsets).
      *
      * We make a list of properties to update and fix them afterwards, as adding
      * types can't be done while iterating over cells as it can potentially make
      * new type objects as well or trigger GC.
      */
-    Vector<TypeSet *> pending(cx);
+    Vector<ConstraintTypeSet *> pending(cx);
     for (gc::CellIter i(cx->zone(), gc::FINALIZE_TYPE_OBJECT); !i.done(); i.next()) {
         TypeObject *object = i.get<TypeObject>();
         unsigned count = object->getPropertyCount();
         for (unsigned i = 0; i < count; i++) {
             Property *prop = object->getProperty(i);
             if (prop && prop->types.hasType(Type::ObjectType(target))) {
                 if (!pending.append(&prop->types))
                     cx->compartment()->types.setPendingNukeTypes(cx);
@@ -2187,17 +2183,17 @@ TypeCompartment::markSetsUnknown(JSConte
 
     for (unsigned i = 0; i < pending.length(); i++)
         pending[i]->addType(cx, Type::AnyObjectType());
 
     for (gc::CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         RootedScript script(cx, i.get<JSScript>());
         if (script->types) {
             unsigned count = TypeScript::NumTypeSets(script);
-            TypeSet *typeArray = script->types->typeArray();
+            StackTypeSet *typeArray = script->types->typeArray();
             for (unsigned i = 0; i < count; i++) {
                 if (typeArray[i].hasType(Type::ObjectType(target)))
                     typeArray[i].addType(cx, Type::AnyObjectType());
             }
         }
     }
 }
 
@@ -2756,17 +2752,17 @@ TypeObject::matchDefiniteProperties(Hand
 
 static inline void
 InlineAddTypeProperty(ExclusiveContext *cx, TypeObject *obj, jsid id, Type type)
 {
     JS_ASSERT(id == IdToTypeId(id));
 
     AutoEnterAnalysis enter(cx);
 
-    TypeSet *types = obj->getProperty(cx, id);
+    HeapTypeSet *types = obj->getProperty(cx, id);
     if (!types || types->hasType(type))
         return;
 
     InferSpew(ISpewOps, "externalType: property %s %s: %s",
               TypeObjectString(obj), TypeIdString(id), TypeString(type));
     types->addType(cx, type);
 }
 
@@ -2806,17 +2802,17 @@ TypeObject::addPropertyType(ExclusiveCon
 
 void
 TypeObject::markPropertyConfigured(ExclusiveContext *cx, jsid id)
 {
     AutoEnterAnalysis enter(cx);
 
     id = IdToTypeId(id);
 
-    TypeSet *types = getProperty(cx, id);
+    HeapTypeSet *types = getProperty(cx, id);
     if (types)
         types->setConfiguredProperty(cx);
 }
 
 bool
 TypeObject::isPropertyConfigured(jsid id)
 {
     TypeSet *types = maybeGetProperty(id);
@@ -2827,17 +2823,17 @@ TypeObject::isPropertyConfigured(jsid id
 
 void
 TypeObject::markStateChange(ExclusiveContext *cxArg)
 {
     if (unknownProperties())
         return;
 
     AutoEnterAnalysis enter(cxArg);
-    TypeSet *types = maybeGetProperty(JSID_EMPTY);
+    HeapTypeSet *types = maybeGetProperty(JSID_EMPTY);
     if (types) {
         if (JSContext *cx = cxArg->maybeJSContext()) {
             TypeConstraint *constraint = types->constraintList;
             while (constraint) {
                 constraint->newObjectState(cx, this);
                 constraint = constraint->next;
             }
         } else {
@@ -3181,20 +3177,20 @@ types::AddClearDefiniteFunctionUsesInScr
     // |script|, and add constraints to ensure that if the type sets' contents
     // change then the definite properties are cleared from the type.
     // This ensures that the inlining performed when the definite properties
     // analysis was done is stable.
 
     TypeObjectKey *calleeKey = Type::ObjectType(calleeScript->function()).objectKey();
 
     unsigned count = TypeScript::NumTypeSets(script);
-    TypeSet *typeArray = script->types->typeArray();
+    StackTypeSet *typeArray = script->types->typeArray();
 
     for (unsigned i = 0; i < count; i++) {
-        TypeSet *types = &typeArray[i];
+        StackTypeSet *types = &typeArray[i];
         if (!types->unknownObject() && types->getObjectCount() == 1) {
             if (calleeKey != types->getObject(0)) {
                 // Also check if the object is the Function.call or
                 // Function.apply native. IonBuilder uses the presence of these
                 // functions during inlining.
                 JSObject *singleton = types->getSingleObject(0);
                 if (!singleton || !singleton->is<JSFunction>())
                     continue;
@@ -3360,17 +3356,17 @@ types::TypeMonitorResult(JSContext *cx, 
         return;
 
     if (!script->hasBaselineScript())
         return;
 
     AutoEnterAnalysis enter(cx);
 
     Type type = GetValueType(rval);
-    TypeSet *types = TypeScript::BytecodeTypes(script, pc);
+    StackTypeSet *types = TypeScript::BytecodeTypes(script, pc);
     if (types->hasType(type))
         return;
 
     InferSpew(ISpewOps, "bytecodeType: #%u:%05u: %s",
               script->id(), pc - script->code, TypeString(type));
     types->addType(cx, type);
 }
 
@@ -3446,17 +3442,17 @@ JSScript::makeTypes(JSContext *cx)
         new(types) TypeScript();
         return analyzedArgsUsage() || ensureRanAnalysis(cx);
     }
 
     AutoEnterAnalysis enter(cx);
 
     unsigned count = TypeScript::NumTypeSets(this);
 
-    types = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(TypeSet) * count));
+    types = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(StackTypeSet) * count));
     if (!types) {
         cx->compartment()->types.setPendingNukeTypes(cx);
         return false;
     }
 
     new(types) TypeScript();
 
     TypeSet *typeArray = types->typeArray();
@@ -3881,17 +3877,17 @@ ExclusiveContext::getLazyType(const Clas
     return type;
 }
 
 /////////////////////////////////////////////////////////////////////
 // Tracing
 /////////////////////////////////////////////////////////////////////
 
 void
-TypeSet::sweep(Zone *zone)
+ConstraintTypeSet::sweep(Zone *zone)
 {
     /*
      * Purge references to type objects that are no longer live. Type sets hold
      * only weak references. For type sets containing more than one object,
      * live entries in the object hash need to be copied to the zone's
      * new arena.
      */
     unsigned objectCount = baseObjectCount();
@@ -4177,17 +4173,17 @@ TypeCompartment::~TypeCompartment()
 /* static */ void
 TypeScript::Sweep(FreeOp *fop, JSScript *script)
 {
     JSCompartment *compartment = script->compartment();
     JS_ASSERT(compartment->zone()->isGCSweeping());
     JS_ASSERT(compartment->zone()->types.inferenceEnabled);
 
     unsigned num = NumTypeSets(script);
-    TypeSet *typeArray = script->types->typeArray();
+    StackTypeSet *typeArray = script->types->typeArray();
 
     /* Remove constraints and references to dead objects from the persistent type sets. */
     for (unsigned i = 0; i < num; i++)
         typeArray[i].sweep(compartment->zone());
 
     /*
      * Freeze constraints on stack type sets need to be regenerated the next
      * time the script is analyzed.
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -342,44 +342,27 @@ enum {
     TYPE_FLAG_LAZYARGS  = 0x40,
     TYPE_FLAG_ANYOBJECT = 0x80,
 
     /* Mask containing all primitives */
     TYPE_FLAG_PRIMITIVE = TYPE_FLAG_UNDEFINED | TYPE_FLAG_NULL | TYPE_FLAG_BOOLEAN |
                           TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE | TYPE_FLAG_STRING,
 
     /* Mask/shift for the number of objects in objectSet */
-    TYPE_FLAG_OBJECT_COUNT_LIMIT  = 7,
+    TYPE_FLAG_OBJECT_COUNT_MASK   = 0x1f00,
     TYPE_FLAG_OBJECT_COUNT_SHIFT  = 8,
-    TYPE_FLAG_OBJECT_COUNT_MASK   = /* = 0x700 */
-        TYPE_FLAG_OBJECT_COUNT_LIMIT << TYPE_FLAG_OBJECT_COUNT_SHIFT,
+    TYPE_FLAG_OBJECT_COUNT_LIMIT  =
+        TYPE_FLAG_OBJECT_COUNT_MASK >> TYPE_FLAG_OBJECT_COUNT_SHIFT,
 
     /* Whether the contents of this type set are totally unknown. */
     TYPE_FLAG_UNKNOWN             = 0x00002000,
 
     /* Mask of normal type flags on a type set. */
     TYPE_FLAG_BASE_MASK           = 0x000020ff,
 
-    /*
-     * Flags describing the kind of type set this is.
-     *
-     * - StackTypeSet are associated with TypeScripts, for arguments and values
-     *   observed at property reads. These are implicitly frozen on compilation
-     *   and do not have constraints attached to them.
-     *
-     * - HeapTypeSet are associated with the properties of TypeObjects. These
-     *   may have constraints added to them to trigger invalidation of compiled
-     *   code.
-     *
-     * - TemporaryTypeSet are created during compilation and do not outlive
-     *   that compilation.
-     */
-    TYPE_FLAG_STACK_SET           = 0x00004000,
-    TYPE_FLAG_HEAP_SET            = 0x00008000,
-
     /* Additional flags for HeapTypeSet sets. */
 
     /*
      * Whether the property has ever been deleted or reconfigured to behave
      * differently from a normal native property (e.g. made non-writable or
      * given a scripted getter or setter).
      */
     TYPE_FLAG_CONFIGURED_PROPERTY = 0x00010000,
@@ -480,39 +463,48 @@ enum {
       | OBJECT_FLAG_SETS_MARKED_UNKNOWN
 };
 typedef uint32_t TypeObjectFlags;
 
 class StackTypeSet;
 class HeapTypeSet;
 class TemporaryTypeSet;
 
-/* Information about the set of types associated with an lvalue. */
+/*
+ * Information about the set of types associated with an lvalue. There are
+ * three kinds of type sets:
+ *
+ * - StackTypeSet are associated with TypeScripts, for arguments and values
+ *   observed at property reads. These are implicitly frozen on compilation
+ *   and do not have constraints attached to them.
+ *
+ * - HeapTypeSet are associated with the properties of TypeObjects. These
+ *   may have constraints added to them to trigger invalidation of compiled
+ *   code.
+ *
+ * - TemporaryTypeSet are created during compilation and do not outlive
+ *   that compilation.
+ */
 class TypeSet
 {
   protected:
     /* Flags for this type set. */
     TypeFlags flags;
 
     /* Possible objects this type set can represent. */
     TypeObjectKey **objectSet;
 
   public:
 
-    /* Chain of constraints which propagate changes out from this type set. */
-    TypeConstraint *constraintList;
-
     TypeSet()
-      : flags(0), objectSet(nullptr), constraintList(nullptr)
+      : flags(0), objectSet(nullptr)
     {}
 
     void print();
 
-    inline void sweep(JS::Zone *zone);
-
     /* Whether this set contains a specific type. */
     inline bool hasType(Type type) const;
 
     TypeFlags baseFlags() const { return flags & TYPE_FLAG_BASE_MASK; }
     bool unknown() const { return !!(flags & TYPE_FLAG_UNKNOWN); }
     bool unknownObject() const { return !!(flags & (TYPE_FLAG_UNKNOWN | TYPE_FLAG_ANYOBJECT)); }
     bool empty() const { return !baseFlags() && !baseObjectCount(); }
 
@@ -531,25 +523,16 @@ class TypeSet
     }
 
     /* Join two type sets into a new set. The result should not be modified further. */
     static TemporaryTypeSet *unionSets(TypeSet *a, TypeSet *b, LifoAlloc *alloc);
 
     /* Add a type to this set using the specified allocator. */
     inline bool addType(Type type, LifoAlloc *alloc, bool *padded = nullptr);
 
-    /*
-     * Add a type to this set, calling any constraint handlers if this is a new
-     * possible type.
-     */
-    inline void addType(ExclusiveContext *cx, Type type);
-
-    /* Mark this type set as representing a configured property. */
-    inline void setConfiguredProperty(ExclusiveContext *cx);
-
     /* Get a list of all types in this set. */
     typedef Vector<Type, 1, SystemAllocPolicy> TypeList;
     bool enumerateTypes(TypeList *list);
 
     /*
      * Iterate through the objects in this set. getObjectCount overapproximates
      * in the hash case (see SET_ARRAY_SIZE in jsinferinlines.h), and getObject
      * may return nullptr.
@@ -569,81 +552,88 @@ class TypeSet
     bool canSetDefinite(unsigned slot) {
         return (slot + 1) <= (TYPE_FLAG_DEFINITE_MASK >> TYPE_FLAG_DEFINITE_SHIFT);
     }
     void setDefinite(unsigned slot) {
         JS_ASSERT(canSetDefinite(slot));
         flags |= ((slot + 1) << TYPE_FLAG_DEFINITE_SHIFT);
     }
 
-    bool isStackSet() {
-        return flags & TYPE_FLAG_STACK_SET;
-    }
-    bool isHeapSet() {
-        return flags & TYPE_FLAG_HEAP_SET;
-    }
-
     /* Whether any values in this set might have the specified type. */
     bool mightBeType(JSValueType type);
 
     /*
      * Get whether this type set is known to be a subset of other.
      * This variant doesn't freeze constraints. That variant is called knownSubset
      */
     bool isSubset(TypeSet *other);
 
     /* Forward all types in this set to the specified constraint. */
     void addTypesToConstraint(JSContext *cx, TypeConstraint *constraint);
 
-    /* Add a new constraint to this set. */
-    void add(JSContext *cx, TypeConstraint *constraint, bool callExisting = true);
-
-    inline StackTypeSet *toStackSet();
-    inline HeapTypeSet *toHeapSet();
-
     // Clone a type set into an arbitrary allocator.
     TemporaryTypeSet *clone(LifoAlloc *alloc) const;
     bool clone(LifoAlloc *alloc, TemporaryTypeSet *result) const;
 
   protected:
     uint32_t baseObjectCount() const {
         return (flags & TYPE_FLAG_OBJECT_COUNT_MASK) >> TYPE_FLAG_OBJECT_COUNT_SHIFT;
     }
     inline void setBaseObjectCount(uint32_t count);
 
     inline void clearObjects();
 };
 
-class StackTypeSet : public TypeSet
+/* Superclass common to stack and heap type sets. */
+class ConstraintTypeSet : public TypeSet
 {
   public:
-    StackTypeSet() { flags |= TYPE_FLAG_STACK_SET; }
+    /* Chain of constraints which propagate changes out from this type set. */
+    TypeConstraint *constraintList;
+
+    ConstraintTypeSet() : constraintList(nullptr) {}
+
+    /*
+     * Add a type to this set, calling any constraint handlers if this is a new
+     * possible type.
+     */
+    inline void addType(ExclusiveContext *cx, Type type);
+
+    /* Add a new constraint to this set. */
+    void add(JSContext *cx, TypeConstraint *constraint, bool callExisting = true);
+
+    inline void sweep(JS::Zone *zone);
 };
 
-class HeapTypeSet : public TypeSet
+class StackTypeSet : public ConstraintTypeSet
 {
   public:
-    HeapTypeSet() { flags |= TYPE_FLAG_HEAP_SET; }
+};
+
+class HeapTypeSet : public ConstraintTypeSet
+{
+  public:
+    /* Mark this type set as representing a configured property. */
+    inline void setConfiguredProperty(ExclusiveContext *cx);
 };
 
 class CompilerConstraintList;
 
 CompilerConstraintList *
 NewCompilerConstraintList();
 
 class TemporaryTypeSet : public TypeSet
 {
   public:
     TemporaryTypeSet() {}
     TemporaryTypeSet(Type type);
 
     TemporaryTypeSet(uint32_t flags, TypeObjectKey **objectSet) {
         this->flags = flags;
         this->objectSet = objectSet;
-        JS_ASSERT(!isStackSet() && !isHeapSet());
     }
 
     /*
      * Constraints for JIT compilation.
      *
      * Methods for JIT compilation. These must be used when a script is
      * currently being compiled (see AutoEnterCompilation) and will add
      * constraints ensuring that if the return value change in the future due
@@ -720,30 +710,16 @@ class TemporaryTypeSet : public TypeSet
 
     /*
      * Whether known double optimizations are possible for element accesses on
      * objects in this type set.
      */
     DoubleConversion convertDoubleElements(CompilerConstraintList *constraints);
 };
 
-inline StackTypeSet *
-TypeSet::toStackSet()
-{
-    JS_ASSERT(isStackSet());
-    return (StackTypeSet *) this;
-}
-
-inline HeapTypeSet *
-TypeSet::toHeapSet()
-{
-    JS_ASSERT(isHeapSet());
-    return (HeapTypeSet *) this;
-}
-
 bool
 AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject *type, jsid id);
 
 void
 AddClearDefiniteFunctionUsesInScript(JSContext *cx, TypeObject *type,
                                      JSScript *script, JSScript *calleeScript);
 
 /* Is this a reasonable PC to be doing inlining on? */
@@ -1393,17 +1369,17 @@ struct TypeCompartment
 
     /*
      * Worklist of types which need to be propagated to constraints. We use a
      * worklist to avoid blowing the native stack.
      */
     struct PendingWork
     {
         TypeConstraint *constraint;
-        TypeSet *source;
+        ConstraintTypeSet *source;
         Type type;
     };
     PendingWork *pendingArray;
     unsigned pendingCount;
     unsigned pendingCapacity;
 
     /* Whether we are currently resolving the pending worklist. */
     bool resolving;
@@ -1436,17 +1412,18 @@ struct TypeCompartment
     JSObject *newTypedObject(JSContext *cx, IdValuePair *properties, size_t nproperties);
 
     TypeCompartment();
     ~TypeCompartment();
 
     inline JSCompartment *compartment();
 
     /* Add a type to register with a list of constraints. */
-    inline void addPending(JSContext *cx, TypeConstraint *constraint, TypeSet *source, Type type);
+    inline void addPending(JSContext *cx, TypeConstraint *constraint,
+                           ConstraintTypeSet *source, Type type);
     bool growPendingArray(JSContext *cx);
 
     /* Resolve pending type registrations, excluding delayed ones. */
     inline void resolvePending(JSContext *cx);
 
     /* Prints results of this compartment if spew is enabled or force is set. */
     void print(JSContext *cx, bool force);
 
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -848,17 +848,18 @@ TypeScript::SetArgument(JSContext *cx, J
 
 inline JSCompartment *
 TypeCompartment::compartment()
 {
     return (JSCompartment *)((char *)this - offsetof(JSCompartment, types));
 }
 
 inline void
-TypeCompartment::addPending(JSContext *cx, TypeConstraint *constraint, TypeSet *source, Type type)
+TypeCompartment::addPending(JSContext *cx, TypeConstraint *constraint,
+                            ConstraintTypeSet *source, Type type)
 {
     JS_ASSERT(this == &cx->compartment()->types);
     JS_ASSERT(!cx->runtime()->isHeapBusy());
 
     InferSpew(ISpewOps, "pending: %sC%p%s %s",
               InferSpewColor(constraint), constraint, InferSpewColorReset(),
               TypeString(type));
 
@@ -1193,25 +1194,22 @@ TypeSet::addType(Type type, LifoAlloc *a
     }
 
     if (padded)
         *padded = true;
     return true;
 }
 
 inline void
-TypeSet::addType(ExclusiveContext *cxArg, Type type)
+ConstraintTypeSet::addType(ExclusiveContext *cxArg, Type type)
 {
     JS_ASSERT(cxArg->compartment()->activeAnalysis);
 
-    // Temporary type sets use a separate LifoAlloc for storage.
-    JS_ASSERT(isStackSet() || isHeapSet());
-
     bool added = false;
-    if (!addType(type, &cxArg->typeLifoAlloc(), &added)) {
+    if (!TypeSet::addType(type, &cxArg->typeLifoAlloc(), &added)) {
         cxArg->compartment()->types.setPendingNukeTypes(cxArg);
         return;
     }
     if (!added)
         return;
 
     InferSpew(ISpewOps, "addType: %sT%p%s %s",
               InferSpewColor(this), this, InferSpewColorReset(),
@@ -1226,17 +1224,17 @@ TypeSet::addType(ExclusiveContext *cxArg
         }
         cx->compartment()->types.resolvePending(cx);
     } else {
         JS_ASSERT(!constraintList);
     }
 }
 
 inline void
-TypeSet::setConfiguredProperty(ExclusiveContext *cxArg)
+HeapTypeSet::setConfiguredProperty(ExclusiveContext *cxArg)
 {
     if (flags & TYPE_FLAG_CONFIGURED_PROPERTY)
         return;
 
     flags |= TYPE_FLAG_CONFIGURED_PROPERTY;
 
     /* Propagate the change to all constraints. */
     if (JSContext *cx = cxArg->maybeJSContext()) {
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -252,17 +252,16 @@ IsJumpOpcode(JSOp op)
 
 static inline bool
 BytecodeFallsThrough(JSOp op)
 {
     switch (op) {
       case JSOP_GOTO:
       case JSOP_DEFAULT:
       case JSOP_RETURN:
-      case JSOP_STOP:
       case JSOP_RETRVAL:
       case JSOP_THROW:
       case JSOP_TABLESWITCH:
         return false;
       case JSOP_GOSUB:
         /* These fall through indirectly, after executing a 'finally'. */
         return true;
       default:
@@ -552,17 +551,17 @@ BytecodeFlowsToBitop(jsbytecode *pc)
 
 extern bool
 IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset);
 
 inline bool
 FlowsIntoNext(JSOp op)
 {
     /* JSOP_YIELD is considered to flow into the next instruction, like JSOP_CALL. */
-    return op != JSOP_STOP && op != JSOP_RETURN && op != JSOP_RETRVAL && op != JSOP_THROW &&
+    return op != JSOP_RETRVAL && op != JSOP_RETURN && op != JSOP_THROW &&
            op != JSOP_GOTO && op != JSOP_RETSUB;
 }
 
 inline bool
 IsArgOp(JSOp op)
 {
     return JOF_OPTYPE(op) == JOF_QARG;
 }
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -40,17 +40,17 @@ 1234567890123456789012345678901234567890
 
 /*
  * Generic nop for the decompiler.
  */
 OPDEF(JSOP_NOP,       0,  "nop",        NULL,         1,  0,  0, JOF_BYTE)
 
 /* Long-standing JavaScript bytecodes. */
 OPDEF(JSOP_UNDEFINED, 1,  js_undefined_str, "",       1,  0,  1, JOF_BYTE)
-OPDEF(JSOP_POPV,      2,  "popv",       NULL,         1,  1,  0, JOF_BYTE)
+OPDEF(JSOP_UNUSED2,   2,  "unused2",    NULL,         1,  1,  0, JOF_BYTE)
 OPDEF(JSOP_ENTERWITH, 3,  "enterwith",  NULL,         1,  1,  1, JOF_BYTE)
 OPDEF(JSOP_LEAVEWITH, 4,  "leavewith",  NULL,         1,  1,  0, JOF_BYTE)
 OPDEF(JSOP_RETURN,    5,  "return",     NULL,         1,  1,  0, JOF_BYTE)
 OPDEF(JSOP_GOTO,      6,  "goto",       NULL,         5,  0,  0, JOF_JUMP)
 OPDEF(JSOP_IFEQ,      7,  "ifeq",       NULL,         5,  1,  0, JOF_JUMP|JOF_DETECTING)
 OPDEF(JSOP_IFNE,      8,  "ifne",       NULL,         5,  1,  0, JOF_JUMP)
 
 /* Get the arguments object for the current, lightweight function activation. */
@@ -348,19 +348,24 @@ OPDEF(JSOP_UNUSED148,     148,"unused148
 
 /* Placeholders for a real jump opcode set during backpatch chain fixup. */
 OPDEF(JSOP_BACKPATCH,     149,"backpatch", NULL,      5,  0,  0,  JOF_JUMP)
 OPDEF(JSOP_UNUSED150,     150,"unused150", NULL,      1,  0,  0,  JOF_BYTE)
 
 /* Set pending exception from the stack, to trigger rethrow. */
 OPDEF(JSOP_THROWING,      151,"throwing", NULL,       1,  1,  0,  JOF_BYTE)
 
-/* Set and get return value pseudo-register in stack frame. */
-OPDEF(JSOP_SETRVAL,       152,"setrval",  NULL,       1,  1,  0,  JOF_BYTE)
-OPDEF(JSOP_RETRVAL,       153,"retrval",  NULL,       1,  0,  0,  JOF_BYTE)
+/* Set the return value pseudo-register in stack frame. */
+OPDEF(JSOP_SETRVAL,       152,"setrval",    NULL,       1,  1,  0,  JOF_BYTE)
+/*
+ * Stop interpretation and return value set by JSOP_SETRVAL. When not set,
+ * returns UndefinedValue. Also emitted at end of script so interpreter
+ * don't need to check if opcode is still in script range.
+ */
+OPDEF(JSOP_RETRVAL,       153,"retrval",    NULL,       1,  0,  0,  JOF_BYTE)
 
 /* Free variable references that must either be found on the global or a ReferenceError */
 OPDEF(JSOP_GETGNAME,      154,"getgname",  NULL,       5,  0,  1, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME)
 OPDEF(JSOP_SETGNAME,      155,"setgname",  NULL,       5,  2,  1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME)
 
 OPDEF(JSOP_UNUSED156,  156, "unused156",   NULL,         1,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_UNUSED157,  157, "unused157",   NULL,         1,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_UNUSED158,  158, "unused158",   NULL,         1,  0,  0,  JOF_BYTE)
@@ -410,21 +415,17 @@ OPDEF(JSOP_UINT24,        188,"uint24", 
 
 OPDEF(JSOP_UNUSED189,     189,"unused189",   NULL,    1,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_UNUSED190,     190,"unused190",   NULL,    1,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_UNUSED191,     191,"unused191",   NULL,    1,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_UNUSED192,     192,"unused192",   NULL,    1,  0,  0,  JOF_BYTE)
 
 OPDEF(JSOP_CALLELEM,      193, "callelem",   NULL,    1,  2,  1, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC)
 
-/*
- * Stop interpretation, emitted at end of script to save the threaded bytecode
- * interpreter an extra branch test on every DO_NEXT_OP (see jsinterp.c).
- */
-OPDEF(JSOP_STOP,          194,"stop",        NULL,    1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED194,     194,"unused194",   NULL,    1,  0,  0,  JOF_BYTE)
 
 /*
  * Get an extant property value, throwing ReferenceError if the identified
  * property does not exist.
  */
 OPDEF(JSOP_GETXPROP,      195,"getxprop",    NULL,    5,  1,  1, JOF_ATOM|JOF_PROP|JOF_TYPESET)
 
 OPDEF(JSOP_UNUSED196,     196,"unused196",   NULL,    1,  0,  0, JOF_BYTE)
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1801,17 +1801,17 @@ JSScript::fullyInitTrivial(ExclusiveCont
 {
     if (!partiallyInit(cx, script, 0, 0, 0, 0, 0))
         return false;
 
     SharedScriptData *ssd = SharedScriptData::new_(cx, 1, 1, 0);
     if (!ssd)
         return false;
 
-    ssd->data[0] = JSOP_STOP;
+    ssd->data[0] = JSOP_RETRVAL;
     ssd->data[1] = SRC_NULL;
     script->length = 1;
     return SaveSharedScriptData(cx, script, ssd, 1);
 }
 
 /* static */ bool
 JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, BytecodeEmitter *bce)
 {
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1001,17 +1001,17 @@ class JSScript : public js::gc::Barriere
      */
     bool isEmpty() const {
         if (length > 3)
             return false;
 
         jsbytecode *pc = code;
         if (noScriptRval && JSOp(*pc) == JSOP_FALSE)
             ++pc;
-        return JSOp(*pc) == JSOP_STOP;
+        return JSOp(*pc) == JSOP_RETRVAL;
     }
 
     bool varIsAliased(unsigned varSlot);
     bool formalIsAliased(unsigned argSlot);
     bool formalLivesInArgumentsObject(unsigned argSlot);
 
   private:
     /*
--- a/js/src/tests/lib/jittests.py
+++ b/js/src/tests/lib/jittests.py
@@ -96,16 +96,17 @@ class Test:
         t.allow_oom = self.allow_oom
         t.valgrind = self.valgrind
         t.tz_pacific = self.tz_pacific
         t.expect_error = self.expect_error
         t.expect_status = self.expect_status
         return t
 
     COOKIE = '|jit-test|'
+    CacheDir = JS_CACHE_DIR
 
     @classmethod
     def from_file(cls, path, options):
         test = cls(path)
 
         line = open(path).readline()
         i = line.find(cls.COOKIE)
         if i != -1:
@@ -174,17 +175,18 @@ class Test:
         # the remote device.
         fmt = 'const platform=%r; const libdir=%r; const scriptdir=%r'
         if remote_prefix:
             fmt = 'const platform="%s"; const libdir="%s"; const scriptdir="%s"'
         expr = fmt % (sys.platform, libdir, scriptdir_var)
 
         # We may have specified '-a' or '-d' twice: once via --jitflags, once
         # via the "|jit-test|" line.  Remove dups because they are toggles.
-        cmd = prefix + list(set(self.jitflags)) + ['-e', expr, '-f', path]
+        cmd = prefix + ['--js-cache', Test.CacheDir]
+        cmd += list(set(self.jitflags)) + ['-e', expr, '-f', path]
         if self.valgrind:
             cmd = self.VALGRIND_CMD + cmd
         return cmd
 
 def find_tests(substring=None):
     ans = []
     for dirpath, dirnames, filenames in os.walk(TEST_DIR):
         dirnames.sort()
@@ -651,16 +653,19 @@ def run_tests_remote(tests, prefix, opti
     # Push js shell and libraries.
     if dm.dirExists(jit_tests_dir):
         dm.removeDir(jit_tests_dir)
     dm.mkDirs(options.remote_test_root)
     push_libs(options, dm)
     push_progs(options, dm, [prefix[0]])
     dm.chmodDir(options.remote_test_root)
 
+    Test.CacheDir = posixpath.join(options.remote_test_root, '.js-cache')
+    dm.mkDirs(Test.CacheDir)
+
     dm.pushDir(ECMA6_DIR, posixpath.join(jit_tests_dir, 'tests', 'ecma_6'), timeout=600)
     dm.pushDir(os.path.dirname(TEST_DIR), options.remote_test_root, timeout=600)
     prefix[0] = os.path.join(options.remote_test_root, 'js')
 
     # Run all tests.
     gen = get_remote_results(tests, dm, prefix, options)
     ok = process_test_results(gen, len(tests), options)
     return ok
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -460,17 +460,17 @@ js::Invoke(JSContext *cx, CallArgs args,
     JSFunction *fun = &callee.as<JSFunction>();
     JS_ASSERT_IF(construct, !fun->isNativeConstructor());
     if (fun->isNative())
         return CallJSNative(cx, fun->native(), args);
 
     if (!fun->getOrCreateScript(cx))
         return false;
 
-    /* Run function until JSOP_STOP, JSOP_RETURN or error. */
+    /* Run function until JSOP_RETRVAL, JSOP_RETURN or error. */
     InvokeState state(cx, args, initial);
 
     // Check to see if useNewType flag should be set for this frame.
     if (construct && cx->typeInferenceEnabled()) {
         ScriptFrameIter iter(cx);
         if (!iter.done()) {
             JSScript *script = iter.script();
             jsbytecode *pc = iter.pc();
@@ -1363,17 +1363,17 @@ Interpret(JSContext *cx, RunState &state
     bool interpReturnOK;
 
     if (!activation.entryFrame()->isGeneratorFrame()) {
         if (!activation.entryFrame()->prologue(cx))
             goto error;
     } else {
         probes::EnterScript(cx, script, script->function(), activation.entryFrame());
     }
-    if (cx->compartment()->debugMode()) {
+    if (JS_UNLIKELY(cx->compartment()->debugMode())) {
         JSTrapStatus status = ScriptDebugPrologue(cx, activation.entryFrame());
         switch (status) {
           case JSTRAP_CONTINUE:
             break;
           case JSTRAP_RETURN:
             interpReturnOK = true;
             goto forced_return;
           case JSTRAP_THROW:
@@ -1464,16 +1464,17 @@ CASE(EnableInterruptsPseudoOpcode)
 
     /* Commence executing the actual opcode. */
     SANITY_CHECKS();
     DISPATCH_TO(op);
 }
 
 /* Various 1-byte no-ops. */
 CASE(JSOP_NOP)
+CASE(JSOP_UNUSED2)
 CASE(JSOP_UNUSED44)
 CASE(JSOP_UNUSED45)
 CASE(JSOP_UNUSED46)
 CASE(JSOP_UNUSED47)
 CASE(JSOP_UNUSED48)
 CASE(JSOP_UNUSED49)
 CASE(JSOP_UNUSED50)
 CASE(JSOP_UNUSED51)
@@ -1520,16 +1521,17 @@ CASE(JSOP_UNUSED179)
 CASE(JSOP_UNUSED180)
 CASE(JSOP_UNUSED181)
 CASE(JSOP_UNUSED182)
 CASE(JSOP_UNUSED183)
 CASE(JSOP_UNUSED189)
 CASE(JSOP_UNUSED190)
 CASE(JSOP_UNUSED191)
 CASE(JSOP_UNUSED192)
+CASE(JSOP_UNUSED194)
 CASE(JSOP_UNUSED196)
 CASE(JSOP_UNUSED200)
 CASE(JSOP_UNUSED201)
 CASE(JSOP_GETFUNNS)
 CASE(JSOP_UNUSED208)
 CASE(JSOP_UNUSED209)
 CASE(JSOP_UNUSED210)
 CASE(JSOP_UNUSED219)
@@ -1595,19 +1597,18 @@ CASE(JSOP_POPN)
     REGS.sp -= GET_UINT16(REGS.pc);
 #ifdef DEBUG
     if (StaticBlockObject *block = REGS.fp()->maybeBlockChain())
         JS_ASSERT(REGS.stackDepth() >= block->stackDepth() + block->slotCount());
 #endif
 END_CASE(JSOP_POPN)
 
 CASE(JSOP_SETRVAL)
-CASE(JSOP_POPV)
     POP_RETURN_VALUE();
-END_CASE(JSOP_POPV)
+END_CASE(JSOP_SETRVAL)
 
 CASE(JSOP_ENTERWITH)
 {
     RootedValue &val = rootValue0;
     val = REGS.sp[-1];
 
     if (!EnterWith(cx, REGS.fp(), val, REGS.stackDepth() - 1))
         goto error;
@@ -1630,34 +1631,33 @@ CASE(JSOP_LEAVEWITH)
     REGS.fp()->popWith(cx);
     REGS.sp--;
 END_CASE(JSOP_LEAVEWITH)
 
 CASE(JSOP_RETURN)
     POP_RETURN_VALUE();
     /* FALL THROUGH */
 
-CASE(JSOP_RETRVAL)    /* fp return value already set */
-CASE(JSOP_STOP)
+CASE(JSOP_RETRVAL)
 {
     /*
      * When the inlined frame exits with an exception or an error, ok will be
      * false after the inline_return label.
      */
     CHECK_BRANCH();
 
     interpReturnOK = true;
     if (activation.entryFrame() != REGS.fp())
   inline_return:
     {
 #if JS_TRACE_LOGGING
         TraceLogging::defaultLogger()->log(TraceLogging::SCRIPT_STOP);
 #endif
 
-        if (cx->compartment()->debugMode())
+        if (JS_UNLIKELY(cx->compartment()->debugMode()))
             interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), interpReturnOK);
 
         if (!REGS.fp()->isYielding())
             REGS.fp()->epilogue(cx);
         else
             probes::ExitScript(cx, script, script->function(), REGS.fp());
 
 #if defined(JS_ION)
@@ -2556,32 +2556,32 @@ CASE(JSOP_FUNCALL)
 
 #if JS_TRACE_LOGGING
     TraceLogging::defaultLogger()->log(TraceLogging::SCRIPT_START, script);
     TraceLogging::defaultLogger()->log(TraceLogging::INFO_ENGINE_INTERPRETER);
 #endif
 
     if (!REGS.fp()->prologue(cx))
         goto error;
-    if (cx->compartment()->debugMode()) {
+    if (JS_UNLIKELY(cx->compartment()->debugMode())) {
         switch (ScriptDebugPrologue(cx, REGS.fp())) {
           case JSTRAP_CONTINUE:
             break;
           case JSTRAP_RETURN:
             interpReturnOK = true;
             goto forced_return;
           case JSTRAP_THROW:
           case JSTRAP_ERROR:
             goto error;
           default:
             MOZ_ASSUME_UNREACHABLE("bad ScriptDebugPrologue status");
         }
     }
 
-    /* Load first op and dispatch it (safe since JSOP_STOP). */
+    /* Load first op and dispatch it (safe since JSOP_RETRVAL). */
     ADVANCE_AND_DISPATCH(0);
 }
 
 CASE(JSOP_SETCALL)
 {
     JS_ALWAYS_FALSE(SetCallOperation(cx));
     goto error;
 }
@@ -3319,17 +3319,17 @@ DEFAULT()
 
     MOZ_ASSUME_UNREACHABLE("Interpreter loop exited via fallthrough");
 
   error:
     JS_ASSERT(uint32_t(REGS.pc - script->code) < script->length);
 
     if (cx->isExceptionPending()) {
         /* Call debugger throw hooks. */
-        if (cx->compartment()->debugMode()) {
+        if (JS_UNLIKELY(cx->compartment()->debugMode())) {
             JSTrapStatus status = DebugExceptionUnwind(cx, REGS.fp(), REGS.pc);
             switch (status) {
               case JSTRAP_ERROR:
                 goto error;
 
               case JSTRAP_CONTINUE:
               case JSTRAP_THROW:
                 break;
@@ -3425,17 +3425,17 @@ DEFAULT()
   forced_return:
     UnwindScope(cx, REGS.fp(), 0);
     REGS.setToEndOfScript();
 
     if (activation.entryFrame() != REGS.fp())
         goto inline_return;
 
   exit:
-    if (cx->compartment()->debugMode())
+    if (JS_UNLIKELY(cx->compartment()->debugMode()))
         interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), interpReturnOK);
     if (!REGS.fp()->isYielding())
         REGS.fp()->epilogue(cx);
     else
         probes::ExitScript(cx, script, script->function(), REGS.fp());
 
     gc::MaybeVerifyBarriers(cx, true);
 
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -749,20 +749,20 @@ bad:
 JS_PUBLIC_API(void)
 JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
 {
     JSPropertyDesc *pd;
     uint32_t i;
 
     pd = pda->array;
     for (i = 0; i < pda->length; i++) {
-        js_RemoveRoot(cx->runtime(), &pd[i].id);
-        js_RemoveRoot(cx->runtime(), &pd[i].value);
+        RemoveRoot(cx->runtime(), &pd[i].id);
+        RemoveRoot(cx->runtime(), &pd[i].value);
         if (pd[i].flags & JSPD_ALIAS)
-            js_RemoveRoot(cx->runtime(), &pd[i].alias);
+            RemoveRoot(cx->runtime(), &pd[i].alias);
     }
     js_free(pd);
     pda->array = nullptr;
     pda->length = 0;
 }
 
 /************************************************************************/
 
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -118,17 +118,17 @@ StackFrame::copyFrameAndValues(JSContext
     srcend = othersp;
     dst = slots();
     for (const Value *src = otherfp->slots(); src < srcend; src++, dst++) {
         *dst = *src;
         if (doPostBarrier)
             HeapValue::writeBarrierPost(*dst, dst);
     }
 
-    if (cx->compartment()->debugMode())
+    if (JS_UNLIKELY(cx->compartment()->debugMode()))
         DebugScopes::onGeneratorFrameChange(otherfp, this, cx);
 }
 
 /* Note: explicit instantiation for js_NewGenerator located in jsiter.cpp. */
 template
 void StackFrame::copyFrameAndValues<StackFrame::NoPostBarrier>(
                                     JSContext *, Value *, StackFrame *, const Value *, Value *);
 template
@@ -299,17 +299,17 @@ StackFrame::epilogue(JSContext *cx)
     JS_ASSERT(!hasBlockChain());
 
     RootedScript script(cx, this->script());
     probes::ExitScript(cx, script, script->function(), this);
 
     if (isEvalFrame()) {
         if (isStrictEvalFrame()) {
             JS_ASSERT_IF(hasCallObj(), scopeChain()->as<CallObject>().isForEval());
-            if (cx->compartment()->debugMode())
+            if (JS_UNLIKELY(cx->compartment()->debugMode()))
                 DebugScopes::onPopStrictEvalScope(this);
         } else if (isDirectEvalFrame()) {
             if (isDebuggerFrame())
                 JS_ASSERT(!scopeChain()->is<ScopeObject>());
         } else {
             /*
              * Debugger.Object.prototype.evalInGlobal creates indirect eval
              * frames scoped to the given global;
@@ -335,17 +335,17 @@ StackFrame::epilogue(JSContext *cx)
     JS_ASSERT(isNonEvalFunctionFrame());
 
     if (fun()->isHeavyweight())
         JS_ASSERT_IF(hasCallObj(),
                      scopeChain()->as<CallObject>().callee().nonLazyScript() == script);
     else
         AssertDynamicScopeMatchesStaticScope(cx, script, scopeChain());
 
-    if (cx->compartment()->debugMode())
+    if (JS_UNLIKELY(cx->compartment()->debugMode()))
         DebugScopes::onPopCall(this, cx);
 
     if (isConstructing() && thisValue().isObject() && returnValue().isPrimitive())
         setReturnValue(ObjectValue(constructorThis()));
 }
 
 bool
 StackFrame::pushBlock(JSContext *cx, StaticBlockObject &block)
@@ -369,31 +369,31 @@ StackFrame::pushBlock(JSContext *cx, Sta
     return true;
 }
 
 void
 StackFrame::popBlock(JSContext *cx)
 {
     JS_ASSERT(hasBlockChain());
 
-    if (cx->compartment()->debugMode())
+    if (JS_UNLIKELY(cx->compartment()->debugMode()))
         DebugScopes::onPopBlock(cx, this);
 
     if (blockChain_->needsClone()) {
         JS_ASSERT(scopeChain_->as<ClonedBlockObject>().staticBlock() == *blockChain_);
         popOffScopeChain();
     }
 
     blockChain_ = blockChain_->enclosingBlock();
 }
 
 void
 StackFrame::popWith(JSContext *cx)
 {
-    if (cx->compartment()->debugMode())
+    if (JS_UNLIKELY(cx->compartment()->debugMode()))
         DebugScopes::onPopWith(this);
 
     JS_ASSERT(scopeChain()->is<WithObject>());
     popOffScopeChain();
 }
 
 void
 StackFrame::mark(JSTracer *trc)
@@ -459,18 +459,18 @@ js::MarkInterpreterActivations(JSRuntime
 
 // Unlike the other methods of this calss, this method is defined here so that
 // we don't have to #include jsautooplen.h in vm/Stack.h.
 void
 FrameRegs::setToEndOfScript()
 {
     JSScript *script = fp()->script();
     sp = fp()->base();
-    pc = script->code + script->length - JSOP_STOP_LENGTH;
-    JS_ASSERT(*pc == JSOP_STOP);
+    pc = script->code + script->length - JSOP_RETRVAL_LENGTH;
+    JS_ASSERT(*pc == JSOP_RETRVAL);
 }
 
 /*****************************************************************************/
 
 StackFrame *
 InterpreterStack::pushInvokeFrame(JSContext *cx, const CallArgs &args, InitialFrameFlags initial)
 {
     LifoAlloc::Mark mark = allocator_.mark();
--- a/js/src/vm/ThreadPool.cpp
+++ b/js/src/vm/ThreadPool.cpp
@@ -181,20 +181,17 @@ ThreadPoolWorker::terminate()
 
 /////////////////////////////////////////////////////////////////////////////
 // ThreadPool
 //
 // The |ThreadPool| starts up workers, submits work to them, and shuts
 // them down when requested.
 
 ThreadPool::ThreadPool(JSRuntime *rt)
-  :
-#if defined(JS_THREADSAFE) || defined(DEBUG)
-    runtime_(rt)
-#endif
+  : runtime_(rt)
 {
 }
 
 ThreadPool::~ThreadPool()
 {
     terminateWorkers();
 }
 
--- a/js/src/vm/ThreadPool.h
+++ b/js/src/vm/ThreadPool.h
@@ -56,19 +56,17 @@ class TaskExecutor
 // have some worker threads pick up (and even finish) their piece of
 // the job before others have even started.
 class ThreadPool
 {
   private:
     friend class ThreadPoolWorker;
 
     // Initialized at startup only:
-#if defined(JS_THREADSAFE) || defined(DEBUG)
     JSRuntime *const runtime_;
-#endif
     js::Vector<ThreadPoolWorker*, 8, SystemAllocPolicy> workers_;
 
     bool lazyStartWorkers(JSContext *cx);
     void terminateWorkers();
     void terminateWorkersAndReportOOM(JSContext *cx);
 
   public:
     ThreadPool(JSRuntime *rt);
--- a/js/xpconnect/public/nsAutoJSValHolder.h
+++ b/js/xpconnect/public/nsAutoJSValHolder.h
@@ -59,17 +59,17 @@ public:
 
   /**
    * Hold by rooting on the runtime.
    * Note that mVal may be JSVAL_NULL, which is not a problem.
    */
   bool Hold(JSRuntime* aRt) {
     // Do we really care about different runtimes?
     if (mRt && aRt != mRt) {
-      js_RemoveRoot(mRt, &mVal);
+      JS_RemoveValueRootRT(mRt, &mVal);
       mRt = nullptr;
     }
 
     if (!mRt && JS_AddNamedValueRootRT(aRt, &mVal, "nsAutoJSValHolder")) {
       mRt = aRt;
     }
 
     return !!mRt;
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -45,16 +45,17 @@
 #include "nsCellMap.h"
 #include "nsTextFrame.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsTextFragment.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "nsHTMLDNSPrefetch.h"
 #include "nsHtml5Module.h"
+#include "mozilla/dom/FallbackEncoding.h"
 #include "nsFocusManager.h"
 #include "nsListControlFrame.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "SVGElementFactory.h"
 #include "nsSVGUtils.h"
 #include "nsMathMLAtoms.h"
 #include "nsMathMLOperators.h"
 #include "Navigator.h"
@@ -253,16 +254,17 @@ nsLayoutStatics::Initialize()
     return rv;
   }
 
   AsyncLatencyLogger::InitializeStatics();
   AudioStream::InitLibrary();
 
   nsContentSink::InitializeStatics();
   nsHtml5Module::InitializeStatics();
+  mozilla::dom::FallbackEncoding::Initialize();
   nsLayoutUtils::Initialize();
   nsIPresShell::InitializeStatics();
   nsRefreshDriver::InitializeStatics();
 
   nsCORSListenerProxy::Startup();
 
   NS_SealStaticAtomTable();
 
@@ -379,16 +381,18 @@ nsLayoutStatics::Shutdown()
   nsCORSListenerProxy::Shutdown();
 
   nsIPresShell::ReleaseStatics();
 
   nsTreeSanitizer::ReleaseStatics();
 
   nsHtml5Module::ReleaseStatics();
 
+  mozilla::dom::FallbackEncoding::Shutdown();
+
   nsRegion::ShutdownStatic();
 
   NS_ShutdownEventTargetChainRecycler();
 
   HTMLInputElement::DestroyUploadLastDir();
 
   nsLayoutUtils::Shutdown();
 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1515,17 +1515,17 @@ pref("intl.charsetmenu.browser.more3",  
 pref("intl.charsetmenu.browser.more4",      "armscii-8, TIS-620, ISO-8859-11, windows-874, IBM857, ISO-8859-9, x-mac-turkish, windows-1254, x-viet-tcvn5712, VISCII, x-viet-vps, windows-1258, x-mac-devanagari, x-mac-gujarati, x-mac-gurmukhi");
 pref("intl.charsetmenu.browser.more5",      "ISO-8859-6, windows-1256, ISO-8859-8-I, windows-1255, ISO-8859-8, IBM862");
 pref("intl.charsetmenu.mailedit",           "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.cache",      "");
 pref("intl.charsetmenu.mailview.cache",     "");
 pref("intl.charsetmenu.composer.cache",     "");
 pref("intl.charsetmenu.browser.cache.size", 5);
 pref("intl.charset.detector",               "chrome://global/locale/intl.properties");
-pref("intl.charset.default",                "chrome://global-platform/locale/intl.properties");
+pref("intl.charset.fallback.override",      "");
 pref("intl.ellipsis",                       "chrome://global-platform/locale/intl.properties");
 pref("intl.locale.matchOS",                 false);
 // fallback charset list for Unicode conversion (converting from Unicode)
 // currently used for mail send only to handle symbol characters (e.g Euro, trademark, smartquotes)
 // for ISO-8859-1
 pref("intl.fallbackCharsetList.ISO-8859-1", "windows-1252");
 pref("font.language.group",                 "chrome://global/locale/intl.properties");
 
@@ -2747,22 +2747,22 @@ pref("font.name-list.fantasy.he", "Times
 
 pref("font.name.serif.ja", "Hiragino Mincho ProN");
 pref("font.name.sans-serif.ja", "Hiragino Kaku Gothic ProN");
 pref("font.name.monospace.ja", "Osaka-Mono"); 
 pref("font.name-list.serif.ja", "Hiragino Mincho ProN,Hiragino Mincho Pro");
 pref("font.name-list.sans-serif.ja", "Hiragino Kaku Gothic ProN,Hiragino Kaku Gothic Pro");
 pref("font.name-list.monospace.ja", "Osaka-Mono"); 
 
-pref("font.name.serif.ko", "AppleMyungjo"); 
-pref("font.name.sans-serif.ko", "AppleGothic"); 
-pref("font.name.monospace.ko", "AppleGothic"); 
-pref("font.name-list.serif.ko", "AppleMyungjo"); 
-pref("font.name-list.sans-serif.ko", "AppleGothic"); 
-pref("font.name-list.monospace.ko", "AppleGothic"); 
+pref("font.name.serif.ko", "AppleMyungjo");
+pref("font.name.sans-serif.ko", "Apple SD Gothic Neo");
+pref("font.name.monospace.ko", "Apple SD Gothic Neo");
+pref("font.name-list.serif.ko", "AppleMyungjo");
+pref("font.name-list.sans-serif.ko", "Apple SD Gothic Neo,AppleGothic");
+pref("font.name-list.monospace.ko", "Apple SD Gothic Neo,AppleGothic");
 
 pref("font.name.serif.th", "Thonburi");
 pref("font.name.sans-serif.th", "Thonburi");
 pref("font.name.monospace.th", "Ayuthaya");
 pref("font.name-list.serif.th", "Thonburi");
 pref("font.name-list.sans-serif.th", "Thonburi");
 pref("font.name-list.monospace.th", "Ayuthaya");
 
--- a/netwerk/streamconv/converters/nsDirIndexParser.cpp
+++ b/netwerk/streamconv/converters/nsDirIndexParser.cpp
@@ -8,19 +8,17 @@
 #include "mozilla/Util.h"
 
 #include "prprf.h"
 
 #include "nsDirIndexParser.h"
 #include "nsEscape.h"
 #include "nsIInputStream.h"
 #include "nsCRT.h"
-#include "nsIPrefService.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefLocalizedString.h"
+#include "mozilla/dom/FallbackEncoding.h"
 #include "nsITextToSubURI.h"
 #include "nsIDirIndex.h"
 #include "nsServiceManagerUtils.h"
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS3(nsDirIndexParser,
                    nsIRequestObserver,
@@ -30,34 +28,17 @@ NS_IMPL_ISUPPORTS3(nsDirIndexParser,
 nsDirIndexParser::nsDirIndexParser() {
 }
 
 nsresult
 nsDirIndexParser::Init() {
   mLineStart = 0;
   mHasDescription = false;
   mFormat = nullptr;
-
-  // get default charset to be used for directory listings (fallback to
-  // ISO-8859-1 if pref is unavailable).
-  NS_NAMED_LITERAL_CSTRING(kFallbackEncoding, "ISO-8859-1");
-  nsXPIDLString defCharset;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
-  if (prefs) {
-    nsCOMPtr<nsIPrefLocalizedString> prefVal;
-    prefs->GetComplexValue("intl.charset.default",
-                           NS_GET_IID(nsIPrefLocalizedString),
-                           getter_AddRefs(prefVal));
-    if (prefVal)
-      prefVal->ToString(getter_Copies(defCharset));
-  }
-  if (!defCharset.IsEmpty())
-    LossyCopyUTF16toASCII(defCharset, mEncoding); // charset labels are always ASCII
-  else
-    mEncoding.Assign(kFallbackEncoding);
+  mozilla::dom::FallbackEncoding::FromLocale(mEncoding);
  
   nsresult rv;
   // XXX not threadsafe
   if (gRefCntParser++ == 0)
     rv = CallGetService(NS_ITEXTTOSUBURI_CONTRACTID, &gTextToSubURI);
   else
     rv = NS_OK;
 
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -297,17 +297,17 @@ nsHtml5StreamParser::SetupDecodingAndWri
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   nsresult rv = NS_OK;
   nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
   if (rv == NS_ERROR_UCONV_NOCONV) {
     mCharset.AssignLiteral("windows-1252"); // lower case is the raw form
-    mCharsetSource = kCharsetFromWeakDocTypeDefault;
+    mCharsetSource = kCharsetFromFallback;
     rv = convManager->GetUnicodeDecoderRaw(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
     mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   }
   NS_ENSURE_SUCCESS(rv, rv);
   return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
 }
 
 nsresult
@@ -607,20 +607,20 @@ nsHtml5StreamParser::FinalizeSniffing(co
       rv = mChardet->Done();
       NS_ENSURE_SUCCESS(rv, rv);
     }
     // fall thru; callback may have changed charset  
   }
   if (mCharsetSource == kCharsetUninitialized) {
     // Hopefully this case is never needed, but dealing with it anyway
     mCharset.AssignLiteral("windows-1252");
-    mCharsetSource = kCharsetFromWeakDocTypeDefault;
+    mCharsetSource = kCharsetFromFallback;
     mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   } else if (mMode == LOAD_AS_DATA &&
-             mCharsetSource == kCharsetFromWeakDocTypeDefault) {
+             mCharsetSource == kCharsetFromFallback) {
     NS_ASSERTION(mReparseForbidden, "Reparse should be forbidden for XHR");
     NS_ASSERTION(!mFeedChardet, "Should not feed chardet for XHR");
     NS_ASSERTION(mCharset.EqualsLiteral("UTF-8"),
                  "XHR should default to UTF-8");
     // Now mark charset source as non-weak to signal that we have a decision
     mCharsetSource = kCharsetFromDocTypeDefault;
     mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   }
@@ -726,17 +726,17 @@ nsHtml5StreamParser::SniffStreamBytes(co
       mMetaScanner = nullptr;
       return WriteSniffingBufferAndCurrentSegment(aFromSegment,
                                                   aCount,
                                                   aWriteCount);
     } else {
       // nsHTMLDocument is supposed to make sure this does not happen. Let's
       // deal with this anyway, since who knows how kCharsetFromOtherComponent
       // is used.
-      mCharsetSource = kCharsetFromWeakDocTypeDefault;
+      mCharsetSource = kCharsetFromFallback;
     }
   }
 
   if (!mMetaScanner && (mMode == NORMAL ||
                         mMode == VIEW_SOURCE_HTML ||
                         mMode == LOAD_AS_DATA)) {
     mMetaScanner = new nsHtml5MetaScanner();
   }
@@ -976,17 +976,17 @@ nsHtml5StreamParser::OnStartRequest(nsIR
 
   // Instantiate the converter here to avoid BOM sniffing.
   nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
   // if we failed to get a decoder, there will be fallback, so don't propagate
   //  the error.
   if (NS_FAILED(rv)) {
-    mCharsetSource = kCharsetFromWeakDocTypeDefault;
+    mCharsetSource = kCharsetFromFallback;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHtml5StreamParser::CheckListenerChain()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
--- a/parser/nsCharsetSource.h
+++ b/parser/nsCharsetSource.h
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCharsetSource_h_
 #define nsCharsetSource_h_
 
 // note: the value order defines the priority; higher numbers take priority
 #define kCharsetUninitialized           0
-#define kCharsetFromWeakDocTypeDefault  1
+#define kCharsetFromFallback            1
 #define kCharsetFromDocTypeDefault      2 // This and up confident for XHR
 #define kCharsetFromCache               3
 #define kCharsetFromParentFrame         4
 #define kCharsetFromAutoDetection       5
 #define kCharsetFromHintPrevDoc         6
 #define kCharsetFromMetaPrescan         7 // this one and smaller: HTML5 Tentative
 #define kCharsetFromMetaTag             8 // this one and greater: HTML5 Confident
 #define kCharsetFromIrreversibleAutoDetection 9
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -422,11 +422,319 @@
     "content/html/content/test/test_bug481335.xhtml":"timed out, bug 870262, :visited support",
     "layout/style/test/test_visited_image_loading.html":"bug 870262, :visited support",
     "layout/style/test/test_visited_image_loading_empty.html":"bug 870262, :visited support",
     "layout/style/test/test_visited_lying.html" : "bug 870262, :visited support",
     "layout/style/test/test_visited_pref.html" : "bug 870262, :visited support",
     "layout/style/test/test_visited_reftests.html":"bug 870262, :visited support",
 
     "Harness_sanity/test_sanityEventUtils.html": "bug 688052",
-    "Harness_sanity/test_sanitySimpletest.html": "bug 688052"
+    "Harness_sanity/test_sanitySimpletest.html": "bug 688052",
+
+    "caps/tests/mochitest/test_bug292789.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/base/test/csp/test_policyuri_regression_from_multipolicy.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/base/test/test_bug326337.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/base/test/test_bug426646.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/base/test/test_bug557892.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/base/test/test_bug578096.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/base/test/test_copyimage.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug322588.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug493251.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug545268.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug650493.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug656379-1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug656379-2.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug656954.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug659350.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug662678.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug667612.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug698929.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug741666.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug742376.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug812744.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug847597.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug855741.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_bug864040.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_clickevent_on_input.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_dblclick_explicit_original_target.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_dom_keyboard_event.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_dom_mouse_event.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_draggableprop.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_eventctors.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_focus_disabled.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/events/test/test_moz_mouse_pixel_scroll_event.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/forms/test_button_attributes_reflection.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/forms/test_change_event.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/forms/test_form_attribute-1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/forms/test_input_event.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/forms/test_input_range_key_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/forms/test_input_range_rounding.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_bug633058.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_bug643051.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_bug651956.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_bug659743.xml": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_bug674558.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_iframe_sandbox_general.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_iframe_sandbox_modal.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_iframe_sandbox_popups.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_iframe_sandbox_popups_inheritance.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/content/test/test_mozaudiochannel.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/document/test/test_bug196523.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/document/test/test_bug199692.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/html/document/test/test_bug871161.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/xbl/test/test_bug310107.html": "Bug 931116, b2g desktop specific, initial triage",
+    "content/xml/document/test/test_bug691215.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/navigation/test_bug278916.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/navigation/test_bug279495.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/navigation/test_bug430723.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/navigation/test_opener.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/navigation/test_sessionhistory.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/navigation/test_sibling-off-domain.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bfcache_plus_hash.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug369814.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug404548.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug509055.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug529119-1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug529119-2.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug540462.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug598895.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug637644.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug640387_1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug660404.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug669671.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug680257.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_bug728939.html": "Bug 931116, b2g desktop specific, initial triage",
+    "docshell/test/test_windowedhistoryframes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/alarm/test/test_alarm_add_data.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/alarm/test/test_alarm_add_date.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/alarm/test/test_alarm_add_respectTimezone.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/alarm/test/test_alarm_remove.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/base/test/test_setting_opener.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/datastore/tests/test_oop.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/datastore/tests/test_readonly.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/datastore/tests/test_revision.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/datastore/tests/test_sync.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_add_put.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_add_twice_failure.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_advance.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_app_isolation_inproc.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_app_isolation_oop.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_autoIncrement.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_autoIncrement_indexes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_bfcache.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_blob_archive.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_blob_simple.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_clear.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_complex_keyPaths.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_count.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_create_index.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_create_index_with_integer_keys.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_create_objectStore.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_cursor_mutation.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_cursor_update_updates_indexes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_cursors.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_deleteDatabase.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_deleteDatabase_interactions.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_error_events_abort_transactions.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_event_propagation.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_event_source.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_exceptions_in_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_array.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_cross_database_copying.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_delete.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_os_delete.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_put_get_object.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_put_get_values.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_quota.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_replace.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_resurrection_delete.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_resurrection_transaction_abort.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_sharing.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_file_transaction_abort.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_filehandle_quota.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_filehandle_serialization.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_filehandle_store_snapshot.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_getAll.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_get_filehandle.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_globalObjects.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_global_data.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_index_empty_keyPath.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_index_getAll.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_index_getAllObjects.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_index_object_cursors.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_index_update_delete.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_indexes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_indexes_bad_values.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_indexes_funny_things.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_key_requirements.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_keys.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_leaving_page.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_multientry.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_names_sorted.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_objectCursors.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_objectStore_getAllKeys.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_objectStore_inline_autoincrement_key_added_on_put.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_objectStore_openKeyCursor.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_objectStore_remove_values.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_object_identity.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_odd_result_order.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_open_empty_db.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_open_for_principal.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_open_objectStore.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_optionalArguments.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_overlapping_transactions.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_persistenceType.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_put_get_values.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_put_get_values_autoIncrement.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_readonly_transactions.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_remove_index.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_remove_objectStore.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_request_readyState.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_setVersion.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_setVersion_abort.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_setVersion_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_setVersion_exclusion.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_success_events_after_abort.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_third_party.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_traffic_jam.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_transaction_abort.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_transaction_abort_hang.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_transaction_lifetimes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_transaction_lifetimes_nested.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_transaction_ordering.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_unique_index_update.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_webapp_clearBrowserData_inproc_inproc.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_webapp_clearBrowserData_inproc_oop.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/indexedDB/test/test_webapp_clearBrowserData_oop_inproc.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/permission/tests/test_embed-apps.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/permission/tests/test_wifi-manage.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_GCrace.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_NPNVdocumentOrigin.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_NPPVpluginWantsAllNetworkStreams.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug532208.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug539565-1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug539565-2.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug771202.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug777098.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug784131.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug813906.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug854082.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_bug863792.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_cookies.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_copyText.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_crash_nested_loop.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_crashing.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_defaultValue.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_enumerate.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_fullpage.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_getauthenticationinfo.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_hanging.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_instance_re-parent.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_instance_unparent1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_instance_unparent2.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_instance_unparent3.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_instantiation.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_multipleinstanceobjects.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_newstreamondestroy.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npn_asynccall.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npn_timers.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npobject_getters.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npruntime_construct.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npruntime_identifiers.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npruntime_npnevaluate.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npruntime_npninvoke.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npruntime_npninvokedefault.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_npruntime_npnsetexception.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_painting.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_asfile.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_asfileonly.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_err.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_geturl.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_geturlnotify.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_newstream.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_post.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_poststream.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_referer.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_seek.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_seek_close.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_src.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_src_dynamic.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_pluginstream_src_referer.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_propertyAndMethod.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_redirect_handling.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_secondPlugin.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_src_url_change.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_streamNotify.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_streamatclose.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_twostreams.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_visibility.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/plugins/test/mochitest/test_zero_opacity.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug346659.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug38959.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug458091.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug49312.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug562433.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug593174.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug622361.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/bugs/test_bug648465.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/dom-level0/test_innerWidthHeight_script.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_connect_events.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_frame_state_sync.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_gamepad_hidden_frame.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/gamepad/test_navigator_gamepads.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_497898.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test__content.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_bug628069_1.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_bug631440.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_frameElementWrapping.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_framedhistoryframes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_interfaces.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_offsets.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_outerHTML.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_outerHTML.xhtml": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_stylesheetPI.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_vibrator.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_windowProperties.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/general/test_windowedhistoryframes.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/sessionstorage/test_sessionStorageClone.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/sessionstorage/test_sessionStorageReplace.html": "Bug 931116, b2g desktop specific, initial triage",
+    "dom/tests/mochitest/whatwg/test_postMessage_closed.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_bug607529.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_bug749186.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_bug770106.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_bug842853.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_bug842853-2.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_bug858459.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_reftests_with_caret.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/base/tests/test_remote_frame.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/generic/test/test_bug735641.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/generic/test/test_bug784410.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/generic/test/test_plugin_clipping.xhtml": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/generic/test/test_plugin_clipping2.xhtml": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/generic/test/test_plugin_clipping_table.xhtml": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/generic/test/test_plugin_clipping_transformed.xhtml": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/style/test/test_property_syntax_errors.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/style/test/test_redundant_font_download.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/style/test/test_rem_unit.html": "Bug 931116, b2g desktop specific, initial triage",
+    "layout/style/test/test_rule_serialization.html": "Bug 931116, b2g desktop specific, initial triage",
+    "toolkit/devtools/apps/tests/test_webapps_actor.html": "Bug 931116, b2g desktop specific, initial triage"
   }
 }
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -131,16 +131,18 @@ class MochitestRunner(MozbuildObject):
         options = parser.parse_args([])[0]
 
         if test_path:
             test_root_file = mozpack.path.join(self.mochitest_dir, 'tests', test_path)
             if not os.path.exists(test_root_file):
                 print('Specified test path does not exist: %s' % test_root_file)
                 return 1
             options.testPath = test_path
+        elif conditions.is_b2g_desktop:
+            options.testManifest = 'b2g-desktop.json'
         else:
             options.testManifest = 'b2g.json'
 
         for k, v in kwargs.iteritems():
             setattr(options, k, v)
 
         options.consoleLevel = 'INFO'
         if conditions.is_b2g_desktop(self):
--- a/toolkit/components/passwordmgr/test/chrome.ini
+++ b/toolkit/components/passwordmgr/test/chrome.ini
@@ -1,7 +1,9 @@
 [DEFAULT]
 support-files =
   formsubmit.sjs
   notification_common.js
   pwmgr_common.js
 
 [test_privbrowsing_perwindowpb.html]
+# Too many intermittent failures (bug 919016)
+skip-if = os == "win"
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -559,17 +559,18 @@ function queryCharsetFromCode(aCode) {
   codes[2561] = "Shift_JIS";
   codes[2562] = "KOI8-R";
   codes[2563] = "Big5";
   codes[2565] = "HZ-GB-2312";
 
   if (codes[aCode])
     return codes[aCode];
 
-  return getLocalizedPref("intl.charset.default", DEFAULT_QUERY_CHARSET);
+  // Don't bother being fancy about what to return in the failure case.
+  return "windows-1252";
 }
 function fileCharsetFromCode(aCode) {
   const codes = [
     "macintosh",             // 0
     "Shift_JIS",             // 1
     "Big5",                  // 2
     "EUC-KR",                // 3
     "X-MAC-ARABIC",          // 4
--- a/toolkit/locales/en-US/chrome/global-platform/mac/intl.properties
+++ b/toolkit/locales/en-US/chrome/global-platform/mac/intl.properties
@@ -1,9 +1,7 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# moved from navigator/locale/navigator.properties
-intl.charset.default=ISO-8859-1
 # LOCALIZATION NOTE (intl.ellipsis): Use the unicode ellipsis char, \u2026,
 # or use "..." if \u2026 doesn't suit traditions in your locale.
 intl.ellipsis=…
--- a/toolkit/locales/en-US/chrome/global-platform/unix/intl.properties
+++ b/toolkit/locales/en-US/chrome/global-platform/unix/intl.properties
@@ -1,9 +1,7 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# moved from navigator/locale/navigator.properties
-intl.charset.default=ISO-8859-1
 # LOCALIZATION NOTE (intl.ellipsis): Use the unicode ellipsis char, \u2026,
 # or use "..." if \u2026 doesn't suit traditions in your locale.
 intl.ellipsis=…
--- a/toolkit/locales/en-US/chrome/global-platform/win/intl.properties
+++ b/toolkit/locales/en-US/chrome/global-platform/win/intl.properties
@@ -1,9 +1,7 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# moved from navigator/locale/navigator.properties
-intl.charset.default=ISO-8859-1
 # LOCALIZATION NOTE (intl.ellipsis): Use the unicode ellipsis char, \u2026,
 # or use "..." if \u2026 doesn't suit traditions in your locale.
 intl.ellipsis=…
--- a/toolkit/locales/en-US/chrome/global/intl.properties
+++ b/toolkit/locales/en-US/chrome/global/intl.properties
@@ -35,28 +35,27 @@ intl.accept_languages=en-US, en
 # LOCALIZATION NOTE (font.language.group):
 # This preference controls the initial setting of the language drop-down menu
 # in the Content > Fonts & Colors > Advanced preference panel.
 #
 # Set it to the value of one of the menuitems in the "selectLangs" menulist in
 # http://mxr.mozilla.org/mozilla/source/browser/components/preferences/fonts.xul
 font.language.group=x-western
 
-# LOCALIZATION NOTE (intl.charset.detector, intl.charset.default, intl.charsetmenu.browser.static, intl.charsetmenu.mailedit):
+# LOCALIZATION NOTE (intl.charset.detector, intl.charsetmenu.browser.static, intl.charsetmenu.mailedit):
 # For the list of canonical charset values, refer to:
 # http://mxr.mozilla.org/mozilla-central/source/intl/locale/src/charsetalias.properties
 #
 # If you are modifying the charset preferences for your locale, be sure to use
 # the values from that list, not the keys. Note that these values are
 # case-sensitive and must be reproduced exactly as listed.
 #
 # Note also that the list of charsets in 'intl.charsetmenu.browser.static'
 # must always include "UTF-8".
 intl.charset.detector=
-intl.charset.default=ISO-8859-1
 intl.charsetmenu.browser.static=ISO-8859-1, UTF-8
 intl.charsetmenu.mailedit=ISO-8859-1, ISO-8859-15, ISO-8859-6, armscii-8, ISO-8859-13, ISO-8859-14, ISO-8859-2, GB2312, GB18030, Big5, KOI8-R, windows-1251, KOI8-U, ISO-8859-7, ISO-8859-8-I, windows-1255, ISO-2022-JP, EUC-KR, ISO-8859-10, ISO-8859-3, TIS-620, ISO-8859-9, UTF-8, VISCII
 
 # LOCALIZATION NOTE (pluralRule): Pick the appropriate plural rule for your
 # language. This will determine how many plural forms of a word you will need
 # to provide and in what order.
 # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
 pluralRule=1
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -188,24 +188,21 @@ AndroidBridge::Init(JNIEnv *jEnv)
 
     if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mAPIVersion, jEnv)) {
         ALOG_BRIDGE("Failed to find API version");
     }
 
     jSurfaceClass = getClassGlobalRef("android/view/Surface");
     if (mAPIVersion <= 8 /* Froyo */) {
         jSurfacePointerField = getField("mSurface", "I");
-    } else {
+    } else if (mAPIVersion > 8 && mAPIVersion < 19 /* KitKat */) {
         jSurfacePointerField = getField("mNativeSurface", "I");
-
-        // Apparently mNativeSurface doesn't exist in Key Lime Pie, so just clear the
-        // exception if we have one and move on.
-        if (jEnv->ExceptionCheck()) {
-            jEnv->ExceptionClear();
-        }
+    } else {
+        // We don't know how to get this, just set it to 0
+        jSurfacePointerField = 0;
     }
 
     jclass eglClass = getClassGlobalRef("com/google/android/gles_jni/EGLSurfaceImpl");
     if (eglClass) {
         jEGLSurfacePointerField = getField("mEGLSurface", "I");
     } else {
         jEGLSurfacePointerField = 0;
     }
--- a/xpcom/tests/TestPLDHash.cpp
+++ b/xpcom/tests/TestPLDHash.cpp
@@ -13,18 +13,17 @@
 // which are unlikely to be hit during normal execution.
 
 namespace TestPLDHash {
 
 static bool test_pldhash_Init_capacity_ok()
 {
   // Try the largest allowed capacity.  With PL_DHASH_MAX_SIZE==1<<26, this
   // will allocate 0.5GB of entry store on 32-bit platforms and 1GB on 64-bit
-  // platforms.  Hopefully that's not too much for the test machines to handle
-  // reliably.
+  // platforms.
   PLDHashTable t;
   bool ok = PL_DHashTableInit(&t, PL_DHashGetStubOps(), nullptr,
                               sizeof(PLDHashEntryStub), PL_DHASH_MAX_SIZE);
   if (ok)
     PL_DHashTableFinish(&t);
 
   return ok;
 }
@@ -57,16 +56,18 @@ static bool test_pldhash_Init_overflow()
   // |nullptr| for |ops| is ok because it's unused due to the failure.
   PLDHashTable t;
   bool ok = PL_DHashTableInit(&t, /* ops = */nullptr, nullptr,
                               sizeof(OneKBEntry), PL_DHASH_MAX_SIZE);
 
   return !ok;   // expected to fail
 }
 
+// See bug 931062, we skip this test on Android due to OOM.
+#ifndef MOZ_WIDGET_ANDROID
 // We insert the integers 0.., so this is has function is (a) as simple as
 // possible, and (b) collision-free.  Both of which are good, because we want
 // this test to be as fast as possible.
 static PLDHashNumber
 hash(PLDHashTable *table, const void *key)
 {
   return (PLDHashNumber)(size_t)key;
 }
@@ -97,30 +98,34 @@ static bool test_pldhash_grow_to_max_cap
     }
     numInserted++;
   }
 
   // We stop when the element count is 96.875% of PL_DHASH_MAX_SIZE (see
   // MaxLoadOnGrowthFailure()).
   return numInserted == PL_DHASH_MAX_SIZE - (PL_DHASH_MAX_SIZE >> 5);
 }
+#endif
 
 //----
 
 typedef bool (*TestFunc)();
 #define DECL_TEST(name) { #name, name }
 
 static const struct Test {
   const char* name;
   TestFunc    func;
 } tests[] = {
   DECL_TEST(test_pldhash_Init_capacity_ok),
   DECL_TEST(test_pldhash_Init_capacity_too_large),
   DECL_TEST(test_pldhash_Init_overflow),
+// See bug 931062, we skip this test on Android due to OOM.
+#ifndef MOZ_WIDGET_ANDROID
   DECL_TEST(test_pldhash_grow_to_max_capacity),
+#endif
   { nullptr, nullptr }
 };
 
 } // namespace TestPLDHash
 
 using namespace TestPLDHash;
 
 int main(int argc, char *argv[])
--- a/xulrunner/config/mozconfigs/macosx-universal/xulrunner
+++ b/xulrunner/config/mozconfigs/macosx-universal/xulrunner
@@ -1,8 +1,9 @@
 . $topsrcdir/build/macosx/universal/mozconfig
 
 export MOZILLA_OFFICIAL=1
 
 ac_add_options --enable-application=xulrunner
 ac_add_options --disable-tests
+ac_add_options --with-xulrunner-stub-name=xulrunner-stub
 
 . "$topsrcdir/xulrunner/config/mozconfigs/common.override"
--- a/xulrunner/stub/moz.build
+++ b/xulrunner/stub/moz.build
@@ -3,18 +3,18 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'xulrunner'
 
 # The value of XULRUNNER_STUB_NAME is generated by configure to allow XULRunner
 # apps to override it using the --with-xulrunner-stub-name=<appname> argument.
-# If this configure argument is not present then the default name is 'xulrunner'
-# for Mac OS X and 'xulrunner-stub' for all other platforms.
+# If this configure argument is not present then the default name is
+# 'xulrunner-stub'.
 PROGRAM = CONFIG['XULRUNNER_STUB_NAME']
 
 SOURCES += [
     'nsXULStub.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     FINAL_TARGET = 'dist/XUL.framework/Versions/%(MOZILLA_VERSION)s' % CONFIG
--- a/xulrunner/stub/nsXULStub.cpp
+++ b/xulrunner/stub/nsXULStub.cpp
@@ -345,34 +345,34 @@ main(int argc, char **argv)
   rv = parser.Init(iniPath);
   if (NS_FAILED(rv)) {
     fprintf(stderr, "Could not read application.ini\n");
     return 1;
   }
 
   if (!greFound) {
 #ifdef XP_MACOSX
-    // Check for <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib
+    // Check for <bundle>/Contents/Frameworks/XUL.framework/Versions/Current/libmozglue.dylib
     CFURLRef fwurl = CFBundleCopyPrivateFrameworksURL(appBundle);
     CFURLRef absfwurl = nullptr;
     if (fwurl) {
       absfwurl = CFURLCopyAbsoluteURL(fwurl);
       CFRelease(fwurl);
     }
 
     if (absfwurl) {
       CFURLRef xulurl =
         CFURLCreateCopyAppendingPathComponent(nullptr, absfwurl,
-                                              CFSTR("XUL.framework"),
+                                              CFSTR("XUL.framework/Versions/Current"),
                                               true);
 
       if (xulurl) {
         CFURLRef xpcomurl =
           CFURLCreateCopyAppendingPathComponent(nullptr, xulurl,
-                                                CFSTR("libxpcom.dylib"),
+                                                CFSTR("libmozglue.dylib"),
                                                 false);
 
         if (xpcomurl) {
           char tbuffer[MAXPATHLEN];
 
           if (CFURLGetFileSystemRepresentation(xpcomurl, true,
                                                (UInt8*) tbuffer,
                                                sizeof(tbuffer)) &&