Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 04 Nov 2013 16:33:35 -0500
changeset 153429 94a672274c2b319732713e02527a542e6b63ae1b
parent 153428 311650f884516d100d36e4d61fedbffe2ca18704 (current diff)
parent 153398 7d298c4380ad7e0f65c421a7ae6345bfb7a3f3f5 (diff)
child 153430 a8131d677d9b5d640e18cb3cab06f669a2175050
push id25587
push userkwierso@gmail.com
push dateTue, 05 Nov 2013 05:07:06 +0000
treeherdermozilla-central@b0bce439c6e2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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)) &&