Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 16 Jan 2014 15:09:31 -0500
changeset 163907 0ea571a61e42c66cbb43f24f15903751550d1bf2
parent 163906 5d45e6b035a3f01377acd17a1b966cb1d14e129f (current diff)
parent 163847 bcbe93f41547d8cbd8bebc916f108c2dbb4d39ac (diff)
child 163908 52058b81ff1fc95c4ab97e325c0b1de0805486fc
push id38584
push usercbook@mozilla.com
push dateFri, 17 Jan 2014 10:04:30 +0000
treeherdermozilla-inbound@28a9d7e2416f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.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.
content/base/src/nsFrameMessageManager.cpp
dom/network/interfaces/nsIDOMConnection.idl
toolkit/components/url-classifier/content/url-crypto-key-manager.js
toolkit/components/url-classifier/tests/unit/test_keymanager.js
toolkit/themes/windows/global/arrow/panelarrow-horizontal-white.png
toolkit/themes/windows/global/arrow/panelarrow-vertical-white.png
--- a/.lldbinit
+++ b/.lldbinit
@@ -1,10 +1,15 @@
 # .lldbinit file for debugging Mozilla
 
+# -----------------------------------------------------------------------------
+# For documentation on all of the commands and type summaries defined here
+# and in the accompanying Python scripts, see python/lldbutils/README.txt.
+# -----------------------------------------------------------------------------
+
 # Mozilla's use of UNIFIED_SOURCES to include multiple source files into a
 # single compiled file breaks lldb breakpoint setting. This works around that.
 # See http://lldb.llvm.org/troubleshooting.html for more info.
 settings set target.inline-breakpoint-strategy always
 
 # Show the dynamic type of an object when using "expr".  This, for example,
 # will show a variable declared as "nsIFrame *" that points to an nsBlockFrame
 # object as being of type "nsBlockFrame *" rather than "nsIFrame *".
@@ -15,8 +20,11 @@ settings set target.prefer-dynamic-value
 # the top level source directory.
 script sys.path.append('python/lldbutils'); import lldbutils; lldbutils.init()
 
 # Show the string value in atoms.
 type summary add nsIAtom --summary-string "${var.mString}"
 
 # Show the value of text nodes.
 type summary add nsTextNode --summary-string "${var.mText}"
+
+# Dump the current JS stack.
+command alias js expr DumpJSStack()
--- a/addon-sdk/source/python-lib/cuddlefish/prefs.py
+++ b/addon-sdk/source/python-lib/cuddlefish/prefs.py
@@ -57,17 +57,16 @@ DEFAULT_FIREFOX_PREFS = {
     'devtools.chrome.enabled' : True,
 
     # From:
     # http://hg.mozilla.org/mozilla-central/file/1dd81c324ac7/build/automation.py.in#l388
     # Make url-classifier updates so rare that they won't affect tests.
     'urlclassifier.updateinterval' : 172800,
     # Point the url-classifier to a nonexistent local URL for fast failures.
     'browser.safebrowsing.provider.0.gethashURL' : 'http://localhost/safebrowsing-dummy/gethash',
-    'browser.safebrowsing.provider.0.keyURL' : 'http://localhost/safebrowsing-dummy/newkey',
     'browser.safebrowsing.provider.0.updateURL' : 'http://localhost/safebrowsing-dummy/update',
     }
 
 # When launching a temporary new Thunderbird profile, use these preferences.
 # Note that these were taken from:
 # http://mxr.mozilla.org/comm-central/source/mail/test/mozmill/runtest.py
 DEFAULT_THUNDERBIRD_PREFS = {
     # say no to slow script warnings
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -238,31 +238,33 @@ pref("ui.-moz-buttonhovertext", "#101010
 pref("ui.-moz-combobox", "#fff");
 pref("ui.-moz-comboboxtext", "#101010");
 pref("ui.buttonface", "#ece7e2");
 pref("ui.buttonhighlight", "#fff");
 pref("ui.buttonshadow", "#aea194");
 pref("ui.buttontext", "#101010");
 pref("ui.captiontext", "#101010");
 pref("ui.graytext", "#b1a598");
-pref("ui.highlight", "#fad184");
 pref("ui.highlighttext", "#1a1a1a");
-pref("ui.infobackground", "#f5f5b5");
-pref("ui.infotext", "#000");
-pref("ui.menu", "#f7f5f3");
-pref("ui.menutext", "#101010");
 pref("ui.threeddarkshadow", "#000");
 pref("ui.threedface", "#ece7e2");
 pref("ui.threedhighlight", "#fff");
 pref("ui.threedlightshadow", "#ece7e2");
 pref("ui.threedshadow", "#aea194");
-pref("ui.window", "#efebe7");
-pref("ui.windowtext", "#101010");
 pref("ui.windowframe", "#efebe7");
 
+// Themable via mozSettings
+pref("ui.menu", "#f97c17");
+pref("ui.menutext", "#ffffff");
+pref("ui.infobackground", "#343e40");
+pref("ui.infotext", "#686868");
+pref("ui.window", "#ffffff");
+pref("ui.windowtext", "#000000");
+pref("ui.highlight", "#b2f2ff");
+
 // replace newlines with spaces on paste into single-line text boxes
 pref("editor.singleLine.pasteNewlines", 2);
 
 // threshold where a tap becomes a drag, in 1/240" reference pixels
 // The names of the preferences are to be in sync with nsEventStateManager.cpp
 pref("ui.dragThresholdX", 25);
 pref("ui.dragThresholdY", 25);
 
@@ -275,17 +277,16 @@ pref("layers.offmainthreadcomposition.as
 pref("layers.async-video.enabled", false);
 #else
 pref("dom.ipc.tabs.disabled", false);
 pref("layers.acceleration.disabled", false);
 pref("layers.offmainthreadcomposition.async-animations", true);
 pref("layers.async-video.enabled", true);
 pref("layers.async-pan-zoom.enabled", true);
 pref("gfx.content.azure.backends", "cairo");
-pref("layers.composer2d.enabled", true);
 #endif
 
 // Web Notifications
 pref("notification.feature.enabled", true);
 
 // IndexedDB
 pref("dom.indexedDB.warningQuota", 5);
 
@@ -315,25 +316,24 @@ pref("dom.w3c_touch_events.safetyY", 120
 #ifdef MOZ_SAFE_BROWSING
 // Safe browsing does nothing unless this pref is set
 pref("browser.safebrowsing.enabled", true);
 
 // Prevent loading of pages identified as malware
 pref("browser.safebrowsing.malware.enabled", true);
 
 // Non-enhanced mode (local url lists) URL list to check for updates
-pref("browser.safebrowsing.provider.0.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.2");
+pref("browser.safebrowsing.provider.0.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.2&key=%GOOGLE_API_KEY%");
 
 pref("browser.safebrowsing.dataProvider", 0);
 
 // Does the provider name need to be localizable?
 pref("browser.safebrowsing.provider.0.name", "Google");
-pref("browser.safebrowsing.provider.0.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client={moz:client}&appver={moz:version}&pver=2.2");
-pref("browser.safebrowsing.provider.0.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
-pref("browser.safebrowsing.provider.0.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.2");
+pref("browser.safebrowsing.provider.0.reportURL", "https://safebrowsing.google.com/safebrowsing/report?");
+pref("browser.safebrowsing.provider.0.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.2");
 
 // HTML report pages
 pref("browser.safebrowsing.provider.0.reportGenericURL", "http://{moz:locale}.phish-generic.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportErrorURL", "http://{moz:locale}.phish-error.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phish-report.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportMalwareURL", "http://{moz:locale}.malware-report.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
 
@@ -348,17 +348,17 @@ pref("urlclassifier.alternate_error_page
 pref("urlclassifier.gethashnoise", 4);
 
 // If an urlclassifier table has not been updated in this number of seconds,
 // a gethash request will be forced to check that the result is still in
 // the database.
 pref("urlclassifier.max-complete-age", 2700);
 
 // URL for checking the reason for a malware warning.
-pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
+pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 #endif
 
 // True if this is the first time we are showing about:firstrun
 pref("browser.firstrun.show.uidiscovery", true);
 pref("browser.firstrun.show.localepicker", true);
 
 // initiated by a user
 pref("content.ime.strict_policy", true);
@@ -614,19 +614,21 @@ pref("javascript.options.mem.gc_allocati
 pref("javascript.options.mem.gc_decommit_threshold_mb", 1);
 
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
 pref("ui.useOverlayScrollbars", 1);
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
-// background.
+// background. Background processes that are perceivable due to playing
+// media are given a longer grace period to accomodate changing tracks, etc.
 pref("dom.ipc.processPriorityManager.enabled", true);
 pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
+pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000);
 pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
 
 // Number of different background levels for background processes.  We use
 // these different levels to force the low-memory killer to kill processes in
 // a LRU order.
 pref("dom.ipc.processPriorityManager.backgroundLRUPoolLevels", 5);
 
 // Kernel parameters for process priorities.  These affect how processes are
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -592,19 +592,62 @@ SettingsListener.observe("debug.fps.enab
   Services.prefs.setBoolPref("layers.acceleration.draw-fps", value);
 });
 SettingsListener.observe("debug.paint-flashing.enabled", false, function(value) {
   Services.prefs.setBoolPref("nglayout.debug.paint_flashing", value);
 });
 SettingsListener.observe("layers.draw-borders", false, function(value) {
   Services.prefs.setBoolPref("layers.draw-borders", value);
 });
-SettingsListener.observe("layers.composer2d.enabled", true, function(value) {
-  Services.prefs.setBoolPref("layers.composer2d.enabled", value);
-});
+
+(function Composer2DSettingToPref() {
+  //layers.composer.enabled can be enabled in three ways
+  //In order of precedence they are:
+  //
+  //1. mozSettings "layers.composer.enabled"
+  //2. a gecko pref "layers.composer.enabled"
+  //3. presence of ro.display.colorfill at the Gonk level
+
+  var req = navigator.mozSettings.createLock().get('layers.composer2d.enabled');
+  req.onsuccess = function() {
+    if (typeof(req.result['layers.composer2d.enabled']) === 'undefined') {
+      var enabled = false;
+      if (Services.prefs.getPrefType('layers.composer2d.enabled') == Ci.nsIPrefBranch.PREF_BOOL) {
+        enabled = Services.prefs.getBoolPref('layers.composer2d.enabled');
+      } else {
+#ifdef MOZ_WIDGET_GONK
+        enabled = (libcutils.property_get('ro.display.colorfill') === '1');
+#endif
+      }
+      navigator.mozSettings.createLock().set({'layers.composer2d.enabled': enabled });
+    }
+
+    SettingsListener.observe("layers.composer2d.enabled", true, function(value) {
+      Services.prefs.setBoolPref("layers.composer2d.enabled", value);
+    });
+  };
+  req.onerror = function() {
+    dump("Error configuring layers.composer2d.enabled setting");
+  };
+
+})();
 
 // ================ Accessibility ============
 SettingsListener.observe("accessibility.screenreader", false, function(value) {
   if (value && !("AccessFu" in this)) {
     Cu.import('resource://gre/modules/accessibility/AccessFu.jsm');
     AccessFu.attach(window);
   }
 });
+
+// ================ Theming ============
+(function themingSettingsListener() {
+  let themingPrefs = ['ui.menu', 'ui.menutext', 'ui.infobackground', 'ui.infotext',
+                      'ui.window', 'ui.windowtext', 'ui.highlight'];
+
+  themingPrefs.forEach(function(pref) {
+    SettingsListener.observe('gaia.' + pref, null, function(value) {
+      if (value) {
+        Services.prefs.setCharPref(pref, value);
+      }
+    });
+  });
+})();
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "35ba072bcabf79e9c32776e9322c41e0020c9264", 
+    "revision": "a4c7ffc5619edd7e87fd763bd8a32291f4d394ac", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -785,27 +785,26 @@ pref("gecko.handlerService.schemes.ircs.
 // By default, we don't want protocol/content handlers to be registered from a different host, see bug 402287
 pref("gecko.handlerService.allowRegisterFromDifferentHost", false);
 
 #ifdef MOZ_SAFE_BROWSING
 pref("browser.safebrowsing.enabled", true);
 pref("browser.safebrowsing.malware.enabled", true);
 pref("browser.safebrowsing.debug", false);
 
-pref("browser.safebrowsing.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
-pref("browser.safebrowsing.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
-pref("browser.safebrowsing.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
+pref("browser.safebrowsing.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
+pref("browser.safebrowsing.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
+pref("browser.safebrowsing.reportURL", "https://safebrowsing.google.com/safebrowsing/report?");
 pref("browser.safebrowsing.reportGenericURL", "http://%LOCALE%.phish-generic.mozilla.com/?hl=%LOCALE%");
 pref("browser.safebrowsing.reportErrorURL", "http://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%");
 pref("browser.safebrowsing.reportPhishURL", "http://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%");
 pref("browser.safebrowsing.reportMalwareURL", "http://%LOCALE%.malware-report.mozilla.com/?hl=%LOCALE%");
 pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%");
 
-pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
+pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 #ifndef MOZILLA_OFFICIAL
 pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download&key=%GOOGLE_API_KEY%");
 #endif
 
 #ifdef MOZILLA_OFFICIAL
 // Normally the "client ID" sent in updates is appinfo.name, but for
 // official Firefox releases from Mozilla we use a special identifier.
 pref("browser.safebrowsing.id", "navclient-auto-ffox");
--- a/browser/components/tabview/test/browser_tabview_bug625269.js
+++ b/browser/components/tabview/test/browser_tabview_bug625269.js
@@ -59,19 +59,18 @@ function onTabViewShown(win) {
   next();
 }
 
 // ----------
 function resizeWindow(win, diffX, diffY, callback) {
   let targetWidth = win.outerWidth + diffX;
   let targetHeight = win.outerHeight + diffY;
 
-  win.addEventListener("resize", function onResize() {
+  (function tryResize() {
     let {outerWidth: width, outerHeight: height} = win;
-    if (width != targetWidth || height != targetHeight)
-      return;
-
-    win.removeEventListener("resize", onResize, false);
-    executeSoon(callback);
-  }, false);
-
-  win.resizeBy(diffX, diffY);
+    if (width != targetWidth || height != targetHeight) {
+      win.resizeTo(targetWidth, targetHeight);
+      executeSoon(tryResize);
+    } else {
+      callback();
+    }
+  })();
 }
--- a/browser/devtools/styleinspector/test/browser_bug726427_csstransform_tooltip.js
+++ b/browser/devtools/styleinspector/test/browser_bug726427_csstransform_tooltip.js
@@ -142,17 +142,23 @@ function testTransformTooltipOnComputedV
 }
 
 function assertTooltipShownOn(tooltip, element, cb) {
   // If there is indeed a show-on-hover on element, the xul panel will be shown
   tooltip.panel.addEventListener("popupshown", function shown() {
     tooltip.panel.removeEventListener("popupshown", shown, true);
     cb();
   }, true);
-  tooltip._showOnHover(element);
+
+  // Run _showOnHover at stable state after the next refresh driver tick.
+  // This way nothing during reflow or painting should be able to
+  // cancel showing the popup.
+  element.ownerDocument.defaultView.requestAnimationFrame(() => {
+      executeSoon(() => { tooltip._showOnHover(element); });
+    });
 }
 
 function assertTooltipNotShownOn(tooltip, element, cb) {
   // The only way to make sure the tooltip is not shown is try and show it, wait
   // for a given amount of time, and then check if it's shown or not
   tooltip._showOnHover(element);
   setTimeout(() => {
     ok(!tooltip.isShown(), "The tooltip did not appear on hover of the element");
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -680,17 +680,23 @@ Desktop browser's sync prefs.
                  type="bool"
                  title="&optionsHeader.reporting.crashes.label;" />
         <checkbox id="prefs-reporting-submitURLs"
                   cropped="end"
                   label="&optionsHeader.reporting.crashes.submitURLs;"
                   command="cmd_reportingCrashesSubmitURLs"/>
       </settings>
       <settings id="prefs-telemetry" label="&optionsHeader.telemetry.title;">
-        <setting pref="toolkit.telemetry.enabled" type="bool" title="&optionsHeader.telemetry.label;"/>
+        <setting
+#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
+          pref="toolkit.telemetry.enabledPreRelease"
+#else
+          pref="toolkit.telemetry.enabled"
+#endif
+          type="bool" title="&optionsHeader.telemetry.label;"/>
       </settings>
       <settings id="prefs-dnt" label="&doNotTrack.title;">
         <setting id="prefs-dnt-value" pref="privacy.donottrackheader.value" type="radio" >
           <radiogroup id="prefs-dnt-options">
             <radio id="prefs-dnt-notrack" class="flyoutpanel-hack"
                    label="&doNotTrack.options.doNotTrack;" value="1"/>
             <radio id="prefs-dnt-oktrack" class="flyoutpanel-hack"
                    label="&doNotTrack.options.doTrack;" value="0"/>
--- a/browser/metro/base/tests/mochitest/browser_selection_inputs.js
+++ b/browser/metro/base/tests/mochitest/browser_selection_inputs.js
@@ -182,17 +182,17 @@ gTests.push({
     let ypos = SelectionHelperUI.endMark.yPos + 10;
     yield touchdrag.start(gWindow, xpos, ypos, xpos, ypos + 150);
     // no touchend here, we want to continue the drag below
 
     yield SelectionHelperUI.pingSelectionHandler();
     is(getTrimmedSelection(gInput).toString(), "straight on like a tunnel for some way and then dipped suddenly down", "selection test");
 
     // left and up with no scrolling - selection should shrink
-    yield touchdrag.move(130, ystartpos);
+    yield touchdrag.move(135, ystartpos);
     touchdrag.end();
 
     yield SelectionHelperUI.pingSelectionHandler();
     is(getTrimmedSelection(gInput).toString(), "straight on like a tunnel for", "selection test");
   },
 });
 
 function test() {
--- a/browser/metro/profile/metro.js
+++ b/browser/metro/profile/metro.js
@@ -82,17 +82,21 @@ pref("toolkit.browser.contentViewExpire"
 
 
 pref("toolkit.defaultChromeURI", "chrome://browser/content/browser.xul");
 pref("browser.chromeURL", "chrome://browser/content/");
 
 pref("browser.tabs.remote", false);
 
 // Telemetry
+#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
+pref("toolkit.telemetry.enabledPreRelease", true);
+#else
 pref("toolkit.telemetry.enabled", true);
+#endif
 pref("toolkit.telemetry.prompted", 2);
 
 pref("toolkit.screen.lock", false);
 
 // From libpref/src/init/all.js. Disabling text zoom in favor of APZ zoom. See bug 936940.
 pref("zoom.minPercent", 100);
 pref("zoom.maxPercent", 100);
 pref("toolkit.zoomManager.zoomValues", "1");
@@ -575,25 +579,24 @@ pref("dom.w3c_touch_events.safetyY", 20)
 #ifdef MOZ_SAFE_BROWSING
 // Safe browsing does nothing unless this pref is set
 pref("browser.safebrowsing.enabled", true);
 
 // Prevent loading of pages identified as malware
 pref("browser.safebrowsing.malware.enabled", true);
 
 // Non-enhanced mode (local url lists) URL list to check for updates
-pref("browser.safebrowsing.provider.0.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.2");
+pref("browser.safebrowsing.provider.0.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.2&key=%GOOGLE_API_KEY%");
 
 pref("browser.safebrowsing.dataProvider", 0);
 
 // Does the provider name need to be localizable?
 pref("browser.safebrowsing.provider.0.name", "Google");
-pref("browser.safebrowsing.provider.0.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client={moz:client}&appver={moz:version}&pver=2.2");
-pref("browser.safebrowsing.provider.0.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
-pref("browser.safebrowsing.provider.0.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.2");
+pref("browser.safebrowsing.provider.0.reportURL", "https://safebrowsing.google.com/safebrowsing/report?");
+pref("browser.safebrowsing.provider.0.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.2");
 
 // HTML report pages
 pref("browser.safebrowsing.provider.0.reportGenericURL", "http://{moz:locale}.phish-generic.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportErrorURL", "http://{moz:locale}.phish-error.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phish-report.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportMalwareURL", "http://{moz:locale}.malware-report.mozilla.com/?hl={moz:locale}");
 pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
 
@@ -611,17 +614,17 @@ pref("urlclassifier.gethashnoise", 4);
 // a gethash request will be forced to check that the result is still in
 // the database.
 pref("urlclassifier.max-complete-age", 2700);
 
 // Maximum size of the sqlite3 cache during an update, in bytes
 pref("urlclassifier.updatecachemax", 41943040);
 
 // URL for checking the reason for a malware warning.
-pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
+pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 #endif
 
 // True if this is the first time we are showing about:firstrun
 pref("browser.firstrun.show.localepicker", false);
 
 // True if you always want dump() to work
 //
 // On Android, you also need to do the following for the output
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1484,17 +1484,17 @@ nsScriptSecurityManager::GetSubjectPrinc
     // or the one associated with its global.
     MOZ_ASSERT(!!compartment);
 
     JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
     return nsJSPrincipals::get(principals);
 }
 
 NS_IMETHODIMP
-nsScriptSecurityManager::GetObjectPrincipal(const JS::Value &aObjectVal,
+nsScriptSecurityManager::GetObjectPrincipal(JS::Handle<JS::Value> aObjectVal,
                                             JSContext *aCx,
                                             nsIPrincipal **result)
 {
     NS_ENSURE_TRUE(aObjectVal.isObject(), NS_ERROR_FAILURE);
     JS::RootedObject obj(aCx, &aObjectVal.toObject());
     nsCOMPtr<nsIPrincipal> principal = doGetObjectPrincipal(obj);
     principal.forget(result);
     return NS_OK;
--- a/config/config.mk
+++ b/config/config.mk
@@ -825,27 +825,36 @@ EXPAND_LD = $(EXPAND_LIBS_EXEC) --uselis
 EXPAND_MKSHLIB_ARGS = --uselist
 ifdef SYMBOL_ORDER
 EXPAND_MKSHLIB_ARGS += --symbol-order $(SYMBOL_ORDER)
 endif
 EXPAND_MKSHLIB = $(EXPAND_LIBS_EXEC) $(EXPAND_MKSHLIB_ARGS) -- $(MKSHLIB)
 
 ifneq (,$(MOZ_LIBSTDCXX_TARGET_VERSION)$(MOZ_LIBSTDCXX_HOST_VERSION))
 ifneq ($(OS_ARCH),Darwin)
-CHECK_STDCXX = objdump -p $(1) | grep -e 'GLIBCXX_3\.4\.\(9\|[1-9][0-9]\)' > /dev/null && echo 'TEST-UNEXPECTED-FAIL | | We do not want these libstdc++ symbols to be used:' && objdump -T $(1) | grep -e 'GLIBCXX_3\.4\.\(9\|[1-9][0-9]\)' && exit 1 || exit 0
+CHECK_STDCXX = @$(TOOLCHAIN_PREFIX)objdump -p $(1) | grep -e 'GLIBCXX_3\.4\.\(9\|[1-9][0-9]\)' > /dev/null && echo 'TEST-UNEXPECTED-FAIL | check_stdcxx | We do not want these libstdc++ symbols to be used:' && $(TOOLCHAIN_PREFIX)objdump -T $(1) | grep -e 'GLIBCXX_3\.4\.\(9\|[1-9][0-9]\)' && false || true
 endif
 
 ifdef MOZ_LIBSTDCXX_TARGET_VERSION
 EXTRA_LIBS += $(call EXPAND_LIBNAME_PATH,stdc++compat,$(DEPTH)/build/unix/stdc++compat)
 endif
 ifdef MOZ_LIBSTDCXX_HOST_VERSION
 HOST_EXTRA_LIBS += $(call EXPAND_LIBNAME_PATH,host_stdc++compat,$(DEPTH)/build/unix/stdc++compat)
 endif
 endif
 
+ifeq (,$(filter $(OS_TARGET),WINNT Darwin OS2))
+CHECK_TEXTREL = @$(TOOLCHAIN_PREFIX)readelf -d $(1) | grep TEXTREL > /dev/null && echo 'TEST-UNEXPECTED-FAIL | check_textrel | We do not want text relocations in libraries and programs' || true
+endif
+
+define CHECK_BINARY
+$(call CHECK_STDCXX,$(1))
+$(call CHECK_TEXTREL,$(1))
+endef
+
 # autoconf.mk sets OBJ_SUFFIX to an error to avoid use before including
 # this file
 OBJ_SUFFIX := $(_OBJ_SUFFIX)
 
 # PGO builds with GCC build objects with instrumentation in a first pass,
 # then objects optimized, without instrumentation, in a second pass. If
 # we overwrite the ojects from the first pass with those from the second,
 # we end up not getting instrumentation data for better optimization on
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -758,17 +758,17 @@ ifdef MSMANIFEST_TOOL
 endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 # touch it a few seconds into the future to work around FAT's
 # 2-second granularity
 	touch -t `date +%Y%m%d%H%M.%S -d 'now+5seconds'` pgo.relink
 endif
 else # !WINNT || GNU_CC
 	$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE) $(STLPORT_LIBS)
-	@$(call CHECK_STDCXX,$@)
+	$(call CHECK_BINARY,$@)
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $(STRIP_FLAGS) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
@@ -814,17 +814,17 @@ ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(STLPORT_LIBS)
-	@$(call CHECK_STDCXX,$@)
+	$(call CHECK_BINARY,$@)
 endif # WINNT && !GNU_CC
 
 ifdef ENABLE_STRIP
 	$(STRIP) $(STRIP_FLAGS) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
 	$(MOZ_POST_PROGRAM_COMMAND) $@
 endif
@@ -916,17 +916,17 @@ ifdef DTRACE_LIB_DEPENDENT
 ifndef XP_MACOSX
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
 endif
 	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
 	@$(RM) $(DTRACE_PROBE_OBJ)
 else # ! DTRACE_LIB_DEPENDENT
 	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(if $(LIB_IS_C_ONLY),,$(STLPORT_LIBS))
 endif # DTRACE_LIB_DEPENDENT
-	@$(call CHECK_STDCXX,$@)
+	$(call CHECK_BINARY,$@)
 
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 ifdef EMBED_MANIFEST_AT
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
 		rm -f $@.manifest; \
 	fi
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -291,17 +291,17 @@ public:
     // Lazily get the content type and size
     mContentType.SetIsVoid(true);
     mName.SetIsVoid(true);
   }
 
   // Overrides
   NS_IMETHOD GetSize(uint64_t* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetType(nsAString& aType) MOZ_OVERRIDE;
-  NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate) MOZ_OVERRIDE;
+  NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE;
   NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate) MOZ_OVERRIDE;
   NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
   NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
 
   void SetPath(const nsAString& aFullPath);
 
 protected:
   // Create slice
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -43,22 +43,22 @@ public:
   {
     return mReadyState;
   }
   DOMError* GetError() const
   {
     return mError;
   }
 
-  NS_METHOD GetOnabort(JSContext* aCx, JS::Value* aValue);
-  NS_METHOD SetOnabort(JSContext* aCx, const JS::Value& aValue);
-  NS_METHOD GetOnerror(JSContext* aCx, JS::Value* aValue);
-  NS_METHOD SetOnerror(JSContext* aCx, const JS::Value& aValue);
-  NS_METHOD GetOnprogress(JSContext* aCx, JS::Value* aValue);
-  NS_METHOD SetOnprogress(JSContext* aCx, const JS::Value& aValue);
+  NS_METHOD GetOnabort(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
+  NS_METHOD SetOnabort(JSContext* aCx, JS::Handle<JS::Value> aValue);
+  NS_METHOD GetOnerror(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
+  NS_METHOD SetOnerror(JSContext* aCx, JS::Handle<JS::Value> aValue);
+  NS_METHOD GetOnprogress(JSContext* aCx, JS::MutableHandle<JS::Value> aValue);
+  NS_METHOD SetOnprogress(JSContext* aCx, JS::Handle<JS::Value> aValue);
 
   IMPL_EVENT_HANDLER(abort)
   IMPL_EVENT_HANDLER(error)
   IMPL_EVENT_HANDLER(progress)
 
   NS_DECL_NSITIMERCALLBACK
 
   NS_DECL_NSISTREAMLISTENER
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -195,17 +195,16 @@ nsContentSink::Init(nsIDocument* aDoc,
   mCSSLoader = aDoc->CSSLoader();
 
   mNodeInfoManager = aDoc->NodeInfoManager();
 
   mBackoffCount = sBackoffCount;
 
   if (sEnablePerfMode != 0) {
     mDynamicLowerValue = sEnablePerfMode == 1;
-    FavorPerformanceHint(!mDynamicLowerValue, 0);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                 bool aWasAlternate,
@@ -1372,25 +1371,16 @@ nsContentSink::DidProcessATokenImpl()
   }
 
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 
 void
-nsContentSink::FavorPerformanceHint(bool perfOverStarvation, uint32_t starvationDelay)
-{
-  static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
-  nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
-  if (appShell)
-    appShell->FavorPerformanceHint(perfOverStarvation, starvationDelay);
-}
-
-void
 nsContentSink::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
 {
   // Remember nested updates from updates that we started.
   if (mInNotification > 0 && mUpdatesInNotification < 2) {
     ++mUpdatesInNotification;
   }
 
   // If we're in a script and we didn't do the notification,
@@ -1457,22 +1447,16 @@ nsContentSink::DropParserAndPerfHint(voi
   // Do this hack to make sure that the parser
   // doesn't get destroyed, accidently, before
   // the circularity, between sink & parser, is
   // actually broken.
   // Drop our reference to the parser to get rid of a circular
   // reference.
   nsRefPtr<nsParserBase> kungFuDeathGrip(mParser.forget());
 
-  if (mDynamicLowerValue) {
-    // Reset the performance hint which was set to FALSE
-    // when mDynamicLowerValue was set.
-    FavorPerformanceHint(true, 0);
-  }
-
   if (!mRunsToCompletion) {
     mDocument->UnblockOnload(true);
   }
 }
 
 bool
 nsContentSink::IsScriptExecutingImpl()
 {
@@ -1500,17 +1484,16 @@ nsContentSink::WillParseImpl(void)
     vm->GetLastUserEventTime(lastEventTime);
 
     bool newDynLower =
       mDocument->IsInBackgroundWindow() ||
       ((currentTime - mBeginLoadTime) > uint32_t(sInitialPerfTime) &&
        (currentTime - lastEventTime) < uint32_t(sInteractiveTime));
     
     if (mDynamicLowerValue != newDynLower) {
-      FavorPerformanceHint(!newDynLower, 0);
       mDynamicLowerValue = newDynLower;
     }
   }
   
   mDeflectedCount = 0;
   mHasPendingEvent = false;
 
   mCurrentParseEndTime = currentTime +
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -232,19 +232,16 @@ protected:
   // we still have stylesheet loads pending.  Otherwise, we'll wait until the
   // stylesheets are all done loading.
 public:
   void StartLayout(bool aIgnorePendingSheets);
 
   static void NotifyDocElementCreated(nsIDocument* aDoc);
 
 protected:
-  void
-  FavorPerformanceHint(bool perfOverStarvation, uint32_t starvationDelay);
-
   inline int32_t GetNotificationInterval()
   {
     if (mDynamicLowerValue) {
       return 1000;
     }
 
     return sNotificationInterval;
   }
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5630,17 +5630,17 @@ nsContentUtils::WrapNative(JSContext *cx
 
   if (!NS_IsMainThread()) {
     MOZ_CRASH();
   }
 
   nsresult rv = NS_OK;
   AutoPushJSContext context(cx);
   rv = sXPConnect->WrapNativeToJSVal(context, scope, native, cache, aIID,
-                                     aAllowWrapping, vp.address());
+                                     aAllowWrapping, vp);
   return rv;
 }
 
 nsresult
 nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
                                   JSObject** aResult)
 {
   if (!aCx) {
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -131,20 +131,23 @@ NS_IMETHODIMP
 nsDOMFileBase::GetPath(nsAString &aPath)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   aPath = mPath;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
+nsDOMFileBase::GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate)
 {
-  JSObject* date = JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC);
-  aLastModifiedDate->setObject(*date);
+  JS::Rooted<JSObject*> date(cx, JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC));
+  if (!date) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  aLastModifiedDate.setObject(*date);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
 
@@ -497,36 +500,36 @@ nsDOMFileFile::CreateSlice(uint64_t aSta
 NS_IMETHODIMP
 nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   return mFile->GetPath(aFilename);
 }
 
 NS_IMETHODIMP
-nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
+nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::MutableHandle<JS::Value> aLastModifiedDate)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
 
   PRTime msecs;
   if (IsDateUnknown()) {
     nsresult rv = mFile->GetLastModifiedTime(&msecs);
     NS_ENSURE_SUCCESS(rv, rv);
     mLastModificationDate = msecs;
   } else {
     msecs = mLastModificationDate;
   }
 
   JSObject* date = JS_NewDateObjectMsec(cx, msecs);
   if (date) {
-    aLastModifiedDate->setObject(*date);
+    aLastModifiedDate.setObject(*date);
   }
   else {
     date = JS_NewDateObjectMsec(cx, JS_Now() / PR_USEC_PER_MSEC);
-    aLastModifiedDate->setObject(*date);
+    aLastModifiedDate.setObject(*date);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileFile::GetSize(uint64_t *aFileSize)
 {
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -179,42 +179,41 @@ nsDOMFileReader::GetReadyState(uint16_t 
   *aReadyState = ReadyState();
   return NS_OK;
 }
 
 JS::Value
 nsDOMFileReader::GetResult(JSContext* aCx, ErrorResult& aRv)
 {
   JS::Rooted<JS::Value> result(aCx);
-  aRv = GetResult(aCx, result.address());
+  aRv = GetResult(aCx, &result);
   return result;
 }
 
 NS_IMETHODIMP
-nsDOMFileReader::GetResult(JSContext* aCx, JS::Value* aResult)
+nsDOMFileReader::GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
 {
   JS::Rooted<JS::Value> result(aCx);
   if (mDataFormat == FILE_AS_ARRAYBUFFER) {
     if (mReadyState == nsIDOMFileReader::DONE && mResultArrayBuffer) {
       result.setObject(*mResultArrayBuffer);
     } else {
       result.setNull();
     }
     if (!JS_WrapValue(aCx, &result)) {
       return NS_ERROR_FAILURE;
     }
-    *aResult = result;
+    aResult.set(result);
     return NS_OK;
   }
 
   nsString tmpResult = mResult;
-  if (!xpc::StringToJsval(aCx, tmpResult, &result)) {
+  if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
     return NS_ERROR_FAILURE;
   }
-  *aResult = result;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileReader::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2586,25 +2586,26 @@ nsDocument::InitCSP(nsIChannel* aChannel
   if ((!cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty()) &&
        !specCompliantEnabled) {
     PR_LOG(gCspPRLog, PR_LOG_DEBUG,
             ("Got spec compliant CSP headers but pref was not set"));
     cspHeaderValue.Truncate();
     cspROHeaderValue.Truncate();
   }
 
-  // If the old header is present, warn that it will be deprecated.
-  if (!cspOldHeaderValue.IsEmpty() || !cspOldROHeaderValue.IsEmpty()) {
+  // If both the new header AND the old header are present, warn that
+  // the old header will be ignored. Otherwise, if the old header is
+  // present, warn that it will be deprecated.
+  bool oldHeaderIsPresent = !cspOldHeaderValue.IsEmpty() || !cspOldROHeaderValue.IsEmpty();
+  bool newHeaderIsPresent = !cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty();
+
+  if (oldHeaderIsPresent && newHeaderIsPresent) {
+    mCSPWebConsoleErrorQueue.Add("BothCSPHeadersPresent");
+  } else if (oldHeaderIsPresent) {
     mCSPWebConsoleErrorQueue.Add("OldCSPHeaderDeprecated");
-
-    // Also, if the new headers AND the old headers were present, warn
-    // that the old headers will be ignored.
-    if (!cspHeaderValue.IsEmpty() || !cspROHeaderValue.IsEmpty()) {
-      mCSPWebConsoleErrorQueue.Add("BothCSPHeadersPresent");
-    }
   }
 
   // Figure out if we need to apply an app default CSP or a CSP from an app manifest
   nsIPrincipal* principal = NodePrincipal();
 
   uint16_t appStatus = principal->GetAppStatus();
   bool applyAppDefaultCSP = appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED ||
                             appStatus == nsIPrincipal::APP_STATUS_CERTIFIED;
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -442,17 +442,17 @@ nsFrameMessageManager::RemoveDelayedFram
       mPendingScriptsGlobalStates.RemoveElementAt(i);
       break;
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::Value* aList)
+nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<JS::Value> aList)
 {
   // Frame message managers may return an incomplete list because scripts
   // that were loaded after it was connected are not added to the list.
   if (!IsGlobal() && !IsWindowLevel()) {
     NS_WARNING("Cannot retrieve list of pending frame scripts for frame"
                "message managers as it may be incomplete");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
@@ -473,18 +473,17 @@ nsFrameMessageManager::GetDelayedFrameSc
     pair = JS_NewArrayObject(aCx, 2, pairElts);
     NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY);
 
     pairVal = JS::ObjectValue(*pair);
     NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, &pairVal),
                    NS_ERROR_OUT_OF_MEMORY);
   }
 
-  *aList = JS::ObjectValue(*array);
-
+  aList.setObject(*array);
   return NS_OK;
 }
 
 static bool
 JSONCreator(const jschar* aBuf, uint32_t aLen, void* aData)
 {
   nsAString* result = static_cast<nsAString*>(aData);
   result->Append(static_cast<const char16_t*>(aBuf),
@@ -522,55 +521,55 @@ GetParamsForMessage(JSContext* aCx,
 
 
 // nsISyncMessageSender
 
 static bool sSendingSyncMessage = false;
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
-                                       const JS::Value& aJSON,
-                                       const JS::Value& aObjects,
+                                       JS::Handle<JS::Value> aJSON,
+                                       JS::Handle<JS::Value> aObjects,
                                        nsIPrincipal* aPrincipal,
                                        JSContext* aCx,
                                        uint8_t aArgc,
-                                       JS::Value* aRetval)
+                                       JS::MutableHandle<JS::Value> aRetval)
 {
   return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
                      aRetval, true);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
-                                      const JS::Value& aJSON,
-                                      const JS::Value& aObjects,
+                                      JS::Handle<JS::Value> aJSON,
+                                      JS::Handle<JS::Value> aObjects,
                                       nsIPrincipal* aPrincipal,
                                       JSContext* aCx,
                                       uint8_t aArgc,
-                                      JS::Value* aRetval)
+                                      JS::MutableHandle<JS::Value> aRetval)
 {
   return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
                      aRetval, false);
 }
 
 nsresult
 nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
-                                   const JS::Value& aJSON,
-                                   const JS::Value& aObjects,
+                                   JS::Handle<JS::Value> aJSON,
+                                   JS::Handle<JS::Value> aObjects,
                                    nsIPrincipal* aPrincipal,
                                    JSContext* aCx,
                                    uint8_t aArgc,
-                                   JS::Value* aRetval,
+                                   JS::MutableHandle<JS::Value> aRetval,
                                    bool aIsSync)
 {
   NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
 
-  *aRetval = JSVAL_VOID;
+  aRetval.setUndefined();
   NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
 
   if (sSendingSyncMessage && aIsSync) {
     // No kind of blocking send should be issued on top of a sync message.
     return NS_ERROR_UNEXPECTED;
   }
 
   StructuredCloneData data;
@@ -613,17 +612,17 @@ nsFrameMessageManager::SendMessage(const
     if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
                       retval[i].Length(), &ret)) {
       return NS_ERROR_UNEXPECTED;
     }
     NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret),
                    NS_ERROR_OUT_OF_MEMORY);
   }
 
-  *aRetval = OBJECT_TO_JSVAL(dataArray);
+  aRetval.setObject(*dataArray);
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
                                                     const nsAString& aMessage,
                                                     const StructuredCloneData& aData,
                                                     JS::Handle<JSObject *> aCpows,
@@ -673,33 +672,33 @@ nsFrameMessageManager::DispatchAsyncMess
                                       aPrincipal);
 }
 
 
 // nsIMessageSender
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
-                                        const JS::Value& aJSON,
-                                        const JS::Value& aObjects,
+                                        JS::Handle<JS::Value> aJSON,
+                                        JS::Handle<JS::Value> aObjects,
                                         nsIPrincipal* aPrincipal,
                                         JSContext* aCx,
                                         uint8_t aArgc)
 {
   return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx,
                               aArgc);
 }
 
 
 // nsIMessageBroadcaster
 
 NS_IMETHODIMP
 nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
-                                             const JS::Value& aJSON,
-                                             const JS::Value& aObjects,
+                                             JS::Handle<JS::Value> aJSON,
+                                             JS::Handle<JS::Value> aObjects,
                                              JSContext* aCx,
                                              uint8_t aArgc)
 {
   return DispatchAsyncMessage(aMessageName, aJSON, aObjects, nullptr, aCx,
                               aArgc);
 }
 
 NS_IMETHODIMP
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -266,22 +266,22 @@ public:
     return sParentProcessManager;
   }
   static nsFrameMessageManager* GetChildProcessManager()
   {
     return sChildProcessManager;
   }
 private:
   nsresult SendMessage(const nsAString& aMessageName,
-                       const JS::Value& aJSON,
-                       const JS::Value& aObjects,
+                       JS::Handle<JS::Value> aJSON,
+                       JS::Handle<JS::Value> aObjects,
                        nsIPrincipal* aPrincipal,
                        JSContext* aCx,
                        uint8_t aArgc,
-                       JS::Value* aRetval,
+                       JS::MutableHandle<JS::Value> aRetval,
                        bool aIsSync);
 protected:
   friend class MMListenerRemover;
   // We keep the message listeners as arrays in a hastable indexed by the
   // message name. That gives us fast lookups in ReceiveMessage().
   nsClassHashtable<nsStringHashKey,
                    nsAutoTObserverArray<nsMessageListenerInfo, 1>> mListeners;
   nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -9,24 +9,26 @@
 #include "nsError.h"
 #include "nsClassHashtable.h"
 #include "nsNetUtil.h"
 #include "nsIPrincipal.h"
 #include "nsIDOMFile.h"
 #include "nsIDOMMediaStream.h"
 #include "mozilla/dom/MediaSource.h"
 #include "nsIMemoryReporter.h"
+#include "mozilla/Preferences.h"
 
 // -----------------------------------------------------------------------
 // Hash table
 struct DataInfo
 {
   // mObject is expected to be an nsIDOMBlob, nsIDOMMediaStream, or MediaSource
   nsCOMPtr<nsISupports> mObject;
   nsCOMPtr<nsIPrincipal> mPrincipal;
+  nsCString mStack;
 };
 
 static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
 
 // Memory reporting for the hash table.
 namespace mozilla {
 
 class HostObjectURLsReporter MOZ_FINAL : public nsIMemoryReporter
@@ -42,28 +44,214 @@ class HostObjectURLsReporter MOZ_FINAL :
       gDataTable ? gDataTable->Count() : 0,
       "The number of host objects stored for access via URLs "
       "(e.g. blobs passed to URL.createObjectURL).");
   }
 };
 
 NS_IMPL_ISUPPORTS1(HostObjectURLsReporter, nsIMemoryReporter)
 
+class BlobURLsReporter MOZ_FINAL : public nsIMemoryReporter
+{
+ public:
+  NS_DECL_ISUPPORTS
+
+  NS_IMETHOD CollectReports(nsIHandleReportCallback* aCallback,
+                            nsISupports* aData)
+  {
+    EnumArg env;
+    env.mCallback = aCallback;
+    env.mData = aData;
+
+    if (gDataTable) {
+      gDataTable->EnumerateRead(CountCallback, &env);
+      gDataTable->EnumerateRead(ReportCallback, &env);
+    }
+    return NS_OK;
+  }
+
+  // Initialize info->mStack to record JS stack info, if enabled.
+  // The string generated here is used in ReportCallback, below.
+  static void GetJSStackForBlob(DataInfo* aInfo)
+  {
+    nsCString& stack = aInfo->mStack;
+    MOZ_ASSERT(stack.IsEmpty());
+    const uint32_t maxFrames = Preferences::GetUint("memory.blob_report.stack_frames");
+
+    if (maxFrames == 0) {
+      return;
+    }
+
+    nsresult rv;
+    nsIXPConnect* xpc = nsContentUtils::XPConnect();
+    nsCOMPtr<nsIStackFrame> frame;
+    rv = xpc->GetCurrentJSStack(getter_AddRefs(frame));
+    NS_ENSURE_SUCCESS_VOID(rv);
+
+    nsAutoCString origin;
+    nsCOMPtr<nsIURI> principalURI;
+    if (NS_SUCCEEDED(aInfo->mPrincipal->GetURI(getter_AddRefs(principalURI)))
+        && principalURI) {
+      principalURI->GetPrePath(origin);
+    }
+
+    for (uint32_t i = 0; i < maxFrames && frame; ++i) {
+      nsAutoCString fileNameEscaped;
+      char* fileName = nullptr;
+      int32_t lineNumber = 0;
+
+      frame->GetFilename(&fileName);
+      frame->GetLineNumber(&lineNumber);
+
+      if (fileName != nullptr && fileName[0] != '\0') {
+        stack += "js(";
+        fileNameEscaped = fileName;
+        if (!origin.IsEmpty()) {
+          // Make the file name root-relative for conciseness if possible.
+          const char* originData;
+          uint32_t originLen;
+
+          originLen = origin.GetData(&originData);
+          // If fileName starts with origin + "/", cut up to that "/".
+          if (strlen(fileName) >= originLen + 1 &&
+              memcmp(fileName, originData, originLen) == 0 &&
+              fileName[originLen] == '/') {
+            fileNameEscaped.Cut(0, originLen);
+          }
+        }
+        fileNameEscaped.ReplaceChar('/', '\\');
+        stack += fileNameEscaped;
+        if (lineNumber > 0) {
+          stack += ", line=";
+          stack.AppendInt(lineNumber);
+        }
+        stack += ")/";
+      }
+
+      rv = frame->GetCaller(getter_AddRefs(frame));
+      NS_ENSURE_SUCCESS_VOID(rv);
+    }
+  }
+
+ private:
+  struct EnumArg {
+    nsIHandleReportCallback* mCallback;
+    nsISupports* mData;
+    nsDataHashtable<nsPtrHashKey<nsIDOMBlob>, uint32_t> mRefCounts;
+  };
+
+  // Determine number of URLs per blob, to handle the case where it's > 1.
+  static PLDHashOperator CountCallback(nsCStringHashKey::KeyType aKey,
+                                       DataInfo* aInfo,
+                                       void* aUserArg)
+  {
+    EnumArg* envp = static_cast<EnumArg*>(aUserArg);
+    nsCOMPtr<nsIDOMBlob> blob;
+
+    blob = do_QueryInterface(aInfo->mObject);
+    if (blob) {
+      envp->mRefCounts.Put(blob, envp->mRefCounts.Get(blob) + 1);
+    }
+    return PL_DHASH_NEXT;
+  }
+
+  static PLDHashOperator ReportCallback(nsCStringHashKey::KeyType aKey,
+                                        DataInfo* aInfo,
+                                        void* aUserArg)
+  {
+    EnumArg* envp = static_cast<EnumArg*>(aUserArg);
+    nsCOMPtr<nsIDOMBlob> blob;
+
+    blob = do_QueryInterface(aInfo->mObject);
+    if (blob) {
+      NS_NAMED_LITERAL_CSTRING
+        (desc, "A blob URL allocated with URL.createObjectURL; the referenced "
+         "blob cannot be freed until all URLs for it have been explicitly "
+         "invalidated with URL.revokeObjectURL.");
+      nsAutoCString path, url, owner, specialDesc;
+      nsCOMPtr<nsIURI> principalURI;
+      uint64_t size;
+      uint32_t refCount = 1;
+      DebugOnly<bool> blobWasCounted;
+
+      blobWasCounted = envp->mRefCounts.Get(blob, &refCount);
+      MOZ_ASSERT(blobWasCounted);
+      MOZ_ASSERT(refCount > 0);
+
+      if (NS_FAILED(blob->GetSize(&size))) {
+        size = 0;
+      }
+
+      path = "blob-urls/";
+      if (NS_SUCCEEDED(aInfo->mPrincipal->GetURI(getter_AddRefs(principalURI))) &&
+          principalURI != nullptr &&
+          NS_SUCCEEDED(principalURI->GetSpec(owner)) &&
+          !owner.IsEmpty()) {
+        owner.ReplaceChar('/', '\\');
+        path += "owner(";
+        path += owner;
+        path += ")";
+      } else {
+        path += "owner unknown";
+      }
+      path += "/";
+      path += aInfo->mStack;
+      url = aKey;
+      url.ReplaceChar('/', '\\');
+      path += url;
+      if (refCount > 1) {
+        nsAutoCString addrStr;
+
+        addrStr = "0x";
+        addrStr.AppendInt((uint64_t)(nsIDOMBlob*)blob, 16);
+
+        path += " ";
+        path.AppendInt(refCount);
+        path += "@";
+        path += addrStr;
+
+        specialDesc = desc;
+        specialDesc += "\n\nNOTE: This blob (address ";
+        specialDesc += addrStr;
+        specialDesc += ") has ";
+        specialDesc.AppendInt(refCount);
+        specialDesc += " URLs; its size is divided ";
+        specialDesc += refCount > 2 ? "among" : "between";
+        specialDesc += " them in this report.";
+      }
+      envp->mCallback->Callback(EmptyCString(),
+                                path,
+                                KIND_OTHER,
+                                UNITS_BYTES,
+                                size / refCount,
+                                (specialDesc.IsEmpty()
+                                 ? static_cast<const nsACString&>(desc)
+                                 : static_cast<const nsACString&>(specialDesc)),
+                                envp->mData);
+    }
+    return PL_DHASH_NEXT;
+  }
+};
+
+NS_IMPL_ISUPPORTS1(BlobURLsReporter, nsIMemoryReporter)
+
 }
 
 nsHostObjectProtocolHandler::nsHostObjectProtocolHandler()
 {
   static bool initialized = false;
 
   if (!initialized) {
     initialized = true;
     RegisterStrongMemoryReporter(new mozilla::HostObjectURLsReporter());
+    RegisterStrongMemoryReporter(new mozilla::BlobURLsReporter());
   }
 }
 
+
 nsresult
 nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
                                           nsISupports* aObject,
                                           nsIPrincipal* aPrincipal,
                                           nsACString& aUri)
 {
   nsresult rv = GenerateURIString(aScheme, aUri);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -71,16 +259,17 @@ nsHostObjectProtocolHandler::AddDataEntr
   if (!gDataTable) {
     gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
   }
 
   DataInfo* info = new DataInfo;
 
   info->mObject = aObject;
   info->mPrincipal = aPrincipal;
+  mozilla::BlobURLsReporter::GetJSStackForBlob(info);
 
   gDataTable->Put(aUri, info);
   return NS_OK;
 }
 
 void
 nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri)
 {
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -699,18 +699,17 @@ nsINode::SetUserData(const nsAString &aK
 
 JS::Value
 nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
                      JS::Handle<JS::Value> aData,
                      nsIDOMUserDataHandler* aHandler, ErrorResult& aError)
 {
   nsCOMPtr<nsIVariant> data;
   JS::Rooted<JS::Value> dataVal(aCx, aData);
-  aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal.address(),
-                                                       getter_AddRefs(data));
+  aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal, getter_AddRefs(data));
   if (aError.Failed()) {
     return JS::UndefinedValue();
   }
 
   nsCOMPtr<nsIVariant> oldData;
   aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData));
   if (aError.Failed()) {
     return JS::UndefinedValue();
@@ -718,17 +717,17 @@ nsINode::SetUserData(JSContext* aCx, con
 
   if (!oldData) {
     return JS::NullValue();
   }
 
   JS::Rooted<JS::Value> result(aCx);
   JSAutoCompartment ac(aCx, GetWrapper());
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
-                                                    result.address());
+                                                    &result);
   return result;
 }
 
 nsIVariant*
 nsINode::GetUserData(const nsAString& aKey)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eGetSetUserData);
   nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
@@ -745,17 +744,17 @@ nsINode::GetUserData(JSContext* aCx, con
   nsIVariant* data = GetUserData(aKey);
   if (!data) {
     return JS::NullValue();
   }
 
   JS::Rooted<JS::Value> result(aCx);
   JSAutoCompartment ac(aCx, GetWrapper());
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
-                                                    result.address());
+                                                    &result);
   return result;
 }
 
 uint16_t
 nsINode::CompareDocumentPosition(nsINode& aOtherNode) const
 {
   if (this == &aOtherNode) {
     return 0;
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -36,35 +36,35 @@ public:
                             nsFrameMessageManager* aChrome);
   virtual ~nsInProcessTabChildGlobal();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
                                            nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
-                             const JS::Value& aObject,
-                             const JS::Value& aRemote,
+                             JS::Handle<JS::Value> aObject,
+                             JS::Handle<JS::Value> aRemote,
                              nsIPrincipal* aPrincipal,
                              JSContext* aCx,
                              uint8_t aArgc,
-                             JS::Value* aRetval)
+                             JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
                                          aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
-                            const JS::Value& aObject,
-                            const JS::Value& aRemote,
+                            JS::Handle<JS::Value> aObject,
+                            JS::Handle<JS::Value> aRemote,
                             nsIPrincipal* aPrincipal,
                             JSContext* aCx,
                             uint8_t aArgc,
-                            JS::Value* aRetval)
+                            JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
                                         aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
   NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -916,20 +916,20 @@ nsXMLHttpRequest::SetResponseType(nsXMLH
 
   // Set the responseType attribute's value to the given value.
   mResponseType = aResponseType;
 
 }
 
 /* readonly attribute jsval response; */
 NS_IMETHODIMP
-nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::Value *aResult)
+nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::MutableHandle<JS::Value> aResult)
 {
   ErrorResult rv;
-  *aResult = GetResponse(aCx, rv);
+  aResult.set(GetResponse(aCx, rv));
   return rv.ErrorCode();
 }
 
 JS::Value
 nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
 {
   switch (mResponseType) {
   case XML_HTTP_RESPONSE_TYPE_DEFAULT:
@@ -2402,17 +2402,17 @@ GetRequestBody(nsIVariant* aBody, nsIInp
     if (sendable) {
       return GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset);
     }
 
     // ArrayBuffer?
     AutoSafeJSContext cx;
     JS::Rooted<JS::Value> realVal(cx);
 
-    nsresult rv = aBody->GetAsJSVal(realVal.address());
+    nsresult rv = aBody->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
       JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(realVal));
       if (JS_IsArrayBufferObject(obj)) {
           ArrayBuffer buf(obj);
           return GetRequestBody(buf.Data(), buf.Length(), aResult,
                                 aContentLength, aContentType, aCharset);
       }
     }
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/file_dual_headers_warning.html^headers^
@@ -0,0 +1,2 @@
+Content-Security-Policy: default-src 'self' 'unsafe-inline';
+X-Content-Security-Policy: allow 'self' 'inline-script';
--- a/content/base/test/csp/mochitest.ini
+++ b/content/base/test/csp/mochitest.ini
@@ -99,16 +99,18 @@ support-files =
   file_policyuri_regression_from_multipolicy_policy
   file_nonce_source.html
   file_nonce_source.html^headers^
   file_CSP_bug941404.html
   file_CSP_bug941404_xhr.html
   file_CSP_bug941404_xhr.html^headers^
   file_hash_source.html
   file_hash_source.html^headers^
+  file_dual_headers_warning.html
+  file_dual_headers_warning.html^headers^
 
 [test_CSP.html]
 [test_CSP_bug663567.html]
 [test_CSP_bug802872.html]
 [test_CSP_bug885433.html]
 [test_CSP_bug888172.html]
 [test_CSP_bug916446.html]
 [test_CSP_evalscript.html]
@@ -121,8 +123,9 @@ support-files =
 [test_bug886164.html]
 [test_csp_redirects.html]
 [test_CSP_bug910139.html]
 [test_CSP_bug909029.html]
 [test_policyuri_regression_from_multipolicy.html]
 [test_nonce_source.html]
 [test_CSP_bug941404.html]
 [test_hash_source.html]
+[test_dual_headers_warning.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/test_dual_headers_warning.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=918397
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 918397</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=918397">Mozilla Bug 918397</a>
+<p id="display"></p>
+
+<iframe id="cspframe"></iframe>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+// Load locale strings during mochitest
+var stringBundleService = SpecialPowers.Cc["@mozilla.org/intl/stringbundle;1"]
+                          .getService(SpecialPowers.Ci.nsIStringBundleService);
+var localizer = stringBundleService.createBundle("chrome://global/locale/security/security.properties");
+var depreHeadersMsg = localizer.GetStringFromName("OldCSPHeaderDeprecated", 0)
+var dualHeadersMsg = localizer.GetStringFromName("BothCSPHeadersPresent", 0)
+
+function cleanup() {
+  SpecialPowers.postConsoleSentinel();
+  SimpleTest.finish();
+}
+
+// listen on the console before loading the iframe
+SpecialPowers.registerConsoleListener(function ConsoleMsgListener(aMsg) {
+  // Note: We do not want to see the deprecation warning appear in the console.
+  // This test can only be sure that the deprecation warning does not appear
+  // iff the deprecation warning appears before the dual header warning appears
+  // in the console.
+  if (aMsg.message.indexOf(depreHeadersMsg) > -1) {
+    ok(false, "Deprecated CSP header warning should not be present.");
+    return;
+  } else if (aMsg.message.indexOf(dualHeadersMsg) > -1) {
+    ok(true, "Dual CSP header warning present.");
+    SimpleTest.executeSoon(cleanup);
+  } else {
+    // if some other console message is present, we wait
+    return;
+  }
+});
+
+// get ready and test
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv(
+  {'set': [["security.csp.speccompliant", true]]},
+  function() {
+    document.getElementById('cspframe').src = 'file_dual_headers_warning.html';
+});
+</script>
+</body>
+</html>
--- a/content/canvas/test/reftest/reftest.list
+++ b/content/canvas/test/reftest/reftest.list
@@ -186,9 +186,9 @@ skip-if(!winWidget) pref(webgl.prefer-na
 # Do we correctly handle multiple clip paths?
 != clip-multiple-paths.html clip-multiple-paths-badref.html
 
 # Bug 815648
 == stroketext-shadow.html stroketext-shadow-ref.html
 
 # focus rings
 pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
-pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
+pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
--- a/content/canvas/test/test_canvas_focusring.html
+++ b/content/canvas/test/test_canvas_focusring.html
@@ -4,16 +4,17 @@
 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
 <body>
 <script>
 
 SimpleTest.waitForExplicitFinish();
 const Cc = SpecialPowers.Cc;
 const Cr = SpecialPowers.Cr;
 SpecialPowers.setBoolPref("canvas.focusring.enabled", true);
+SpecialPowers.setBoolPref("canvas.customfocusring.enabled", true);
 </script>
 
 <p>Canvas test: drawCustomFocusRing</p>
 <canvas id="c688" class="output" width="100" height="50">+
     <input id="button1" type="range" min="1" max="12"></input>
     <input id="button2" type="range" min="1" max="12"></input>
 </canvas>
 <script type="text/javascript">
@@ -85,14 +86,15 @@ function runTests() {
   try {
   test_drawFocusIfNeeded_canvas();
  } catch(e) {
   throw e;
   ok(false, "unexpected exception thrown in: test_drawFocusIfNeeded_canvas");
  }
 
  SpecialPowers.setBoolPref("canvas.focusring.enabled", false);
+ SpecialPowers.setBoolPref("canvas.customfocusring.enabled", false);
  SimpleTest.finish();
 }
 
 addLoadEvent(runTests);
 
 </script>
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -322,17 +322,17 @@ HTMLCanvasElement::ParseAttribute(int32_
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 
 // HTMLCanvasElement::toDataURL
 
 NS_IMETHODIMP
-HTMLCanvasElement::ToDataURL(const nsAString& aType, const JS::Value& aParams,
+HTMLCanvasElement::ToDataURL(const nsAString& aType, JS::Handle<JS::Value> aParams,
                              JSContext* aCx, nsAString& aDataURL)
 {
   // do a trust check if this is a write-only canvas
   if (mWriteOnly && !nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   return ToDataURLImpl(aCx, aType, aParams, aDataURL);
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -1637,24 +1637,24 @@ HTMLMediaElement::MozGetMetadata(JSConte
       return nullptr;
     }
   }
 
   return tags;
 }
 
 NS_IMETHODIMP
-HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::Value* aValue)
+HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::MutableHandle<JS::Value> aValue)
 {
   ErrorResult rv;
 
   JSObject* obj = MozGetMetadata(cx, rv);
   if (!rv.Failed()) {
     MOZ_ASSERT(obj);
-    *aValue = JS::ObjectValue(*obj);
+    aValue.setObject(*obj);
   }
 
   return rv.ErrorCode();
 }
 
 uint32_t
 HTMLMediaElement::GetMozFrameBufferLength(ErrorResult& aRv) const
 {
--- a/content/media/TextTrack.cpp
+++ b/content/media/TextTrack.cpp
@@ -88,17 +88,19 @@ TextTrack::SetMode(TextTrackMode aValue)
     }
   }
 }
 
 void
 TextTrack::AddCue(TextTrackCue& aCue)
 {
   mCueList->AddCue(aCue);
-  mMediaElement->AddCue(aCue);
+  if (mMediaElement) {
+    mMediaElement->AddCue(aCue);
+  }
   SetDirty();
 }
 
 void
 TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv)
 {
   mCueList->RemoveCue(aCue, aRv);
   SetDirty();
--- a/content/media/TextTrackCue.cpp
+++ b/content/media/TextTrackCue.cpp
@@ -3,19 +3,16 @@
  * 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/HTMLTrackElement.h"
 #include "mozilla/dom/TextTrackCue.h"
 #include "nsComponentManagerUtils.h"
 #include "mozilla/ClearOnShutdown.h"
 
-// Alternate value for the 'auto' keyword.
-#define WEBVTT_AUTO -1
-
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_4(TextTrackCue,
                                      nsDOMEventTargetHelper,
                                      mDocument,
                                      mTrack,
                                      mTrackElement,
@@ -33,17 +30,17 @@ StaticRefPtr<nsIWebVTTParserWrapper> Tex
 void
 TextTrackCue::SetDefaultCueSettings()
 {
   mPosition = 50;
   mPositionAlign = AlignSetting::Middle;
   mSize = 100;
   mPauseOnExit = false;
   mSnapToLines = true;
-  mLine = WEBVTT_AUTO;
+  mLineIsAutoKeyword = true;
   mAlign = AlignSetting::Middle;
   mLineAlign = AlignSetting::Start;
   mVertical = DirectionSetting::_empty;
 }
 
 TextTrackCue::TextTrackCue(nsISupports* aGlobal,
                            double aStartTime,
                            double aEndTime,
--- a/content/media/TextTrackCue.h
+++ b/content/media/TextTrackCue.h
@@ -10,16 +10,17 @@
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/VTTCueBinding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIWebVTTParserWrapper.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIDocument.h"
 #include "mozilla/dom/HTMLDivElement.h"
+#include "mozilla/dom/UnionTypes.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLTrackElement;
 class TextTrack;
 
 class TextTrackCue MOZ_FINAL : public nsDOMEventTargetHelper
@@ -163,26 +164,40 @@ public:
       return;
     }
 
     mReset = true;
     mSnapToLines = aSnapToLines;
     CueChanged();
   }
 
-  double Line() const
+  void GetLine(OwningLongOrAutoKeyword& aLine) const
   {
-    return mLine;
+    if (mLineIsAutoKeyword) {
+      aLine.SetAsAutoKeyword() = AutoKeyword::Auto;
+      return;
+    }
+    aLine.SetAsLong() = mLineLong;
   }
 
-  void SetLine(double aLine)
+  void SetLine(const LongOrAutoKeyword& aLine)
   {
-    //XXX: TODO Line position can be a keyword auto. bug882299
-    mReset = true;
-    mLine = aLine;
+    if (aLine.IsLong() &&
+        (mLineIsAutoKeyword || (aLine.GetAsLong() != mLineLong))) {
+      mLineIsAutoKeyword = false;
+      mLineLong = aLine.GetAsLong();
+      CueChanged();
+      mReset = true;
+      return;
+    }
+    if (aLine.IsAutoKeyword() && !mLineIsAutoKeyword) {
+      mLineIsAutoKeyword = true;
+      CueChanged();
+      mReset = true;
+    }
   }
 
   AlignSetting LineAlign() const
   {
     return mLineAlign;
   }
 
   void SetLineAlign(AlignSetting& aLineAlign, ErrorResult& aRv)
@@ -350,17 +365,18 @@ private:
   nsString mId;
   int32_t mPosition;
   AlignSetting mPositionAlign;
   int32_t mSize;
   bool mPauseOnExit;
   bool mSnapToLines;
   nsString mRegionId;
   DirectionSetting mVertical;
-  int mLine;
+  bool mLineIsAutoKeyword;
+  long mLineLong;
   AlignSetting mAlign;
   AlignSetting mLineAlign;
 
   // Holds the computed DOM elements that represent the parsed cue text.
   // http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-display-state
   nsRefPtr<nsGenericHTMLElement> mDisplayState;
   // Tells whether or not we need to recompute mDisplayState. This is set
   // anytime a property that relates to the display of the TextTrackCue is
--- a/content/media/WebVTTListener.cpp
+++ b/content/media/WebVTTListener.cpp
@@ -150,17 +150,17 @@ WebVTTListener::OnDataAvailable(nsIReque
     }
     count -= read;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WebVTTListener::OnCue(const JS::Value &aCue, JSContext* aCx)
+WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx)
 {
   if (!aCue.isObject()) {
     return NS_ERROR_FAILURE;
   }
 
   TextTrackCue* cue;
   nsresult rv = UNWRAP_OBJECT(VTTCue, &aCue.toObject(), cue);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -168,17 +168,17 @@ WebVTTListener::OnCue(const JS::Value &a
   cue->SetTrackElement(mElement);
   mElement->mTrack->AddCue(*cue);
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
-WebVTTListener::OnRegion(const JS::Value &aRegion, JSContext* aCx)
+WebVTTListener::OnRegion(JS::Handle<JS::Value> aRegion, JSContext* aCx)
 {
   if (!aRegion.isObject()) {
     return NS_ERROR_FAILURE;
   }
 
   TextTrackRegion* region;
   nsresult rv = UNWRAP_OBJECT(VTTRegion, &aRegion.toObject(), region);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -191,16 +191,17 @@ support-files =
 [test_bug495300.html]
 [test_bug654550.html]
 [test_bug686942.html]
 [test_bug874897.html]
 [test_bug883173.html]
 [test_bug895305.html]
 [test_bug895091.html]
 [test_bug919265.html]
+[test_bug957847.html]
 [test_can_play_type.html]
 [test_can_play_type_mpeg.html]
 [test_closing_connections.html]
 [test_constants.html]
 [test_controls.html]
 [test_currentTime.html]
 [test_decode_error.html]
 [test_defaultMuted.html]
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_bug957847.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=957847
+-->
+<head>
+  <meta charset='utf-8'>
+  <title>Regression test for bug 957847 - Crash on TextTrack::AddCue </title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
+  function() {
+    var trackElement = document.createElement('track');
+    trackElement.track.addCue(new VTTCue(0, 1, "A"));
+    // We need to assert something for Mochitest to be happy.
+    ok(true);
+    SimpleTest.finish();
+  }
+);
+</script>
+</pre>
+</body>
+</html>
\ No newline at end of file
--- a/content/media/test/test_texttrackcue.html
+++ b/content/media/test/test_texttrackcue.html
@@ -125,16 +125,23 @@ SpecialPowers.pushPrefEnv({"set": [["med
       }
       ok(exceptionHappened, "Exception should have happened.");
 
       cue.positionAlign = "start";
       is(cue.positionAlign, "start", "Cue's position align should be start.");
       cue.positionAlign = "end";
       is(cue.positionAlign, "end", "Cue's position align should be end.");
 
+      // Check cue.line
+      is(cue.line, "auto", "Cue's line value should initially be auto.");
+      cue.line = 12410
+      is(cue.line, 12410, "Cue's line value should now be 12410.");
+      cue.line = "auto";
+      is(cue.line, "auto", "Cue's line value should now be auto.");
+
       // Check that we can create and add new VTTCues
       var vttCue = new VTTCue(3.999, 4, "foo");
       trackElement.track.addCue(vttCue);
       is(cueList.length, 7, "Cue list length should now be 7.");
 
       // Check that new VTTCue was added correctly
       cue = cueList[6];
       is(cue.startTime, 3.999, "Cue's start time should be 3.999.");
--- a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
+++ b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
@@ -147,17 +147,17 @@ SpeechTaskChild::SpeechTaskChild(SpeechS
 NS_IMETHODIMP
 SpeechTaskChild::Setup(nsISpeechTaskCallback* aCallback,
                        uint32_t aChannels, uint32_t aRate, uint8_t argc)
 {
   MOZ_CRASH("Should never be called from child");
 }
 
 NS_IMETHODIMP
-SpeechTaskChild::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
+SpeechTaskChild::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                            JSContext* aCx)
 {
   MOZ_CRASH("Should never be called from child");
 }
 
 NS_IMETHODIMP
 SpeechTaskChild::SendAudioNative(int16_t* aData, uint32_t aDataLen)
 {
--- a/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h
+++ b/content/media/webspeech/synth/ipc/SpeechSynthesisChild.h
@@ -74,17 +74,17 @@ class SpeechTaskChild : public nsSpeechT
   friend class SpeechSynthesisRequestChild;
 public:
 
   SpeechTaskChild(SpeechSynthesisUtterance* aUtterance);
 
   NS_IMETHOD Setup(nsISpeechTaskCallback* aCallback,
                    uint32_t aChannels, uint32_t aRate, uint8_t argc) MOZ_OVERRIDE;
 
-  NS_IMETHOD SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
+  NS_IMETHOD SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                        JSContext* aCx) MOZ_OVERRIDE;
 
   NS_IMETHOD SendAudioNative(int16_t* aData, uint32_t aDataLen) MOZ_OVERRIDE;
 
   virtual void Pause();
 
   virtual void Resume();
 
--- a/content/media/webspeech/synth/nsSpeechTask.cpp
+++ b/content/media/webspeech/synth/nsSpeechTask.cpp
@@ -151,17 +151,17 @@ nsSpeechTask::Setup(nsISpeechTaskCallbac
   mStream->AddTrack(1, aRate, 0, segment);
   mStream->AddAudioOutput(this);
   mStream->SetAudioOutputVolume(this, mVolume);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSpeechTask::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
+nsSpeechTask::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                         JSContext* aCx)
 {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
 
   NS_ENSURE_TRUE(mStream, NS_ERROR_NOT_AVAILABLE);
   NS_ENSURE_FALSE(mStream->IsDestroyed(), NS_ERROR_NOT_AVAILABLE);
   NS_ENSURE_TRUE(mChannels, NS_ERROR_FAILURE);
 
--- a/docshell/base/nsAboutRedirector.cpp
+++ b/docshell/base/nsAboutRedirector.cpp
@@ -60,16 +60,18 @@ static RedirEntry kRedirMap[] = {
       nsIAboutModule::ALLOW_SCRIPT |
       nsIAboutModule::HIDE_FROM_ABOUTABOUT },
     { "support", "chrome://global/content/aboutSupport.xhtml",
       nsIAboutModule::ALLOW_SCRIPT },
     { "telemetry", "chrome://global/content/aboutTelemetry.xhtml",
       nsIAboutModule::ALLOW_SCRIPT },
     { "networking", "chrome://global/content/aboutNetworking.xhtml",
        nsIAboutModule::ALLOW_SCRIPT },
+    { "webrtc", "chrome://global/content/aboutWebrtc.xhtml",
+       nsIAboutModule::ALLOW_SCRIPT },
     // about:srcdoc is unresolvable by specification.  It is included here
     // because the security manager would disallow srcdoc iframes otherwise.
     { "srcdoc", "about:blank",
       nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
       nsIAboutModule::HIDE_FROM_ABOUTABOUT }
 };
 static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -206,19 +206,16 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // True means sUseErrorPages has been added to preferences var cache.
 static bool gAddedPreferencesVarCache = false;
 
 bool nsDocShell::sUseErrorPages = false;
 
-// Number of documents currently loading
-static int32_t gNumberOfDocumentsLoading = 0;
-
 // Global count of existing docshells.
 static int32_t gDocShellCount = 0;
 
 // Global count of docshells with the private attribute set
 static uint32_t gNumberOfPrivateDocShells = 0;
 
 // Global reference to the URI fixup service.
 nsIURIFixup *nsDocShell::sURIFixup = 0;
@@ -239,27 +236,16 @@ static uint32_t gValidateOrigin = 0xffff
 static PRLogModuleInfo* gDocShellLog;
 #endif
 static PRLogModuleInfo* gDocShellLeakLog;
 #endif
 
 const char kBrandBundleURL[]      = "chrome://branding/locale/brand.properties";
 const char kAppstringsBundleURL[] = "chrome://global/locale/appstrings.properties";
 
-static void
-FavorPerformanceHint(bool perfOverStarvation)
-{
-    nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
-    if (appShell) {
-        appShell->FavorPerformanceHint(perfOverStarvation,
-                                       Preferences::GetUint("docshell.event_starvation_delay_hint",
-                                                            NS_EVENT_STARVATION_DELAY_HINT));
-    }
-}
-
 //*****************************************************************************
 // <a ping> support
 //*****************************************************************************
 
 #define PREF_PINGS_ENABLED           "browser.send_pings"
 #define PREF_PINGS_MAX_PER_LINK      "browser.send_pings.max_per_link"
 #define PREF_PINGS_REQUIRE_SAME_HOST "browser.send_pings.require_same_host"
 
@@ -4141,17 +4127,26 @@ nsDocShell::IsPrintingOrPP(bool aDisplay
   }
 
   return mIsPrintingOrPP;
 }
 
 bool
 nsDocShell::IsNavigationAllowed(bool aDisplayPrintErrorDialog)
 {
-    return !IsPrintingOrPP(aDisplayPrintErrorDialog) && !mFiredUnloadEvent;
+  bool isAllowed = !IsPrintingOrPP(aDisplayPrintErrorDialog) && !mFiredUnloadEvent;
+  if (!isAllowed) {
+    return false;
+  }
+  if (!mContentViewer) {
+    return true;
+  }
+  bool firingBeforeUnload;
+  mContentViewer->GetBeforeUnloadFiring(&firingBeforeUnload);
+  return !firingBeforeUnload;
 }
 
 //*****************************************************************************
 // nsDocShell::nsIWebNavigation
 //*****************************************************************************   
 
 NS_IMETHODIMP
 nsDocShell::GetCanGoBack(bool * aCanGoBack)
@@ -6860,24 +6855,16 @@ nsDocShell::EndPageLoad(nsIWebProgress *
     // Notify the ContentViewer that the Document has finished loading.  This
     // will cause any OnLoad(...) and PopState(...) handlers to fire.
     if (!mEODForCurrentDocument && mContentViewer) {
         mIsExecutingOnLoadHandler = true;
         mContentViewer->LoadComplete(aStatus);
         mIsExecutingOnLoadHandler = false;
 
         mEODForCurrentDocument = true;
-
-        // If all documents have completed their loading
-        // favor native event dispatch priorities
-        // over performance
-        if (--gNumberOfDocumentsLoading == 0) {
-          // Hint to use normal native event dispatch priorities 
-          FavorPerformanceHint(false);
-        }
     }
     /* Check if the httpChannel has any cache-control related response headers,
      * like no-store, no-cache. If so, update SHEntry so that 
      * when a user goes back/forward to this page, we appropriately do 
      * form value restoration or load from server.
      */
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
     if (!httpChannel) // HttpChannel could be hiding underneath a Multipart channel.    
@@ -7871,22 +7858,16 @@ nsDocShell::RestoreFromHistory()
     // but we don't want them to stay around in case the page is reloaded.
     SetLayoutHistoryState(nullptr);
 
     // This is the end of our Embed() replacement
 
     mSavingOldViewer = false;
     mEODForCurrentDocument = false;
 
-    // Tell the event loop to favor plevents over user events, see comments
-    // in CreateContentViewer.
-    if (++gNumberOfDocumentsLoading == 1)
-        FavorPerformanceHint(true);
-
-
     if (oldMUDV && newMUDV) {
         newMUDV->SetMinFontSize(minFontSize);
         newMUDV->SetTextZoom(textZoom);
         newMUDV->SetFullZoom(pageZoom);
         newMUDV->SetAuthorStyleDisabled(styleDisabled);
     }
 
     nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
@@ -8273,26 +8254,16 @@ nsDocShell::CreateContentViewer(const ch
         if (doc) {
           uint32_t partID;
           multiPartChannel->GetPartID(&partID);
           doc->SetPartID(partID);
         }
       }
     }
 
-    // Give hint to native plevent dispatch mechanism. If a document
-    // is loading the native plevent dispatch mechanism should favor
-    // performance over normal native event dispatch priorities.
-    if (++gNumberOfDocumentsLoading == 1) {
-      // Hint to favor performance for the plevent notification mechanism.
-      // We want the pages to load as fast as possible even if its means 
-      // native messages might be starved.
-      FavorPerformanceHint(true);
-    }
-
     if (onLocationChangeNeeded) {
       FireOnLocationChange(this, request, mCurrentURI, 0);
     }
   
     return NS_OK;
 }
 
 nsresult
@@ -10450,17 +10421,17 @@ nsDocShell::SetReferrerURI(nsIURI * aURI
     mReferrerURI = aURI;        // This assigment addrefs
 }
 
 //*****************************************************************************
 // nsDocShell: Session History
 //*****************************************************************************
 
 NS_IMETHODIMP
-nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
+nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
                      const nsAString& aURL, bool aReplace, JSContext* aCx)
 {
     // Implements History.pushState and History.replaceState
 
     // Here's what we do, roughly in the order specified by HTML5:
     // 1. Serialize aData using structured clone.
     // 2. If the third argument is present,
     //     a. Resolve the url, relative to the first script's base URL
--- a/docshell/base/nsIContentViewer.idl
+++ b/docshell/base/nsIContentViewer.idl
@@ -23,17 +23,17 @@ class nsDOMNavigationTiming;
 [ptr] native nsIWidgetPtr(nsIWidget);
 [ptr] native nsIDocumentPtr(nsIDocument);
 [ref] native nsIntRectRef(nsIntRect);
 [ptr] native nsIPresShellPtr(nsIPresShell);
 [ptr] native nsPresContextPtr(nsPresContext);
 [ptr] native nsViewPtr(nsView);
 [ptr] native nsDOMNavigationTimingPtr(nsDOMNavigationTiming);
 
-[scriptable, builtinclass, uuid(1b22be51-efe8-42ac-a9a0-06f50f39beee)]
+[scriptable, builtinclass, uuid(a73d693a-6260-468a-ae64-d64237f0858c)]
 interface nsIContentViewer : nsISupports
 {
 
   [noscript] void init(in nsIWidgetPtr aParentWidget,
                        [const] in nsIntRectRef aBounds);
 
   attribute nsIDocShell container;
 
@@ -54,16 +54,22 @@ interface nsIContentViewer : nsISupports
    * As above, but this passes around the aShouldPrompt argument to keep
    * track of whether the user has responded to a prompt.
    * Used internally by the scriptable version to ensure we only prompt once.
    */
   [noscript,nostdcall] boolean permitUnloadInternal(in boolean aCallerClosesWindow,
                                                     inout boolean aShouldPrompt);
 
   /**
+   * Exposes whether we're in the process of firing the beforeunload event.
+   * In this case, the corresponding docshell will not allow navigation.
+   */
+  readonly attribute boolean beforeUnloadFiring;
+
+  /**
    * Works in tandem with permitUnload, if the caller decides not to close the
    * window it indicated it will, it is the caller's responsibility to reset
    * that with this method.
    *
    * @Note this method is only meant to be called on documents for which the
    *  caller has indicated that it will close the window. If that is not the case
    *  the behavior of this method is undefined.
    */
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -177,16 +177,17 @@ const mozilla::Module::ContractIDEntry k
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "neterror", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "compartments", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "memory", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "addons", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newaddon", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "networking", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
+  { NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
   { NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID },
   { NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
   { NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
   { NS_MIMESERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default", &kNS_EXTERNALPROTOCOLHANDLER_CID },
   { NS_PREFETCHSERVICE_CONTRACTID, &kNS_PREFETCHSERVICE_CID },
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -75,19 +75,19 @@ DOMRequest::GetReadyState(nsAString& aRe
     default:
       MOZ_CRASH("Unrecognized readyState.");
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMRequest::GetResult(JS::Value* aResult)
+DOMRequest::GetResult(JS::MutableHandle<JS::Value> aResult)
 {
-  *aResult = Result();
+  aResult.set(Result());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequest::GetError(nsISupports** aError)
 {
   NS_IF_ADDREF(*aError = GetError());
   return NS_OK;
@@ -197,21 +197,20 @@ DOMRequestService::CreateCursor(nsIDOMWi
   NS_ENSURE_STATE(win);
   NS_ADDREF(*aCursor = new DOMCursor(win, aCallback));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireSuccess(nsIDOMDOMRequest* aRequest,
-                               const JS::Value& aResult)
+                               JS::Handle<JS::Value> aResult)
 {
   NS_ENSURE_STATE(aRequest);
-  static_cast<DOMRequest*>(aRequest)->
-    FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(&aResult));
+  static_cast<DOMRequest*>(aRequest)->FireSuccess(aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireError(nsIDOMDOMRequest* aRequest,
                              const nsAString& aError)
 {
@@ -311,17 +310,17 @@ public:
   }
 private:
   nsRefPtr<DOMRequest> mReq;
   nsString mError;
 };
 
 NS_IMETHODIMP
 DOMRequestService::FireSuccessAsync(nsIDOMDOMRequest* aRequest,
-                                    const JS::Value& aResult)
+                                    JS::Handle<JS::Value> aResult)
 {
   NS_ENSURE_STATE(aRequest);
   return FireSuccessAsyncTask::Dispatch(static_cast<DOMRequest*>(aRequest), aResult);
 }
 
 NS_IMETHODIMP
 DOMRequestService::FireErrorAsync(nsIDOMDOMRequest* aRequest,
                                   const nsAString& aError)
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1260,23 +1260,24 @@ Navigator::GetGamepads(nsTArray<nsRefPtr
 }
 #endif
 
 //*****************************************************************************
 //    Navigator::nsIMozNavigatorNetwork
 //*****************************************************************************
 
 NS_IMETHODIMP
-Navigator::GetMozConnection(nsIDOMMozConnection** aConnection)
+Navigator::GetMozConnection(nsISupports** aConnection)
 {
-  NS_IF_ADDREF(*aConnection = GetMozConnection());
+  nsCOMPtr<nsINetworkProperties> properties = GetMozConnection();
+  properties.forget(aConnection);
   return NS_OK;
 }
 
-nsIDOMMozConnection*
+network::Connection*
 Navigator::GetMozConnection()
 {
   if (!mConnection) {
     NS_ENSURE_TRUE(mWindow, nullptr);
     NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
 
     mConnection = new network::Connection();
     mConnection->Init(mWindow);
@@ -1316,17 +1317,17 @@ Navigator::EnsureMessagesManager()
 
   nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
     do_QueryInterface(messageManager);
   NS_ENSURE_TRUE(gpi, NS_ERROR_FAILURE);
 
   // We don't do anything with the return value.
   AutoJSContext cx;
   JS::Rooted<JS::Value> prop_val(cx);
-  rv = gpi->Init(mWindow, prop_val.address());
+  rv = gpi->Init(mWindow, &prop_val);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mMessagesManager = messageManager.forget();
 
   return NS_OK;
 }
 
 bool
@@ -1573,17 +1574,17 @@ Navigator::DoNewResolve(JSContext* aCx, 
 
   nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
 
   if (gpi) {
     if (!mWindow) {
       return Throw(aCx, NS_ERROR_UNEXPECTED);
     }
 
-    rv = gpi->Init(mWindow, prop_val.address());
+    rv = gpi->Init(mWindow, &prop_val);
     if (NS_FAILED(rv)) {
       return Throw(aCx, rv);
     }
   }
 
   if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
     rv = nsContentUtils::WrapNative(aCx, aObject, native, &prop_val, true);
 
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -190,17 +190,17 @@ public:
   void GetDeviceStorages(const nsAString& aType,
                          nsTArray<nsRefPtr<nsDOMDeviceStorage> >& aStores,
                          ErrorResult& aRv);
   DesktopNotificationCenter* GetMozNotification(ErrorResult& aRv);
   bool MozIsLocallyAvailable(const nsAString& aURI, bool aWhenOffline,
                              ErrorResult& aRv);
   nsIDOMMozMobileMessageManager* GetMozMobileMessage();
   Telephony* GetMozTelephony(ErrorResult& aRv);
-  nsIDOMMozConnection* GetMozConnection();
+  network::Connection* GetMozConnection();
   nsDOMCameraManager* GetMozCameras(ErrorResult& aRv);
   void MozSetMessageHandler(const nsAString& aType,
                             systemMessageCallback* aCallback,
                             ErrorResult& aRv);
   bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
 #ifdef MOZ_B2G_RIL
   network::MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv);
   CellBroadcast* GetMozCellBroadcast(ErrorResult& aRv);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -149,17 +149,16 @@
 #include "mozilla/dom/HTMLCollectionBinding.h"
 
 #include "nsIDOMMobileMessageManager.h"
 #include "nsIDOMMozSmsMessage.h"
 #include "nsIDOMMozMmsMessage.h"
 #include "nsIDOMSmsFilter.h"
 #include "nsIDOMSmsSegmentInfo.h"
 #include "nsIDOMMozMobileMessageThread.h"
-#include "nsIDOMConnection.h"
 
 #ifdef MOZ_B2G_RIL
 #include "nsIDOMIccManager.h"
 #include "nsIDOMMobileConnection.h"
 #endif // MOZ_B2G_RIL
 
 #ifdef MOZ_B2G_FM
 #include "FMRadio.h"
@@ -448,19 +447,16 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozSmsSegmentInfo, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozMobileMessageThread, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(MozConnection, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
 #ifdef MOZ_B2G_RIL
   NS_DEFINE_CLASSINFO_DATA(MozMobileConnection, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
@@ -612,17 +608,17 @@ WrapNative(JSContext *cx, JSObject *scop
 
   JSObject *wrapper = xpc_FastGetCachedWrapper(cache, scope, vp);
   if (wrapper) {
     return NS_OK;
   }
 
   return nsDOMClassInfo::XPConnect()->WrapNativeToJSVal(cx, scope, native,
                                                         cache, aIID,
-                                                        aAllowWrapping, vp.address());
+                                                        aAllowWrapping, vp);
 }
 
 static inline nsresult
 WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
            const nsIID* aIID, bool aAllowWrapping, JS::MutableHandle<JS::Value> vp)
 {
   return WrapNative(cx, scope, native, nullptr, aIID, vp, aAllowWrapping);
 }
@@ -1142,21 +1138,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(MozSmsSegmentInfo, nsIDOMMozSmsSegmentInfo)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsSegmentInfo)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozMobileMessageThread, nsIDOMMozMobileMessageThread)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMobileMessageThread)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(MozConnection, nsIDOMMozConnection)
-     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozConnection)
-     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
-  DOM_CLASSINFO_MAP_END
-
 #ifdef MOZ_B2G_RIL
   DOM_CLASSINFO_MAP_BEGIN(MozMobileConnection, nsIDOMMozMobileConnection)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMobileConnection)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 #endif // MOZ_B2G_RIL
 
   DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
@@ -1657,17 +1648,17 @@ nsDOMClassInfo::Construct(nsIXPConnectWr
 {
   NS_WARNING("nsDOMClassInfo::Construct Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                            JSObject *obj, const jsval &val, bool *bp,
+                            JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
                             bool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::HasInstance Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
@@ -3129,17 +3120,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
 
     nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JS::Rooted<JS::Value> prop_val(cx, JS::UndefinedValue()); // Property value.
 
     nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
     if (gpi) {
-      rv = gpi->Init(aWin, prop_val.address());
+      rv = gpi->Init(aWin, &prop_val);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
       JSObject *scope;
 
       if (aWin->IsOuterWindow()) {
         nsGlobalWindow *inner = aWin->GetCurrentInnerWindowInternal();
@@ -4503,17 +4494,17 @@ nsDOMConstructorSH::Construct(nsIXPConne
   }
 #endif
 
   return wrapped->Construct(wrapper, cx, obj, args, _retval);
 }
 
 NS_IMETHODIMP
 nsDOMConstructorSH::HasInstance(nsIXPConnectWrappedNative *wrapper,
-                                JSContext *cx, JSObject *aObj, const jsval &val,
+                                JSContext *cx, JSObject *aObj, JS::Handle<JS::Value> val,
                                 bool *bp, bool *_retval)
 {
   JS::Rooted<JSObject*> obj(cx, aObj);
   nsDOMConstructor *wrapped =
     static_cast<nsDOMConstructor *>(wrapper->Native());
 
 #ifdef DEBUG
   {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -569,17 +569,17 @@ public:
                         JSObject **objp, bool *_retval) MOZ_OVERRIDE;
   NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                   JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
 
   NS_IMETHOD Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                        JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
 
   NS_IMETHOD HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, const JS::Value &val, bool *bp,
+                         JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
                          bool *_retval);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsDOMConstructorSH(aData);
   }
 };
 
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -79,17 +79,16 @@ DOMCI_CLASS(ModalContentWindow)
 
 DOMCI_CLASS(MozMobileMessageManager)
 DOMCI_CLASS(MozSmsMessage)
 DOMCI_CLASS(MozMmsMessage)
 DOMCI_CLASS(MozSmsFilter)
 DOMCI_CLASS(MozSmsSegmentInfo)
 DOMCI_CLASS(MozMobileMessageThread)
 
-DOMCI_CLASS(MozConnection)
 #ifdef MOZ_B2G_RIL
 DOMCI_CLASS(MozMobileConnection)
 #endif
 
 // @font-face in CSS
 DOMCI_CLASS(CSSFontFaceRule)
 
 DOMCI_CLASS(DataTransfer)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2130,17 +2130,18 @@ nsDOMWindowUtils::SendContentCommandEven
     event.mTransferable = aTransferable;
   }
 
   nsEventStatus status;
   return widget->DispatchEvent(&event, status);
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetClassName(const JS::Value& aObject, JSContext* aCx, char** aName)
+nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
+                               char** aName)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // Our argument must be a non-null object.
   if (JSVAL_IS_PRIMITIVE(aObject)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
@@ -2215,39 +2216,39 @@ nsDOMWindowUtils::IsInModalState(bool *r
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
   *retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetParent(const JS::Value& aObject,
+nsDOMWindowUtils::GetParent(JS::Handle<JS::Value> aObject,
                             JSContext* aCx,
-                            JS::Value* aParent)
+                            JS::MutableHandle<JS::Value> aParent)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // First argument must be an object.
-  if (JSVAL_IS_PRIMITIVE(aObject)) {
+  if (aObject.isPrimitive()) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
-  JS::Rooted<JSObject*> parent(aCx, JS_GetParent(JSVAL_TO_OBJECT(aObject)));
-  *aParent = OBJECT_TO_JSVAL(parent);
+  JS::Rooted<JSObject*> parent(aCx, JS_GetParent(&aObject.toObject()));
 
   // Outerize if necessary.
   if (parent) {
     if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
-      *aParent = OBJECT_TO_JSVAL(outerize(aCx, parent));
+      parent = outerize(aCx, parent);
     }
   }
 
+  aParent.setObject(*parent);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
@@ -2862,18 +2863,18 @@ GetFileOrBlob(const nsAString& aName, co
   rv = domFile->InitBlob(aCx, aOptionalArgCount, args, GetXPConnectNative);
   NS_ENSURE_SUCCESS(rv, rv);
 
   file.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetFile(const nsAString& aName, const JS::Value& aBlobParts,
-                          const JS::Value& aParameters, JSContext* aCx,
+nsDOMWindowUtils::GetFile(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
+                          JS::Handle<JS::Value> aParameters, JSContext* aCx,
                           uint8_t aOptionalArgCount, nsIDOMFile** aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsISupports> file;
   nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx,
@@ -2882,18 +2883,18 @@ nsDOMWindowUtils::GetFile(const nsAStrin
 
   nsCOMPtr<nsIDOMFile> result = do_QueryInterface(file);
   result.forget(aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetBlob(const JS::Value& aBlobParts,
-                          const JS::Value& aParameters, JSContext* aCx,
+nsDOMWindowUtils::GetBlob(JS::Handle<JS::Value> aBlobParts,
+                          JS::Handle<JS::Value> aParameters, JSContext* aCx,
                           uint8_t aOptionalArgCount, nsIDOMBlob** aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsISupports> blob;
   nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx,
@@ -2902,17 +2903,17 @@ nsDOMWindowUtils::GetBlob(const JS::Valu
 
   nsCOMPtr<nsIDOMBlob> result = do_QueryInterface(blob);
   result.forget(aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetFileId(const JS::Value& aFile, JSContext* aCx,
+nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
                             int64_t* aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (!JSVAL_IS_PRIMITIVE(aFile)) {
     JSObject* obj = JSVAL_TO_OBJECT(aFile);
@@ -2934,17 +2935,17 @@ nsDOMWindowUtils::GetFileId(const JS::Va
   }
 
   *aResult = -1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
-                                    const jsval& aOptions,
+                                    JS::Handle<JS::Value> aOptions,
                                     int32_t* aRefCnt, int32_t* aDBRefCnt,
                                     int32_t* aSliceRefCnt, JSContext* aCx,
                                     bool* aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
@@ -3092,17 +3093,17 @@ nsDOMWindowUtils::GetPaintingSuppressed(
   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
   *aPaintingSuppressed = presShell->IsPaintingSuppressed();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::Value* aPlugins)
+nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
@@ -3110,17 +3111,17 @@ nsDOMWindowUtils::GetPlugins(JSContext* 
 
   nsTArray<nsIObjectLoadingContent*> plugins;
   doc->GetPlugins(plugins);
 
   JS::Rooted<JSObject*> jsPlugins(cx);
   nsresult rv = nsTArrayToJSArray(cx, plugins, jsPlugins.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aPlugins = OBJECT_TO_JSVAL(jsPlugins);
+  aPlugins.setObject(*jsPlugins);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3747,17 +3747,17 @@ nsGlobalWindow::GetContent(JSContext* aC
   // Something tries to get .content on a ChromeWindow, try to fetch the CPOW.
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
   if (!treeOwner) {
     aError.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   JS::Rooted<JS::Value> val(aCx, JS::NullValue());
-  aError = treeOwner->GetContentWindow(aCx, val.address());
+  aError = treeOwner->GetContentWindow(aCx, &val);
   if (aError.Failed()) {
     return nullptr;
   }
 
   return val.toObjectOrNull();
 }
 
 already_AddRefed<nsIDOMWindow>
@@ -3813,22 +3813,22 @@ nsGlobalWindow::GetContent(nsIDOMWindow*
 {
   ErrorResult rv;
   *aContent = GetContentInternal(rv).get();
 
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::Value* aVal)
+nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
 {
   ErrorResult rv;
   JS::Rooted<JSObject*> content(aCx, GetContent(aCx, rv));
   if (!rv.Failed()) {
-    *aVal = JS::ObjectOrNullValue(content);
+    aVal.setObjectOrNull(content);
   }
 
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetPrompter(nsIPrompt** aPrompt)
 {
@@ -4950,17 +4950,17 @@ nsGlobalWindow::RequestAnimationFrame(co
   }
 
   int32_t handle;
   aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle);
   return handle;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::RequestAnimationFrame(const JS::Value& aCallback,
+nsGlobalWindow::RequestAnimationFrame(JS::Handle<JS::Value> aCallback,
                                       JSContext* cx,
                                       int32_t* aHandle)
 {
   if (!aCallback.isObject() || !JS_ObjectIsCallable(cx, &aCallback.toObject())) {
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::Rooted<JSObject*> callbackObj(cx, &aCallback.toObject());
@@ -7945,25 +7945,23 @@ nsGlobalWindow::PostMessageMoz(JSContext
       return;
     }
   }
 
   PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray, aError);
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::PostMessageMoz(const JS::Value& aMessage,
+nsGlobalWindow::PostMessageMoz(JS::Handle<JS::Value> aMessage,
                                const nsAString& aOrigin,
-                               const JS::Value& aTransfer,
+                               JS::Handle<JS::Value> aTransfer,
                                JSContext* aCx)
 {
-  JS::Rooted<JS::Value> message(aCx, aMessage);
-  JS::Rooted<JS::Value> transfer(aCx, aTransfer);
-  ErrorResult rv;
-  PostMessageMoz(aCx, message, aOrigin, transfer, rv);
+  ErrorResult rv;
+  PostMessageMoz(aCx, aMessage, aOrigin, aTransfer, rv);
 
   return rv.ErrorCode();
 }
 
 class nsCloseEvent : public nsRunnable {
 
   nsRefPtr<nsGlobalWindow> mWindow;
   bool mIndirect;
@@ -8778,32 +8776,32 @@ JS::Value
 nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
                                 const Optional<JS::Handle<JS::Value> >& aArgument,
                                 const nsAString& aOptions,
                                 ErrorResult& aError)
 {
   nsCOMPtr<nsIVariant> args;
   if (aArgument.WasPassed()) {
     aError = nsContentUtils::XPConnect()->JSToVariant(aCx,
-                                                      aArgument.Value().get(),
+                                                      aArgument.Value(),
                                                       getter_AddRefs(args));
   } else {
     args = CreateVoidVariant();
   }
 
   nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aUrl, args, aOptions, aError);
   if (aError.Failed()) {
     return JS::UndefinedValue();
   }
 
   JS::Rooted<JS::Value> result(aCx);
   if (retVal) {
     aError = nsContentUtils::XPConnect()->VariantToJS(aCx,
                                                       FastGetGlobalJSObject(),
-                                                      retVal, result.address());
+                                                      retVal, &result);
   } else {
     result = JS::NullValue();
   }
   return result;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
@@ -13274,79 +13272,79 @@ nsGlobalWindow::DisableNetworkEvent(uint
       }
       break;
   }
 }
 #endif // MOZ_B2G
 
 #define EVENT(name_, id_, type_, struct_)                                    \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
-                                             JS::Value *vp) {                \
+                                             JS::MutableHandle<JS::Value> vp) { \
     EventHandlerNonNull* h = GetOn##name_();                                 \
-    vp->setObjectOrNull(h ? h->Callable().get() : nullptr);                  \
+    vp.setObjectOrNull(h ? h->Callable().get() : nullptr);                   \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
-                                             const JS::Value &v) {           \
+                                             JS::Handle<JS::Value> v) {      \
     nsRefPtr<EventHandlerNonNull> handler;                                   \
     JS::Rooted<JSObject*> callable(cx);                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
       handler = new EventHandlerNonNull(callable, GetIncumbentGlobal());     \
     }                                                                        \
     SetOn##name_(handler);                                                   \
     return NS_OK;                                                            \
   }
 #define ERROR_EVENT(name_, id_, type_, struct_)                              \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
-                                             JS::Value *vp) {                \
+                                             JS::MutableHandle<JS::Value> vp) { \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
     if (elm) {                                                               \
       OnErrorEventHandlerNonNull* h = elm->GetOnErrorEventHandler();         \
       if (h) {                                                               \
-        *vp = JS::ObjectValue(*h->Callable());                               \
+        vp.setObject(*h->Callable());                                        \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
-    *vp = JSVAL_NULL;                                                        \
+    vp.setNull();                                                            \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
-                                             const JS::Value &v) {           \
+                                             JS::Handle<JS::Value> v) {      \
     nsEventListenerManager *elm = GetOrCreateListenerManager();              \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnErrorEventHandlerNonNull> handler;                            \
     JS::Rooted<JSObject*> callable(cx);                                      \
     if (v.isObject() &&                                                      \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
       handler = new OnErrorEventHandlerNonNull(callable, GetIncumbentGlobal()); \
     }                                                                        \
     elm->SetEventHandler(handler);                                           \
     return NS_OK;                                                            \
   }
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                       \
   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
-                                             JS::Value *vp) {                \
+                                             JS::MutableHandle<JS::Value> vp) { \
     nsEventListenerManager *elm = GetExistingListenerManager();              \
     if (elm) {                                                               \
       OnBeforeUnloadEventHandlerNonNull* h =                                 \
         elm->GetOnBeforeUnloadEventHandler();                                \
       if (h) {                                                               \
-        *vp = JS::ObjectValue(*h->Callable());                               \
+        vp.setObject(*h->Callable());                                        \
         return NS_OK;                                                        \
       }                                                                      \
     }                                                                        \
-    *vp = JSVAL_NULL;                                                        \
+    vp.setNull();                                                            \
     return NS_OK;                                                            \
   }                                                                          \
   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
-                                             const JS::Value &v) {           \
+                                             JS::Handle<JS::Value> v) {      \
     nsEventListenerManager *elm = GetOrCreateListenerManager();              \
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handler;                     \
     JS::Rooted<JSObject*> callable(cx);                                      \
     if (v.isObject() &&                                                      \
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -120,17 +120,17 @@ nsHistory::GetState(JSContext* aCx, Erro
     return JS::UndefinedValue();
   }
 
   nsCOMPtr<nsIVariant> variant;
   doc->GetStateObject(getter_AddRefs(variant));
 
   if (variant) {
     JS::Rooted<JS::Value> jsData(aCx);
-    aRv = variant->GetAsJSVal(jsData.address());
+    aRv = variant->GetAsJSVal(&jsData);
 
     if (aRv.Failed()) {
       return JS::UndefinedValue();
     }
 
     if (!JS_WrapValue(aCx, &jsData)) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
       return JS::UndefinedValue();
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1251,17 +1251,19 @@ nsJSContext::ConvertSupportsTojsvals(nsI
       argsArray->QueryElementAt(argCtr, NS_GET_IID(nsISupports),
                                 getter_AddRefs(arg));
       if (!arg) {
         *thisval = JSVAL_NULL;
         continue;
       }
       nsCOMPtr<nsIVariant> variant(do_QueryInterface(arg));
       if (variant != nullptr) {
-        rv = xpc->VariantToJS(cx, aScope, variant, thisval);
+        JS::Rooted<JS::Value> temp(cx);
+        rv = xpc->VariantToJS(cx, aScope, variant, &temp);
+        *thisval = temp.get();
       } else {
         // And finally, support the nsISupportsPrimitives supplied
         // by the AppShell.  It generally will pass only strings, but
         // as we have code for handling all, we may as well use it.
         rv = AddSupportsPrimitiveTojsvals(arg, thisval);
         if (rv == NS_ERROR_NO_INTERFACE) {
           // something else - probably an event object or similar -
           // just wrap it.
@@ -1278,17 +1280,19 @@ nsJSContext::ConvertSupportsTojsvals(nsI
             *thisval = v;
           }
         }
       }
     }
   } else {
     nsCOMPtr<nsIVariant> variant = do_QueryInterface(aArgs);
     if (variant) {
-      rv = xpc->VariantToJS(cx, aScope, variant, argv);
+      JS::Rooted<JS::Value> temp(cx);
+      rv = xpc->VariantToJS(cx, aScope, variant, &temp);
+      *argv = temp.get();
     } else {
       NS_ERROR("Not an array, not an interface?");
       rv = NS_ERROR_UNEXPECTED;
     }
   }
   if (NS_FAILED(rv))
     return rv;
   *aArgv = argv;
@@ -3300,17 +3304,19 @@ NS_IMETHODIMP nsJSArgArray::GetLength(ui
 /* void queryElementAt (in unsigned long index, in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
 NS_IMETHODIMP nsJSArgArray::QueryElementAt(uint32_t index, const nsIID & uuid, void * *result)
 {
   *result = nullptr;
   if (index >= mArgc)
     return NS_ERROR_INVALID_ARG;
 
   if (uuid.Equals(NS_GET_IID(nsIVariant)) || uuid.Equals(NS_GET_IID(nsISupports))) {
-    return nsContentUtils::XPConnect()->JSToVariant(mContext, mArgv[index],
+    // Have to copy a Heap into a Rooted to work with it.
+    JS::Rooted<JS::Value> val(mContext, mArgv[index]);
+    return nsContentUtils::XPConnect()->JSToVariant(mContext, val,
                                                     (nsIVariant **)result);
   }
   NS_WARNING("nsJSArgArray only handles nsIVariant");
   return NS_ERROR_NO_INTERFACE;
 }
 
 /* unsigned long indexOf (in unsigned long startIndex, in nsISupports element); */
 NS_IMETHODIMP nsJSArgArray::IndexOf(uint32_t startIndex, nsISupports *element, uint32_t *_retval)
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -233,21 +233,19 @@ nsScreen::GetLockOrientationPermission()
     return LOCK_ALLOWED;
   }
 
   // Other content must be full-screen in order to lock orientation.
   return doc->MozFullScreen() ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
 }
 
 NS_IMETHODIMP
-nsScreen::MozLockOrientation(const JS::Value& aOrientation_, JSContext* aCx,
+nsScreen::MozLockOrientation(JS::Handle<JS::Value> aOrientation, JSContext* aCx,
                              bool* aReturn)
 {
-  JS::Rooted<JS::Value> aOrientation(aCx, aOrientation_);
-
   if (aOrientation.isObject()) {
     JS::Rooted<JSObject*> seq(aCx, &aOrientation.toObject());
     if (IsArrayLike(aCx, seq)) {
       uint32_t length;
       // JS_GetArrayLength actually works on all objects
       if (!JS_GetArrayLength(aCx, seq, &length)) {
         return NS_ERROR_FAILURE;
       }
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -34,17 +34,17 @@ nsStructuredCloneContainer::nsStructured
 }
 
 nsStructuredCloneContainer::~nsStructuredCloneContainer()
 {
   free(mData);
 }
 
 nsresult
-nsStructuredCloneContainer::InitFromJSVal(const JS::Value & aData,
+nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
                                           JSContext* aCx)
 {
   NS_ENSURE_STATE(!mData);
   NS_ENSURE_ARG_POINTER(aCx);
 
   // Make sure that we serialize in the right context.
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   JS::Rooted<JS::Value> jsData(aCx, aData);
@@ -119,18 +119,17 @@ nsStructuredCloneContainer::DeserializeT
   // We want to be sure that mData doesn't contain transferable objects
   MOZ_ASSERT(!hasTransferable);
   NS_ENSURE_STATE(success && !hasTransferable);
 
   // Now wrap the JS::Value as an nsIVariant.
   nsCOMPtr<nsIVariant> varStateObj;
   nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
   NS_ENSURE_STATE(xpconnect);
-  xpconnect->JSValToVariant(aCx, jsStateObj.address(),
-                            getter_AddRefs(varStateObj));
+  xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
   NS_ENSURE_STATE(varStateObj);
 
   NS_ADDREF(*aData = varStateObj);
   return NS_OK;
 }
 
 nsresult
 nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2029,17 +2029,17 @@ ConstructJSImplementation(JSContext* aCx
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
     // Initialize the object, if it implements nsIDOMGlobalPropertyInitializer.
     nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
       do_QueryInterface(implISupports);
     if (gpi) {
       JS::Rooted<JS::Value> initReturn(aCx);
-      nsresult rv = gpi->Init(window, initReturn.address());
+      nsresult rv = gpi->Init(window, &initReturn);
       if (NS_FAILED(rv)) {
         aRv.Throw(rv);
         return nullptr;
       }
       // With JS-implemented WebIDL, the return value of init() is not used to determine
       // if init() failed, so init() should only return undefined. Any kind of permission
       // or pref checking must happen by adding an attribute to the WebIDL interface.
       if (!initReturn.isUndefined()) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -795,16 +795,20 @@ DOMInterfaces = {
 {
     'workers': True,
 }],
 
 'MozCellBroadcast': {
     'nativeType': 'mozilla::dom::CellBroadcast',
 },
 
+'MozConnection': {
+    'nativeType': 'mozilla::dom::network::Connection',
+},
+
 'MozIcc': {
     'nativeType': 'mozilla::dom::Icc',
 },
 
 'MozMobileConnectionArray': {
     'nativeType': 'mozilla::dom::network::MobileConnectionArray',
     'resultNotAddRefed': [ 'item' ]
 },
@@ -1877,17 +1881,16 @@ addExternalIface('DOMStringList')
 addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
 addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
-addExternalIface('MozConnection', headerFile='nsIDOMConnection.h')
 addExternalIface('MozControllers', nativeType='nsIControllers')
 addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
 addExternalIface('MozFrameRequestCallback', nativeType='nsIFrameRequestCallback',
                  notflattened=True)
 addExternalIface('MozIccInfo', headerFile='nsIDOMIccInfo.h')
 addExternalIface('MozIccManager', headerFile='nsIDOMIccManager.h')
 addExternalIface('MozMobileConnection', headerFile='nsIDOMMobileConnection.h')
 addExternalIface('MozMobileMessageManager', headerFile='nsIDOMMobileMessageManager.h')
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -835,17 +835,19 @@ def UnionTypes(descriptors, dictionaries
                     # For a dictionary, we need to see its declaration in
                     # UnionTypes.h so we have its sizeof and know how big to
                     # make our union.
                     headers.add(CGHeaders.getDeclarationFilename(f.inner))
                     # And if it needs rooting, we need RootedDictionary too
                     if typeNeedsRooting(f):
                         headers.add("mozilla/dom/RootedDictionary.h")
                 elif f.isEnum():
-                    headers.add(CGHeaders.getDeclarationFilename(f))
+                    # Need to see the actual definition of the enum,
+                    # unfortunately.
+                    headers.add(CGHeaders.getDeclarationFilename(f.inner))
 
     map(addInfoForType, getAllTypes(descriptors, dictionaries, callbacks))
 
     return (headers, implheaders, declarations,
             CGList(itertools.chain(SortedDictValues(unionStructs),
                                    SortedDictValues(owningUnionStructs)), "\n"))
 
 def UnionConversions(descriptors, dictionaries, callbacks, config):
--- a/dom/bluetooth/BluetoothPropertyContainer.cpp
+++ b/dom/bluetooth/BluetoothPropertyContainer.cpp
@@ -7,31 +7,33 @@
 #include "base/basictypes.h"
 #include "BluetoothPropertyContainer.h"
 #include "BluetoothService.h"
 #include "DOMRequest.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "nsServiceManagerUtils.h"
 
+#include "js/Value.h"
+
 USING_BLUETOOTH_NAMESPACE
 
 already_AddRefed<mozilla::dom::DOMRequest>
 BluetoothPropertyContainer::FirePropertyAlreadySet(nsPIDOMWindow* aOwner,
                                                    ErrorResult& aRv)
 {
   nsCOMPtr<nsIDOMRequestService> rs =
     do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
   if (!rs) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<mozilla::dom::DOMRequest> request = new DOMRequest(aOwner);
-  rs->FireSuccess(request, JS::UndefinedValue());
+  rs->FireSuccess(request, JS::UndefinedHandleValue);
 
   return request.forget();
 }
 
 already_AddRefed<mozilla::dom::DOMRequest>
 BluetoothPropertyContainer::SetProperty(nsPIDOMWindow* aOwner,
                                         const BluetoothNamedValue& aProperty,
                                         ErrorResult& aRv)
--- a/dom/bluetooth/BluetoothService.cpp
+++ b/dom/bluetooth/BluetoothService.cpp
@@ -241,17 +241,17 @@ private:
   bool mIsStartup;
 };
 
 class BluetoothService::StartupTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (!aResult.isBoolean()) {
       BT_WARNING("Setting for '" BLUETOOTH_ENABLED_SETTING "' is not a boolean!");
       return NS_OK;
     }
 
@@ -852,12 +852,12 @@ BluetoothService::Notify(const Bluetooth
     BT_WARNING(warningMsg.get());
     return;
   }
 
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE_VOID(systemMessenger);
 
-  systemMessenger->BroadcastMessage(type,
-                                    OBJECT_TO_JSVAL(obj),
-                                    JS::UndefinedValue());
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
+  systemMessenger->BroadcastMessage(type, value,
+                                    JS::UndefinedHandleValue);
 }
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
@@ -811,18 +811,18 @@ BluetoothA2dpManager::IsAvrcpConnected()
 /*
  * This function only updates meta data in BluetoothA2dpManager
  * Send "Get Element Attributes response" in AvrcpGetElementAttrCallback
  */
 void
 BluetoothA2dpManager::UpdateMetaData(const nsAString& aTitle,
                                      const nsAString& aArtist,
                                      const nsAString& aAlbum,
-                                     uint32_t aMediaNumber,
-                                     uint32_t aTotalMediaCount,
+                                     uint64_t aMediaNumber,
+                                     uint64_t aTotalMediaCount,
                                      uint32_t aDuration)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
 #if ANDROID_VERSION > 17
   NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
 
   // Send track changed and position changed if track num is not the same.
@@ -900,17 +900,17 @@ BluetoothA2dpManager::UpdatePlayStatus(u
   mPosition = aPosition;
   mPlayStatus = aPlayStatus;
 #endif
 }
 
 /*
  * This function handles RegisterNotification request from
  * AvrcpRegisterNotificationCallback, which updates current
- * track/status/position status.
+ * track/status/position status in the INTERRIM response.
  *
  * aParam is only valid when position changed
  */
 void
 BluetoothA2dpManager::UpdateRegisterNotification(int aEventId, int aParam)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -920,26 +920,44 @@ BluetoothA2dpManager::UpdateRegisterNoti
   btrc_register_notification_t param;
 
   switch (aEventId) {
     case BTRC_EVT_PLAY_STATUS_CHANGED:
       mPlayPosChangedNotifyType = BTRC_NOTIFICATION_TYPE_INTERIM;
       param.play_status = (btrc_play_status_t)mPlayStatus;
       break;
     case BTRC_EVT_TRACK_CHANGE:
+      // In AVRCP 1.3 and 1.4, the identifier parameter of EVENT_TRACK_CHANGED
+      // is different.
+      // AVRCP 1.4: If no track is selected, we shall return 0xFFFFFFFFFFFFFFFF,
+      // otherwise return 0x0 in the INTERRIM response. The expanded text in
+      // version 1.4 is to allow for new UID feature. As for AVRCP 1.3, we shall
+      // return 0xFFFFFFFF. Since PTS enforces to check this part to comply with
+      // the most updated spec.
       mTrackChangedNotifyType = BTRC_NOTIFICATION_TYPE_INTERIM;
       // needs to convert to network big endian format since track stores
-      // as uint8[8]. 56 = 8 * (BTRC_UID_SIZE -1)
-      for (int i = 0; i < BTRC_UID_SIZE; ++i) {
-        param.track[i] = (mMediaNumber >> (56 - 8 * i));
+      // as uint8[8]. 56 = 8 * (BTRC_UID_SIZE -1).
+      for (int index = 0; index < BTRC_UID_SIZE; ++index) {
+        // We cannot easily check if a track is selected, so whenever A2DP is
+        // streaming, we assume a track is selected.
+        if (mSinkState == BluetoothA2dpManager::SinkState::SINK_PLAYING) {
+          param.track[index] = 0x0;
+        } else {
+          param.track[index] = 0xFF;
+        }
       }
       break;
     case BTRC_EVT_PLAY_POS_CHANGED:
+      // If no track is selected, return 0xFFFFFFFF in the INTERIM response
       mPlayPosChangedNotifyType = BTRC_NOTIFICATION_TYPE_INTERIM;
-      param.song_pos = mPosition;
+      if (mSinkState == BluetoothA2dpManager::SinkState::SINK_PLAYING) {
+        param.song_pos = mPosition;
+      } else {
+        param.song_pos = 0xFFFFFFFF;
+      }
       mPlaybackInterval = aParam;
       break;
     default:
       break;
   }
 
   sBtAvrcpInterface->register_notification_rsp((btrc_event_id_t)aEventId,
                                                BTRC_NOTIFICATION_TYPE_INTERIM,
@@ -966,23 +984,23 @@ BluetoothA2dpManager::GetPlayStatus()
 }
 
 uint32_t
 BluetoothA2dpManager::GetPosition()
 {
   return mPosition;
 }
 
-uint32_t
+uint64_t
 BluetoothA2dpManager::GetMediaNumber()
 {
   return mMediaNumber;
 }
 
-uint32_t
+uint64_t
 BluetoothA2dpManager::GetTotalMediaNumber()
 {
   return mTotalMediaCount;
 }
 
 void
 BluetoothA2dpManager::GetTitle(nsAString& aTitle)
 {
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
@@ -40,29 +40,29 @@ public:
   void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
 
   // AVRCP-specific functions
   void SetAvrcpConnected(bool aConnected);
   bool IsAvrcpConnected();
   void UpdateMetaData(const nsAString& aTitle,
                       const nsAString& aArtist,
                       const nsAString& aAlbum,
-                      uint32_t aMediaNumber,
-                      uint32_t aTotalMediaCount,
+                      uint64_t aMediaNumber,
+                      uint64_t aTotalMediaCount,
                       uint32_t aDuration);
   void UpdatePlayStatus(uint32_t aDuration,
                         uint32_t aPosition,
                         ControlPlayStatus aPlayStatus);
   void UpdateRegisterNotification(int aEventId, int aParam);
   void GetAlbum(nsAString& aAlbum);
   uint32_t GetDuration();
   ControlPlayStatus GetPlayStatus();
   uint32_t GetPosition();
-  uint32_t GetMediaNumber();
-  uint32_t GetTotalMediaNumber();
+  uint64_t GetMediaNumber();
+  uint64_t GetTotalMediaNumber();
   void GetTitle(nsAString& aTitle);
   void GetArtist(nsAString& aArtist);
 private:
   class SinkPropertyChangedHandler;
   BluetoothA2dpManager();
   bool Init();
   void HandleShutdown();
   void NotifyConnectionStatusChanged();
@@ -75,18 +75,18 @@ private:
   SinkState mSinkState;
 
   // AVRCP data member
   bool mAvrcpConnected;
   nsString mAlbum;
   nsString mArtist;
   nsString mTitle;
   uint32_t mDuration;
-  uint32_t mMediaNumber;
-  uint32_t mTotalMediaCount;
+  uint64_t mMediaNumber;
+  uint64_t mTotalMediaCount;
   uint32_t mPosition;
   /*
    * mPlaybackInterval specifies the time interval (in seconds) at which
    * the change in playback position will be notified. If the song is being
    * forwarded / rewound, a notification will be received whenever the playback
    * position will change by this value.
    */
   uint32_t mPlaybackInterval;
--- a/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
@@ -200,17 +200,17 @@ IsValidDtmf(const char aChar) {
 }
 
 class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD
-  Handle(const nsAString& aName, const JS::Value& aResult)
+  Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     if (!aResult.isNumber()) {
       BT_WARNING("'" AUDIO_VOLUME_BT_SCO_ID "' is not a number!");
@@ -847,17 +847,19 @@ BluetoothHfpManager::HandleVoiceConnecti
   mRoam = (roaming) ? 1 : 0;
 
   // Service
   nsString regState;
   voiceInfo->GetState(regState);
   mService = (regState.EqualsLiteral("registered")) ? 1 : 0;
 
   // Signal
-  JS::Value value;
+  JSContext* cx = nsContentUtils::GetSafeJSContext();
+  NS_ENSURE_TRUE_VOID(cx);
+  JS::Rooted<JS::Value> value(cx);
   voiceInfo->GetRelSignalStrength(&value);
   NS_ENSURE_TRUE_VOID(value.isNumber());
   mSignal = (int)ceil(value.toNumber() / 20.0);
 
   UpdateDeviceCIND();
 
   // Operator name
   nsCOMPtr<nsIDOMMozMobileNetworkInfo> network;
--- a/dom/bluetooth/bluedroid/BluetoothUtils.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothUtils.cpp
@@ -123,19 +123,19 @@ BroadcastSystemMessage(const nsAString& 
     BT_WARNING("Failed to set properties of system message!");
     return false;
   }
 
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE(systemMessenger, false);
 
-  systemMessenger->BroadcastMessage(aType,
-                                    OBJECT_TO_JSVAL(obj),
-                                    JS::UndefinedValue());
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
+  systemMessenger->BroadcastMessage(aType, value,
+                                    JS::UndefinedHandleValue);
 
   return true;
 }
 
 void
 DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
                        const BluetoothValue& aValue,
                        const nsAString& aErrorStr)
--- a/dom/bluetooth/bluez/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothA2dpManager.cpp
@@ -385,18 +385,18 @@ BluetoothA2dpManager::IsAvrcpConnected()
 {
   return mAvrcpConnected;
 }
 
 void
 BluetoothA2dpManager::UpdateMetaData(const nsAString& aTitle,
                                      const nsAString& aArtist,
                                      const nsAString& aAlbum,
-                                     uint32_t aMediaNumber,
-                                     uint32_t aTotalMediaCount,
+                                     uint64_t aMediaNumber,
+                                     uint64_t aTotalMediaCount,
                                      uint32_t aDuration)
 {
   mTitle.Assign(aTitle);
   mArtist.Assign(aArtist);
   mAlbum.Assign(aAlbum);
   mMediaNumber = aMediaNumber;
   mTotalMediaCount = aTotalMediaCount;
   mDuration = aDuration;
@@ -431,17 +431,17 @@ BluetoothA2dpManager::GetPlayStatus()
 }
 
 uint32_t
 BluetoothA2dpManager::GetPosition()
 {
   return mPosition;
 }
 
-uint32_t
+uint64_t
 BluetoothA2dpManager::GetMediaNumber()
 {
   return mMediaNumber;
 }
 
 void
 BluetoothA2dpManager::GetTitle(nsAString& aTitle)
 {
--- a/dom/bluetooth/bluez/BluetoothA2dpManager.h
+++ b/dom/bluetooth/bluez/BluetoothA2dpManager.h
@@ -41,27 +41,27 @@ public:
   void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
 
   // AVRCP-specific functions
   void SetAvrcpConnected(bool aConnected);
   bool IsAvrcpConnected();
   void UpdateMetaData(const nsAString& aTitle,
                       const nsAString& aArtist,
                       const nsAString& aAlbum,
-                      uint32_t aMediaNumber,
-                      uint32_t aTotalMediaCount,
+                      uint64_t aMediaNumber,
+                      uint64_t aTotalMediaCount,
                       uint32_t aDuration);
   void UpdatePlayStatus(uint32_t aDuration,
                         uint32_t aPosition,
                         ControlPlayStatus aPlayStatus);
   void GetAlbum(nsAString& aAlbum);
   uint32_t GetDuration();
   ControlPlayStatus GetPlayStatus();
   uint32_t GetPosition();
-  uint32_t GetMediaNumber();
+  uint64_t GetMediaNumber();
   void GetTitle(nsAString& aTitle);
 
 private:
   BluetoothA2dpManager();
   bool Init();
 
   void HandleShutdown();
   void NotifyConnectionStatusChanged();
@@ -74,17 +74,17 @@ private:
   SinkState mSinkState;
 
   // AVRCP data member
   bool mAvrcpConnected;
   nsString mAlbum;
   nsString mArtist;
   nsString mTitle;
   uint32_t mDuration;
-  uint32_t mMediaNumber;
-  uint32_t mTotalMediaCount;
+  uint64_t mMediaNumber;
+  uint64_t mTotalMediaCount;
   uint32_t mPosition;
   ControlPlayStatus mPlayStatus;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -157,17 +157,17 @@ static CINDItem sCINDItems[] = {
 };
 
 class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD
-  Handle(const nsAString& aName, const JS::Value& aResult)
+  Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     if (!aResult.isNumber()) {
       BT_WARNING("'" AUDIO_VOLUME_BT_SCO_ID "' is not a number!");
@@ -615,17 +615,19 @@ BluetoothHfpManager::HandleVoiceConnecti
   voiceInfo->GetState(regState);
   bool service = regState.EqualsLiteral("registered");
   if (service != sCINDItems[CINDType::SERVICE].value) {
     // Notify BluetoothRilListener of service change
     mListener->ServiceChanged(aClientId, service);
   }
   UpdateCIND(CINDType::SERVICE, service);
 
-  JS::Value value;
+  JSContext* cx = nsContentUtils::GetSafeJSContext();
+  NS_ENSURE_TRUE_VOID(cx);
+  JS::Rooted<JS::Value> value(cx);
   voiceInfo->GetRelSignalStrength(&value);
   NS_ENSURE_TRUE_VOID(value.isNumber());
   uint8_t signal = ceil(value.toNumber() / 20.0);
   UpdateCIND(CINDType::SIGNAL, signal);
 
   /**
    * Possible return values for mode are:
    * - null (unknown): set mNetworkSelectionMode to 0 (auto)
--- a/dom/bluetooth/bluez/BluetoothUtils.cpp
+++ b/dom/bluetooth/bluez/BluetoothUtils.cpp
@@ -121,19 +121,19 @@ BroadcastSystemMessage(const nsAString& 
     BT_WARNING("Failed to set properties of system message!");
     return false;
   }
 
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE(systemMessenger, false);
 
-  systemMessenger->BroadcastMessage(aType,
-                                    OBJECT_TO_JSVAL(obj),
-                                    JS::UndefinedValue());
+  JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
+  systemMessenger->BroadcastMessage(aType, value,
+                                    JS::UndefinedHandleValue);
 
   return true;
 }
 
 void
 DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
                        const BluetoothValue& aValue,
                        const nsAString& aErrorStr)
--- a/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp
@@ -2365,24 +2365,25 @@ BluetoothDBusService::SetProperty(Blueto
                                 DBUS_TYPE_INVALID)) {
     BT_WARNING("Couldn't append arguments to dbus message!");
     return NS_ERROR_FAILURE;
   }
 
   int type;
   int tmp_int;
   void* val;
+  const char* tempStr;
   nsCString str;
   if (aValue.value().type() == BluetoothValue::Tuint32_t) {
     tmp_int = aValue.value().get_uint32_t();
     val = &tmp_int;
     type = DBUS_TYPE_UINT32;
   } else if (aValue.value().type() == BluetoothValue::TnsString) {
     str = NS_ConvertUTF16toUTF8(aValue.value().get_nsString());
-    const char* tempStr = str.get();
+    tempStr = str.get();
     val = &tempStr;
     type = DBUS_TYPE_STRING;
   } else if (aValue.value().type() == BluetoothValue::Tbool) {
     tmp_int = aValue.value().get_bool() ? 1 : 0;
     val = &(tmp_int);
     type = DBUS_TYPE_BOOLEAN;
   } else {
     BT_WARNING("Property type not handled!");
--- a/dom/camera/DOMCameraCapabilities.cpp
+++ b/dom/camera/DOMCameraCapabilities.cpp
@@ -156,99 +156,111 @@ DOMCameraCapabilities::ParameterListToNe
       ++p;
     }
   }
 
   return JS_FreezeObject(aCx, aArray) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
-DOMCameraCapabilities::StringListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey)
+DOMCameraCapabilities::StringListToNewObject(JSContext* aCx,
+                                             JS::MutableHandle<JS::Value> aArray,
+                                             uint32_t aKey)
 {
   JS::Rooted<JSObject*> array(aCx);
 
   nsresult rv = ParameterListToNewArray(aCx, &array, aKey, ParseStringItemAndAdd);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aArray = OBJECT_TO_JSVAL(array);
+  aArray.setObjectOrNull(array);
   return NS_OK;
 }
 
 nsresult
-DOMCameraCapabilities::DimensionListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey)
+DOMCameraCapabilities::DimensionListToNewObject(JSContext* aCx,
+                                                JS::MutableHandle<JS::Value> aArray,
+                                                uint32_t aKey)
 {
   JS::Rooted<JSObject*> array(aCx);
-  nsresult rv;
 
-  rv = ParameterListToNewArray(aCx, &array, aKey, ParseDimensionItemAndAdd);
+  nsresult rv = ParameterListToNewArray(aCx, &array, aKey, ParseDimensionItemAndAdd);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aArray = OBJECT_TO_JSVAL(array);
+  aArray.setObjectOrNull(array);
   return NS_OK;
 }
 
 /* readonly attribute jsval previewSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetPreviewSizes(JSContext* cx, JS::Value* aPreviewSizes)
+DOMCameraCapabilities::GetPreviewSizes(JSContext* cx,
+                                       JS::MutableHandle<JS::Value> aPreviewSizes)
 {
   return DimensionListToNewObject(cx, aPreviewSizes, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES);
 }
 
 /* readonly attribute jsval pictureSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetPictureSizes(JSContext* cx, JS::Value* aPictureSizes)
+DOMCameraCapabilities::GetPictureSizes(JSContext* cx,
+                                       JS::MutableHandle<JS::Value> aPictureSizes)
 {
   return DimensionListToNewObject(cx, aPictureSizes, CAMERA_PARAM_SUPPORTED_PICTURESIZES);
 }
 
 /* readonly attribute jsval thumbnailSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetThumbnailSizes(JSContext* cx, JS::Value* aThumbnailSizes)
+DOMCameraCapabilities::GetThumbnailSizes(JSContext* cx,
+                                         JS::MutableHandle<JS::Value> aThumbnailSizes)
 {
   return DimensionListToNewObject(cx, aThumbnailSizes, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES);
 }
 
 /* readonly attribute jsval fileFormats; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetFileFormats(JSContext* cx, JS::Value* aFileFormats)
+DOMCameraCapabilities::GetFileFormats(JSContext* cx,
+                                      JS::MutableHandle<JS::Value> aFileFormats)
 {
   return StringListToNewObject(cx, aFileFormats, CAMERA_PARAM_SUPPORTED_PICTUREFORMATS);
 }
 
 /* readonly attribute jsval whiteBalanceModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetWhiteBalanceModes(JSContext* cx, JS::Value* aWhiteBalanceModes)
+DOMCameraCapabilities::GetWhiteBalanceModes(JSContext* cx,
+                                            JS::MutableHandle<JS::Value> aWhiteBalanceModes)
 {
   return StringListToNewObject(cx, aWhiteBalanceModes, CAMERA_PARAM_SUPPORTED_WHITEBALANCES);
 }
 
 /* readonly attribute jsval sceneModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetSceneModes(JSContext* cx, JS::Value* aSceneModes)
+DOMCameraCapabilities::GetSceneModes(JSContext* cx,
+                                     JS::MutableHandle<JS::Value> aSceneModes)
 {
   return StringListToNewObject(cx, aSceneModes, CAMERA_PARAM_SUPPORTED_SCENEMODES);
 }
 
 /* readonly attribute jsval effects; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetEffects(JSContext* cx, JS::Value* aEffects)
+DOMCameraCapabilities::GetEffects(JSContext* cx,
+                                  JS::MutableHandle<JS::Value> aEffects)
 {
   return StringListToNewObject(cx, aEffects, CAMERA_PARAM_SUPPORTED_EFFECTS);
 }
 
 /* readonly attribute jsval flashModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetFlashModes(JSContext* cx, JS::Value* aFlashModes)
+DOMCameraCapabilities::GetFlashModes(JSContext* cx,
+                                     JS::MutableHandle<JS::Value> aFlashModes)
 {
   return StringListToNewObject(cx, aFlashModes, CAMERA_PARAM_SUPPORTED_FLASHMODES);
 }
 
 /* readonly attribute jsval focusModes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetFocusModes(JSContext* cx, JS::Value* aFocusModes)
+DOMCameraCapabilities::GetFocusModes(JSContext* cx,
+                                     JS::MutableHandle<JS::Value> aFocusModes)
 {
   return StringListToNewObject(cx, aFocusModes, CAMERA_PARAM_SUPPORTED_FOCUSMODES);
 }
 
 /* readonly attribute long maxFocusAreas; */
 NS_IMETHODIMP
 DOMCameraCapabilities::GetMaxFocusAreas(JSContext* cx, int32_t* aMaxFocusAreas)
 {
@@ -330,48 +342,48 @@ DOMCameraCapabilities::GetMaxMeteringAre
   }
 
   *aMaxMeteringAreas = atoi(value);
   return NS_OK;
 }
 
 /* readonly attribute jsval zoomRatios; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetZoomRatios(JSContext* cx, JS::Value* aZoomRatios)
+DOMCameraCapabilities::GetZoomRatios(JSContext* cx, JS::MutableHandle<JS::Value> aZoomRatios)
 {
   NS_ENSURE_TRUE(mCamera, NS_ERROR_NOT_AVAILABLE);
 
   const char* value = mCamera->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_ZOOM);
   if (!value || strcmp(value, "true") != 0) {
     // if zoom is not supported, return a null object
-    *aZoomRatios = JSVAL_NULL;
+    aZoomRatios.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> array(cx);
 
   nsresult rv = ParameterListToNewArray(cx, &array, CAMERA_PARAM_SUPPORTED_ZOOMRATIOS, ParseZoomRatioItemAndAdd);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aZoomRatios = OBJECT_TO_JSVAL(array);
+  aZoomRatios.setObjectOrNull(array);
   return NS_OK;
 }
 
 /* readonly attribute jsval videoSizes; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetVideoSizes(JSContext* cx, JS::Value* aVideoSizes)
+DOMCameraCapabilities::GetVideoSizes(JSContext* cx, JS::MutableHandle<JS::Value> aVideoSizes)
 {
   NS_ENSURE_TRUE(mCamera, NS_ERROR_NOT_AVAILABLE);
 
   nsTArray<mozilla::idl::CameraSize> sizes;
   nsresult rv = mCamera->GetVideoSizes(sizes);
   NS_ENSURE_SUCCESS(rv, rv);
   if (sizes.Length() == 0) {
-    // video recording not supported, return a null object
-    *aVideoSizes = JSVAL_NULL;
+    // video recording not supported, return null
+    aVideoSizes.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, 0, nullptr));
   if (!array) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -387,31 +399,31 @@ DOMCameraCapabilities::GetVideoSizes(JSC
     }
 
     v = OBJECT_TO_JSVAL(o);
     if (!JS_SetElement(cx, array, i, &v)) {
       return NS_ERROR_FAILURE;
     }
   }
 
-  *aVideoSizes = OBJECT_TO_JSVAL(array);
+  aVideoSizes.setObject(*array);
   return NS_OK;
 }
 
 /* readonly attribute jsval recorderProfiles; */
 NS_IMETHODIMP
-DOMCameraCapabilities::GetRecorderProfiles(JSContext* cx, JS::Value* aRecorderProfiles)
+DOMCameraCapabilities::GetRecorderProfiles(JSContext* cx, JS::MutableHandle<JS::Value> aRecorderProfiles)
 {
   NS_ENSURE_TRUE(mCamera, NS_ERROR_NOT_AVAILABLE);
 
   nsRefPtr<RecorderProfileManager> profileMgr = mCamera->GetRecorderProfileManager();
   if (!profileMgr) {
-    *aRecorderProfiles = JSVAL_NULL;
+    aRecorderProfiles.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> o(cx);
   nsresult rv = profileMgr->GetJsObject(cx, o.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aRecorderProfiles = OBJECT_TO_JSVAL(o);
+  aRecorderProfiles.setObject(*o);
   return NS_OK;
 }
--- a/dom/camera/DOMCameraCapabilities.h
+++ b/dom/camera/DOMCameraCapabilities.h
@@ -27,18 +27,22 @@ public:
   }
 
   nsresult ParameterListToNewArray(
     JSContext* cx,
     JS::MutableHandle<JSObject*> aArray,
     uint32_t aKey,
     ParseItemAndAddFunc aParseItemAndAdd
   );
-  nsresult StringListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey);
-  nsresult DimensionListToNewObject(JSContext* aCx, JS::Value* aArray, uint32_t aKey);
+  nsresult StringListToNewObject(JSContext* aCx,
+                                 JS::MutableHandle<JS::Value> aArray,
+                                 uint32_t aKey);
+  nsresult DimensionListToNewObject(JSContext* aCx,
+                                    JS::MutableHandle<JS::Value> aArray,
+                                    uint32_t aKey);
 
 private:
   DOMCameraCapabilities(const DOMCameraCapabilities&) MOZ_DELETE;
   DOMCameraCapabilities& operator=(const DOMCameraCapabilities&) MOZ_DELETE;
 
 protected:
   /* additional members */
   ~DOMCameraCapabilities()
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -21,26 +21,29 @@ namespace mozilla {
  * TextComposition
  ******************************************************************************/
 
 TextComposition::TextComposition(nsPresContext* aPresContext,
                                  nsINode* aNode,
                                  WidgetGUIEvent* aEvent) :
   mPresContext(aPresContext), mNode(aNode),
   mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext),
+  mCompositionStartOffset(0), mCompositionTargetOffset(0),
   mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests)
 {
 }
 
 TextComposition::TextComposition(const TextComposition& aOther)
 {
   mNativeContext = aOther.mNativeContext;
   mPresContext = aOther.mPresContext;
   mNode = aOther.mNode;
   mLastData = aOther.mLastData;
+  mCompositionStartOffset = aOther.mCompositionStartOffset;
+  mCompositionTargetOffset = aOther.mCompositionTargetOffset;
   mIsSynthesizedForTests = aOther.mIsSynthesizedForTests;
 }
 
 bool
 TextComposition::MatchesNativeContext(nsIWidget* aWidget) const
 {
   return mNativeContext == aWidget->GetInputContext().mNativeIMEContext;
 }
@@ -51,16 +54,61 @@ TextComposition::DispatchEvent(WidgetGUI
                                nsDispatchingCallback* aCallBack)
 {
   if (aEvent->message == NS_COMPOSITION_UPDATE) {
     mLastData = aEvent->AsCompositionEvent()->data;
   }
 
   nsEventDispatcher::Dispatch(mNode, mPresContext,
                               aEvent, nullptr, aStatus, aCallBack);
+
+  // Notify composition update to widget if possible
+  NotityUpdateComposition(aEvent);
+}
+
+void
+TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
+{
+  nsEventStatus status;
+
+  // When compositon start, notify the rect of first offset character.
+  // When not compositon start, notify the rect of selected composition
+  // string if text event.
+  if (aEvent->message == NS_COMPOSITION_START) {
+    nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
+    // Update composition start offset
+    WidgetQueryContentEvent selectedTextEvent(true,
+                                              NS_QUERY_SELECTED_TEXT,
+                                              widget);
+    widget->DispatchEvent(&selectedTextEvent, status);
+    if (selectedTextEvent.mSucceeded) {
+      mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
+    } else {
+      // Unknown offset
+      NS_WARNING("Cannot get start offset of IME composition");
+      mCompositionStartOffset = 0;
+    }
+    mCompositionTargetOffset = mCompositionStartOffset;
+  } else if (aEvent->eventStructType != NS_TEXT_EVENT) {
+    return;
+  } else {
+    WidgetTextEvent* textEvent = aEvent->AsTextEvent();
+    mCompositionTargetOffset = mCompositionStartOffset;
+
+    for (uint32_t i = 0; i < textEvent->rangeCount; i++) {
+      TextRange& range = textEvent->rangeArray[i];
+      if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
+          range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
+        mCompositionTargetOffset += range.mStartOffset;
+        break;
+      }
+    }
+  }
+
+  NotifyIME(widget::NotificationToIME::NOTIFY_IME_OF_COMPOSITION_UPDATE);
 }
 
 void
 TextComposition::DispatchCompsotionEventRunnable(uint32_t aEventMessage,
                                                  const nsAString& aData)
 {
   nsContentUtils::AddScriptRunner(
     new CompositionEventDispatcher(mPresContext, mNode,
--- a/dom/events/TextComposition.h
+++ b/dom/events/TextComposition.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_TextComposition_h
 #define mozilla_TextComposition_h
 
 #include "nsCOMPtr.h"
 #include "nsINode.h"
 #include "nsIWidget.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
+#include "nsPresContext.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventForwards.h"
 
 class nsDispatchingCallback;
 class nsIMEStateManager;
 class nsIWidget;
 
 namespace mozilla {
@@ -61,47 +62,63 @@ public:
   void SynthesizeCommit(bool aDiscard);
 
   /**
    * Send a notification to IME.  It depends on the IME or platform spec what
    * will occur (or not occur).
    */
   nsresult NotifyIME(widget::NotificationToIME aNotification);
 
+  /**
+   * the offset of first selected clause or start of of compositon
+   */
+  uint32_t OffsetOfTargetClause() const { return mCompositionTargetOffset; }
+
 private:
   // This class holds nsPresContext weak.  This instance shouldn't block
   // destroying it.  When the presContext is being destroyed, it's notified to
   // nsIMEStateManager::OnDestroyPresContext(), and then, it destroy
   // this instance.
   nsPresContext* mPresContext;
   nsCOMPtr<nsINode> mNode;
 
   // mNativeContext stores a opaque pointer.  This works as the "ID" for this
   // composition.  Don't access the instance, it may not be available.
   void* mNativeContext;
 
   // mLastData stores the data attribute of the latest composition event (except
   // the compositionstart event).
   nsString mLastData;
 
+  // Offset of the composition string from start of the editor
+  uint32_t mCompositionStartOffset;
+  // Offset of the selected clause of the composition string from start of the
+  // editor
+  uint32_t mCompositionTargetOffset;
+
   // See the comment for IsSynthesizedForTests().
   bool mIsSynthesizedForTests;
 
   // Hide the default constructor
   TextComposition() {}
 
   /**
    * DispatchEvent() dispatches the aEvent to the mContent synchronously.
    * The caller must ensure that it's safe to dispatch the event.
    */
   void DispatchEvent(WidgetGUIEvent* aEvent,
                      nsEventStatus* aStatus,
                      nsDispatchingCallback* aCallBack);
 
   /**
+   * Calculate composition offset then notify composition update to widget
+   */
+  void NotityUpdateComposition(WidgetGUIEvent* aEvent);
+
+  /**
    * CompositionEventDispatcher dispatches the specified composition (or text)
    * event.
    */
   class CompositionEventDispatcher : public nsRunnable
   {
   public:
     CompositionEventDispatcher(nsPresContext* aPresContext,
                                nsINode* aEventTarget,
--- a/dom/events/nsDOMEventTargetHelper.h
+++ b/dom/events/nsDOMEventTargetHelper.h
@@ -167,34 +167,36 @@ private:
   bool                       mHasOrHasHadOwnerWindow;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMEventTargetHelper,
                               NS_DOMEVENTTARGETHELPER_IID)
 
 // XPIDL event handlers
 #define NS_IMPL_EVENT_HANDLER(_class, _event)                                 \
-    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
+    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx,                       \
+                                        JS::MutableHandle<JS::Value> aValue)  \
     {                                                                         \
-      GetEventHandler(nsGkAtoms::on##_event, aCx, aValue);                    \
+      GetEventHandler(nsGkAtoms::on##_event, aCx, aValue.address());          \
       return NS_OK;                                                           \
     }                                                                         \
     NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
-                                        const JS::Value& aValue)              \
+                                        JS::Handle<JS::Value> aValue)         \
     {                                                                         \
       return SetEventHandler(nsGkAtoms::on##_event, aCx, aValue);             \
     }
 
 #define NS_IMPL_FORWARD_EVENT_HANDLER(_class, _event, _baseclass)             \
-    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
+    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx,                       \
+                                        JS::MutableHandle<JS::Value> aValue)  \
     {                                                                         \
       return _baseclass::GetOn##_event(aCx, aValue);                          \
     }                                                                         \
     NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
-                                        const JS::Value& aValue)              \
+                                        JS::Handle<JS::Value> aValue)         \
     {                                                                         \
       return _baseclass::SetOn##_event(aCx, aValue);                          \
     }
 
 // WebIDL event handlers
 #define IMPL_EVENT_HANDLER(_event)                                        \
   inline mozilla::dom::EventHandlerNonNull* GetOn##_event()               \
   {                                                                       \
--- a/dom/events/nsDOMMessageEvent.cpp
+++ b/dom/events/nsDOMMessageEvent.cpp
@@ -58,20 +58,20 @@ nsDOMMessageEvent::~nsDOMMessageEvent()
 
 JSObject*
 nsDOMMessageEvent::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return mozilla::dom::MessageEventBinding::Wrap(aCx, aScope, this);
 }
 
 NS_IMETHODIMP
-nsDOMMessageEvent::GetData(JSContext* aCx, JS::Value* aData)
+nsDOMMessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData)
 {
   ErrorResult rv;
-  *aData = GetData(aCx, rv);
+  aData.set(GetData(aCx, rv));
   return rv.ErrorCode();
 }
 
 JS::Value
 nsDOMMessageEvent::GetData(JSContext* aCx, ErrorResult& aRv)
 {
   JS::Rooted<JS::Value> data(aCx, mData);
   if (!JS_WrapValue(aCx, &data)) {
@@ -166,17 +166,17 @@ nsDOMMessageEvent::Constructor(const moz
 
   return event.forget();
 }
 
 NS_IMETHODIMP
 nsDOMMessageEvent::InitMessageEvent(const nsAString& aType,
                                     bool aCanBubble,
                                     bool aCancelable,
-                                    const JS::Value& aData,
+                                    JS::Handle<JS::Value> aData,
                                     const nsAString& aOrigin,
                                     const nsAString& aLastEventId,
                                     nsIDOMWindow* aSource)
 {
   nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mData = aData;
--- a/dom/events/nsDOMNotifyAudioAvailableEvent.cpp
+++ b/dom/events/nsDOMNotifyAudioAvailableEvent.cpp
@@ -61,39 +61,39 @@ nsDOMNotifyAudioAvailableEvent::~nsDOMNo
   MOZ_COUNT_DTOR(nsDOMNotifyAudioAvailableEvent);
   if (mCachedArray) {
     mCachedArray = nullptr;
     mozilla::DropJSObjects(this);
   }
 }
 
 NS_IMETHODIMP
-nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, JS::Value* aResult)
+nsDOMNotifyAudioAvailableEvent::GetFrameBuffer(JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
 {
   if (!mAllowAudioData) {
     // Media is not same-origin, don't allow the data out.
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (mCachedArray) {
-    *aResult = OBJECT_TO_JSVAL(mCachedArray);
+    aResult.setObject(*mCachedArray);
     return NS_OK;
   }
 
   // Cache this array so we don't recreate on next call.
   mozilla::HoldJSObjects(this);
 
   mCachedArray = JS_NewFloat32Array(aCx, mFrameBufferLength);
   if (!mCachedArray) {
     mozilla::DropJSObjects(this);
     return NS_ERROR_FAILURE;
   }
   memcpy(JS_GetFloat32ArrayData(mCachedArray), mFrameBuffer.get(), mFrameBufferLength * sizeof(float));
 
-  *aResult = OBJECT_TO_JSVAL(mCachedArray);
+  aResult.setObject(*mCachedArray);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMNotifyAudioAvailableEvent::GetTime(float *aRetVal)
 {
   *aRetVal = Time();
   return NS_OK;
--- a/dom/events/nsDOMNotifyAudioAvailableEvent.h
+++ b/dom/events/nsDOMNotifyAudioAvailableEvent.h
@@ -46,17 +46,17 @@ public:
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE
   {
     return mozilla::dom::NotifyAudioAvailableEventBinding::Wrap(aCx, aScope, this);
   }
 
   JSObject* GetFrameBuffer(JSContext* aCx, mozilla::ErrorResult& aRv)
   {
     JS::Rooted<JS::Value> dummy(aCx);
-    aRv = GetFrameBuffer(aCx, dummy.address());
+    aRv = GetFrameBuffer(aCx, &dummy);
     return mCachedArray;
   }
 
   float Time()
   {
     return mTime;
   }
 
--- a/dom/events/nsEventListenerService.cpp
+++ b/dom/events/nsEventListenerService.cpp
@@ -60,20 +60,21 @@ nsEventListenerInfo::GetAllowsUntrusted(
 NS_IMETHODIMP
 nsEventListenerInfo::GetInSystemEventGroup(bool* aInSystemEventGroup)
 {
   *aInSystemEventGroup = mInSystemEventGroup;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsEventListenerInfo::GetListenerObject(JSContext* aCx, JS::Value* aObject)
+nsEventListenerInfo::GetListenerObject(JSContext* aCx,
+                                       JS::MutableHandle<JS::Value> aObject)
 {
   mozilla::Maybe<JSAutoCompartment> ac;
-  GetJSVal(aCx, ac, aObject);
+  GetJSVal(aCx, ac, aObject.address());
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS1(nsEventListenerService, nsIEventListenerService)
 
 // Caller must root *aJSVal!
 bool
 nsEventListenerInfo::GetJSVal(JSContext* aCx,
--- a/dom/events/nsEventStateManager.cpp
+++ b/dom/events/nsEventStateManager.cpp
@@ -1209,24 +1209,28 @@ nsEventStateManager::PreHandleEvent(nsPr
       if (RemoteQueryContentEvent(aEvent))
         break;
       nsContentEventHandler handler(mPresContext);
       handler.OnQueryTextContent(aEvent->AsQueryContentEvent());
     }
     break;
   case NS_QUERY_CARET_RECT:
     {
-      // XXX remote event
+      if (RemoteQueryContentEvent(aEvent)) {
+        break;
+      }
       nsContentEventHandler handler(mPresContext);
       handler.OnQueryCaretRect(aEvent->AsQueryContentEvent());
     }
     break;
   case NS_QUERY_TEXT_RECT:
     {
-      // XXX remote event
+      if (RemoteQueryContentEvent(aEvent)) {
+        break;
+      }
       nsContentEventHandler handler(mPresContext);
       handler.OnQueryTextRect(aEvent->AsQueryContentEvent());
     }
     break;
   case NS_QUERY_EDITOR_RECT:
     {
       // XXX remote event
       nsContentEventHandler handler(mPresContext);
--- a/dom/events/nsIMEStateManager.cpp
+++ b/dom/events/nsIMEStateManager.cpp
@@ -593,16 +593,17 @@ nsIMEStateManager::NotifyIME(Notificatio
     composition = sTextCompositions->GetCompositionFor(aWidget);
   }
   if (!composition || !composition->IsSynthesizedForTests()) {
     switch (aNotification) {
       case NOTIFY_IME_OF_CURSOR_POS_CHANGED:
         return aWidget->NotifyIME(aNotification);
       case REQUEST_TO_COMMIT_COMPOSITION:
       case REQUEST_TO_CANCEL_COMPOSITION:
+      case NOTIFY_IME_OF_COMPOSITION_UPDATE:
         return composition ? aWidget->NotifyIME(aNotification) : NS_OK;
       default:
         MOZ_CRASH("Unsupported notification");
     }
     MOZ_CRASH(
       "Failed to handle the notification for non-synthesized composition");
   }
 
@@ -1120,8 +1121,14 @@ nsIMEStateManager::GetFocusSelectionAndR
     return NS_ERROR_NOT_AVAILABLE;
 
   NS_ASSERTION(sTextStateObserver->mSel && sTextStateObserver->mRootContent,
                "uninitialized text state observer");
   NS_ADDREF(*aSel = sTextStateObserver->mSel);
   NS_ADDREF(*aRoot = sTextStateObserver->mRootContent);
   return NS_OK;
 }
+
+TextComposition*
+nsIMEStateManager::GetTextComposition(nsIWidget* aWidget)
+{
+  return sTextCompositions->GetCompositionFor(aWidget);
+}
--- a/dom/events/nsIMEStateManager.h
+++ b/dom/events/nsIMEStateManager.h
@@ -15,16 +15,17 @@ class nsIDOMMouseEvent;
 class nsINode;
 class nsPIDOMWindow;
 class nsPresContext;
 class nsTextStateManager;
 class nsISelection;
 
 namespace mozilla {
 class TextCompositionArray;
+class TextComposition;
 } // namespace mozilla
 
 /*
  * IME state manager
  */
 
 class nsIMEStateManager
 {
@@ -90,16 +91,21 @@ public:
    */
   static void DispatchCompositionEvent(nsINode* aEventTargetNode,
                                        nsPresContext* aPresContext,
                                        mozilla::WidgetEvent* aEvent,
                                        nsEventStatus* aStatus,
                                        nsDispatchingCallback* aCallBack);
 
   /**
+   * Get TextComposition from widget.
+   */
+  static mozilla::TextComposition* GetTextComposition(nsIWidget* aWidget);
+
+  /**
    * Send a notification to IME.  It depends on the IME or platform spec what
    * will occur (or not occur).
    */
   static nsresult NotifyIME(mozilla::widget::NotificationToIME aNotification,
                             nsIWidget* aWidget);
   static nsresult NotifyIME(mozilla::widget::NotificationToIME aNotification,
                             nsPresContext* aPresContext);
 
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -486,53 +486,52 @@ LockedFile::GetActive(bool* aActive)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   *aActive = IsOpen();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LockedFile::GetLocation(JSContext* aCx,
-                        JS::Value* aLocation)
+                        JS::MutableHandle<JS::Value> aLocation)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (mLocation == UINT64_MAX) {
-    *aLocation = JSVAL_NULL;
+    aLocation.setNull();
   }
   else {
-    *aLocation = JS_NumberValue(double(mLocation));
+    aLocation.setDouble(double(mLocation));
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LockedFile::SetLocation(JSContext* aCx,
-                        const JS::Value& aLocation)
+                        JS::Handle<JS::Value> aLocation)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // Null means the end-of-file.
-  if (JSVAL_IS_NULL(aLocation)) {
+  if (aLocation.isNull()) {
     mLocation = UINT64_MAX;
     return NS_OK;
   }
 
   uint64_t location;
-  JS::Rooted<JS::Value> value(aCx, aLocation);
-  if (!JS::ToUint64(aCx, value, &location)) {
+  if (!JS::ToUint64(aCx, aLocation, &location)) {
     return NS_ERROR_TYPE_ERR;
   }
 
   mLocation = location;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LockedFile::GetMetadata(const JS::Value& aParameters,
+LockedFile::GetMetadata(JS::Handle<JS::Value> aParameters,
                         JSContext* aCx,
                         nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!IsOpen()) {
     return NS_ERROR_DOM_FILEHANDLE_LOCKEDFILE_INACTIVE_ERR;
   }
@@ -541,17 +540,17 @@ LockedFile::GetMetadata(const JS::Value&
   if (!GetOwner()) {
     return NS_OK;
   }
 
   nsRefPtr<MetadataParameters> params = new MetadataParameters();
 
   // Get optional arguments.
   if (!JSVAL_IS_VOID(aParameters) && !JSVAL_IS_NULL(aParameters)) {
-    nsresult rv = params->Init(aCx, &aParameters);
+    nsresult rv = params->Init(aCx, aParameters);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
     if (!params->IsConfigured()) {
       return NS_ERROR_TYPE_ERR;
     }
   }
   else {
     params->Init(true, true);
@@ -653,27 +652,27 @@ LockedFile::ReadAsText(uint64_t aSize,
   mLocation += aSize;
 
   nsRefPtr<nsIDOMDOMRequest> request = fileRequest.forget();
   request.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LockedFile::Write(const JS::Value& aValue,
+LockedFile::Write(JS::Handle<JS::Value> aValue,
                   JSContext* aCx,
                   nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return WriteOrAppend(aValue, aCx, _retval, false);
 }
 
 NS_IMETHODIMP
-LockedFile::Append(const JS::Value& aValue,
+LockedFile::Append(JS::Handle<JS::Value> aValue,
                    JSContext* aCx,
                    nsISupports** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return WriteOrAppend(aValue, aCx, _retval, true);
 }
 
--- a/dom/file/MetadataHelper.h
+++ b/dom/file/MetadataHelper.h
@@ -26,19 +26,19 @@ class MetadataHelper;
 class MetadataParameters
 {
   friend class MetadataHelper;
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataParameters)
 
   nsresult
-  Init(JSContext* aCx, const JS::Value* aVal)
+  Init(JSContext* aCx, JS::Handle<JS::Value> aVal)
   {
-    return mConfig.Init(aCx, aVal);
+    return mConfig.Init(aCx, aVal.address());
   }
 
   void
   Init(bool aRequestSize, bool aRequestLastModified)
   {
     mConfig.size = aRequestSize;
     mConfig.lastModified = aRequestLastModified;
   }
--- a/dom/fmradio/FMRadioService.cpp
+++ b/dom/fmradio/FMRadioService.cpp
@@ -132,17 +132,17 @@ class ReadRilSettingTask MOZ_FINAL : pub
 {
 public:
   NS_DECL_ISUPPORTS
 
   ReadRilSettingTask(nsRefPtr<FMRadioReplyRunnable> aPendingRequest)
     : mPendingRequest(aPendingRequest) { }
 
   NS_IMETHOD
-  Handle(const nsAString& aName, const JS::Value& aResult)
+  Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     FMRadioService* fmRadioService = FMRadioService::Singleton();
     MOZ_ASSERT(mPendingRequest == fmRadioService->mPendingRequest);
 
     fmRadioService->mHasReadRilSetting = true;
 
     if (!aResult.isBoolean()) {
       // Failed to read the setting value, set the state back to Disabled.
--- a/dom/icc/src/Icc.cpp
+++ b/dom/icc/src/Icc.cpp
@@ -51,17 +51,17 @@ Icc::NotifyStkEvent(const nsAString& aNa
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   AutoPushJSContext cx(sc->GetNativeContext());
   JS::Rooted<JS::Value> value(cx);
 
   if (!aMessage.IsEmpty()) {
     nsCOMPtr<nsIJSON> json(new nsJSON());
-    nsresult rv = json->DecodeToJSVal(aMessage, cx, value.address());
+    nsresult rv = json->DecodeToJSVal(aMessage, cx, &value);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     value = JS::NullValue();
   }
 
   MozStkCommandEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
@@ -110,18 +110,18 @@ Icc::GetCardState(nsString& aCardState) 
 
   nsresult rv = mProvider->GetCardState(mClientId, aCardState);
   if (NS_FAILED(rv)) {
     aCardState.SetIsVoid(true);
   }
 }
 
 void
-Icc::SendStkResponse(const JSContext* aCx, const JS::Value& aCommand,
-                     const JS::Value& aResponse, ErrorResult& aRv)
+Icc::SendStkResponse(const JSContext* aCx, JS::Handle<JS::Value> aCommand,
+                     JS::Handle<JS::Value> aResponse, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsresult rv = mProvider->SendStkResponse(mClientId, GetOwner(), aCommand,
                                            aResponse);
@@ -144,33 +144,33 @@ Icc::SendStkMenuSelection(uint16_t aItem
                                                 aItemIdentifier,
                                                 aHelpRequested);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
 void
-Icc::SendStkTimerExpiration(const JSContext* aCx, const JS::Value& aTimer,
+Icc::SendStkTimerExpiration(const JSContext* aCx, JS::Handle<JS::Value> aTimer,
                             ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsresult rv = mProvider->SendStkTimerExpiration(mClientId, GetOwner(),
                                                   aTimer);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
 void
-Icc::SendStkEventDownload(const JSContext* aCx, const JS::Value& aEvent,
+Icc::SendStkEventDownload(const JSContext* aCx, JS::Handle<JS::Value> aEvent,
                           ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsresult rv = mProvider->SendStkEventDownload(mClientId, GetOwner(), aEvent);
@@ -194,17 +194,17 @@ Icc::GetCardLock(const nsAString& aLockT
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
-Icc::UnlockCardLock(const JSContext* aCx, const JS::Value& aInfo,
+Icc::UnlockCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
                     ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
@@ -214,17 +214,18 @@ Icc::UnlockCardLock(const JSContext* aCx
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
-Icc::SetCardLock(const JSContext* aCx, const JS::Value& aInfo, ErrorResult& aRv)
+Icc::SetCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
+                 ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
   nsresult rv = mProvider->SetCardLock(mClientId, GetOwner(), aInfo,
@@ -274,17 +275,17 @@ Icc::ReadContacts(const nsAString& aCont
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
 Icc::UpdateContact(const JSContext* aCx, const nsAString& aContactType,
-                   const JS::Value& aContact, const nsAString& aPin2,
+                   JS::Handle<JS::Value> aContact, const nsAString& aPin2,
                    ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
@@ -314,18 +315,18 @@ Icc::IccOpenChannel(const nsAString& aAi
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
 already_AddRefed<nsISupports>
-Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel, const jsval& aApdu,
-                     ErrorResult& aRv)
+Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
+                     JS::Handle<JS::Value> aApdu, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
   nsresult rv = mProvider->IccExchangeAPDU(mClientId, GetOwner(), aChannel,
--- a/dom/icc/src/Icc.h
+++ b/dom/icc/src/Icc.h
@@ -46,58 +46,59 @@ public:
   // MozIcc WebIDL
   already_AddRefed<nsIDOMMozIccInfo>
   GetIccInfo() const;
 
   void
   GetCardState(nsString& aCardState) const;
 
   void
-  SendStkResponse(const JSContext* aCx, const JS::Value& aCommand,
-                  const JS::Value& aResponse, ErrorResult& aRv);
+  SendStkResponse(const JSContext* aCx, JS::Handle<JS::Value> aCommand,
+                  JS::Handle<JS::Value> aResponse, ErrorResult& aRv);
 
   void
   SendStkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested,
                        ErrorResult& aRv);
 
   void
-  SendStkTimerExpiration(const JSContext* aCx, const JS::Value& aTimer,
+  SendStkTimerExpiration(const JSContext* aCx, JS::Handle<JS::Value> aTimer,
                          ErrorResult& aRv);
 
   void
-  SendStkEventDownload(const JSContext* aCx, const JS::Value& aEvent,
+  SendStkEventDownload(const JSContext* aCx, JS::Handle<JS::Value> aEvent,
                        ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   GetCardLock(const nsAString& aLockType, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
-  UnlockCardLock(const JSContext* aCx, const JS::Value& aInfo,
+  UnlockCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
                  ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
-  SetCardLock(const JSContext* aCx, const JS::Value& aInfo, ErrorResult& aRv);
+  SetCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
+              ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   GetCardLockRetryCount(const nsAString& aLockType, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   ReadContacts(const nsAString& aContactType, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   UpdateContact(const JSContext* aCx, const nsAString& aContactType,
-                const JS::Value& aContact, const nsAString& aPin2,
+                JS::Handle<JS::Value> aContact, const nsAString& aPin2,
                 ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   IccOpenChannel(const nsAString& aAid, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
-  IccExchangeAPDU(const JSContext* aCx, int32_t aChannel, const jsval& aApdu,
-                  ErrorResult& aRv);
+  IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
+                  JS::Handle<JS::Value> aApdu, ErrorResult& aRv);
 
   already_AddRefed<nsISupports>
   IccCloseChannel(int32_t aChannel, ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(iccinfochange)
   IMPL_EVENT_HANDLER(cardstatechange)
   IMPL_EVENT_HANDLER(stkcommand)
   IMPL_EVENT_HANDLER(stksessionend)
--- a/dom/icc/src/IccManager.cpp
+++ b/dom/icc/src/IccManager.cpp
@@ -125,17 +125,17 @@ IccManager::Unroot()
     mozilla::DropJSObjects(this);
     mRooted = false;
   }
 }
 
 // nsIDOMMozIccManager
 
 NS_IMETHODIMP
-IccManager::GetIccIds(JS::Value* aIccIds)
+IccManager::GetIccIds(JS::MutableHandle<JS::Value> aIccIds)
 {
   if (!mJsIccIds) {
     nsTArray<nsString> iccIds;
     for (uint32_t i = 0; i < mIccListeners.Length(); i++) {
       nsRefPtr<Icc> icc = mIccListeners[i]->GetIcc();
       if (icc) {
         iccIds.AppendElement(icc->GetIccId());
       }
@@ -149,17 +149,17 @@ IccManager::GetIccIds(JS::Value* aIccIds
     JS::Rooted<JSObject*> jsIccIds(cx);
     rv = nsTArrayToJSArray(cx, iccIds, jsIccIds.address());
     NS_ENSURE_SUCCESS(rv, rv);
 
     mJsIccIds = jsIccIds;
     Root();
   }
 
-  aIccIds->setObject(*mJsIccIds);
+  aIccIds.setObject(*mJsIccIds);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 IccManager::GetIccById(const nsAString& aIccId, nsISupports** aIcc)
 {
   *aIcc = nullptr;
 
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -641,17 +641,17 @@ IndexedDatabaseManager::BlockAndGetFileR
 }
 
 NS_IMPL_ADDREF(IndexedDatabaseManager)
 NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy())
 NS_IMPL_QUERY_INTERFACE2(IndexedDatabaseManager, nsIIndexedDatabaseManager,
                                                  nsIObserver)
 
 NS_IMETHODIMP
-IndexedDatabaseManager::InitWindowless(const jsval& aGlobal, JSContext* aCx)
+IndexedDatabaseManager::InitWindowless(JS::Handle<JS::Value> aGlobal, JSContext* aCx)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   JS::Rooted<JSObject*> global(aCx, JSVAL_TO_OBJECT(aGlobal));
   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
     NS_WARNING("Passed object is not a global object!");
     return NS_ERROR_FAILURE;
   }
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -1048,26 +1048,27 @@ public:
 
   virtual void*
   GetPBlob() MOZ_OVERRIDE
   {
     return static_cast<typename ActorType::ProtocolType*>(mActor);
   }
 
   NS_IMETHOD
-  GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate) MOZ_OVERRIDE
+  GetLastModifiedDate(JSContext* cx,
+                      JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE
   {
     if (IsDateUnknown()) {
-      aLastModifiedDate->setNull();
+      aLastModifiedDate.setNull();
     } else {
       JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
       if (!date) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      aLastModifiedDate->setObject(*date);
+      aLastModifiedDate.setObject(*date);
     }
     return NS_OK;
   }
 };
 
 template <>
 void
 RemoteBlob<Parent>::MaybeSetInputStream(const ConstructorParamsType& aParams)
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -127,16 +127,25 @@ parent:
      *  newEnd       New ending offset after insertion
      *
      *  for insertion, offset == end
      *  for deletion, offset == newEnd
      */
     NotifyIMETextChange(uint32_t offset, uint32_t end, uint32_t newEnd);
 
     /**
+     * Notifies chrome that there is a IME compostion rect updated
+     *
+     *  offset       The starting offset of this rect
+     *  rect         The rect of first character of selected IME composition
+     *  caretRect    The rect of IME caret
+     */
+    NotifyIMESelectedCompositionRect(uint32_t offset, nsIntRect rect, nsIntRect caretRect);
+
+    /**
      * Notifies chrome that there has been a change in selection
      * Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
      *
      *  seqno        Current seqno value on the content side
      *  anchor       Offset where the selection started
      *  focus        Offset where the caret is
      */
     NotifyIMESelection(uint32_t seqno, uint32_t anchor, uint32_t focus);
@@ -222,19 +231,22 @@ parent:
 
     PContentDialog(uint32_t aType, nsCString aName, nsCString aFeatures,
                    int32_t[] aIntParams, nsString[] aStringParams);
 
     /**
      * Create a layout frame (encapsulating a remote layer tree) for
      * the page that is currently loaded in the <browser>.
      */
-    sync PRenderFrame()
+    sync PRenderFrame();
+
+    sync InitRenderFrame(PRenderFrame aFrame)
         returns (ScrollingBehavior scrolling,
-                 TextureFactoryIdentifier textureFactoryIdentifier, uint64_t layersId);
+                 TextureFactoryIdentifier textureFactoryIdentifier, uint64_t layersId,
+                 bool success);
 
     /** 
      * Starts an offline application cache update.
      * @param manifestURI
      *   URI of the manifest to fetch, the application cache group ID
      * @param documentURI
      *   URI of the document that referred the manifest
      * @param stickDocument
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -802,17 +802,26 @@ ParticularProcessPriorityManager::OnFram
 }
 
 void
 ParticularProcessPriorityManager::ResetPriority()
 {
   ProcessPriority processPriority = ComputePriority();
   if (mPriority == PROCESS_PRIORITY_UNKNOWN ||
       mPriority > processPriority) {
-    ScheduleResetPriority("backgroundGracePeriodMS");
+    // Apps set at a perceivable background priority are often playing media.
+    // Most media will have short gaps while changing tracks between songs,
+    // switching videos, etc.  Give these apps a longer grace period so they
+    // can get their next track started, if there is one, before getting
+    // downgraded.
+    if (mPriority == PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE) {
+      ScheduleResetPriority("backgroundPerceivableGracePeriodMS");
+    } else {
+      ScheduleResetPriority("backgroundGracePeriodMS");
+    }
     return;
   }
 
   SetPriorityNow(processPriority);
 }
 
 void
 ParticularProcessPriorityManager::ResetPriorityNow()
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2190,19 +2190,17 @@ TabChild::RecvDestroy()
 bool
 TabChild::RecvSetUpdateHitRegion(const bool& aEnabled)
 {
     mUpdateHitRegion = aEnabled;
     return true;
 }
 
 PRenderFrameChild*
-TabChild::AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
-                            TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                            uint64_t* aLayersId)
+TabChild::AllocPRenderFrameChild()
 {
     return new RenderFrameChild();
 }
 
 bool
 TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
 {
     delete aFrame;
@@ -2249,22 +2247,28 @@ TabChild::InitTabChildGlobal(FrameScript
 }
 
 bool
 TabChild::InitRenderingState()
 {
     static_cast<PuppetWidget*>(mWidget.get())->InitIMEState();
 
     uint64_t id;
+    bool success;
     RenderFrameChild* remoteFrame =
-        static_cast<RenderFrameChild*>(SendPRenderFrameConstructor(
-                                         &mScrolling, &mTextureFactoryIdentifier, &id));
+        static_cast<RenderFrameChild*>(SendPRenderFrameConstructor());
     if (!remoteFrame) {
-      NS_WARNING("failed to construct RenderFrame");
-      return false;
+        NS_WARNING("failed to construct RenderFrame");
+        return false;
+    }
+    SendInitRenderFrame(remoteFrame, &mScrolling, &mTextureFactoryIdentifier, &id, &success);
+    if (!success) {
+        NS_WARNING("failed to construct RenderFrame");
+        PRenderFrameChild::Send__delete__(remoteFrame);
+        return false;
     }
 
     PLayerTransactionChild* shadowManager = nullptr;
     if (id != 0) {
         // Pushing layers transactions directly to a separate
         // compositor context.
         PCompositorChild* compositorChild = CompositorChild::Get();
         if (!compositorChild) {
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -57,35 +57,35 @@ class TabChildGlobal : public nsDOMEvent
 public:
   TabChildGlobal(TabChild* aTabChild);
   void Init();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
-                             const JS::Value& aObject,
-                             const JS::Value& aRemote,
+                             JS::Handle<JS::Value> aObject,
+                             JS::Handle<JS::Value> aRemote,
                              nsIPrincipal* aPrincipal,
                              JSContext* aCx,
                              uint8_t aArgc,
-                             JS::Value* aRetval)
+                             JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
                                          aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
-                            const JS::Value& aObject,
-                            const JS::Value& aRemote,
+                            JS::Handle<JS::Value> aObject,
+                            JS::Handle<JS::Value> aRemote,
                             nsIPrincipal* aPrincipal,
                             JSContext* aCx,
                             uint8_t aArgc,
-                            JS::Value* aRetval)
+                            JS::MutableHandle<JS::Value> aRetval)
   {
     return mMessageManager
       ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
                                         aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
   NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
@@ -362,19 +362,17 @@ public:
     GetFrom(nsIDOMWindow* aWindow)
     {
       nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
       nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
       return GetFrom(docShell);
     }
 
 protected:
-    virtual PRenderFrameChild* AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
-                                                      TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                                      uint64_t* aLayersId) MOZ_OVERRIDE;
+    virtual PRenderFrameChild* AllocPRenderFrameChild() MOZ_OVERRIDE;
     virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) MOZ_OVERRIDE;
     virtual bool RecvDestroy() MOZ_OVERRIDE;
     virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) MOZ_OVERRIDE;
 
     nsEventStatus DispatchWidgetEvent(WidgetGUIEvent& event);
 
     virtual PIndexedDBChild* AllocPIndexedDBChild(const nsCString& aGroup,
                                                   const nsCString& aASCIIOrigin,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -202,16 +202,17 @@ TabParent::TabParent(ContentParent* aMan
   : TabContext(aContext)
   , mFrameElement(nullptr)
   , mIMESelectionAnchor(0)
   , mIMESelectionFocus(0)
   , mIMEComposing(false)
   , mIMECompositionEnding(false)
   , mIMECompositionStart(0)
   , mIMESeqno(0)
+  , mIMECompositionRectOffset(0)
   , mEventCaptureDepth(0)
   , mRect(0, 0, 0, 0)
   , mDimensions(0, 0)
   , mOrientation(0)
   , mDPI(0)
   , mDefaultScale(0)
   , mShown(false)
   , mUpdatedDimensions(false)
@@ -798,16 +799,20 @@ bool TabParent::SendRealTouchEvent(Widge
         e.touches.RemoveElementAt(i);
       }
     }
   }
 
   ScrollableLayerGuid guid;
   MaybeForwardEventToRenderFrame(event, &guid, &e);
 
+  if (mIsDestroyed) {
+    return false;
+  }
+
   MapEventCoordinatesForChildProcess(mChildProcessOffsetAtTouchStart, &e);
 
   return (e.message == NS_TOUCH_MOVE) ?
     PBrowserParent::SendRealTouchMoveEvent(e, guid) :
     PBrowserParent::SendRealTouchEvent(e, guid);
 }
 
 /*static*/ TabParent*
@@ -988,16 +993,34 @@ TabParent::RecvNotifyIMETextChange(const
   if (!widget)
     return true;
 
   widget->NotifyIMEOfTextChange(aStart, aEnd, aNewEnd);
   return true;
 }
 
 bool
+TabParent::RecvNotifyIMESelectedCompositionRect(const uint32_t& aOffset,
+                                                const nsIntRect& aRect,
+                                                const nsIntRect& aCaretRect)
+{
+  // add rect to cache for another query
+  mIMECompositionRectOffset = aOffset;
+  mIMECompositionRect = aRect;
+  mIMECaretRect = aCaretRect;
+
+  nsCOMPtr<nsIWidget> widget = GetWidget();
+  if (!widget) {
+    return true;
+  }
+  widget->NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);
+  return true;
+}
+
+bool
 TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
                                   const uint32_t& aAnchor,
                                   const uint32_t& aFocus)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return true;
 
@@ -1034,29 +1057,63 @@ TabParent::RecvRequestFocus(const bool& 
   if (aCanRaise)
     flags |= nsIFocusManager::FLAG_RAISE;
 
   nsCOMPtr<nsIDOMElement> node = do_QueryInterface(mFrameElement);
   fm->SetFocus(node, flags);
   return true;
 }
 
+nsIntPoint
+TabParent::GetChildProcessOffset()
+{
+  // The "toplevel widget" in child processes is always at position
+  // 0,0.  Map the event coordinates to match that.
+
+  nsIntPoint offset(0, 0);
+  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
+  if (!frameLoader) {
+    return offset;
+  }
+  nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
+  if (!targetFrame) {
+    return offset;
+  }
+
+  // Find out how far we're offset from the nearest widget.
+  nsCOMPtr<nsIWidget> widget = GetWidget();
+  if (!widget) {
+    return offset;
+  }
+  nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget,
+                                                            nsIntPoint(0, 0),
+                                                            targetFrame);
+
+  return LayoutDeviceIntPoint::ToUntyped(LayoutDeviceIntPoint::FromAppUnitsToNearest(
+           pt, targetFrame->PresContext()->AppUnitsPerDevPixel()));
+}
+
 /**
  * Try to answer query event using cached text.
  *
  * For NS_QUERY_SELECTED_TEXT, fail if the cache doesn't contain the whole
  *  selected range. (This shouldn't happen because PuppetWidget should have
  *  already sent the whole selection.)
  *
  * For NS_QUERY_TEXT_CONTENT, fail only if the cache doesn't overlap with
  *  the queried range. Note the difference from above. We use
  *  this behavior because a normal NS_QUERY_TEXT_CONTENT event is allowed to
  *  have out-of-bounds offsets, so that widget can request content without
  *  knowing the exact length of text. It's up to widget to handle cases when
  *  the returned offset/length are different from the queried offset/length.
+ *
+ * For NS_QUERY_TEXT_RECT, fail if cached offset/length aren't equals to input.
+ *   Cocoa widget always queries selected offset, so it works on it.
+ *
+ * For NS_QUERY_CARET_RECT, fail if cached offset isn't equals to input
  */
 bool
 TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
 {
   aEvent.mSucceeded = false;
   aEvent.mWasAsync = false;
   aEvent.mReply.mFocusedWidget = nsCOMPtr<nsIWidget>(GetWidget()).get();
 
@@ -1097,16 +1154,39 @@ TabParent::HandleQueryContentEvent(Widge
       }
       aEvent.mReply.mOffset = inputOffset;
       aEvent.mReply.mString = Substring(mIMECacheText,
                                         inputOffset,
                                         inputEnd - inputOffset);
       aEvent.mSucceeded = true;
     }
     break;
+  case NS_QUERY_TEXT_RECT:
+    {
+      if (aEvent.mInput.mOffset != mIMECompositionRectOffset ||
+          aEvent.mInput.mLength != 1) {
+        break;
+      }
+
+      aEvent.mReply.mOffset = mIMECompositionRectOffset;
+      aEvent.mReply.mRect = mIMECompositionRect - GetChildProcessOffset();
+      aEvent.mSucceeded = true;
+    }
+    break;
+  case NS_QUERY_CARET_RECT:
+    {
+      if (aEvent.mInput.mOffset != mIMECompositionRectOffset) {
+        break;
+      }
+
+      aEvent.mReply.mOffset = mIMECompositionRectOffset;
+      aEvent.mReply.mRect = mIMECaretRect - GetChildProcessOffset();
+      aEvent.mSucceeded = true;
+    }
+    break;
   }
   return true;
 }
 
 bool
 TabParent::SendCompositionEvent(WidgetCompositionEvent& event)
 {
   if (mIsDestroyed) {
@@ -1520,33 +1600,46 @@ TabParent::HandleDelayedDialogs()
   }
   if (ShouldDelayDialogs() && mDelayedDialogs.Length()) {
     nsContentUtils::DispatchTrustedEvent(mFrameElement->OwnerDoc(), mFrameElement,
                                          NS_LITERAL_STRING("MozDelayedModalDialog"),
                                          true, true);
   }
 }
 
-PRenderFrameParent*
-TabParent::AllocPRenderFrameParent(ScrollingBehavior* aScrolling,
-                                   TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                   uint64_t* aLayersId)
+bool
+TabParent::RecvInitRenderFrame(PRenderFrameParent* aFrame,
+                               ScrollingBehavior* aScrolling,
+                               TextureFactoryIdentifier* aTextureFactoryIdentifier,
+                               uint64_t* aLayersId,
+                               bool *aSuccess)
 {
-  MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
+  *aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
+  *aTextureFactoryIdentifier = TextureFactoryIdentifier();
+  *aLayersId = 0;
 
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   if (!frameLoader) {
-    NS_WARNING("Can't allocate graphics resources, aborting subprocess");
-    return nullptr;
+    NS_WARNING("Can't allocate graphics resources. May already be shutting down.");
+    *aSuccess = false;
+    return true;
   }
 
-  *aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
-  return new RenderFrameParent(frameLoader,
-                               *aScrolling,
-                               aTextureFactoryIdentifier, aLayersId);
+  static_cast<RenderFrameParent*>(aFrame)->Init(frameLoader, *aScrolling,
+                                                aTextureFactoryIdentifier, aLayersId);
+
+  *aSuccess = true;
+  return true;
+}
+
+PRenderFrameParent*
+TabParent::AllocPRenderFrameParent()
+{
+  MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
+  return new RenderFrameParent();
 }
 
 bool
 TabParent::DeallocPRenderFrameParent(PRenderFrameParent* aFrame)
 {
   delete aFrame;
   return true;
 }
@@ -1687,20 +1780,17 @@ TabParent::RecvBrowserFrameOpenWindow(PB
   BrowserElementParent::OpenWindowResult opened =
     BrowserElementParent::OpenWindowOOP(static_cast<TabParent*>(aOpener),
                                         this, aURL, aName, aFeatures);
   *aOutWindowOpened = (opened != BrowserElementParent::OPEN_WINDOW_CANCELLED);
   return true;
 }
 
 bool
-TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor,
-                                       ScrollingBehavior* scrolling,
-                                       TextureFactoryIdentifier* factoryIdentifier,
-                                       uint64_t* layersId)
+TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor)
 {
   return true;
 }
 
 bool
 TabParent::RecvZoomToRect(const uint32_t& aPresShellId,
                           const ViewID& aViewId,
                           const CSSRect& aRect)
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -107,20 +107,22 @@ public:
      * capturer.
      */
     bool TryCapture(const WidgetGUIEvent& aEvent);
 
     void Destroy();
 
     virtual bool RecvMoveFocus(const bool& aForward);
     virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
-    virtual bool RecvPRenderFrameConstructor(PRenderFrameParent* actor,
-                                             ScrollingBehavior* scrolling,
-                                             TextureFactoryIdentifier* identifier,
-                                             uint64_t* layersId);
+    virtual bool RecvPRenderFrameConstructor(PRenderFrameParent* actor);
+    virtual bool RecvInitRenderFrame(PRenderFrameParent* aFrame,
+                                     ScrollingBehavior* scrolling,
+                                     TextureFactoryIdentifier* identifier,
+                                     uint64_t* layersId,
+                                     bool *aSuccess);
     virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                             const nsString& aURL,
                                             const nsString& aName,
                                             const nsString& aFeatures,
                                             bool* aOutWindowOpened);
     virtual bool AnswerCreateWindow(PBrowserParent** retval);
     virtual bool RecvSyncMessage(const nsString& aMessage,
                                  const ClonedMessageData& aData,
@@ -137,16 +139,19 @@ public:
                                   const InfallibleTArray<CpowEntry>& aCpows,
                                   const IPC::Principal& aPrincipal);
     virtual bool RecvNotifyIMEFocus(const bool& aFocus,
                                     nsIMEUpdatePreference* aPreference,
                                     uint32_t* aSeqno);
     virtual bool RecvNotifyIMETextChange(const uint32_t& aStart,
                                          const uint32_t& aEnd,
                                          const uint32_t& aNewEnd);
+    virtual bool RecvNotifyIMESelectedCompositionRect(const uint32_t& aOffset,
+                                                      const nsIntRect& aRect,
+                                                      const nsIntRect& aCaretRect) MOZ_OVERRIDE;
     virtual bool RecvNotifyIMESelection(const uint32_t& aSeqno,
                                         const uint32_t& aAnchor,
                                         const uint32_t& aFocus);
     virtual bool RecvNotifyIMETextHint(const nsString& aText);
     virtual bool RecvEndIMEComposition(const bool& aCancel,
                                        nsString* aComposition);
     virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
                                      int32_t* aIMEOpen,
@@ -306,35 +311,38 @@ protected:
       nsCString mName;
       nsCString mFeatures;
       nsCOMPtr<nsIDialogParamBlock> mParams;
     };
     InfallibleTArray<DelayedDialogData*> mDelayedDialogs;
 
     bool ShouldDelayDialogs();
     bool AllowContentIME();
+    nsIntPoint GetChildProcessOffset();
 
-    virtual PRenderFrameParent* AllocPRenderFrameParent(ScrollingBehavior* aScrolling,
-                                                        TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                                        uint64_t* aLayersId) MOZ_OVERRIDE;
+    virtual PRenderFrameParent* AllocPRenderFrameParent() MOZ_OVERRIDE;
     virtual bool DeallocPRenderFrameParent(PRenderFrameParent* aFrame) MOZ_OVERRIDE;
 
     // IME
     static TabParent *mIMETabParent;
     nsString mIMECacheText;
     uint32_t mIMESelectionAnchor;
     uint32_t mIMESelectionFocus;
     bool mIMEComposing;
     bool mIMECompositionEnding;
     // Buffer to store composition text during ResetInputState
     // Compositions in almost all cases are small enough for nsAutoString
     nsAutoString mIMECompositionText;
     uint32_t mIMECompositionStart;
     uint32_t mIMESeqno;
 
+    uint32_t mIMECompositionRectOffset;
+    nsIntRect mIMECompositionRect;
+    nsIntRect mIMECaretRect;
+
     // The number of event series we're currently capturing.
     int32_t mEventCaptureDepth;
 
     nsRect mRect;
     nsIntSize mDimensions;
     ScreenOrientation mOrientation;
     float mDPI;
     CSSToLayoutDeviceScale mDefaultScale;
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -166,24 +166,27 @@ WebrtcGlobalInformation.prototype = {
     // only callback once. (Bug 958221)
     if (_globalPCList) {
       _globalPCList.getStatsForEachPC(successCallback, failureCallback);
     } else {
       failureCallback("No global PeerConnection list");
     }
   },
 
-  getCandPairLogs: function(candPairId, callback, errorCallback) {
-    let pattern = 'CAND-PAIR(' + candPairId + ')';
+  getLogs: function(pattern, callback, errorCallback) {
     if (_globalPCList) {
       _globalPCList.getLoggingFromFirstPC(pattern, callback, errorCallback);
     } else {
       errorCallback("No global PeerConnection list");
     }
   },
+
+  getCandPairLogs: function(candPairId, callback, errorCallback) {
+    this.getLogs('CAND-PAIR(' + candPairId + ')', callback, errorCallback);
+  },
 };
 
 function RTCIceCandidate() {
   this.candidate = this.sdpMid = this.sdpMLineIndex = null;
 }
 RTCIceCandidate.prototype = {
   classDescription: "mozRTCIceCandidate",
   classID: PC_ICE_CID,
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -466,24 +466,24 @@ MmsMessage::GetDelivery(nsAString& aDeli
     default:
       MOZ_CRASH("We shouldn't get any other delivery state!");
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MmsMessage::GetDeliveryInfo(JSContext* aCx, JS::Value* aDeliveryInfo)
+MmsMessage::GetDeliveryInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aDeliveryInfo)
 {
   // TODO Bug 850525 It'd be better to depend on the delivery of MmsMessage
   // to return a more correct value. Ex, if .delivery = 'received', we should
   // also make .deliveryInfo = null, since the .deliveryInfo is useless.
   uint32_t length = mDeliveryInfo.Length();
   if (length == 0) {
-    *aDeliveryInfo = JSVAL_NULL;
+    aDeliveryInfo.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> deliveryInfo(
     aCx, JS_NewArrayObject(aCx, length, nullptr));
   NS_ENSURE_TRUE(deliveryInfo, NS_ERROR_OUT_OF_MEMORY);
 
   for (uint32_t i = 0; i < length; ++i) {
@@ -547,35 +547,35 @@ MmsMessage::GetDeliveryInfo(JSContext* a
     }
 
     tmpJsVal = OBJECT_TO_JSVAL(infoJsObj);
     if (!JS_SetElement(aCx, deliveryInfo, i, &tmpJsVal)) {
       return NS_ERROR_FAILURE;
     }
   }
 
-  aDeliveryInfo->setObject(*deliveryInfo);
+  aDeliveryInfo.setObject(*deliveryInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetSender(nsAString& aSender)
 {
   aSender = mSender;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MmsMessage::GetReceivers(JSContext* aCx, JS::Value* aReceivers)
+MmsMessage::GetReceivers(JSContext* aCx, JS::MutableHandle<JS::Value> aReceivers)
 {
   JS::Rooted<JSObject*> reveiversObj(aCx);
   nsresult rv = nsTArrayToJSArray(aCx, mReceivers, reveiversObj.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aReceivers->setObject(*reveiversObj);
+  aReceivers.setObject(*reveiversObj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetTimestamp(DOMTimeStamp* aTimestamp)
 {
   *aTimestamp = mTimestamp;
   return NS_OK;
@@ -605,17 +605,17 @@ MmsMessage::GetSubject(nsAString& aSubje
 NS_IMETHODIMP
 MmsMessage::GetSmil(nsAString& aSmil)
 {
   aSmil = mSmil;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MmsMessage::GetAttachments(JSContext* aCx, JS::Value* aAttachments)
+MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachments)
 {
   uint32_t length = mAttachments.Length();
 
   JS::Rooted<JSObject*> attachments(
     aCx, JS_NewArrayObject(aCx, length, nullptr));
   NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY);
 
   for (uint32_t i = 0; i < length; ++i) {
@@ -667,17 +667,17 @@ MmsMessage::GetAttachments(JSContext* aC
     }
 
     tmpJsVal = OBJECT_TO_JSVAL(attachmentObj);
     if (!JS_SetElement(aCx, attachments, i, &tmpJsVal)) {
       return NS_ERROR_FAILURE;
     }
   }
 
-  aAttachments->setObject(*attachments);
+  aAttachments.setObject(*attachments);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MmsMessage::GetExpiryDate(DOMTimeStamp* aExpiryDate)
 {
   *aExpiryDate = mExpiryDate;
   return NS_OK;
--- a/dom/mobilemessage/src/MobileMessageManager.cpp
+++ b/dom/mobilemessage/src/MobileMessageManager.cpp
@@ -158,24 +158,23 @@ MobileMessageManager::Send(JSContext* aC
     return rv;
   }
 
   *aRequest = rval;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MobileMessageManager::Send(const JS::Value& aNumber_,
+MobileMessageManager::Send(JS::Handle<JS::Value> aNumber,
                            const nsAString& aMessage,
-                           const JS::Value& aSendParams,
+                           JS::Handle<JS::Value> aSendParams,
                            JSContext* aCx,
                            uint8_t aArgc,
-                           JS::Value* aReturn)
+                           JS::MutableHandle<JS::Value> aReturn)
 {
-  JS::Rooted<JS::Value> aNumber(aCx, aNumber_);
   if (!aNumber.isString() &&
       !(aNumber.isObject() && JS_IsArrayObject(aCx, &aNumber.toObject()))) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -205,17 +204,17 @@ MobileMessageManager::Send(const JS::Val
     }
     if (sendParams.mServiceId.WasPassed()) {
       serviceId = sendParams.mServiceId.Value();
     }
   }
 
   if (aNumber.isString()) {
     JS::Rooted<JSString*> str(aCx, aNumber.toString());
-    return Send(aCx, global, serviceId, str, aMessage, aReturn);
+    return Send(aCx, global, serviceId, str, aMessage, aReturn.address());
   }
 
   // Must be an array then.
   JS::Rooted<JSObject*> numbers(aCx, &aNumber.toObject());
 
   uint32_t size;
   if (!JS_GetArrayLength(aCx, numbers, &size)) {
     return NS_ERROR_FAILURE;
@@ -243,23 +242,23 @@ MobileMessageManager::Send(const JS::Val
   }
 
   JS::Rooted<JSObject*> obj(aCx);
   obj = JS_NewArrayObject(aCx, requests.length(), requests.begin());
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
-  aReturn->setObject(*obj);
+  aReturn.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MobileMessageManager::SendMMS(const JS::Value& aParams,
-                              const JS::Value& aSendParams,
+MobileMessageManager::SendMMS(JS::Handle<JS::Value> aParams,
+                              JS::Handle<JS::Value> aSendParams,
                               JSContext* aCx,
                               uint8_t aArgc,
                               nsIDOMDOMRequest** aRequest)
 {
   nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(mmsService, NS_ERROR_FAILURE);
 
   // Use the default one unless |aSendParams.serviceId| is available.
@@ -318,17 +317,17 @@ MobileMessageManager::GetMessageId(JSCon
   if (mmsMessage) {
     return mmsMessage->GetId(aId);
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
-MobileMessageManager::Delete(const JS::Value& aParam, JSContext* aCx,
+MobileMessageManager::Delete(JS::Handle<JS::Value> aParam, JSContext* aCx,
                              nsIDOMDOMRequest** aRequest)
 {
   // We expect Int32, SmsMessage, MmsMessage, Int32[], SmsMessage[], MmsMessage[]
   if (!aParam.isObject() && !aParam.isInt32()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsresult rv = NS_OK;
--- a/dom/mobilemessage/src/MobileMessageService.cpp
+++ b/dom/mobilemessage/src/MobileMessageService.cpp
@@ -33,19 +33,19 @@ MobileMessageService::CreateSmsMessage(i
                                        uint64_t aThreadId,
                                        const nsAString& aIccId,
                                        const nsAString& aDelivery,
                                        const nsAString& aDeliveryStatus,
                                        const nsAString& aSender,
                                        const nsAString& aReceiver,
                                        const nsAString& aBody,
                                        const nsAString& aMessageClass,
-                                       const JS::Value& aTimestamp,
-                                       const JS::Value& aSentTimestamp,
-                                       const JS::Value& aDeliveryTimestamp,
+                                       JS::Handle<JS::Value> aTimestamp,
+                                       JS::Handle<JS::Value> aSentTimestamp,
+                                       JS::Handle<JS::Value> aDeliveryTimestamp,
                                        const bool aRead,
                                        JSContext* aCx,
                                        nsIDOMMozSmsMessage** aMessage)
 {
   return SmsMessage::Create(aId,
                             aThreadId,
                             aIccId,
                             aDelivery,
@@ -62,26 +62,26 @@ MobileMessageService::CreateSmsMessage(i
                             aMessage);
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateMmsMessage(int32_t               aId,
                                        uint64_t              aThreadId,
                                        const nsAString&      aIccId,
                                        const nsAString&      aDelivery,
-                                       const JS::Value&      aDeliveryInfo,
+                                       JS::Handle<JS::Value> aDeliveryInfo,
                                        const nsAString&      aSender,
-                                       const JS::Value&      aReceivers,
-                                       const JS::Value&      aTimestamp,
-                                       const JS::Value&      aSentTimestamp,
+                                       JS::Handle<JS::Value> aReceivers,
+                                       JS::Handle<JS::Value> aTimestamp,
+                                       JS::Handle<JS::Value> aSentTimestamp,
                                        bool                  aRead,
                                        const nsAString&      aSubject,
                                        const nsAString&      aSmil,
-                                       const JS::Value&      aAttachments,
-                                       const JS::Value&      aExpiryDate,
+                                       JS::Handle<JS::Value> aAttachments,
+                                       JS::Handle<JS::Value> aExpiryDate,
                                        bool                  aReadReportRequested,
                                        JSContext*            aCx,
                                        nsIDOMMozMmsMessage** aMessage)
 {
   return MmsMessage::Create(aId,
                             aThreadId,
                             aIccId,
                             aDelivery,
@@ -109,18 +109,18 @@ MobileMessageService::CreateSmsSegmentIn
   nsCOMPtr<nsIDOMMozSmsSegmentInfo> info =
       new SmsSegmentInfo(aSegments, aCharsPerSegment, aCharsAvailableInLastSegment);
   info.forget(aSegmentInfo);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateThread(uint64_t aId,
-                                   const JS::Value& aParticipants,
-                                   const JS::Value& aTimestamp,
+                                   JS::Handle<JS::Value> aParticipants,
+                                   JS::Handle<JS::Value> aTimestamp,
                                    const nsAString& aLastMessageSubject,
                                    const nsAString& aBody,
                                    uint64_t aUnreadCount,
                                    const nsAString& aLastMessageType,
                                    JSContext* aCx,
                                    nsIDOMMozMobileMessageThread** aThread)
 {
   return MobileMessageThread::Create(aId,
--- a/dom/mobilemessage/src/MobileMessageThread.cpp
+++ b/dom/mobilemessage/src/MobileMessageThread.cpp
@@ -157,24 +157,24 @@ NS_IMETHODIMP
 MobileMessageThread::GetUnreadCount(uint64_t* aUnreadCount)
 {
   *aUnreadCount = mData.unreadCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageThread::GetParticipants(JSContext* aCx,
-                                     JS::Value* aParticipants)
+                                     JS::MutableHandle<JS::Value> aParticipants)
 {
   JS::Rooted<JSObject*> obj(aCx);
 
   nsresult rv = nsTArrayToJSArray(aCx, mData.participants(), obj.address());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aParticipants->setObject(*obj);
+  aParticipants.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileMessageThread::GetTimestamp(DOMTimeStamp* aDate)
 {
   *aDate = mData.timestamp();
   return NS_OK;
--- a/dom/mobilemessage/src/SmsFilter.cpp
+++ b/dom/mobilemessage/src/SmsFilter.cpp
@@ -46,33 +46,33 @@ SmsFilter::SmsFilter(const SmsFilterData
 /* static */ nsresult
 SmsFilter::NewSmsFilter(nsISupports** aSmsFilter)
 {
   NS_ADDREF(*aSmsFilter = new SmsFilter());
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetStartDate(JSContext* aCx, JS::Value* aStartDate)
+SmsFilter::GetStartDate(JSContext* aCx, JS::MutableHandle<JS::Value> aStartDate)
 {
   if (mData.startDate() == 0) {
-    *aStartDate = JSVAL_NULL;
+    aStartDate.setNull();
     return NS_OK;
   }
 
-  aStartDate->setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.startDate()));
-  NS_ENSURE_TRUE(aStartDate->isObject(), NS_ERROR_FAILURE);
+  aStartDate.setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.startDate()));
+  NS_ENSURE_TRUE(aStartDate.isObject(), NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetStartDate(JSContext* aCx, const JS::Value& aStartDate)
+SmsFilter::SetStartDate(JSContext* aCx, JS::Handle<JS::Value> aStartDate)
 {
-  if (aStartDate == JSVAL_NULL) {
+  if (aStartDate.isNull()) {
     mData.startDate() = 0;
     return NS_OK;
   }
 
   if (!aStartDate.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -81,33 +81,33 @@ SmsFilter::SetStartDate(JSContext* aCx, 
     return NS_ERROR_INVALID_ARG;
   }
 
   mData.startDate() = js_DateGetMsecSinceEpoch(obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetEndDate(JSContext* aCx, JS::Value* aEndDate)
+SmsFilter::GetEndDate(JSContext* aCx, JS::MutableHandle<JS::Value> aEndDate)
 {
   if (mData.endDate() == 0) {
-    *aEndDate = JSVAL_NULL;
+    aEndDate.setNull();
     return NS_OK;
   }
 
-  aEndDate->setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.endDate()));
-  NS_ENSURE_TRUE(aEndDate->isObject(), NS_ERROR_FAILURE);
+  aEndDate.setObjectOrNull(JS_NewDateObjectMsec(aCx, mData.endDate()));
+  NS_ENSURE_TRUE(aEndDate.isObject(), NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetEndDate(JSContext* aCx, const JS::Value& aEndDate)
+SmsFilter::SetEndDate(JSContext* aCx, JS::Handle<JS::Value> aEndDate)
 {
-  if (aEndDate == JSVAL_NULL) {
+  if (aEndDate.isNull()) {
     mData.endDate() = 0;
     return NS_OK;
   }
 
   if (!aEndDate.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -116,22 +116,22 @@ SmsFilter::SetEndDate(JSContext* aCx, co
     return NS_ERROR_INVALID_ARG;
   }
 
   mData.endDate() = js_DateGetMsecSinceEpoch(obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetNumbers(JSContext* aCx, JS::Value* aNumbers)
+SmsFilter::GetNumbers(JSContext* aCx, JS::MutableHandle<JS::Value> aNumbers)
 {
   uint32_t length = mData.numbers().Length();
 
   if (length == 0) {
-    *aNumbers = JSVAL_NULL;
+    aNumbers.setNull();
     return NS_OK;
   }
 
   JS::AutoValueVector numbers(aCx);
   if (!numbers.resize(length)) {
     return NS_ERROR_FAILURE;
   }
 
@@ -145,24 +145,24 @@ SmsFilter::GetNumbers(JSContext* aCx, JS
     numbers[i].setString(str);
   }
 
   JSObject* obj = JS_NewArrayObject(aCx, numbers.length(), numbers.begin());
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
-  aNumbers->setObject(*obj);
+  aNumbers.setObject(*obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetNumbers(JSContext* aCx, const JS::Value& aNumbers)
+SmsFilter::SetNumbers(JSContext* aCx, JS::Handle<JS::Value> aNumbers)
 {
-  if (aNumbers == JSVAL_NULL) {
+  if (aNumbers.isNull()) {
     mData.numbers().Clear();
     return NS_OK;
   }
 
   if (!aNumbers.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -236,61 +236,59 @@ SmsFilter::SetDelivery(const nsAString& 
     mData.delivery() = eDeliveryState_Sent;
     return NS_OK;
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetRead(JSContext* aCx, JS::Value* aRead)
+SmsFilter::GetRead(JSContext* aCx, JS::MutableHandle<JS::Value> aRead)
 {
   if (mData.read() == eReadState_Unknown) {
-    *aRead = JSVAL_NULL;
+    aRead.setNull();
     return NS_OK;
   }
 
-  aRead->setBoolean(mData.read());
-
+  aRead.setBoolean(mData.read());
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetRead(JSContext* aCx, const JS::Value& aRead)
+SmsFilter::SetRead(JSContext* aCx, JS::Handle<JS::Value> aRead)
 {
-  if (aRead == JSVAL_NULL) {
+  if (aRead.isNull()) {
     mData.read() = eReadState_Unknown;
     return NS_OK;
   }
 
   if (!aRead.isBoolean()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mData.read() = aRead.toBoolean() ? eReadState_Read : eReadState_Unread;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::GetThreadId(JSContext* aCx, JS::Value* aThreadId)
+SmsFilter::GetThreadId(JSContext* aCx, JS::MutableHandle<JS::Value> aThreadId)
 {
   if (!mData.threadId()) {
-    *aThreadId = JSVAL_NULL;
+    aThreadId.setNull();
     return NS_OK;
   }
 
-  aThreadId->setNumber(static_cast<double>(mData.threadId()));
-
+  aThreadId.setNumber(static_cast<double>(mData.threadId()));
   return NS_OK;
 }
 
 NS_IMETHODIMP
-SmsFilter::SetThreadId(JSContext* aCx, const JS::Value& aThreadId)
+SmsFilter::SetThreadId(JSContext* aCx, JS::Handle<JS::Value> aThreadId)
 {
-  if (aThreadId == JSVAL_NULL) {
+  if (aThreadId.isNull()) {
     mData.threadId() = 0;
     return NS_OK;
   }
 
   if (!aThreadId.isNumber()) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp
+++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp
@@ -310,17 +310,17 @@ NS_IMETHODIMP
 SmsIPCService::GetMmsDefaultServiceId(uint32_t* aServiceId)
 {
   *aServiceId = mMmsDefaultServiceId;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SmsIPCService::Send(uint32_t aServiceId,
-                    const JS::Value& aParameters,
+                    JS::Handle<JS::Value> aParameters,
                     nsIMobileMessageCallback *aRequest)
 {
   SendMmsMessageRequest req;
   if (!GetSendMmsMessageRequestFromParams(aServiceId, aParameters, req)) {
     return NS_ERROR_INVALID_ARG;
   }
   return SendRequest(SendMessageRequest(req), aRequest);
 }
--- a/dom/network/interfaces/moz.build
+++ b/dom/network/interfaces/moz.build
@@ -1,16 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 XPIDL_SOURCES += [
-    'nsIDOMConnection.idl',
     'nsIDOMTCPServerSocket.idl',
     'nsIDOMTCPSocket.idl',
     'nsIMozNavigatorNetwork.idl',
     'nsITCPServerSocketChild.idl',
     'nsITCPServerSocketParent.idl',
     'nsITCPSocketChild.idl',
     'nsITCPSocketParent.idl',
     'nsIUDPSocketChild.idl',
deleted file mode 100644
--- a/dom/network/interfaces/nsIDOMConnection.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-/* 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 "nsISupports.idl"
-
-interface nsIDOMEventListener;
-
-[scriptable, uuid(a0eb16f3-5fa2-4cbd-bf7a-4ce7704b13ea)]
-interface nsIDOMMozConnection : nsISupports
-{
-  readonly attribute double  bandwidth;
-  readonly attribute boolean metered;
-
-  [implicit_jscontext] attribute jsval onchange;
-};
--- a/dom/network/interfaces/nsIMozNavigatorNetwork.idl
+++ b/dom/network/interfaces/nsIMozNavigatorNetwork.idl
@@ -1,13 +1,12 @@
 /* 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 "nsISupports.idl"
 
-interface nsIDOMMozConnection;
-
 [uuid(7f021f5d-f704-4a29-b166-829595169aaf)]
 interface nsIMozNavigatorNetwork : nsISupports
 {
-  readonly attribute nsIDOMMozConnection mozConnection;
+  // This is a MozConnection
+  readonly attribute nsISupports mozConnection;
 };
--- a/dom/network/src/Connection.cpp
+++ b/dom/network/src/Connection.cpp
@@ -1,55 +1,50 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 <limits>
 #include "mozilla/Hal.h"
-#include "Connection.h"
+#include "mozilla/dom/network/Connection.h"
+#include "mozilla/dom/MozConnectionBinding.h"
 #include "nsIDOMClassInfo.h"
 #include "mozilla/Preferences.h"
 #include "nsDOMEvent.h"
 #include "Constants.h"
 
 /**
  * We have to use macros here because our leak analysis tool things we are
  * leaking strings when we have |static const nsString|. Sad :(
  */
 #define CHANGE_EVENT_NAME NS_LITERAL_STRING("change")
 
-DOMCI_DATA(MozConnection, mozilla::dom::network::Connection)
-
 namespace mozilla {
 namespace dom {
 namespace network {
 
 const char* Connection::sMeteredPrefName     = "dom.network.metered";
 const bool  Connection::sMeteredDefaultValue = false;
 
-NS_INTERFACE_MAP_BEGIN(Connection)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMMozConnection)
-  NS_INTERFACE_MAP_ENTRY(nsINetworkProperties)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozConnection)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+NS_IMPL_QUERY_INTERFACE_INHERITED1(Connection, nsDOMEventTargetHelper,
+                                   nsINetworkProperties)
 
 // Don't use |Connection| alone, since that confuses nsTraceRefcnt since
 // we're not the only class with that name.
 NS_IMPL_ADDREF_INHERITED(dom::network::Connection, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(dom::network::Connection, nsDOMEventTargetHelper)
 
-NS_IMPL_EVENT_HANDLER(Connection, change)
-
 Connection::Connection()
   : mCanBeMetered(kDefaultCanBeMetered)
   , mBandwidth(kDefaultBandwidth)
   , mIsWifi(kDefaultIsWifi)
   , mDHCPGateway(kDefaultDHCPGateway)
 {
+  SetIsDOMBinding();
 }
 
 void
 Connection::Init(nsPIDOMWindow* aWindow)
 {
   BindToOwner(aWindow);
 
   hal::RegisterNetworkObserver(this);
@@ -61,39 +56,34 @@ Connection::Init(nsPIDOMWindow* aWindow)
 }
 
 void
 Connection::Shutdown()
 {
   hal::UnregisterNetworkObserver(this);
 }
 
-NS_IMETHODIMP
-Connection::GetBandwidth(double* aBandwidth)
+double
+Connection::Bandwidth() const
 {
   if (mBandwidth == kDefaultBandwidth) {
-    *aBandwidth = std::numeric_limits<double>::infinity();
-    return NS_OK;
+    return std::numeric_limits<double>::infinity();
   }
 
-  *aBandwidth = mBandwidth;
-  return NS_OK;
+  return mBandwidth;
 }
 
-NS_IMETHODIMP
-Connection::GetMetered(bool* aMetered)
+bool
+Connection::Metered() const
 {
   if (!mCanBeMetered) {
-    *aMetered = false;
-    return NS_OK;
+    return false;
   }
 
-  *aMetered = Preferences::GetBool(sMeteredPrefName,
-                                   sMeteredDefaultValue);
-  return NS_OK;
+  return Preferences::GetBool(sMeteredPrefName, sMeteredDefaultValue);
 }
 
 NS_IMETHODIMP
 Connection::GetIsWifi(bool *aIsWifi)
 {
   *aIsWifi = mIsWifi;
   return NS_OK;
 }
@@ -125,12 +115,17 @@ Connection::Notify(const hal::NetworkInf
   if (previousBandwidth == mBandwidth &&
       previousCanBeMetered == mCanBeMetered) {
     return;
   }
 
   DispatchTrustedEvent(CHANGE_EVENT_NAME);
 }
 
+JSObject*
+Connection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+{
+  return MozConnectionBinding::Wrap(aCx, aScope, this);
+}
+
 } // namespace network
 } // namespace dom
 } // namespace mozilla
-
--- a/dom/network/src/Connection.h
+++ b/dom/network/src/Connection.h
@@ -1,52 +1,60 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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_network_Connection_h
 #define mozilla_dom_network_Connection_h
 
-#include "nsIDOMConnection.h"
 #include "nsINetworkProperties.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Observer.h"
 #include "Types.h"
 
 namespace mozilla {
 
 namespace hal {
 class NetworkInformation;
 } // namespace hal
 
 namespace dom {
 namespace network {
 
-class Connection : public nsDOMEventTargetHelper
-                 , public nsIDOMMozConnection
-                 , public NetworkObserver
-                 , public nsINetworkProperties
+class Connection MOZ_FINAL : public nsDOMEventTargetHelper
+                           , public NetworkObserver
+                           , public nsINetworkProperties
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMMOZCONNECTION
   NS_DECL_NSINETWORKPROPERTIES
 
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
 
   Connection();
 
   void Init(nsPIDOMWindow *aWindow);
   void Shutdown();
 
   // For IObserver
   void Notify(const hal::NetworkInformation& aNetworkInfo);
 
+  // WebIDL
+
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  double Bandwidth() const;
+
+  bool Metered() const;
+
+  IMPL_EVENT_HANDLER(change)
+
 private:
   /**
    * Update the connection information stored in the object using a
    * NetworkInformation object.
    */
   void UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo);
 
   /**
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -437,51 +437,51 @@ MobileConnection::SetCallForwardingOptio
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest);
 }
 
 NS_IMETHODIMP
-MobileConnection::GetCallBarringOption(const JS::Value& aOption,
+MobileConnection::GetCallBarringOption(JS::Handle<JS::Value> aOption,
                                        nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
 }
 
 NS_IMETHODIMP
-MobileConnection::SetCallBarringOption(const JS::Value& aOption,
+MobileConnection::SetCallBarringOption(JS::Handle<JS::Value> aOption,
                                        nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
 }
 
 NS_IMETHODIMP
-MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo,
+MobileConnection::ChangeCallBarringPassword(JS::Handle<JS::Value> aInfo,
                                             nsIDOMDOMRequest** aRequest)
 {
   *aRequest = nullptr;
 
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
--- a/dom/network/src/MobileConnectionArray.cpp
+++ b/dom/network/src/MobileConnectionArray.cpp
@@ -28,41 +28,53 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileCo
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileConnectionArray)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MobileConnectionArray)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 MobileConnectionArray::MobileConnectionArray(nsPIDOMWindow* aWindow)
-: mWindow(aWindow)
+: mWindow(aWindow), mInitialized(false)
 {
-  int32_t numRil = mozilla::Preferences::GetInt("ril.numRadioInterfaces", 1);
+  uint32_t numRil = mozilla::Preferences::GetUint("ril.numRadioInterfaces", 1);
   MOZ_ASSERT(numRil > 0);
 
-  for (int32_t id = 0; id < numRil; id++) {
-    nsRefPtr<MobileConnection> mobileConnection = new MobileConnection(id);
-    mobileConnection->Init(aWindow);
-    mMobileConnections.AppendElement(mobileConnection);
-  }
+  bool ret = mMobileConnections.SetLength(numRil);
+  MOZ_ASSERT(ret);
 
   SetIsDOMBinding();
 }
 
 MobileConnectionArray::~MobileConnectionArray()
 {
   DropConnections();
 }
 
 void
+MobileConnectionArray::Init()
+{
+  mInitialized = true;
+
+  for (uint32_t id = 0; id < mMobileConnections.Length(); id++) {
+    nsRefPtr<MobileConnection> mobileConnection = new MobileConnection(id);
+    mobileConnection->Init(mWindow);
+    mMobileConnections[id] = mobileConnection;
+  }
+}
+
+void
 MobileConnectionArray::DropConnections()
 {
-  for (uint32_t i = 0; i < mMobileConnections.Length(); i++) {
-    mMobileConnections[i]->Shutdown();
+  if (mInitialized) {
+    for (uint32_t i = 0; i < mMobileConnections.Length(); i++) {
+      mMobileConnections[i]->Shutdown();
+    }
   }
+
   mMobileConnections.Clear();
 }
 
 nsPIDOMWindow*
 MobileConnectionArray::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
@@ -70,28 +82,32 @@ MobileConnectionArray::GetParentObject()
 
 JSObject*
 MobileConnectionArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return MozMobileConnectionArrayBinding::Wrap(aCx, aScope, this);
 }
 
 nsIDOMMozMobileConnection*
-MobileConnectionArray::Item(uint32_t aIndex) const
+MobileConnectionArray::Item(uint32_t aIndex)
 {
   bool unused;
   return IndexedGetter(aIndex, unused);
 }
 
 uint32_t
 MobileConnectionArray::Length() const
 {
   return mMobileConnections.Length();
 }
 
 nsIDOMMozMobileConnection*
-MobileConnectionArray::IndexedGetter(uint32_t aIndex, bool& aFound) const
+MobileConnectionArray::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
+  if (!mInitialized) {
+    Init();
+  }
+
   aFound = false;
   aFound = aIndex < mMobileConnections.Length();
 
   return aFound ? mMobileConnections[aIndex] : nullptr;
 }
--- a/dom/network/src/MobileConnectionArray.h
+++ b/dom/network/src/MobileConnectionArray.h
@@ -29,28 +29,34 @@ public:
   GetParentObject() const;
 
   // WrapperCache
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   //  WebIDL
   nsIDOMMozMobileConnection*
-  Item(uint32_t aIndex) const;
+  Item(uint32_t aIndex);
 
   uint32_t
   Length() const;
 
   nsIDOMMozMobileConnection*
-  IndexedGetter(uint32_t aIndex, bool& aFound) const;
+  IndexedGetter(uint32_t aIndex, bool& aFound);
 
 private:
   ~MobileConnectionArray();
 
-  void DropConnections();
+  void
+  Init();
+
+  void
+  DropConnections();
+
+  bool mInitialized;
 
   nsCOMPtr<nsPIDOMWindow> mWindow;
   nsTArray<nsRefPtr<MobileConnection>> mMobileConnections;
 };
 
 } // namespace network
 } // namespace dom
 } // namespace mozilla
--- a/dom/network/src/TCPSocketChild.cpp
+++ b/dom/network/src/TCPSocketChild.cpp
@@ -75,17 +75,17 @@ TCPSocketChild::TCPSocketChild()
 : mWindowObj(nullptr)
 {
 }
 
 NS_IMETHODIMP
 TCPSocketChild::SendOpen(nsITCPSocketInternal* aSocket,
                          const nsAString& aHost, uint16_t aPort,
                          bool aUseSSL, const nsAString& aBinaryType,
-                         nsIDOMWindow* aWindow, const JS::Value& aWindowObj,
+                         nsIDOMWindow* aWindow, JS::Handle<JS::Value> aWindowObj,
                          JSContext* aCx)
 {
   mSocket = aSocket;
 
   MOZ_ASSERT(aWindowObj.isObject());
   mWindowObj = js::CheckedUnwrap(&aWindowObj.toObject());
   if (!mWindowObj) {
     return NS_ERROR_FAILURE;
@@ -193,17 +193,17 @@ TCPSocketChild::SendResume()
 NS_IMETHODIMP
 TCPSocketChild::SendClose()
 {
   PTCPSocketChild::SendClose();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-TCPSocketChild::SendSend(const JS::Value& aData,
+TCPSocketChild::SendSend(JS::Handle<JS::Value> aData,
                          uint32_t aByteOffset,
                          uint32_t aByteLength,
                          uint32_t aTrackingNumber,
                          JSContext* aCx)
 {
   if (aData.isString()) {
     JSString* jsstr = aData.toString();
     nsDependentJSString str;
@@ -229,17 +229,17 @@ TCPSocketChild::SendSend(const JS::Value
     arr.SwapElements(fallibleArr);
     SendData(arr, aTrackingNumber);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TCPSocketChild::SetSocketAndWindow(nsITCPSocketInternal *aSocket,
-                                   const JS::Value& aWindowObj,
+                                   JS::Handle<JS::Value> aWindowObj,
                                    JSContext* aCx)
 {
   mSocket = aSocket;
   MOZ_ASSERT(aWindowObj.isObject());
   mWindowObj = js::CheckedUnwrap(&aWindowObj.toObject());
   if (!mWindowObj) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -116,17 +116,17 @@ TCPSocketParent::RecvOpen(const nsString
     FireInteralError(this, __LINE__);
     return true;
   }
 
   return true;
 }
 
 NS_IMETHODIMP
-TCPSocketParent::InitJS(const JS::Value& aIntermediary, JSContext* aCx)
+TCPSocketParent::InitJS(JS::Handle<JS::Value> aIntermediary, JSContext* aCx)
 {
   MOZ_ASSERT(aIntermediary.isObject());
   mIntermediaryObj = &aIntermediary.toObject();
   return NS_OK;
 }
 
 bool
 TCPSocketParent::RecvStartTLS()
@@ -190,17 +190,17 @@ TCPSocketParent::RecvClose()
 {
   NS_ENSURE_TRUE(mSocket, true);
   nsresult rv = mSocket->Close();
   NS_ENSURE_SUCCESS(rv, true);
   return true;
 }
 
 NS_IMETHODIMP
-TCPSocketParent::SendEvent(const nsAString& aType, const JS::Value& aDataVal,
+TCPSocketParent::SendEvent(const nsAString& aType, JS::Handle<JS::Value> aDataVal,
                            const nsAString& aReadyState, JSContext* aCx)
 {
   if (!mIPCOpen) {
     NS_WARNING("Dropping callback due to no IPC connection");
     return NS_OK;
   }
 
   CallbackData data;
--- a/dom/network/src/moz.build
+++ b/dom/network/src/moz.build
@@ -1,15 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla.dom.network += [
+    'Connection.h',
     'Constants.h',
     'TCPServerSocketChild.h',
     'TCPServerSocketParent.h',
     'TCPSocketChild.h',
     'TCPSocketParent.h',
     'Types.h',
     'UDPSocketChild.h',
     'UDPSocketParent.h',
--- a/dom/network/tests/marionette/manifest.ini
+++ b/dom/network/tests/marionette/manifest.ini
@@ -15,8 +15,9 @@ disabled = Bug 808783
 [test_mobile_data_state.js]
 [test_mobile_mmi.js]
 [test_mobile_roaming_preference.js]
 [test_call_barring_get_option.js]
 [test_call_barring_set_error.js]
 [test_call_barring_change_password.js]
 [test_mobile_set_radio.js]
 [test_mobile_last_known_network.js]
+[test_mobile_connections_array_uninitialized.js]
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/marionette/test_mobile_connections_array_uninitialized.js
@@ -0,0 +1,32 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 1000;
+
+SpecialPowers.addPermission("mobileconnection", true, document);
+
+// Permission changes can't change existing Navigator.prototype
+// objects, so grab our objects from a new Navigator
+let ifr = document.createElement("iframe");
+let connections;
+
+ifr.onload = function() {
+  connections = ifr.contentWindow.navigator.mozMobileConnections;
+
+  // mozMobileConnections hasn't been initialized yet.
+  ok(connections);
+  is(connections.length, 1);
+
+  ifr.parentNode.removeChild(ifr);
+  ifr = null;
+  connections = null;
+
+  SpecialPowers.gc();
+  cleanUp();
+};
+document.body.appendChild(ifr);
+
+function cleanUp() {
+  SpecialPowers.removePermission("mobileconnection", document);
+  finish();
+}
--- a/dom/network/tests/test_network_basics.html
+++ b/dom/network/tests/test_network_basics.html
@@ -14,33 +14,40 @@
 
 /** Test for Network API **/
 
 function checkInterface(aInterface) {
   ok(!(aInterface in window), aInterface + " should be prefixed");
   ok(("Moz" + aInterface) in window, aInterface + " should be prefixed");
 }
 
-ok('mozConnection' in navigator, "navigator.mozConnection should exist");
+function test() {
+  ok('mozConnection' in navigator, "navigator.mozConnection should exist");
 
-ok(navigator.mozConnection, "navigator.mozConnection returns an object");
+  ok(navigator.mozConnection, "navigator.mozConnection returns an object");
 
-ok(navigator.mozConnection instanceof MozConnection,
-   "navigator.mozConnection is a MozConnection object");
-ok(navigator.mozConnection instanceof EventTarget,
-   "navigator.mozConnection is a EventTarget object");
+  ok(navigator.mozConnection instanceof MozConnection,
+     "navigator.mozConnection is a MozConnection object");
+  ok(navigator.mozConnection instanceof EventTarget,
+     "navigator.mozConnection is a EventTarget object");
+
+  checkInterface("Connection");
 
-checkInterface("Connection");
+  ok('bandwidth' in navigator.mozConnection,
+     "bandwidth should be a Connection attribute");
+  is(navigator.mozConnection.bandwidth, Infinity,
+     "By default connection.bandwidth is equals to Infinity");
 
-ok('bandwidth' in navigator.mozConnection,
-   "bandwidth should be a Connection attribute");
-is(navigator.mozConnection.bandwidth, Infinity,
-   "By default connection.bandwidth is equals to Infinity");
+  ok('metered' in navigator.mozConnection,
+     "metered should be a Connection attribute");
+  is(navigator.mozConnection.metered, false,
+     "By default the connection is not metered");
 
-ok('metered' in navigator.mozConnection,
-   "metered should be a Connection attribute");
-is(navigator.mozConnection.metered, false,
-   "By default the connection is not metered");
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({'set': [["dom.network.enabled", true]]}, test);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -125,17 +125,17 @@ public:
   GeolocationSettingsCallback() {
     MOZ_COUNT_CTOR(GeolocationSettingsCallback);
   }
 
   virtual ~GeolocationSettingsCallback() {
     MOZ_COUNT_DTOR(GeolocationSettingsCallback);
   }
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     // The geolocation is enabled by default:
     bool value = true;
     if (aResult.isBoolean()) {
       value = aResult.toBoolean();
     }
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -54,17 +54,17 @@ WarnDeprecatedMethod(DeprecationWarning 
                                          NS_LITERAL_CSTRING("DOM Core"), nullptr,
                                          nsContentUtils::eDOM_PROPERTIES,
                                          warning == EncodeWarning
                                          ? "nsIJSONEncodeDeprecatedWarning"
                                          : "nsIJSONDecodeDeprecatedWarning");
 }
 
 NS_IMETHODIMP
-nsJSON::Encode(const JS::Value& aValue, JSContext* cx, uint8_t aArgc,
+nsJSON::Encode(JS::Handle<JS::Value> aValue, JSContext* cx, uint8_t aArgc,
                nsAString &aJSON)
 {
   // This function should only be called from JS.
   nsresult rv = WarnDeprecatedMethod(EncodeWarning);
   if (NS_FAILED(rv))
     return rv;
 
   if (aArgc == 0) {
@@ -107,17 +107,17 @@ static nsresult CheckCharset(const char*
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJSON::EncodeToStream(nsIOutputStream *aStream,
                        const char* aCharset,
                        const bool aWriteBOM,
-                       const JS::Value& val,
+                       JS::Handle<JS::Value> val,
                        JSContext* cx,
                        uint8_t aArgc)
 {
   // This function should only be called from JS.
   NS_ENSURE_ARG(aStream);
   nsresult rv;
 
   rv = CheckCharset(aCharset);
@@ -354,17 +354,18 @@ nsJSONWriter::WriteToStream(nsIOutputStr
 
   NS_Free(destBuf);
   mDidWrite = true;
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsJSON::Decode(const nsAString& json, JSContext* cx, JS::Value* aRetval)
+nsJSON::Decode(const nsAString& json, JSContext* cx,
+               JS::MutableHandle<JS::Value> aRetval)
 {
   nsresult rv = WarnDeprecatedMethod(DecodeWarning);
   if (NS_FAILED(rv))
     return rv;
 
   const char16_t *data;
   uint32_t len = NS_StringGetData(json, &data);
   nsCOMPtr<nsIInputStream> stream;
@@ -373,57 +374,55 @@ nsJSON::Decode(const nsAString& json, JS
                              len * sizeof(char16_t),
                              NS_ASSIGNMENT_DEPEND);
   NS_ENSURE_SUCCESS(rv, rv);
   return DecodeInternal(cx, stream, len, false, aRetval);
 }
 
 NS_IMETHODIMP
 nsJSON::DecodeFromStream(nsIInputStream *aStream, int32_t aContentLength,
-                         JSContext* cx, JS::Value* aRetval)
+                         JSContext* cx, JS::MutableHandle<JS::Value> aRetval)
 {
   return DecodeInternal(cx, aStream, aContentLength, true, aRetval);
 }
 
 NS_IMETHODIMP
-nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx, JS::Value *result)
+nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx,
+                      JS::MutableHandle<JS::Value> result)
 {
-  JS::Rooted<JS::Value> value(cx);
   if (!JS_ParseJSON(cx, static_cast<const jschar*>(PromiseFlatString(str).get()),
-                    str.Length(), &value)) {
+                    str.Length(), result)) {
     return NS_ERROR_UNEXPECTED;
   }
-
-  *result = value;
   return NS_OK;
 }
 
 nsresult
 nsJSON::DecodeInternal(JSContext* cx,
                        nsIInputStream *aStream,
                        int32_t aContentLength,
                        bool aNeedsConverter,
-                       JS::Value* aRetval)
+                       JS::MutableHandle<JS::Value> aRetval)
 {
   // Consume the stream
   nsCOMPtr<nsIChannel> jsonChannel;
   if (!mURI) {
     NS_NewURI(getter_AddRefs(mURI), NS_LITERAL_CSTRING("about:blank"), 0, 0 );
     if (!mURI)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsresult rv =
     NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), mURI, aStream,
                              NS_LITERAL_CSTRING("application/json"));
   if (!jsonChannel || NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   nsRefPtr<nsJSONListener> jsonListener =
-    new nsJSONListener(cx, aRetval, aNeedsConverter);
+    new nsJSONListener(cx, aRetval.address(), aNeedsConverter);
 
   //XXX this stream pattern should be consolidated in netwerk
   rv = jsonListener->OnStartRequest(jsonChannel, nullptr);
   if (NS_FAILED(rv)) {
     jsonChannel->Cancel(rv);
     return rv;
   }
 
--- a/dom/src/json/nsJSON.h
+++ b/dom/src/json/nsJSON.h
@@ -54,17 +54,17 @@ protected:
   nsresult EncodeInternal(JSContext* cx,
                           const JS::Value& val,
                           nsJSONWriter* writer);
 
   nsresult DecodeInternal(JSContext* cx,
                           nsIInputStream* aStream,
                           int32_t aContentLength,
                           bool aNeedsConverter,
-                          JS::Value* aRetVal);
+                          JS::MutableHandle<JS::Value> aRetVal);
   nsCOMPtr<nsIURI> mURI;
 };
 
 nsresult
 NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult);
 
 class nsJSONListener : public nsIStreamListener
 {
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -288,17 +288,17 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         JSAutoCompartment ac(cx, sandboxObj);
 
         // Push our JSContext on the context stack so the EvalInSandboxObject call (and
         // JS_ReportPendingException, if relevant) will use the principal of cx.
         nsCxPusher pusher;
         pusher.Push(cx);
         rv = xpc->EvalInSandboxObject(NS_ConvertUTF8toUTF16(script),
                                       /* filename = */ nullptr, cx,
-                                      sandboxObj, true, v.address());
+                                      sandboxObj, true, &v);
 
         // Propagate and report exceptions that happened in the
         // sandbox.
         if (JS_IsExceptionPending(cx)) {
             JS_ReportPendingException(cx);
         }
     } else {
         // No need to use the sandbox, evaluate the script directly in
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -116,17 +116,17 @@ public:
 
 class AudioChannelVolInitCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   AudioChannelVolInitCallback() {}
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     nsCOMPtr<nsIAudioManager> audioManager =
       do_GetService(NS_AUDIOMANAGER_CONTRACTID);
     NS_ENSURE_TRUE(JSVAL_IS_INT(aResult), NS_OK);
 
     int32_t volIndex = JSVAL_TO_INT(aResult);
     if (aName.EqualsLiteral("audio.volume.content")) {
       audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_CONTENT, volIndex);
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -36,17 +36,17 @@ namespace system {
 
 class SettingsServiceCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   SettingsServiceCallback() {}
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     if (JSVAL_IS_INT(aResult)) {
       int32_t mode = JSVAL_TO_INT(aResult);
       SetAutoMounterMode(mode);
     }
     return NS_OK;
   }
 
@@ -62,17 +62,17 @@ NS_IMPL_ISUPPORTS1(SettingsServiceCallba
 class CheckVolumeSettingsCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   CheckVolumeSettingsCallback(const nsACString& aVolumeName)
   : mVolumeName(aVolumeName) {}
 
-  NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
+  NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
   {
     if (JSVAL_IS_BOOLEAN(aResult)) {
       bool isSharingEnabled = JSVAL_TO_BOOLEAN(aResult);
       SetAutoMounterSharingMode(mVolumeName, isSharingEnabled);
     }
     return NS_OK;
   }
 
@@ -114,18 +114,22 @@ AutoMounterSetting::AutoMounterSetting()
     do_GetService("@mozilla.org/settingsService;1");
   if (!settingsService) {
     ERR("Failed to get settingsLock service!");
     return;
   }
   nsCOMPtr<nsISettingsServiceLock> lock;
   settingsService->CreateLock(getter_AddRefs(lock));
   nsCOMPtr<nsISettingsServiceCallback> callback = new SettingsServiceCallback();
-  lock->Set(UMS_MODE, INT_TO_JSVAL(AUTOMOUNTER_DISABLE), callback, nullptr);
-  lock->Set(UMS_STATUS, INT_TO_JSVAL(mStatus), nullptr, nullptr);
+  mozilla::AutoSafeJSContext cx;
+  JS::Rooted<JS::Value> value(cx);
+  value.setInt32(AUTOMOUNTER_DISABLE);
+  lock->Set(UMS_MODE, value, callback, nullptr);
+  value.setInt32(mStatus);
+  lock->Set(UMS_STATUS, value, nullptr, nullptr);
 }
 
 AutoMounterSetting::~AutoMounterSetting()
 {
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (observerService) {
     observerService->RemoveObserver(this, MOZSETTINGS_CHANGED);
@@ -188,17 +192,19 @@ public:
     MOZ_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsISettingsService> settingsService =
       do_GetService("@mozilla.org/settingsService;1");
     NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
     nsCOMPtr<nsISettingsServiceLock> lock;
     settingsService->CreateLock(getter_AddRefs(lock));
     // lock may be null if this gets called during shutdown.
     if (lock) {
-      lock->Set(UMS_STATUS, INT_TO_JSVAL(mStatus), nullptr, nullptr);
+      mozilla::AutoSafeJSContext cx;
+      JS::Rooted<JS::Value> value(cx, JS::Int32Value(mStatus));
+      lock->Set(UMS_STATUS, value, nullptr, nullptr);
     }
     return NS_OK;
   }
 
 private:
   int32_t mStatus;
 };
 
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -718,17 +718,17 @@ GonkGPSGeolocationProvider::ReceiveDataC
 {
   return NS_OK;
 }
 
 /** nsISettingsServiceCallback **/
 
 NS_IMETHODIMP
 GonkGPSGeolocationProvider::Handle(const nsAString& aName,
-                                   const JS::Value& aResult)
+                                   JS::Handle<JS::Value> aResult)
 {
   if (aName.EqualsLiteral("ril.supl.apn")) {
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     // When we get the APN, we attempt to call data_call_open of AGPS.
     if (aResult.isString()) {
       // NB: No need to enter a compartment to read the contents of a string.
--- a/dom/system/gonk/NetworkService.js
+++ b/dom/system/gonk/NetworkService.js
@@ -3,16 +3,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/FileUtils.jsm");
 
 const NETWORKSERVICE_CONTRACTID = "@mozilla.org/network/service;1";
 const NETWORKSERVICE_CID = Components.ID("{c14cabaf-bb8e-470d-a2f1-2cb6de6c5e5c}");
 
 // 1xx - Requested action is proceeding
 const NETD_COMMAND_PROCEEDING   = 100;
 // 2xx - Requested action has been successfully completed
 const NETD_COMMAND_OKAY         = 200;
@@ -47,17 +49,17 @@ function debug(msg) {
  * This component watches for network interfaces changing state and then
  * adjusts routes etc. accordingly.
  */
 function NetworkService() {
   if(DEBUG) debug("Starting net_worker.");
   this.worker = new ChromeWorker("resource://gre/modules/net_worker.js");
   this.worker.onmessage = this.handleWorkerMessage.bind(this);
   this.worker.onerror = function onerror(event) {
-    if(DEBUG) debug("Received error from worker: " + event.filename + 
+    if(DEBUG) debug("Received error from worker: " + event.filename +
                     ":" + event.lineno + ": " + event.message + "\n");
     // Prevent the event from bubbling any further.
     event.preventDefault();
   };
 
   // Callbacks to invoke when a reply arrives from the net_worker.
   this.controlCallbacks = Object.create(null);
 }
@@ -102,28 +104,47 @@ NetworkService.prototype = {
       delete this.controlCallbacks[id];
     }
   },
 
   // nsINetworkService
 
   getNetworkInterfaceStats: function(networkName, callback) {
     if(DEBUG) debug("getNetworkInterfaceStats for " + networkName);
+    let file = new FileUtils.File("/proc/net/dev");
 
-    let params = {
-      cmd: "getNetworkInterfaceStats",
-      ifname: networkName
-    };
+    if (!file) {
+      callback.networkStatsAvailable(false, -1, -1, new Date());
+      return;
+    }
+
+    NetUtil.asyncFetch(file, function(inputStream, status) {
+      let result = {
+        success: true,  // netd always return success even interface doesn't exist.
+        rxBytes: 0,
+        txBytes: 0
+      };
+      result.date = new Date();
 
-    params.report = true;
-    params.isAsync = true;
+      if (Components.isSuccessCode(status)) {
+        // Find record for corresponding interface.
+        let statExpr = / +(\S+): +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+/;
+        let data = NetUtil.readInputStreamToString(inputStream,
+                    inputStream.available()).split("\n");
+        for (let i = 2; i < data.length; i++) {
+          let parseResult = statExpr.exec(data[i]);
+          if (parseResult && parseResult[1] === networkName) {
+            result.rxBytes = parseInt(parseResult[2], 10);
+            result.txBytes = parseInt(parseResult[3], 10);
+            break;
+          }
+        }
+      }
 
-    this.controlMessage(params, function(result) {
-      let success = !isError(result.resultCode);
-      callback.networkStatsAvailable(success, result.rxBytes,
+      callback.networkStatsAvailable(result.success, result.rxBytes,
                                      result.txBytes, result.date);
     });
   },
 
   setNetworkInterfaceAlarm: function(networkName, threshold, callback) {
     if (!networkName) {
       callback.networkUsageAlarmResult(-1);
       return;
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -2766,23 +2766,38 @@ RadioInterface.prototype = {
         let offset = parseInt(data, 10);
         if (this._lastNitzMessage) {
           this._lastNitzMessage.receiveTimeInMS += offset;
         }
         this._sntp.updateOffset(offset);
         break;
       case kNetworkInterfaceStateChangedTopic:
         let network = subject.QueryInterface(Ci.nsINetworkInterface);
-        if (network.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
-          // Check SNTP when we have data connection, this may not take
-          // effect immediately before the setting get enabled.
-          if (this._sntp.isExpired()) {
-            this._sntp.request();
+        if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
+          return;
+        }
+
+        // SNTP can only update when we have mobile or Wifi connections.
+        if (network.type != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI &&
+            network.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
+          return;
+        }
+
+        // If the network comes from RIL, make sure the RIL service is matched.
+        if (subject instanceof Ci.nsIRilNetworkInterface) {
+          network = subject.QueryInterface(Ci.nsIRilNetworkInterface);
+          if (network.serviceId != this.clientId) {
+            return;
           }
         }
+
+        // SNTP won't update unless the SNTP is already expired.
+        if (this._sntp.isExpired()) {
+          this._sntp.request();
+        }
         break;
       case kScreenStateChangedTopic:
         this.workerMessenger.send("setScreenState", { on: (data === "on") });
         break;
     }
   },
 
   supportedNetworkTypes: null,
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -338,47 +338,47 @@ SystemWorkerManager::GetInterface(const 
   }
 
   NS_WARNING("Got nothing for the requested IID!");
   return NS_ERROR_NO_INTERFACE;
 }
 
 nsresult
 SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
-                                       const JS::Value& aWorker,
+                                       JS::Handle<JS::Value> aWorker,
                                        JSContext *aCx)
 {
 #ifndef MOZ_B2G_RIL
   return NS_ERROR_NOT_IMPLEMENTED;
 #else
-  NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aWorker), NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED);
 
-  JSAutoCompartment ac(aCx, JSVAL_TO_OBJECT(aWorker));
+  JSAutoCompartment ac(aCx, &aWorker.toObject());
 
   WorkerCrossThreadDispatcher *wctd =
     GetWorkerCrossThreadDispatcher(aCx, aWorker);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for ril");
     return NS_ERROR_FAILURE;
   }
 
   return RilConsumer::Register(aClientId, wctd);
 #endif // MOZ_B2G_RIL
 }
 
 nsresult
-SystemWorkerManager::RegisterNfcWorker(const JS::Value& aWorker,
+SystemWorkerManager::RegisterNfcWorker(JS::Handle<JS::Value> aWorker,
                                        JSContext* aCx)
 {
 #ifndef MOZ_NFC
   return NS_ERROR_NOT_IMPLEMENTED;
 #else
-  NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aWorker), NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(aWorker.isObject(), NS_ERROR_UNEXPECTED);
 
-  JSAutoCompartment ac(aCx, JSVAL_TO_OBJECT(aWorker));
+  JSAutoCompartment ac(aCx, &aWorker.toObject());
 
   WorkerCrossThreadDispatcher* wctd =
     GetWorkerCrossThreadDispatcher(aCx, aWorker);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for nfc");
     return NS_ERROR_FAILURE;
   }
 
@@ -387,22 +387,22 @@ SystemWorkerManager::RegisterNfcWorker(c
 }
 
 nsresult
 SystemWorkerManager::InitNetd(JSContext *cx)
 {
   nsCOMPtr<nsIWorkerHolder> worker = do_GetService(kNetworkServiceCID);
   NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
 
-  JS::Value workerval;
+  JS::Rooted<JS::Value> workerval(cx);
   nsresult rv = worker->GetWorker(&workerval);
   NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(workerval), NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(workerval.isObject(), NS_ERROR_UNEXPECTED);
 
-  JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(workerval));
+  JSAutoCompartment ac(cx, &workerval.toObject());
 
   WorkerCrossThreadDispatcher *wctd =
     GetWorkerCrossThreadDispatcher(cx, workerval);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for netd");
     return NS_ERROR_FAILURE;
   }
 
--- a/dom/system/gonk/TimeZoneSettingObserver.cpp
+++ b/dom/system/gonk/TimeZoneSettingObserver.cpp
@@ -47,17 +47,17 @@ public:
 
 class TimeZoneSettingCb MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   TimeZoneSettingCb() {}
 
-  NS_IMETHOD Handle(const nsAString &aName, const JS::Value &aResult) {
+  NS_IMETHOD Handle(const nsAString &aName, JS::Handle<JS::Value> aResult) {
 
     JSContext *cx = nsContentUtils::GetCurrentJSContext();
     NS_ENSURE_TRUE(cx, NS_OK);
 
     // If we don't have time.timezone value in the settings, we need
     // to initialize the settings based on the current system timezone
     // to make settings consistent with system. This usually happens
     // at the very first boot. After that, settings must have a value.
@@ -69,28 +69,34 @@ public:
       int32_t timeZoneOffset = hal::GetTimezoneOffset();
       nsPrintfCString curTimeZone("UTC%+03d:%02d",
                                   -timeZoneOffset / 60,
                                   abs(timeZoneOffset) % 60);
 
       // Convert it to a JS string.
       NS_ConvertUTF8toUTF16 utf16Str(curTimeZone);
 
-      JSString *jsStr = JS_NewUCStringCopyN(cx, utf16Str.get(), utf16Str.Length());
+      JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
+                                                          utf16Str.get(),
+                                                          utf16Str.Length()));
+      if (!jsStr) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
 
       // Set the settings based on the current system timezone.
       nsCOMPtr<nsISettingsServiceLock> lock;
       nsCOMPtr<nsISettingsService> settingsService =
         do_GetService("@mozilla.org/settingsService;1");
       if (!settingsService) {
         ERR("Failed to get settingsLock service!");
         return NS_OK;
       }
       settingsService->CreateLock(getter_AddRefs(lock));
-      lock->Set(TIME_TIMEZONE, STRING_TO_JSVAL(jsStr), nullptr, nullptr);
+      JS::Rooted<JS::Value> value(cx, JS::StringValue(jsStr));
+      lock->Set(TIME_TIMEZONE, value, nullptr, nullptr);
       return NS_OK;
     }
 
     // Set the system timezone based on the current settings.
     if (aResult.isString()) {
       return TimeZoneSettingObserver::SetTimeZone(aResult, cx);
     }
 
--- a/dom/system/gonk/net_worker.js
+++ b/dom/system/gonk/net_worker.js
@@ -137,29 +137,16 @@ function usbTetheringFail(params) {
 }
 
 function usbTetheringSuccess(params) {
   // Notify the main thread.
   postMessage(params);
   return true;
 }
 
-function networkInterfaceStatsFail(params) {
-  // Notify the main thread.
-  postMessage(params);
-  return true;
-}
-
-function networkInterfaceStatsSuccess(params) {
-  // Notify the main thread.
-  params.txBytes = parseFloat(params.resultReason);
-  postMessage(params);
-  return true;
-}
-
 function networkInterfaceAlarmFail(params) {
   // Notify the main thread.
   postMessage(params);
   return true;
 }
 
 function networkInterfaceAlarmSuccess(params) {
   // Notify the main thread.
@@ -602,28 +589,16 @@ function startSoftAP(params, callback) {
   return doCommand(command, callback);
 }
 
 function stopSoftAP(params, callback) {
   let command = "softap stopap";
   return doCommand(command, callback);
 }
 
-function getRxBytes(params, callback) {
-  let command = "interface readrxcounter " + params.ifname;
-  return doCommand(command, callback);
-}
-
-function getTxBytes(params, callback) {
-  params.rxBytes = parseFloat(params.resultReason);
-
-  let command = "interface readtxcounter " + params.ifname;
-  return doCommand(command, callback);
-}
-
 function enableAlarm(params, callback) {
   let command = "bandwidth enable";
   return doCommand(command, callback);
 }
 
 function disableAlarm(params, callback) {
   let command = "bandwidth disable";
   return doCommand(command, callback);
@@ -928,34 +903,16 @@ function setUSBTethering(params) {
     // Disable USB tetehring.
     debug("Stopping USB Tethering on " +
            params.internalIfname + "<->" + params.externalIfname);
     chain(params, gUSBDisableChain, usbTetheringFail);
   }
   return true;
 }
 
-let gNetworkInterfaceStatsChain = [getRxBytes,
-                                   getTxBytes,
-                                   networkInterfaceStatsSuccess];
-
-/**
- * handling main thread's get network interface stats request
- */
-function getNetworkInterfaceStats(params) {
-  debug("getNetworkInterfaceStats: " + params.ifname);
-
-  params.rxBytes = -1;
-  params.txBytes = -1;
-  params.date = new Date();
-
-  chain(params, gNetworkInterfaceStatsChain, networkInterfaceStatsFail);
-  return true;
-}
-
 let gNetworkInterfaceEnableAlarmChain = [enableAlarm,
                                          setQuota,
                                          setAlarm,
                                          networkInterfaceAlarmSuccess];
 
 function enableNetworkInterfaceAlarm(params) {
   debug("enableNetworkInterfaceAlarms: " + params.ifname);
 
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -614,17 +614,17 @@ var interfaceNamesInGlobalScope =
     {name: "MozActivity", b2g: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozApplicationEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozCellBroadcast", b2g: true, pref: "dom.cellbroadcast.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MozCellBroadcastEvent", b2g: true, pref: "dom.cellbroadcast.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "MozConnection",
+    {name: "MozConnection", pref: "dom.network.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "mozContact",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozContactChangeEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozCSSKeyframeRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MozCSSKeyframesRule",
--- a/dom/tests/mochitest/general/test_vibrator.html
+++ b/dom/tests/mochitest/general/test_vibrator.html
@@ -52,17 +52,17 @@ function testSuccesses() {
   expectSuccess(1000);
   expectSuccess(1000.1);
   expectSuccess([0, 0, 0]);
   expectSuccess(['1000', 1000]);
   expectSuccess([1000, 1000]);
   expectSuccess([1000, 1000.1]);
 
   // The following loop shouldn't cause us to crash.  See bug 701716.
-  for (var i = 0; i < 10000; i++) {
+  for (var i = 0; i < 1000; i++) {
     navigator.vibrate([100, 100]);
   }
   ok(true, "Didn't crash after issuing a lot of vibrate() calls.");
 }
 
 var origVibratorEnabled = SpecialPowers.getBoolPref('dom.vibrator.enabled');
 
 // Test with the vibrator pref enabled.
--- a/dom/tests/mochitest/pointerlock/file_screenClientXYConst.html
+++ b/dom/tests/mochitest/pointerlock/file_screenClientXYConst.html
@@ -46,19 +46,19 @@ https://bugzilla.mozilla.org/show_bug.cg
         is(unLockedCoords.screenY, lockedCoords.screenY,
            "screenY should be equal to where the mouse was originaly locked");
       }
 
       function moveUnlocked(e) {
         var firstCall = !unLockedCoords;
         if (!firstCall) {
           todo(false, "mousemove is fired twice.");
+        } else {
+          isUnlocked = !document.mozPointerLockElement;
         }
-
-        isUnlocked = !document.mozPointerLockElement;
         unLockedCoords = {
           screenX: e.screenX,
           screenY: e.screenY,
           clientX: e.clientX,
           clientY: e.clientY
         };
 
         if (!firstCall) {
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -79,17 +79,17 @@ interface CanvasRenderingContext2D {
   // path API (see also CanvasPathMethods)
   void beginPath();
   void fill(optional CanvasWindingRule winding = "nonzero");
 // NOT IMPLEMENTED  void fill(Path path);
   void stroke();
 // NOT IMPLEMENTED  void stroke(Path path);
   [Pref="canvas.focusring.enabled"] void drawFocusIfNeeded(Element element);
 // NOT IMPLEMENTED  void drawSystemFocusRing(Path path, HTMLElement element);
-  [Pref="canvas.focusring.enabled"] boolean drawCustomFocusRing(Element element);
+  [Pref="canvas.customfocusring.enabled"] boolean drawCustomFocusRing(Element element);
 // NOT IMPLEMENTED  boolean drawCustomFocusRing(Path path, HTMLElement element);
 // NOT IMPLEMENTED  void scrollPathIntoView();
 // NOT IMPLEMENTED  void scrollPathIntoView(Path path);
   void clip(optional CanvasWindingRule winding = "nonzero");
 // NOT IMPLEMENTED  void clip(Path path);
 // NOT IMPLEMENTED  void resetClip();
   boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
 // NOT IMPLEMENTED  boolean isPointInPath(Path path, unrestricted double x, unrestricted double y);
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MozConnection.webidl
@@ -0,0 +1,13 @@
+/* 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/.
+ */
+
+[Pref="dom.network.enabled"]
+interface MozConnection : EventTarget {
+  readonly attribute unrestricted double bandwidth;
+  readonly attribute boolean metered;
+
+  attribute EventHandler onchange;
+};
+
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -224,17 +224,16 @@ partial interface Navigator {
 // nsIDOMMozNavigatorMobileMessage
 interface MozMobileMessageManager;
 partial interface Navigator {
   [Func="Navigator::HasMobileMessageSupport"]
   readonly attribute MozMobileMessageManager? mozMobileMessage;
 };
 
 // nsIDOMMozNavigatorNetwork
-interface MozConnection;
 partial interface Navigator {
   [Pref="dom.network.enabled"]
   readonly attribute MozConnection? mozConnection;
 };
 
 // nsIDOMNavigatorCamera
 partial interface Navigator {
   [Throws, Func="Navigator::HasCameraSupport"]
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -145,12 +145,15 @@ callback RTCLogCallback = void (sequence
  ChromeOnly,
  Constructor ()]
 interface WebrtcGlobalInformation {
     void getAllStats(RTCStatsCallback callback,
                      RTCPeerConnectionErrorCallback errorCallback);
     void getCandPairLogs(DOMString candPairId,
                          RTCLogCallback callback,
                          RTCPeerConnectionErrorCallback errorCallback);
+    void getLogs(DOMString pattern,
+                 RTCLogCallback callback,
+                 RTCPeerConnectionErrorCallback errorCallback);
 };
 
 
 
--- a/dom/webidl/VTTCue.webidl
+++ b/dom/webidl/VTTCue.webidl
@@ -30,18 +30,17 @@ interface VTTCue : EventTarget {
 
   attribute DOMString id;
   attribute double startTime;
   attribute double endTime;
   attribute boolean pauseOnExit;
   attribute DOMString regionId;
   attribute DirectionSetting vertical;
   attribute boolean snapToLines;
-  // XXXhumph: https://www.w3.org/Bugs/Public/show_bug.cgi?id=20651
-  // attribute (long or AutoKeyword) line;
+  attribute (long or AutoKeyword) line;
   [SetterThrows]
   attribute AlignSetting lineAlign;
   [SetterThrows]
   attribute long position;
   [SetterThrows]
   attribute AlignSetting positionAlign;
   [SetterThrows]
   attribute long size;
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -224,16 +224,17 @@ WEBIDL_FILES = [
     'MessagePort.webidl',
     'MessagePortList.webidl',
     'MimeType.webidl',
     'MimeTypeArray.webidl',
     'MobileMessageManager.webidl',
     'MouseEvent.webidl',
     'MouseScrollEvent.webidl',
     'MozActivity.webidl',
+    'MozConnection.webidl',
     'MozMmsMessage.webidl',
     'MozNamedAttrMap.webidl',
     'MozPowerManager.webidl',
     'MozTimeManager.webidl',
     'MozWakeLock.webidl',
     'MutationEvent.webidl',
     'MutationObserver.webidl',
     'NetDashboard.webidl',
--- a/dom/wifi/WifiProxyService.cpp
+++ b/dom/wifi/WifiProxyService.cpp
@@ -232,24 +232,24 @@ WifiProxyService::Shutdown()
   if (mControlThread) {
     mControlThread->Shutdown();
     mControlThread = nullptr;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-WifiProxyService::SendCommand(const JS::Value& aOptions, const nsACString& aInterface,
+WifiProxyService::SendCommand(JS::Handle<JS::Value> aOptions,
+                              const nsACString& aInterface,
                               JSContext* aCx)
 {
   MOZ_ASSERT(NS_IsMainThread());
   WifiCommandOptions options;
 
-  if (!options.Init(aCx,
-                    JS::Handle<JS::Value>::fromMarkedLocation(&aOptions))) {
+  if (!options.Init(aCx, aOptions)) {
     NS_WARNING("Bad dictionary passed to WifiProxyService::SendCommand");
     return NS_ERROR_FAILURE;
   }
 
   // Dispatch the command to the control thread.
   CommandOptions commandOptions(options);
   nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions, aInterface);
   mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -405,22 +405,19 @@ private:
 
   static bool
   GetLastModifiedDateImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
     JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
     nsIDOMFile* file = GetInstancePrivate(aCx, obj, "lastModifiedDate");
     MOZ_ASSERT(file);
 
-    JS::Rooted<JS::Value> value(aCx);
-    if (NS_FAILED(file->GetLastModifiedDate(aCx, value.address()))) {
+    if (NS_FAILED(file->GetLastModifiedDate(aCx, aArgs.rval()))) {
       return false;
     }
-
-    aArgs.rval().set(value);
     return true;
   }
 
   static bool
   GetLastModifiedDate(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
     JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
     return JS::CallNonGenericMethod<IsFile, GetLastModifiedDateImpl>(aCx, args);
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1154,17 +1154,17 @@ EventRunnable::PreDispatch(JSContext* aC
   if (NS_SUCCEEDED(mResponseTextResult)) {
     mResponseResult = mResponseTextResult;
     if (mResponseText.IsVoid()) {
       mResponse = JSVAL_NULL;
     }
   }
   else {
     JS::Rooted<JS::Value> response(aCx);
-    mResponseResult = xhr->GetResponse(aCx, response.address());
+    mResponseResult = xhr->GetResponse(aCx, &response);
     if (NS_SUCCEEDED(mResponseResult)) {
       if (JSVAL_IS_UNIVERSAL(response)) {
         mResponse = response;
       }
       else {
         // Anything subject to GC must be cloned.
         JSStructuredCloneCallbacks* callbacks =
           aWorkerPrivate->IsChromeWorker() ?
@@ -1454,18 +1454,17 @@ SendRunnable::MainThreadRun()
 
     JSStructuredCloneCallbacks* callbacks =
       mWorkerPrivate->IsChromeWorker() ?
       ChromeWorkerStructuredCloneCallbacks(true) :
       WorkerStructuredCloneCallbacks(true);
 
     JS::Rooted<JS::Value> body(cx);
     if (mBody.read(cx, &body, callbacks, &mClonedObjects)) {
-      if (NS_FAILED(xpc->JSValToVariant(cx, body.address(),
-                                        getter_AddRefs(variant)))) {
+      if (NS_FAILED(xpc->JSValToVariant(cx, body, getter_AddRefs(variant)))) {
         rv = NS_ERROR_DOM_INVALID_STATE_ERR;
       }
     }
     else {
       rv = NS_ERROR_DOM_DATA_CLONE_ERR;
     }
 
     mBody.clear();
--- a/editor/reftests/xul/autocomplete-1.xul
+++ b/editor/reftests/xul/autocomplete-1.xul
@@ -2,11 +2,13 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox type="autocomplete" value="test"/>
+  <!-- leading space in the value to ensure no pixels of t get clipped
+       in one rendering but not the other -->
+  <textbox type="autocomplete" value=" test"/>
       
 </window>
--- a/editor/reftests/xul/autocomplete-ref.xul
+++ b/editor/reftests/xul/autocomplete-ref.xul
@@ -3,11 +3,11 @@
 <?xml-stylesheet href="input.css" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <html:input class="ac" value="test"/>
+  <html:input class="ac" value=" test"/>
       
 </window>
--- a/editor/reftests/xul/empty-1.xul
+++ b/editor/reftests/xul/empty-1.xul
@@ -3,11 +3,11 @@
 <?xml-stylesheet href="placeholder-reset.css" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox placeholder="test"/>
+  <textbox placeholder=" test"/>
       
 </window>
--- a/editor/reftests/xul/empty-2.xul
+++ b/editor/reftests/xul/empty-2.xul
@@ -2,11 +2,11 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox placeholder="test" value="value"/>
+  <textbox placeholder=" test" value="value"/>
       
 </window>
--- a/editor/reftests/xul/empty-ref.xul
+++ b/editor/reftests/xul/empty-ref.xul
@@ -3,11 +3,11 @@
 <?xml-stylesheet href="input.css" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <html:input class="empty" value="test"/>
+  <html:input class="empty" value=" test"/>
       
 </window>
--- a/editor/reftests/xul/input.css
+++ b/editor/reftests/xul/input.css
@@ -1,45 +1,49 @@
 @namespace url('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul');
 @namespace html url('http://www.w3.org/1999/xhtml');
 
 #mac html|input, #mac html|textarea {
   margin: 4px;
-  padding: 0;
+  padding: 0 1px;
 }
 
 #win html|input, #win html|textarea {
   margin: 2px 4px;
-  padding: 2px 2px 3px;
-  -moz-padding-start: 4px;
+  padding: 2px 3px 3px;
+  -moz-padding-start: 5px;
 }
 
 #win html|input:-moz-system-metric(windows-default-theme) {
-  padding: 1px 1px 2px;
-  -moz-padding-start: 3px;
+  padding: 1px 2px 2px;
+  -moz-padding-start: 4px;
 }
 
 #linux html|input, #linux html|textarea {
   margin: 2px 4px;
-  padding: 2px 4px 3px;
+  padding: 2px 5px 3px;
 }
 
 textbox[multiline="true"], html|textarea {
   border: none !important;
   -moz-appearance: none !important;
   border-top-right-radius: 0;
   border-bottom-left-radius: 0;
 }
 
 html|input, html|textarea {
   font: inherit;
 }
 
 html|input.ac {
-  padding:  0 3px !important;
+  padding: 0 4px !important;
+}
+
+#mac html|input.ac {
+  padding: 0 3px !important;
 }
 
 html|input.empty {
   color: graytext;
 }
 
 :root:not(.winxp) html|input.empty:-moz-system-metric(windows-default-theme) {
   font-style: italic;
@@ -54,16 +58,17 @@ html|input.num {
 }
 
 #win html|input.num {
   padding: 0 !important;
 }
 
 #linux html|input.num {
   -moz-margin-end: 3px;
-  padding: 3px;
+  padding: 3px 4px;
 }
 
 html|div.plainfield {
   -moz-margin-start: 1px;
   color: -moz-fieldtext;
+  white-space: pre;
 }
 
--- a/editor/reftests/xul/plain-1.xul
+++ b/editor/reftests/xul/plain-1.xul
@@ -2,11 +2,11 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox value="test" class="plain"/>
+  <textbox value=" test" class="plain"/>
       
 </window>
--- a/editor/reftests/xul/plain-ref.xul
+++ b/editor/reftests/xul/plain-ref.xul
@@ -3,11 +3,11 @@
 <?xml-stylesheet href="input.css" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <html:div class="plainfield">test</html:div>
+  <html:div class="plainfield"> test</html:div>
       
 </window>
--- a/editor/reftests/xul/textbox-1.xul
+++ b/editor/reftests/xul/textbox-1.xul
@@ -2,11 +2,11 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox value="test"/>
+  <textbox value=" test"/>
       
 </window>
--- a/editor/reftests/xul/textbox-disabled.xul
+++ b/editor/reftests/xul/textbox-disabled.xul
@@ -2,11 +2,11 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox value="test" disabled="true"/>
+  <textbox value=" test" disabled="true"/>
       
 </window>
--- a/editor/reftests/xul/textbox-readonly.xul
+++ b/editor/reftests/xul/textbox-readonly.xul
@@ -2,11 +2,11 @@
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <textbox value="test" readonly="true"/>
+  <textbox value=" test" readonly="true"/>
       
 </window>
--- a/editor/reftests/xul/textbox-ref.xul
+++ b/editor/reftests/xul/textbox-ref.xul
@@ -3,11 +3,11 @@
 <?xml-stylesheet href="input.css" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="Textbox tests">
 
   <script type="text/javascript" src="platform.js"/>
 
-  <html:input value="test"/>
+  <html:input value=" test"/>
       
 </window>
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -357,17 +357,18 @@ nsDocShellTreeOwner::GetPrimaryContentSh
 
    *aShell = (mPrimaryContentShell ? mPrimaryContentShell : mWebBrowser->mDocShell);
    NS_IF_ADDREF(*aShell);
 
    return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShellTreeOwner::GetContentWindow(JSContext* aCx, JS::Value* aVal)
+nsDocShellTreeOwner::GetContentWindow(JSContext* aCx,
+                                      JS::MutableHandle<JS::Value> aVal)
 {
   if (mTreeOwner)
     return mTreeOwner->GetContentWindow(aCx, aVal);
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -113,14 +113,14 @@ nsresult EvaluateAdminConfigScript(const
     }
 
     AutoSafeJSContext cx;
     JSAutoCompartment ac(cx, autoconfigSb);
 
     nsAutoCString script(js_buffer, length);
     JS::RootedValue v(cx);
     rv = xpc->EvalInSandboxObject(NS_ConvertASCIItoUTF16(script), filename, cx, autoconfigSb,
-                                  /* returnStringOnly = */ false, v.address());
+                                  /* returnStringOnly = */ false, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -18,16 +18,18 @@
 // to be able to hold on to a GLContext.
 #include "mozilla/GenericRefCounted.h"
 
 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
 // outparams using the &-operator. But it will have to do as there's no easy
 // solution.
 #include "mozilla/RefPtr.h"
 
+#include "mozilla/DebugOnly.h"
+
 #ifdef MOZ_ENABLE_FREETYPE
 #include <string>
 #endif
 
 struct _cairo_surface;
 typedef _cairo_surface cairo_surface_t;
 
 struct _cairo_scaled_font;
@@ -332,41 +334,67 @@ public:
    * DataSourceSurface's data can be accessed directly.
    */
   virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
 };
 
 class DataSourceSurface : public SourceSurface
 {
 public:
+  DataSourceSurface()
+    : mIsMapped(false)
+  {
+  }
+
+  struct MappedSurface {
+    uint8_t *mData;
+    int32_t mStride;
+  };
+
+  enum MapType {
+    READ,
+    WRITE,
+    READ_WRITE
+  };
+
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
-  /*
+  /* [DEPRECATED]
    * Get the raw bitmap data of the surface.
    * Can return null if there was OOM allocating surface data.
    */
   virtual uint8_t *GetData() = 0;
 
-  /*
+  /* [DEPRECATED]
    * Stride of the surface, distance in bytes between the start of the image
    * data belonging to row y and row y+1. This may be negative.
    * Can return 0 if there was OOM allocating surface data.
    */
   virtual int32_t Stride() = 0;
 
-  /*
-   * This function is called after modifying the data on the source surface
-   * directly through the data pointer.
-   */
-  virtual void MarkDirty() {}
+  virtual bool Map(MapType, MappedSurface *aMappedSurface)
+  {
+    aMappedSurface->mData = GetData();
+    aMappedSurface->mStride = Stride();
+    mIsMapped = true;
+    return true;
+  }
+
+  virtual void Unmap()
+  {
+    MOZ_ASSERT(mIsMapped);
+    mIsMapped = false;
+  }
 
   /*
    * Returns a DataSourceSurface with the same data as this one, but
    * guaranteed to have surface->GetType() == SurfaceType::DATA.
    */
   virtual TemporaryRef<DataSourceSurface> GetDataSurface();
+
+  DebugOnly<bool> mIsMapped;
 };
 
 /* This is an abstract object that accepts path segments. */
 class PathSink : public RefCounted<PathSink>
 {
 public:
   virtual ~PathSink() {}
 
--- a/gfx/2d/DataSourceSurfaceWrapper.h
+++ b/gfx/2d/DataSourceSurfaceWrapper.h
@@ -22,17 +22,16 @@ public:
 
   virtual SurfaceType GetType() const MOZ_OVERRIDE { return SurfaceType::DATA; }
 
   virtual uint8_t *GetData() MOZ_OVERRIDE { return mSurface->GetData(); }
   virtual int32_t Stride() MOZ_OVERRIDE { return mSurface->Stride(); }
   virtual IntSize GetSize() const MOZ_OVERRIDE { return mSurface->GetSize(); }
   virtual SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mSurface->GetFormat(); }
   virtual bool IsValid() const MOZ_OVERRIDE { return mSurface->IsValid(); }
-  virtual void MarkDirty() { mSurface->MarkDirty(); }
 
 private:
   RefPtr<DataSourceSurface> mSurface;
 };
 
 }
 }
 
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -201,16 +201,33 @@ public:
 
   bool IsIntegerTranslation() const
   {
     return IsTranslation() &&
            FuzzyEqual(_31, floorf(_31 + 0.5f)) &&
            FuzzyEqual(_32, floorf(_32 + 0.5f));
   }
 
+  /**
+   * Returns true if matrix is multiple of 90 degrees rotation with flipping,
+   * scaling and translation.
+   */
+  bool PreservesAxisAlignedRectangles() const {
+      return ((FuzzyEqual(_11, 0.0) && FuzzyEqual(_22, 0.0))
+          || (FuzzyEqual(_12, 0.0) && FuzzyEqual(_21, 0.0)));
+  }
+
+  /**
+   * Returns true if the matrix has non-integer scale
+   */
+  bool HasNonIntegerScale() const {
+      return !FuzzyEqual(_11, floor(_11 + 0.5)) ||
+             !FuzzyEqual(_22, floor(_22 + 0.5));
+  }
+
 private:
   static bool FuzzyEqual(Float aV1, Float aV2) {
     // XXX - Check if fabs does the smart thing and just negates the sign bit.
     return fabs(aV2 - aV1) < 1e-6;
   }
 };
 
 class Matrix4x4
--- a/gfx/2d/SourceSurfaceD2D.cpp
+++ b/gfx/2d/SourceSurfaceD2D.cpp
@@ -169,17 +169,17 @@ DataSourceSurfaceD2D::DataSourceSurfaceD
 
   renderTarget->BeginDraw();
   renderTarget->DrawBitmap(aSourceSurface->mBitmap,
                            D2D1::RectF(0, 0,
                                        Float(mSize.width),
                                        Float(mSize.height)));
   renderTarget->EndDraw();
 
-  desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
+  desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
   desc.Usage = D3D10_USAGE_STAGING;
   desc.BindFlags = 0;
   hr = aSourceSurface->mDevice->CreateTexture2D(&desc, nullptr, byRef(mTexture));
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create staging texture. Code: " << hr;
     mTexture = nullptr;
     return;
   }
@@ -223,19 +223,66 @@ DataSourceSurfaceD2D::GetSize() const
 }
 
 SurfaceFormat
 DataSourceSurfaceD2D::GetFormat() const
 {
   return mFormat;
 }
 
+bool
+DataSourceSurfaceD2D::Map(MapType aMapType, MappedSurface *aMappedSurface)
+{
+  // DataSourceSurfaces used with the new Map API should not be used with GetData!!
+  MOZ_ASSERT(!mMapped);
+  MOZ_ASSERT(!mIsMapped);
+
+  if (!mTexture) {
+    return false;
+  }
+
+  D3D10_MAP mapType;
+
+  if (aMapType == MapType::READ) {
+    mapType = D3D10_MAP_READ;
+  } else if (aMapType == MapType::WRITE) {
+    mapType = D3D10_MAP_WRITE;
+  } else {
+    mapType = D3D10_MAP_READ_WRITE;
+  }
+
+  D3D10_MAPPED_TEXTURE2D map;
+
+  HRESULT hr = mTexture->Map(0, mapType, 0, &map);
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Texture map failed with code: " << hr;
+    return false;
+  }
+
+  aMappedSurface->mData = (uint8_t*)map.pData;
+  aMappedSurface->mStride = map.RowPitch;
+
+  return true;
+}
+
+void
+DataSourceSurfaceD2D::Unmap()
+{
+  MOZ_ASSERT(mIsMapped);
+
+  mTexture->Unmap(0);
+}
+
 void
 DataSourceSurfaceD2D::EnsureMappedTexture()
 {
+  // Do not use GetData() after having used Map!
+  MOZ_ASSERT(!mIsMapped);
+
   if (mMapped ||
       !mTexture) {
     return;
   }
 
   HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mData);
   if (FAILED(hr)) {
     gfxWarning() << "Failed to map texture. Code: " << hr;
--- a/gfx/2d/SourceSurfaceD2D.h
+++ b/gfx/2d/SourceSurfaceD2D.h
@@ -57,16 +57,18 @@ class DataSourceSurfaceD2D : public Data
 public:
   DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface);
   virtual ~DataSourceSurfaceD2D();
 
   virtual unsigned char* GetData();
   virtual int32_t Stride();
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
+  virtual bool Map(MapType, MappedSurface *aMappedSurface);
+  virtual void Unmap();
 
   bool IsValid()
   {
     return mTexture;
   }
 
 private:
   void EnsureMappedTexture();
--- a/gfx/2d/SourceSurfaceD2D1.cpp
+++ b/gfx/2d/SourceSurfaceD2D1.cpp
@@ -136,27 +136,58 @@ DataSourceSurfaceD2D1::GetSize() const
 uint8_t*
 DataSourceSurfaceD2D1::GetData()
 {
   EnsureMapped();
 
   return mMap.bits;
 }
 
+bool
+DataSourceSurfaceD2D1::Map(MapType aMapType, MappedSurface *aMappedSurface)
+{
+  // DataSourceSurfaces used with the new Map API should not be used with GetData!!
+  MOZ_ASSERT(!mMapped);
+  MOZ_ASSERT(!mIsMapped);
+
+  D2D1_MAP_OPTIONS options;
+  if (aMapType == MapType::READ) {
+    options = D2D1_MAP_OPTIONS_READ;
+  } else {
+    MOZ_CRASH("No support for Write maps on D2D1 DataSourceSurfaces yet!");
+  }
+
+  D2D1_MAPPED_RECT map;
+  mBitmap->Map(D2D1_MAP_OPTIONS_READ, &map);
+  aMappedSurface->mData = map.bits;
+  aMappedSurface->mStride = map.pitch;
+
+  mIsMapped = true;
+  return true;
+}
+
+void
+DataSourceSurfaceD2D1::Unmap()
+{
+  mBitmap->Unmap();
+}
+
 int32_t
 DataSourceSurfaceD2D1::Stride()
 {
   EnsureMapped();
 
   return mMap.pitch;
 }
 
 void
 DataSourceSurfaceD2D1::EnsureMapped()
 {
+  // Do not use GetData() after having used Map!
+  MOZ_ASSERT(!mIsMapped);
   if (mMapped) {
     return;
   }
   mBitmap->Map(D2D1_MAP_OPTIONS_READ, &mMap);
   mMapped = true;
 }
 
 }
--- a/gfx/2d/SourceSurfaceD2D1.h
+++ b/gfx/2d/SourceSurfaceD2D1.h
@@ -65,16 +65,18 @@ public:
   DataSourceSurfaceD2D1(ID2D1Bitmap1 *aMappableBitmap, SurfaceFormat aFormat);
   ~DataSourceSurfaceD2D1();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const { return mFormat; }
   virtual uint8_t *GetData();
   virtual int32_t Stride();
+  virtual bool Map(MapType, MappedSurface *aMappedSurface);
+  virtual void Unmap();
 
 private:
   friend class SourceSurfaceD2DTarget;
   void EnsureMapped();
 
   mutable RefPtr<ID2D1Bitmap1> mBitmap;
   SurfaceFormat mFormat;
   D2D1_MAPPED_RECT mMap;
--- a/gfx/2d/SourceSurfaceD2DTarget.cpp
+++ b/gfx/2d/SourceSurfaceD2DTarget.cpp
@@ -231,19 +231,65 @@ DataSourceSurfaceD2DTarget::GetData()
 
 int32_t
 DataSourceSurfaceD2DTarget::Stride()
 {
   EnsureMapped();
   return mMap.RowPitch;
 }
 
+bool
+DataSourceSurfaceD2DTarget::Map(MapType aMapType, MappedSurface *aMappedSurface)
+{
+  // DataSourceSurfaces used with the new Map API should not be used with GetData!!
+  MOZ_ASSERT(!mMapped);
+  MOZ_ASSERT(!mIsMapped);
+
+  if (!mTexture) {
+    return false;
+  }
+
+  D3D10_MAP mapType;
+
+  if (aMapType == MapType::READ) {
+    mapType = D3D10_MAP_READ;
+  } else if (aMapType == MapType::WRITE) {
+    mapType = D3D10_MAP_WRITE;
+  } else {
+    mapType = D3D10_MAP_READ_WRITE;
+  }
+
+  D3D10_MAPPED_TEXTURE2D map;
+
+  HRESULT hr = mTexture->Map(0, mapType, 0, &map);
+
+  if (FAILED(hr)) {
+    gfxWarning() << "Texture map failed with code: " << hr;
+    return false;
+  }
+
+  aMappedSurface->mData = (uint8_t*)map.pData;
+  aMappedSurface->mStride = map.RowPitch;
+
+  return true;
+}
+
+void
+DataSourceSurfaceD2DTarget::Unmap()
+{
+  MOZ_ASSERT(mIsMapped);
+
+  mTexture->Unmap(0);
+}
+
 void
 DataSourceSurfaceD2DTarget::EnsureMapped()
 {
+  // Do not use GetData() after having used Map!
+  MOZ_ASSERT(!mIsMapped);
   if (!mMapped) {
     HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mMap);
     if (FAILED(hr)) {
       gfxWarning() << "Failed to map texture to memory. Code: " << hr;
       return;
     }
     mMapped = true;
   }
--- a/gfx/2d/SourceSurfaceD2DTarget.h
+++ b/gfx/2d/SourceSurfaceD2DTarget.h
@@ -63,16 +63,18 @@ public:
   DataSourceSurfaceD2DTarget(SurfaceFormat aFormat);
   ~DataSourceSurfaceD2DTarget();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual uint8_t *GetData();
   virtual int32_t Stride();
+  virtual bool Map(MapType, MappedSurface *aMappedSurface);
+  virtual void Unmap();
 
 private:
   friend class SourceSurfaceD2DTarget;
   void EnsureMapped();
 
   mutable RefPtr<ID3D10Texture2D> mTexture;
   SurfaceFormat mFormat;
   D3D10_MAPPED_TEXTURE2D mMap;
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -171,23 +171,26 @@ SharedSurface_EGLImage::Fence()
 
         if (!mPixels) {
             SurfaceFormat format =
                   HasAlpha() ? SurfaceFormat::B8G8R8A8
                              : SurfaceFormat::B8G8R8X8;
             mPixels = Factory::CreateDataSourceSurface(Size(), format);
         }
 
+        DataSourceSurface::MappedSurface map;
+        mPixels->Map(DataSourceSurface::MapType::WRITE, &map);
+
         nsRefPtr<gfxImageSurface> wrappedData =
-            new gfxImageSurface(mPixels->GetData(),
+            new gfxImageSurface(map.mData,
                                 ThebesIntSize(mPixels->GetSize()),
-                                mPixels->Stride(),
+                                map.mStride,
                                 SurfaceFormatToImageFormat(mPixels->GetFormat()));
         ReadScreenIntoImageSurface(mGL, wrappedData);
-        mPixels->MarkDirty();
+        mPixels->Unmap();
         return;
     }
     MOZ_ASSERT(mPipeActive);
     MOZ_ASSERT(mCurConsGL);
 
     if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
         mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
     {
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -299,23 +299,26 @@ SharedSurface_Basic::~SharedSurface_Basi
 }
 
 void
 SharedSurface_Basic::Fence()
 {
     MOZ_ASSERT(mData->GetSize() == mGL->OffscreenSize());
 
     mGL->MakeCurrent();
+
+    DataSourceSurface::MappedSurface map;
+    mData->Map(DataSourceSurface::MapType::WRITE, &map);
     nsRefPtr<gfxImageSurface> wrappedData =
-      new gfxImageSurface(mData->GetData(),
+      new gfxImageSurface(map.mData,
                           ThebesIntSize(mData->GetSize()),
-                          mData->Stride(),
+                          map.mStride,
                           SurfaceFormatToImageFormat(mData->GetFormat()));
     ReadScreenIntoImageSurface(mGL, wrappedData);
-    mData->MarkDirty();
+    mData->Unmap();
 }
 
 
 
 SharedSurface_GLTexture*
 SharedSurface_GLTexture::Create(GLContext* prodGL,
                                 GLContext* consGL,
                                 const GLFormats& formats,
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -105,16 +105,17 @@
 
 class nsIWidget;
 struct gfxMatrix;
 struct nsIntSize;
 class nsIntRegion;
 
 namespace mozilla {
 namespace gfx {
+class Matrix;
 class Matrix4x4;
 class DrawTarget;
 }
 
 namespace layers {
 
 struct Effect;
 struct EffectChain;
@@ -319,32 +320,32 @@ public:
    * for the clip rect).
    *
    * If aRenderBoundsOut is non-null, it will be set to the render bounds
    * actually used by the compositor in window space. If aRenderBoundsOut
    * is returned empty, composition should be aborted.
    */
   virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
                           const gfx::Rect* aClipRectIn,
-                          const gfxMatrix& aTransform,
+                          const gfx::Matrix& aTransform,
                           const gfx::Rect& aRenderBounds,
                           gfx::Rect* aClipRectOut = nullptr,
                           gfx::Rect* aRenderBoundsOut = nullptr) = 0;
 
   /**
    * Flush the current frame to the screen and tidy up.
    */
   virtual void EndFrame() = 0;
 
   /**
    * Post-rendering stuff if the rendering is done outside of this Compositor
    * e.g., by Composer2D.
    * aTransform is the transform from user space to window space.
    */
-  virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) = 0;
+  virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0;
 
   /**
    * Tidy up if BeginFrame has been called, but EndFrame won't be.
    */
   virtual void AbortFrame() = 0;
 
   /**
    * Setup the viewport and projection matrix for rendering to a target of the
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -554,17 +554,17 @@ Layer::MayResample()
   gfxMatrix transform2d;
   return !GetEffectiveTransform().Is2D(&transform2d) ||
          transform2d.HasNonIntegerTranslation() ||
          AncestorLayerMayChangeTransform(this);
 }
 
 nsIntRect
 Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
-                            const gfxMatrix* aWorldTransform)
+                            const gfx::Matrix* aWorldTransform)
 {
   ContainerLayer* container = GetParent();
   NS_ASSERTION(container, "This can't be called on the root!");
 
   // Establish initial clip rect: it's either the one passed in, or
   // if the parent has an intermediate surface, it's the extents of that surface.
   nsIntRect currentClip;
   if (container->UseIntermediateSurface()) {
@@ -600,20 +600,20 @@ Layer::CalculateScissorRect(const nsIntR
     // Find the nearest ancestor with an intermediate surface
     do {
       container = container->GetParent();
     } while (container && !container->UseIntermediateSurface());
   }
   if (container) {
     scissor.MoveBy(-container->GetIntermediateSurfaceRect().TopLeft());
   } else if (aWorldTransform) {
-    gfxRect r(scissor.x, scissor.y, scissor.width, scissor.height);
-    gfxRect trScissor = aWorldTransform->TransformBounds(r);
+    gfx::Rect r(scissor.x, scissor.y, scissor.width, scissor.height);
+    gfx::Rect trScissor = aWorldTransform->TransformBounds(r);
     trScissor.Round();
-    if (!gfxUtils::GfxRectToIntRect(trScissor, &scissor))
+    if (!gfxUtils::GfxRectToIntRect(ThebesRect(trScissor), &scissor))
       return nsIntRect(currentClip.TopLeft(), nsIntSize(0, 0));
   }
   return currentClip.Intersect(scissor);
 }
 
 const gfx3DMatrix
 Layer::GetTransform() const
 {
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1250,17 +1250,17 @@ public:
    * nearest ancestor that has an intermediate surface, or relative to the root
    * viewport if no ancestor has an intermediate surface, corresponding to the
    * clip rect for this layer intersected with aCurrentScissorRect.
    * If no ancestor has an intermediate surface, the clip rect is transformed
    * by aWorldTransform before being combined with aCurrentScissorRect, if
    * aWorldTransform is non-null.
    */
   nsIntRect CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
-                                 const gfxMatrix* aWorldTransform);
+                                 const gfx::Matrix* aWorldTransform);
 
   virtual const char* Name() const =0;
   virtual LayerType GetType() const =0;
 
   /**
    * Only the implementation should call this. This is per-implementation
    * private data. Normally, all layers with a given layer manager
    * use the same type of ImplData.
--- a/gfx/layers/YCbCrImageDataSerializer.cpp
+++ b/gfx/layers/YCbCrImageDataSerializer.cpp
@@ -10,16 +10,19 @@
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Types.h"
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "yuv_convert.h"                // for ConvertYCbCrToRGB32, etc
 
 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
 
 namespace mozilla {
+
+using namespace gfx;
+
 namespace layers {
 
 // The Data is layed out as follows:
 //
 //  +-----------------+   -++ --+ --+ <-- Beginning of the buffer
 //  | YCbCrBufferInfo |     |   |   |
 //  +-----------------+   --+   |   |
 //  |      data       |         |   | YCbCrBufferInfo->[mY/mCb/mCr]Offset
@@ -241,28 +244,31 @@ YCbCrImageDataSerializer::CopyData(const
       CopyLineWithSkip(aCrData + i * aCbCrStride,
                        GetCrData() + i * GetCbCrStride(),
                        aCbCrSize.width, aCbCrSkip);
     }
   }
   return true;
 }
 
-TemporaryRef<gfx::DataSourceSurface>
+TemporaryRef<DataSourceSurface>
 YCbCrImageDataDeserializer::ToDataSourceSurface()
 {
-  RefPtr<gfx::DataSourceSurface> result =
-    gfx::Factory::CreateDataSourceSurface(GetYSize(), gfx::SurfaceFormat::R8G8B8X8);
+  RefPtr<DataSourceSurface> result =
+    Factory::CreateDataSourceSurface(GetYSize(), gfx::SurfaceFormat::R8G8B8X8);
+
+  DataSourceSurface::MappedSurface map;
+  result->Map(DataSourceSurface::MapType::WRITE, &map);
 
   gfx::ConvertYCbCrToRGB32(GetYData(), GetCbData(), GetCrData(),
-                           result->GetData(),
+                           map.mData,
                            0, 0, //pic x and y
                            GetYSize().width, GetYSize().height,
                            GetYStride(), GetCbCrStride(),
-                           result->Stride(),
+                           map.mStride,
                            gfx::YV12);
-  result->MarkDirty();
+  result->Unmap();
   return result.forget();
 }
 
 
 } // namespace
 } // namespace
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -525,17 +525,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
   }
 
   buffer->PopClip();
 }
 
 void
 BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
                             const gfx::Rect *aClipRectIn,
-                            const gfxMatrix& aTransform,
+                            const gfx::Matrix& aTransform,
                             const gfx::Rect& aRenderBounds,
                             gfx::Rect *aClipRectOut /* = nullptr */,
                             gfx::Rect *aRenderBoundsOut /* = nullptr */)
 {
   nsIntRect intRect;
   mWidget->GetClientBounds(intRect);
   Rect rect = Rect(0, 0, intRect.width, intRect.height);
 
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -81,22 +81,22 @@ public:
   virtual void DrawQuad(const gfx::Rect& aRect,
                         const gfx::Rect& aClipRect,
                         const EffectChain &aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE;
 
   virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
                           const gfx::Rect *aClipRectIn,
-                          const gfxMatrix& aTransform,
+                          const gfx::Matrix& aTransform,
                           const gfx::Rect& aRenderBounds,
                           gfx::Rect *aClipRectOut = nullptr,
                           gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
   virtual void EndFrame() MOZ_OVERRIDE;
-  virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE
+  virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE
   {
     NS_RUNTIMEABORT("We shouldn't ever hit this");
   }
   virtual void AbortFrame() MOZ_OVERRIDE;
 
   virtual bool SupportsPartialTextureUpdate() { return true; }
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE { return true; }
   virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE { return INT32_MAX; }
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -15,17 +15,16 @@
 #include "GeckoProfiler.h"              // for profiler_set_frame_number, etc
 #include "ImageLayerComposite.h"        // for ImageLayerComposite
 #include "Layers.h"                     // for Layer, ContainerLayer, etc
 #include "ThebesLayerComposite.h"       // for ThebesLayerComposite
 #include "TiledLayerBuffer.h"           // for TiledLayerComposer
 #include "Units.h"                      // for ScreenIntRect
 #include "gfx2DGlue.h"                  // for ToMatrix4x4
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxMatrix.h"                  // for gfxMatrix
 #include "gfxPlatform.h"                // for gfxPlatform
 #ifdef XP_MACOSX
 #include "gfxPlatformMac.h"
 #endif
 #include "gfxRect.h"                    // for gfxRect
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef
 #include "mozilla/gfx/2D.h"             // for DrawTarget
@@ -411,36 +410,36 @@ LayerManagerComposite::Render()
   }
 
   mCompositor->GetWidget()->PostRender(this);
 
   RecordFrame();
 }
 
 void
-LayerManagerComposite::SetWorldTransform(const gfxMatrix& aMatrix)
+LayerManagerComposite::SetWorldTransform(const gfx::Matrix& aMatrix)
 {
   NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
                "SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
   NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
                "SetWorldTransform only accepts matrices with integer scale");
 
   mWorldMatrix = aMatrix;
 }
 
-gfxMatrix&
+gfx::Matrix&
 LayerManagerComposite::GetWorldTransform(void)
 {
   return mWorldMatrix;
 }
 
 void
 LayerManagerComposite::WorldTransformRect(nsIntRect& aRect)
 {
-  gfxRect grect(aRect.x, aRect.y, aRect.width, aRect.height);
+  gfx::Rect grect(aRect.x, aRect.y, aRect.width, aRect.height);
   grect = mWorldMatrix.TransformBounds(grect);
   aRect.SetRect(grect.X(), grect.Y(), grect.Width(), grect.Height());
 }
 
 static void
 SubtractTransformedRegion(nsIntRegion& aRegion,
                           const nsIntRegion& aRegionToSubtract,
                           const gfx3DMatrix& aTransform)
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -5,17 +5,16 @@
 
 #ifndef GFX_LayerManagerComposite_H
 #define GFX_LayerManagerComposite_H
 
 #include <stdint.h>                     // for int32_t, uint32_t
 #include "GLDefs.h"                     // for GLenum
 #include "Layers.h"
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
-#include "gfxMatrix.h"                  // for gfxMatrix
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/gfx/Rect.h"           // for Rect
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend, etc
@@ -157,18 +156,18 @@ public:
     DontApplyWorldTransform
   };
 
   /**
    * Setup World transform matrix.
    * Transform will be ignored if it is not PreservesAxisAlignedRectangles
    * or has non integer scale
    */
-  void SetWorldTransform(const gfxMatrix& aMatrix);
-  gfxMatrix& GetWorldTransform(void);
+  void SetWorldTransform(const gfx::Matrix& aMatrix);
+  gfx::Matrix& GetWorldTransform(void);
 
   /**
    * RAII helper class to add a mask effect with the compositable from aMaskLayer
    * to the EffectChain aEffect and notify the compositable when we are done.
    */
   class AutoAddMaskEffect
   {
   public:
@@ -254,17 +253,17 @@ private:
    * Render debug overlays such as the FPS/FrameCounter above the frame.
    */
   void RenderDebugOverlay(const gfx::Rect& aBounds);
 
   void WorldTransformRect(nsIntRect& aRect);
 
   RefPtr<Compositor> mCompositor;
 
-  gfxMatrix mWorldMatrix;
+  gfx::Matrix mWorldMatrix;
 
   bool mInTransaction;
   bool mIsCompositorReady;
   nsIntRegion mInvalidRegion;
   nsAutoPtr<LayerProperties> mClonedLayerTreeProperties;
   bool mDebugOverlayWantsNextFrame;
 };
 
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -664,17 +664,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
   if (restoreBlendMode) {
     mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
   }
 }
 
 void
 CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
                             const Rect* aClipRectIn,
-                            const gfxMatrix& aTransform,
+                            const gfx::Matrix& aTransform,
                             const Rect& aRenderBounds,
                             Rect* aClipRectOut,
                             Rect* aRenderBoundsOut)
 {
   // Don't composite if we are minimised. Other than for the sake of efficency,
   // this is important because resizing our buffers when mimised will fail and
   // cause a crash when we're restored.
   NS_ASSERTION(mHwnd, "Couldn't find an HWND when initialising?");
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -97,31 +97,31 @@ public:
                         const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE;
 
   /**
    * Start a new frame. If aClipRectIn is null, sets *aClipRectOut to the
    * screen dimensions. 
    */
   virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
                           const gfx::Rect *aClipRectIn,
-                          const gfxMatrix& aTransform,
+                          const gfx::Matrix& aTransform,
                           const gfx::Rect& aRenderBounds,
                           gfx::Rect *aClipRectOut = nullptr,
                           gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
 
   /**
    * Flush the current frame to the screen.
    */
   virtual void EndFrame() MOZ_OVERRIDE;
 
   /**
    * Post rendering stuff if the rendering is outside of this Compositor
    * e.g., by Composer2D
    */
-  virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE {}
+  virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE {}
 
   /**
    * Tidy up if BeginFrame has been called, but EndFrame won't be
    */
   virtual void AbortFrame() MOZ_OVERRIDE {}
 
   /**
    * Setup the viewport and projection matrix for rendering
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -581,17 +581,17 @@ CancelCompositing(Rect* aRenderBoundsOut
   if (aRenderBoundsOut) {
     *aRenderBoundsOut = Rect(0, 0, 0, 0);
   }
 }
 
 void
 CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion,
                            const Rect *aClipRectIn,
-                           const gfxMatrix& aTransform,
+                           const gfx::Matrix& aTransform,
                            const Rect& aRenderBounds,
                            Rect *aClipRectOut,
                            Rect *aRenderBoundsOut)
 {
   MOZ_ASSERT(mDeviceManager && mSwapChain);
 
   mDeviceManager->SetupRenderState();
 
--- a/gfx/layers/d3d9/CompositorD3D9.h
+++ b/gfx/layers/d3d9/CompositorD3D9.h
@@ -58,24 +58,24 @@ public:
   virtual void DrawQuad(const gfx::Rect &aRect,
                         const gfx::Rect &aClipRect,
                         const EffectChain &aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE;
 
   virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
                           const gfx::Rect *aClipRectIn,
-                          const gfxMatrix& aTransform,
+                          const gfx::Matrix& aTransform,
                           const gfx::Rect& aRenderBounds,
                           gfx::Rect *aClipRectOut = nullptr,
                           gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
 
   virtual void EndFrame() MOZ_OVERRIDE;
 
-  virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE {}
+  virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE {}
 
   virtual void AbortFrame() MOZ_OVERRIDE {}
 
   virtual void PrepareViewport(const gfx::IntSize& aSize,
                                const gfxMatrix& aWorldTransform) MOZ_OVERRIDE;
 
   virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE{ return true; }
 
--- a/gfx/layers/opengl/Composer2D.h
+++ b/gfx/layers/opengl/Composer2D.h
@@ -21,19 +21,22 @@
  *
  * Composer2D is a very simple interface to this class of hardware
  * that allows an implementation to "try rendering" with the fast
  * path.  If the given layer tree requires more generality than the
  * hardware provides, the implementation should bail and have the
  * layer manager fall back on full GPU composition.
  */
 
-struct gfxMatrix;
+namespace mozilla {
 
-namespace mozilla {
+namespace gfx {
+struct Matrix;
+}
+
 namespace layers {
 
 class Layer;
 
 class Composer2D {
   NS_INLINE_DECL_REFCOUNTING(Composer2D)
 
 public:
@@ -48,15 +51,15 @@ public:
    * rendering to the framebuffer.  This is a global transform on the
    * entire scene, defined in GL space.  If the Composer2D
    * implementation is unable to honor the transform, it should return
    * false.
    *
    * Currently, when TryRender() returns true, the entire framebuffer
    * must have been rendered.
    */
-  virtual bool TryRender(Layer* aRoot, const gfxMatrix& aWorldTransform) = 0;
+  virtual bool TryRender(Layer* aRoot, const gfx::Matrix& aWorldTransform) = 0;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_Composer2D_h
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -765,48 +765,48 @@ CalculatePOTSize(const IntSize& aSize, G
     return aSize;
 
   return IntSize(NextPowerOfTwo(aSize.width), NextPowerOfTwo(aSize.height));
 }
 
 void
 CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
                           const Rect *aClipRectIn,
-                          const gfxMatrix& aTransform,
+                          const gfx::Matrix& aTransform,
                           const Rect& aRenderBounds,
                           Rect *aClipRectOut,
                           Rect *aRenderBoundsOut)
 {
   PROFILER_LABEL("CompositorOGL", "BeginFrame");
   MOZ_ASSERT(!mFrameInProgress, "frame still in progress (should have called EndFrame or AbortFrame");
 
   LayerScope::BeginFrame(mGLContext, PR_Now());
 
   mVBOs.Reset();
 
   mFrameInProgress = true;
-  gfxRect rect;
+  gfx::Rect rect;
   if (mUseExternalSurfaceSize) {
-    rect = gfxRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
+    rect = gfx::Rect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
   } else {
-    rect = gfxRect(aRenderBounds.x, aRenderBounds.y, aRenderBounds.width, aRenderBounds.height);
+    rect = gfx::Rect(aRenderBounds.x, aRenderBounds.y, aRenderBounds.width, aRenderBounds.height);
     // If render bounds is not updated explicitly, try to infer it from widget
     if (rect.width == 0 || rect.height == 0) {
       // FIXME/bug XXXXXX this races with rotation changes on the main
       // thread, and undoes all the care we take with layers txns being
       // sent atomically with rotation changes
       nsIntRect intRect;
       mWidget->GetClientBounds(intRect);
-      rect = gfxRect(0, 0, intRect.width, intRect.height);
+      rect = gfx::Rect(0, 0, intRect.width, intRect.height);
     }
   }
 
   rect = aTransform.TransformBounds(rect);
   if (aRenderBoundsOut) {
-    *aRenderBoundsOut = Rect(rect.x, rect.y, rect.width, rect.height);
+    *aRenderBoundsOut = rect;
   }
 
   GLint width = rect.width;
   GLint height = rect.height;
 
   // We can't draw anything to something with no area
   // so just return
   if (width == 0 || height == 0)
@@ -829,17 +829,17 @@ CompositorOGL::BeginFrame(const nsIntReg
   mPixelsFilled = 0;
 
 #if MOZ_ANDROID_OMTC
   TexturePoolOGL::Fill(gl());
 #endif
 
   mCurrentRenderTarget = CompositingRenderTargetOGL::RenderTargetForWindow(this,
                             IntSize(width, height),
-                            aTransform);
+                            ThebesMatrix(aTransform));
   mCurrentRenderTarget->BindRenderTarget();
 #ifdef DEBUG
   mWindowRenderTarget = mCurrentRenderTarget;
 #endif
 
   // Default blend function implements "OVER"
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                  LOCAL_GL_ONE, LOCAL_GL_ONE);
@@ -1422,30 +1422,30 @@ CompositorOGL::EndFrame()
     mFPS->DrawFPS(TimeStamp::Now(), unsigned(fillRatio), mGLContext, GetProgram(RGBXLayerProgramType));
   }
 
   mGLContext->SwapBuffers();
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 }
 
 void
-CompositorOGL::EndFrameForExternalComposition(const gfxMatrix& aTransform)
+CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform)
 {
   if (sDrawFPS) {
     if (!mFPS) {
       mFPS = new FPSState();
     }
     double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());
     printf_stderr("HWComposer: FPS is %g\n", fps);
   }
 
   // This lets us reftest and screenshot content rendered externally
   if (mTarget) {
     MakeCurrent();
-    CopyToTarget(mTarget, aTransform);
+    CopyToTarget(mTarget, ThebesMatrix(aTransform));
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
   }
 }
 
 void
 CompositorOGL::AbortFrame()
 {
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
@@ -1482,24 +1482,27 @@ CompositorOGL::CopyToTarget(DrawTarget *
   if (!mGLContext->IsGLES2()) {
     // GLES2 promises that binding to any custom FBO will attach
     // to GL_COLOR_ATTACHMENT0 attachment point.
     mGLContext->fReadBuffer(LOCAL_GL_BACK);
   }
 
   RefPtr<DataSourceSurface> source =
         Factory::CreateDataSourceSurface(rect.Size(), gfx::SurfaceFormat::B8G8R8A8);
+
+  DataSourceSurface::MappedSurface map;
+  source->Map(DataSourceSurface::MapType::WRITE, &map);
   // XXX we should do this properly one day without using the gfxImageSurface
   nsRefPtr<gfxImageSurface> surf =
-    new gfxImageSurface(source->GetData(),
+    new gfxImageSurface(map.mData,
                         gfxIntSize(width, height),
-                        source->Stride(),
+                        map.mStride,
                         gfxImageFormatARGB32);
   ReadPixelsIntoImageSurface(mGLContext, surf);
-  source->MarkDirty();
+  source->Unmap();
 
   // Map from GL space to Cairo space and reverse the world transform.
   Matrix glToCairoTransform = ToMatrix(aTransform);
   glToCairoTransform.Invert();
   glToCairoTransform.Scale(1.0, -1.0);
   glToCairoTransform.Translate(0.0, -height);
 
   Matrix oldMatrix = aTarget->GetTransform();
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -107,17 +107,17 @@ public:
   virtual void DrawLines(const std::vector<gfx::Point>& aLines,
                          const gfx::Rect& aClipRect,
                          const gfx::Color& aColor,
                          gfx::Float aOpacity,
                          const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE;
 
 
   virtual void EndFrame() MOZ_OVERRIDE;
-  virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE;
+  virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE;
   virtual void AbortFrame() MOZ_OVERRIDE;
 
   virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE;
 
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE
   {
     if (!mGLContext)
       return false;
@@ -252,18 +252,18 @@ private:
    */
   bool mFrameInProgress;
 
   /* Start a new frame. If aClipRectIn is null and aClipRectOut is non-null,
    * sets *aClipRectOut to the screen dimensions.
    */
   virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
                           const gfx::Rect *aClipRectIn,
-                          const gfxMatrix& aTransform,
-                          const gfx::Rect& aRenderBounds, 
+                          const gfx::Matrix& aTransform,
+                          const gfx::Rect& aRenderBounds,
                           gfx::Rect *aClipRectOut = nullptr,
                           gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
 
   ShaderProgramType GetProgramTypeForEffect(Effect* aEffect) const;
 
   /**
    * Updates all layer programs with a new projection matrix.
    */
--- a/gfx/src/nsScriptableRegion.cpp
+++ b/gfx/src/nsScriptableRegion.cpp
@@ -122,31 +122,31 @@ NS_IMETHODIMP nsScriptableRegion::Contai
 
 
 NS_IMETHODIMP nsScriptableRegion::GetRegion(nsIntRegion* outRgn)
 {
   *outRgn = mRegion;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::Value* aRects)
+NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandle<JS::Value> aRects)
 {
   uint32_t numRects = mRegion.GetNumRects();
 
   if (!numRects) {
-    *aRects = JSVAL_NULL;
+    aRects.setNull();
     return NS_OK;
   }
 
   JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4, nullptr));
   if (!destArray) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  *aRects = OBJECT_TO_JSVAL(destArray);
+  aRects.setObject(*destArray);
 
   uint32_t n = 0;
   nsIntRegionRectIterator iter(mRegion);
   const nsIntRect *rect;
 
   while ((rect = iter.Next())) {
     if (!JS_DefineElement(aCx, destArray, n, INT_TO_JSVAL(rect->x), nullptr, nullptr, JSPROP_ENUMERATE) ||
         !JS_DefineElement(aCx, destArray, n + 1, INT_TO_JSVAL(rect->y), nullptr, nullptr, JSPROP_ENUMERATE) ||
--- a/js/ductwork/debugger/JSDebugger.cpp
+++ b/js/ductwork/debugger/JSDebugger.cpp
@@ -31,17 +31,17 @@ JSDebugger::JSDebugger()
 {
 }
 
 JSDebugger::~JSDebugger()
 {
 }
 
 NS_IMETHODIMP
-JSDebugger::AddClass(const JS::Value &global, JSContext* cx)
+JSDebugger::AddClass(JS::Handle<JS::Value> global, JSContext* cx)
 {
   nsresult rv;
   nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
 
   if (!global.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/js/jsd/jsd_high.cpp
+++ b/js/jsd/jsd_high.cpp
@@ -355,28 +355,28 @@ jsd_DebugErrorHook(JSContext *cx, const 
     switch(errorReporter(jsdc, cx, message, report, errorReporterData))
     {
         case JSD_ERROR_REPORTER_PASS_ALONG:
             return true;
         case JSD_ERROR_REPORTER_RETURN:
             return false;
         case JSD_ERROR_REPORTER_DEBUG:
         {
-            jsval rval;
+            JS::RootedValue rval(cx);
             JSD_ExecutionHookProc   hook;
             void*                   hookData;
 
             /* local in case hook gets cleared on another thread */
             JSD_LOCK();
             hook = jsdc->debugBreakHook;
             hookData = jsdc->debugBreakHookData;
             JSD_UNLOCK();
 
             jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_DEBUG_REQUESTED,
-                                  hook, hookData, &rval);
+                                  hook, hookData, rval.address());
             /* XXX Should make this dependent on ExecutionHook retval */
             return true;
         }
         case JSD_ERROR_REPORTER_CLEAR_RETURN:
             if(report && JSREPORT_IS_EXCEPTION(report->flags))
                 JS_ClearPendingException(cx);
             return false;
         default:
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -2359,26 +2359,24 @@ NS_IMETHODIMP
 jsdValue::Refresh()
 {
     ASSERT_VALID_EPHEMERAL;
     JSD_RefreshValue (mCx, mValue);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-jsdValue::GetWrappedValue(JSContext* aCx, JS::Value* aRetval)
+jsdValue::GetWrappedValue(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval)
 {
     ASSERT_VALID_EPHEMERAL;
 
-    JS::RootedValue value(aCx, JSD_GetValueWrappedJSVal(mCx, mValue));
-    if (!JS_WrapValue(aCx, &value)) {
+    aRetval.set(JSD_GetValueWrappedJSVal(mCx, mValue));
+    if (!JS_WrapValue(aCx, aRetval))
         return NS_ERROR_FAILURE;
-    }
-
-    *aRetval = value;
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdValue::GetScript(jsdIScript **_rval)
 {
     ASSERT_VALID_EPHEMERAL;
     JSDScript *script = JSD_GetScriptForValue(mCx, mValue);
@@ -2982,17 +2980,17 @@ jsdService::ClearAllBreakpoints (void)
 
     JSD_LockScriptSubsystem(mCx);
     JSD_ClearAllExecutionHooks (mCx);
     JSD_UnlockScriptSubsystem(mCx);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-jsdService::WrapValue(const JS::Value &value, jsdIValue **_rval)
+jsdService::WrapValue(JS::Handle<JS::Value> value, jsdIValue **_rval)
 {
     ASSERT_VALID_CONTEXT;
     JSDValue *jsdv = JSD_NewValue(mCx, value);
     if (!jsdv)
         return NS_ERROR_FAILURE;
     
     *_rval = jsdValue::FromPtr (mCx, jsdv);
     return NS_OK;
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -451,17 +451,17 @@ JSVAL_IS_STRING_IMPL(jsval_layout l)
 {
     return l.s.tag == JSVAL_TAG_STRING;
 }
 
 static inline jsval_layout
 STRING_TO_JSVAL_IMPL(JSString *str)
 {
     jsval_layout l;
-    MOZ_ASSERT(str);
+    MOZ_ASSERT(uintptr_t(str) > 0x1000);
     l.s.tag = JSVAL_TAG_STRING;
     l.s.payload.str = str;
     return l;
 }
 
 static inline JSString *
 JSVAL_TO_STRING_IMPL(jsval_layout l)
 {
@@ -519,17 +519,17 @@ JSVAL_TO_OBJECT_IMPL(jsval_layout l)
 {
     return l.s.payload.obj;
 }
 
 static inline jsval_layout
 OBJECT_TO_JSVAL_IMPL(JSObject *obj)
 {
     jsval_layout l;
-    MOZ_ASSERT(obj);
+    MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x42);
     l.s.tag = JSVAL_TAG_OBJECT;
     l.s.payload.obj = obj;
     return l;
 }
 
 static inline bool
 JSVAL_IS_NULL_IMPL(jsval_layout l)
 {
@@ -673,17 +673,17 @@ JSVAL_IS_STRING_IMPL(jsval_layout l)
     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING;
 }
 
 static inline jsval_layout
 STRING_TO_JSVAL_IMPL(JSString *str)
 {
     jsval_layout l;
     uint64_t strBits = (uint64_t)str;
-    MOZ_ASSERT(str);
+    MOZ_ASSERT(uintptr_t(str) > 0x1000);
     MOZ_ASSERT((strBits >> JSVAL_TAG_SHIFT) == 0);
     l.asBits = strBits | JSVAL_SHIFTED_TAG_STRING;
     return l;
 }
 
 static inline JSString *
 JSVAL_TO_STRING_IMPL(jsval_layout l)
 {
@@ -744,17 +744,17 @@ JSVAL_TO_OBJECT_IMPL(jsval_layout l)
     return (JSObject *)ptrBits;
 }
 
 static inline jsval_layout
 OBJECT_TO_JSVAL_IMPL(JSObject *obj)
 {
     jsval_layout l;
     uint64_t objBits = (uint64_t)obj;
-    MOZ_ASSERT(obj);
+    MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x42);
     MOZ_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
     l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT;
     return l;
 }
 
 static inline bool
 JSVAL_IS_NULL_IMPL(jsval_layout l)
 {
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1473,17 +1473,17 @@ static const JSFunctionSpecWithHelp Test
 "    5: Verify pre write barriers between paints\n"
 "    6: Verify stack rooting\n"
 "    7: Collect the nursery every N nursery allocations\n"
 "    8: Incremental GC in two slices: 1) mark roots 2) finish collection\n"
 "    9: Incremental GC in two slices: 1) mark all 2) new marking and finish\n"
 "   10: Incremental GC in multiple slices\n"
 "   11: Verify post write barriers between instructions\n"
 "   12: Verify post write barriers between paints\n"
-"   13: Purge analysis state when memory is allocated\n"
+"   13: Check internal hashtables on minor GC\n"
 "  Period specifies that collection happens every n allocations.\n"),
 
     JS_FN_HELP("schedulegc", ScheduleGC, 1, 0,
 "schedulegc(num | obj)",
 "  If num is given, schedule a GC after num allocations.\n"
 "  If obj is given, schedule a GC of obj's compartment."),
 
     JS_FN_HELP("selectforgc", SelectForGC, 0, 0,
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4457,16 +4457,18 @@ dnl ====================================
 
 AC_HAVE_FUNCS(setlocale)
 AC_HAVE_FUNCS(localeconv)
 
 AC_SUBST(MOZILLA_VERSION)
 
 AC_SUBST(ac_configure_args)
 
+AC_SUBST(TOOLCHAIN_PREFIX)
+
 dnl Spit out some output
 dnl ========================================================
 
 AC_OUTPUT()
 
 # Produce the js-config script at configure time; see the comments for
 # 'js*-config' in Makefile.in.
 AC_MSG_RESULT(invoking $MAKE to create $JS_CONFIG_NAME script)
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -607,24 +607,26 @@ js::Nursery::MinorGCCallback(JSTracer *j
     MinorCollectionTracer *trc = static_cast<MinorCollectionTracer *>(jstrc);
     if (ShouldMoveToTenured(trc, thingp))
         *thingp = trc->nursery->moveToTenured(trc, static_cast<JSObject *>(*thingp));
 }
 
 static void
 CheckHashTablesAfterMovingGC(JSRuntime *rt)
 {
-#if defined(DEBUG)
-    /* Check that internal hash tables no longer have any pointers into the nursery. */
-    for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
-        c->checkNewTypeObjectTableAfterMovingGC();
-        c->checkInitialShapesTableAfterMovingGC();
-        c->checkWrapperMapAfterMovingGC();
-        if (c->debugScopes)
-            c->debugScopes->checkHashTablesAfterMovingGC(rt);
+#ifdef JS_GC_ZEAL
+    if (rt->gcZeal() == ZealCheckHashTablesOnMinorGC) {
+        /* Check that internal hash tables no longer have any pointers into the nursery. */
+        for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
+            c->checkNewTypeObjectTableAfterMovingGC();
+            c->checkInitialShapesTableAfterMovingGC();
+            c->checkWrapperMapAfterMovingGC();
+            if (c->debugScopes)
+                c->debugScopes->checkHashTablesAfterMovingGC(rt);
+        }
     }
 #endif
 }
 
 void
 js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList *pretenureTypes)
 {
     JS_AbortIfWrongThread(rt);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/arguments/bug956173.js
@@ -0,0 +1,6 @@
+function foo() {
+    let (x=arguments) {
+      return function() { return x; };
+    }
+}
+foo()();
--- a/js/src/jit/BaselineFrame.cpp
+++ b/js/src/jit/BaselineFrame.cpp
@@ -31,17 +31,17 @@ BaselineFrame::trace(JSTracer *trc)
     }
 
     // Mark scope chain, if it exists.
     if (scopeChain_)
         gc::MarkObjectRoot(trc, &scopeChain_, "baseline-scopechain");
 
     // Mark return value.
     if (hasReturnValue())
-        gc::MarkValueRoot(trc, returnValue(), "baseline-rval");
+        gc::MarkValueRoot(trc, returnValue().address(), "baseline-rval");
 
     if (isEvalFrame())
         gc::MarkScriptRoot(trc, &evalScript_, "baseline-evalscript");
 
     if (hasArgsObj())
         gc::MarkObjectRoot(trc, &argsObj_, "baseline-args-obj");
 
     // Mark locals and stack values.
--- a/js/src/jit/BaselineFrame.h
+++ b/js/src/jit/BaselineFrame.h
@@ -195,22 +195,22 @@ class BaselineFrame
                          offsetOfArg(0));
     }
 
     bool copyRawFrameSlots(AutoValueVector *vec) const;
 
     bool hasReturnValue() const {
         return flags_ & HAS_RVAL;
     }
-    Value *returnValue() {
-        return reinterpret_cast<Value *>(&loReturnValue_);
+    MutableHandleValue returnValue() {
+        return MutableHandleValue::fromMarkedLocation(reinterpret_cast<Value *>(&loReturnValue_));
     }
     void setReturnValue(const Value &v) {
         flags_ |= HAS_RVAL;
-        *returnValue() = v;
+        returnValue().set(v);
     }
     inline Value *addressOfReturnValue() {
         return reinterpret_cast<Value *>(&loReturnValue_);
     }
 
     bool hasCallObj() const {
         return flags_ & HAS_CALL_OBJ;
     }
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -7421,21 +7421,21 @@ CodeGenerator::visitInstanceOfO(LInstanc
 }
 
 bool
 CodeGenerator::visitInstanceOfV(LInstanceOfV *ins)
 {
     return emitInstanceOf(ins, ins->mir()->prototypeObject());
 }
 
-// Wrap IsDelegate, which takes a Value for the lhs of an instanceof.
+// Wrap IsDelegateOfObject, which takes a JSObject*, not a HandleObject
 static bool
 IsDelegateObject(JSContext *cx, HandleObject protoObj, HandleObject obj, bool *res)
 {
-    return IsDelegate(cx, protoObj, ObjectValue(*obj), res);
+    return IsDelegateOfObject(cx, protoObj, obj, res);
 }
 
 typedef bool (*IsDelegateObjectFn)(JSContext *, HandleObject, HandleObject, bool *);
 static const VMFunction IsDelegateObjectInfo = FunctionInfo<IsDelegateObjectFn>(IsDelegateObject);
 
 bool
 CodeGenerator::emitInstanceOf(LInstruction *ins, JSObject *prototypeObject)
 {
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -341,16 +341,20 @@ ScriptAnalysis::analyzeBytecode(JSContex
           case JSOP_CALLELEM:
             numPropertyReads_++;
             break;
 
           case JSOP_FINALLY:
             hasTryFinally_ = true;
             break;
 
+          case JSOP_PUSHBLOCKSCOPE:
+            localsAliasStack_ = true;
+            break;
+
           default:
             break;
         }
 
         bool jump = IsJumpOpcode(op);
 
         /* Check basic jump opcodes, which may or may not have a fallthrough. */
         if (jump) {
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -118,18 +118,18 @@ static JSTrapStatus
 ThrowHook(JSContext *cx, JSScript *, jsbytecode *, jsval *rval, void *closure)
 {
     JS_ASSERT(!closure);
     calledThrowHook = true;
 
     JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
 
     char text[] = "new Error()";
-    jsval _;
-    JS_EvaluateScript(cx, global, text, strlen(text), "", 0, &_);
+    JS::RootedValue _(cx);
+    JS_EvaluateScript(cx, global, text, strlen(text), "", 0, _.address());
 
     return JSTRAP_CONTINUE;
 }
 
 BEGIN_TEST(testDebugger_throwHook)
 {
     CHECK(JS_SetDebugMode(cx, true));
     CHECK(JS_SetThrowHook(rt, ThrowHook, nullptr));
@@ -221,18 +221,18 @@ bool testIndirectEval(JS::HandleObject s
     EXEC("hits = 0;");
 
     {
         JSAutoCompartment ae(cx, scope);
         JSString *codestr = JS_NewStringCopyZ(cx, code);
         CHECK(codestr);
         jsval argv[1] = { STRING_TO_JSVAL(codestr) };
         JS::AutoArrayRooter rooter(cx, 1, argv);
-        jsval v;
-        CHECK(JS_CallFunctionName(cx, scope, "eval", 1, argv, &v));
+        JS::RootedValue v(cx);
+        CHECK(JS_CallFunctionName(cx, scope, "eval", 1, argv, v.address()));
     }
 
     JS::RootedValue hitsv(cx);
     EVAL("hits", hitsv.address());
     CHECK_SAME(hitsv, INT_TO_JSVAL(1));
     return true;
 }
 END_TEST(testDebugger_newScriptHook)
--- a/js/src/jsapi-tests/testOriginPrincipals.cpp
+++ b/js/src/jsapi-tests/testOriginPrincipals.cpp
@@ -46,32 +46,33 @@ BEGIN_TEST(testOriginPrincipals)
 
 static void
 ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     sOriginPrincipalsInErrorReporter = report->originPrincipals;
 }
 
 bool
-eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, jsval *rval)
+eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, JS::MutableHandleValue rval)
 {
     size_t len = strlen(asciiChars);
     jschar *chars = new jschar[len+1];
     for (size_t i = 0; i < len; ++i)
         chars[i] = asciiChars[i];
     chars[len] = 0;
 
     JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook));
     CHECK(global);
     JSAutoCompartment ac(cx, global);
     CHECK(JS_InitStandardClasses(cx, global));
     bool ok = JS_EvaluateUCScriptForPrincipalsVersionOrigin(cx, global,
                                                             principals,
                                                             originPrincipals,
-                                                            chars, len, "", 0, rval,
+                                                            chars, len, "", 0,
+							    rval.address(),
                                                             JSVERSION_DEFAULT);
     delete[] chars;
     return ok;
 }
 
 bool
 testOuter(const char *asciiChars)
 {
@@ -79,27 +80,27 @@ testOuter(const char *asciiChars)
     CHECK(testInner(asciiChars, &prin1, &prin2));
     return true;
 }
 
 bool
 testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal)
 {
     JS::RootedValue rval(cx);
-    CHECK(eval(asciiChars, principal, originPrincipal, rval.address()));
+    CHECK(eval(asciiChars, principal, originPrincipal, &rval));
 
     JSScript *script = JS_GetFunctionScript(cx, &rval.toObject().as<JSFunction>());
     CHECK(JS_GetScriptPrincipals(script) == principal);
     CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal);
 
     return true;
 }
 
 bool
 testError(const char *asciiChars)
 {
-    jsval rval;
+    JS::RootedValue rval(cx);
     CHECK(!eval(asciiChars, &prin1, &prin2 /* = originPrincipals */, &rval));
     CHECK(JS_ReportPendingException(cx));
     CHECK(sOriginPrincipalsInErrorReporter == &prin2);
     return true;
 }
 END_TEST(testOriginPrincipals)
--- a/js/src/jsapi-tests/testProfileStrings.cpp
+++ b/js/src/jsapi-tests/testProfileStrings.cpp
@@ -35,19 +35,19 @@ test_fn(JSContext *cx, unsigned argc, js
 {
     max_stack = psize;
     return true;
 }
 
 static bool
 test_fn2(JSContext *cx, unsigned argc, jsval *vp)
 {
-    jsval r;
+    JS::RootedValue r(cx);
     JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
-    return JS_CallFunctionName(cx, global, "d", 0, nullptr, &r);
+    return JS_CallFunctionName(cx, global, "d", 0, nullptr, r.address());
 }
 
 static bool
 enable(JSContext *cx, unsigned argc, jsval *vp)
 {
     js::EnableRuntimeProfilingStack(cx->runtime(), true);
     return true;
 }
--- a/js/src/jsapi-tests/testScriptObject.cpp
+++ b/js/src/jsapi-tests/testScriptObject.cpp
@@ -21,18 +21,18 @@ struct ScriptObjectFixture : public JSAP
     bool tryScript(JS::HandleObject global, JSScript *scriptArg)
     {
         JS::RootedScript script(cx, scriptArg);
         CHECK(script);
 
         JS_GC(rt);
 
         /* After a garbage collection, the script should still work. */
-        jsval result;
-        CHECK(JS_ExecuteScript(cx, global, script, &result));
+        JS::RootedValue result(cx);
+        CHECK(JS_ExecuteScript(cx, global, script, result.address()));
 
         return true;
     }
 };
 
 const char ScriptObjectFixture::code[] =
     "(function(a, b){return a+' '+b;}('hello', 'world'))";
 const int ScriptObjectFixture::code_size = sizeof(ScriptObjectFixture::code) - 1;
--- a/js/src/jsapi-tests/testStringBuffer.cpp
+++ b/js/src/jsapi-tests/testStringBuffer.cpp
@@ -16,14 +16,14 @@ BEGIN_TEST(testStringBuffer_finishString
     CHECK(str);
 
     JS::Rooted<JSAtom*> atom(cx, js::AtomizeString(cx, str));
     CHECK(atom);
 
     js::StringBuffer buffer(cx);
     CHECK(buffer.append("foopy"));
 
-    JSAtom *finishedAtom = buffer.finishAtom();
+    JS::Rooted<JSAtom*> finishedAtom(cx, buffer.finishAtom());
     CHECK(finishedAtom);
     CHECK_EQUAL(atom, finishedAtom);
     return true;
 }
 END_TEST(testStringBuffer_finishString)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2831,47 +2831,43 @@ JS_LookupUCProperty(JSContext *cx, JSObj
                     MutableHandleValue vp)
 {
     RootedObject obj(cx, objArg);
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     return atom && JS_LookupPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *objArg, jsid id_, unsigned flags,
-                               JSObject **objpArg, MutableHandleValue vp)
-{
-    RootedObject obj(cx, objArg);
-    RootedObject objp(cx, *objpArg);
-    RootedId id(cx, id_);
+JS_LookupPropertyWithFlagsById(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
+                               MutableHandleObject objp, MutableHandleValue vp)
+{
     RootedShape prop(cx);
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     if (!(obj->isNative()
-          ? LookupPropertyWithFlags(cx, obj, id, flags, &objp, &prop)
-          : JSObject::lookupGeneric(cx, obj, id, &objp, &prop)))
+          ? LookupPropertyWithFlags(cx, obj, id, flags, objp, &prop)
+          : JSObject::lookupGeneric(cx, obj, id, objp, &prop)))
         return false;
 
-    if (!LookupResult(cx, obj, objp, id, prop, vp))
-        return false;
-
-    *objpArg = objp;
-    return true;
+    return LookupResult(cx, obj, objp, id, prop, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_LookupPropertyWithFlags(JSContext *cx, JSObject *objArg, const char *name, unsigned flags,
+JS_LookupPropertyWithFlags(JSContext *cx, HandleObject obj, const char *name, unsigned flags,
                            MutableHandleValue vp)
 {
-    RootedObject obj(cx, objArg);
-    JSObject *obj2;
+    RootedObject obj2(cx);
     JSAtom *atom = Atomize(cx, name, strlen(name));
-    return atom && JS_LookupPropertyWithFlagsById(cx, obj, AtomToId(atom), flags, &obj2, vp);
+    if (!atom)
+        false;
+
+    RootedId id(cx, AtomToId(atom));
+    return JS_LookupPropertyWithFlagsById(cx, obj, id, flags, &obj2, vp);
 }
 
 JS_PUBLIC_API(bool)
 JS_HasPropertyById(JSContext *cx, JSObject *objArg, jsid idArg, bool *foundp)
 {
     RootedObject obj(cx, objArg);
     RootedId id(cx, idArg);
     RootedObject obj2(cx);
@@ -3088,21 +3084,20 @@ JS_DefineElement(JSContext *cx, JSObject
     RootedId id(cx);
     if (!IndexToId(cx, index, &id))
         return false;
     return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter),
                               SetterWrapper(setter), attrs, 0, 0);
 }
 
 static bool
-DefineProperty(JSContext *cx, HandleObject obj, const char *name, const Value &value_,
+DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleValue value,
                const JSPropertyOpWrapper &getter, const JSStrictPropertyOpWrapper &setter,
                unsigned attrs, unsigned flags, int tinyid)
 {
-    RootedValue value(cx, value_);
     AutoRooterGetterSetter gsRoot(cx, attrs, const_cast<JSPropertyOp *>(&getter.op),
                                   const_cast<JSStrictPropertyOp *>(&setter.op));
 
     RootedId id(cx);
     if (attrs & JSPROP_INDEX) {
         id.set(INT_TO_JSID(intptr_t(name)));
         attrs &= ~JSPROP_INDEX;
     } else {
@@ -3156,17 +3151,17 @@ DefineSelfHostedProperty(JSContext *cx,
         {
             return false;
         }
         JS_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
         setterFunc = &getterValue.toObject().as<JSFunction>();
     }
     JSStrictPropertyOp setterOp = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setterFunc.get());
 
-    return DefineProperty(cx, obj, name, UndefinedValue(),
+    return DefineProperty(cx, obj, name, JS::UndefinedHandleValue,
                           GetterWrapper(getterOp), SetterWrapper(setterOp),
                           attrs, flags, tinyid);
 }
 
 JS_PUBLIC_API(bool)
 JS_DefineProperty(JSContext *cx, JSObject *objArg, const char *name, jsval valueArg,
                   PropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
 {
@@ -3247,38 +3242,37 @@ JS_DefineObject(JSContext *cx, JSObject 
     const Class *clasp = Valueify(jsclasp);
     if (!clasp)
         clasp = &JSObject::class_;    /* default class is Object */
 
     RootedObject nobj(cx, NewObjectWithClassProto(cx, clasp, proto, obj));
     if (!nobj)
         return nullptr;
 
-    if (!DefineProperty(cx, obj, name, ObjectValue(*nobj), GetterWrapper(nullptr),
+    RootedValue nobjValue(cx, ObjectValue(*nobj));
+    if (!DefineProperty(cx, obj, name, nobjValue, GetterWrapper(nullptr),
                         SetterWrapper(nullptr), attrs, 0, 0))
-    {
         return nullptr;
-    }
 
     return nobj;
 }
 
 JS_PUBLIC_API(bool)
 JS_DefineConstDoubles(JSContext *cx, JSObject *objArg, const JSConstDoubleSpec *cds)
 {
     RootedObject obj(cx, objArg);
     bool ok;
     unsigned attrs;
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JSPropertyOpWrapper noget = GetterWrapper(nullptr);
     JSStrictPropertyOpWrapper noset = SetterWrapper(nullptr);
     for (ok = true; cds->name; cds++) {
-        Value value = DoubleValue(cds->dval);
+        RootedValue value(cx, DoubleValue(cds->dval));
         attrs = cds->flags;
         if (!attrs)
             attrs = JSPROP_READONLY | JSPROP_PERMANENT;
         ok = DefineProperty(cx, obj, cds->name, value, noget, noset, attrs, 0, 0);
         if (!ok)
             break;
     }
     return ok;
@@ -3294,17 +3288,17 @@ JS_DefineProperties(JSContext *cx, JSObj
             // If you declare native accessors, then you should have a native
             // getter.
             JS_ASSERT(ps->getter.propertyOp.op);
             // If you do not have a self-hosted getter, you should not have a
             // self-hosted setter. This is the closest approximation to that
             // assertion we can have with our setup.
             JS_ASSERT_IF(ps->setter.propertyOp.info, ps->setter.propertyOp.op);
 
-            ok = DefineProperty(cx, obj, ps->name, UndefinedValue(),
+            ok = DefineProperty(cx, obj, ps->name, JS::UndefinedHandleValue,
                                 ps->getter.propertyOp, ps->setter.propertyOp,
                                 ps->flags, Shape::HAS_SHORTID, ps->tinyid);
         } else {
             // If you have self-hosted getter/setter, you can't have a
             // native one.
             JS_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op);
             JS_ASSERT(ps->flags & JSPROP_GETTER);
             /*
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2802,22 +2802,22 @@ JS_HasPropertyById(JSContext *cx, JSObje
 
 extern JS_PUBLIC_API(bool)
 JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
-JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name,
+JS_LookupPropertyWithFlags(JSContext *cx, JS::HandleObject obj, const char *name,
                            unsigned flags, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
-JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *obj, jsid id,
-                               unsigned flags, JSObject **objp, JS::MutableHandleValue vp);
+JS_LookupPropertyWithFlagsById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
+                               unsigned flags, JS::MutableHandleObject objp, JS::MutableHandleValue vp);
 
 struct JSPropertyDescriptor {
     JSObject           *obj;
     unsigned           attrs;
     unsigned           shortid;
     JSPropertyOp       getter;
     JSStrictPropertyOp setter;
     JS::Value          value;
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -228,17 +228,17 @@ class WrapperMapRef : public BufferableR
         if (!p)
             return;
 
         /* Rekey the entry. */
         map->rekeyAs(prior, key, key);
     }
 };
 
-#ifdef DEBUG
+#ifdef JS_GC_ZEAL
 void
 JSCompartment::checkWrapperMapAfterMovingGC()
 {
     /*
      * Assert that the postbarriers have worked and that nothing is left in
      * wrapperMap that points into the nursery, and that the hash table entries
      * are discoverable.
      */
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -242,17 +242,17 @@ struct JSCompartment
     /* Set of initial shapes in the compartment. */
     js::InitialShapeSet          initialShapes;
     void sweepInitialShapeTable();
 
     /* Set of default 'new' or lazy types in the compartment. */
     js::types::TypeObjectWithNewScriptSet newTypeObjects;
     js::types::TypeObjectWithNewScriptSet lazyTypeObjects;
     void sweepNewTypeObjectTable(js::types::TypeObjectWithNewScriptSet &table);
-#if defined(DEBUG) && defined(JSGC_GENERATIONAL)
+#if defined(JSGC_GENERATIONAL) and defined(JS_GC_ZEAL)
     void checkNewTypeObjectTableAfterMovingGC();
     void checkInitialShapesTableAfterMovingGC();
     void checkWrapperMapAfterMovingGC();
 #endif
 
     /*
      * Hash table of all manually call site-cloned functions from within
      * self-hosted code. Cloning according to call site provides extra
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -1350,17 +1350,18 @@ const int ZealVerifierPreValue = 4;
 const int ZealFrameVerifierPreValue = 5;
 const int ZealStackRootingValue = 6;
 const int ZealGenerationalGCValue = 7;
 const int ZealIncrementalRootsThenFinish = 8;
 const int ZealIncrementalMarkAllThenFinish = 9;
 const int ZealIncrementalMultipleSlices = 10;
 const int ZealVerifierPostValue = 11;
 const int ZealFrameVerifierPostValue = 12;
-const int ZealLimit = 12;
+const int ZealCheckHashTablesOnMinorGC = 13;
+const int ZealLimit = 13;
 
 enum VerifierType {
     PreBarrierVerifier,
     PostBarrierVerifier
 };
 
 #ifdef JS_GC_ZEAL
 
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -4068,17 +4068,17 @@ ExclusiveContext::getNewType(const Class
             AddTypeProperty(this, type, "columnNumber", types::Type::Int32Type());
             AddTypeProperty(this, type, "stack", types::Type::StringType());
         }
     }
 
     return type;
 }
 
-#if defined(DEBUG) && defined(JSGC_GENERATIONAL)
+#if defined(JSGC_GENERATIONAL) and defined(JS_GC_ZEAL)
 void
 JSCompartment::checkNewTypeObjectTableAfterMovingGC()
 {
     /*
      * Assert that the postbarriers have worked and that nothing is left in
      * newTypeObjects that points into the nursery, and that the hash table
      * entries are discoverable.
      */
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5247,25 +5247,31 @@ js::CheckAccess(JSContext *cx, JSObject 
 
 bool
 js::IsDelegate(JSContext *cx, HandleObject obj, const js::Value &v, bool *result)
 {
     if (v.isPrimitive()) {
         *result = false;
         return true;
     }
-    RootedObject obj2(cx, &v.toObject());
+    return IsDelegateOfObject(cx, obj, &v.toObject(), result);
+}
+
+bool
+js::IsDelegateOfObject(JSContext *cx, HandleObject protoObj, JSObject* obj, bool *result)
+{
+    RootedObject obj2(cx, obj);
     for (;;) {
         if (!JSObject::getProto(cx, obj2, &obj2))
             return false;
         if (!obj2) {
             *result = false;
             return true;
         }
-        if (obj2 == obj) {
+        if (obj2 == protoObj) {
             *result = true;
             return true;
         }
     }
 }
 
 JSObject *
 js::GetClassPrototypePure(GlobalObject *global, JSProtoKey protoKey)
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1531,16 +1531,21 @@ HasDataProperty(JSContext *cx, JSObject 
 
 extern bool
 CheckAccess(JSContext *cx, JSObject *obj, HandleId id, JSAccessMode mode,
             MutableHandleValue v, unsigned *attrsp);
 
 extern bool
 IsDelegate(JSContext *cx, HandleObject obj, const Value &v, bool *result);
 
+// obj is a JSObject*, but we root it immediately up front. We do it
+// that way because we need a Rooted temporary in this method anyway.
+extern bool
+IsDelegateOfObject(JSContext *cx, HandleObject protoObj, JSObject* obj, bool *result);
+
 bool
 GetObjectElementOperationPure(ThreadSafeContext *cx, JSObject *obj, const Value &prop, Value *vp);
 
 /* Wrap boolean, number or string as Boolean, Number or String object. */
 extern JSObject *
 PrimitiveToObject(JSContext *cx, const Value &v);
 
 } /* namespace js */
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -874,17 +874,18 @@ Debugger::newCompletionValue(JSContext *
         return false;
     }
 
     result.setObject(*obj);
     return true;
 }
 
 bool
-Debugger::receiveCompletionValue(Maybe<AutoCompartment> &ac, bool ok, Value val,
+Debugger::receiveCompletionValue(Maybe<AutoCompartment> &ac, bool ok,
+                                 HandleValue val,
                                  MutableHandleValue vp)
 {
     JSContext *cx = ac.ref().context()->asJSContext();
 
     JSTrapStatus status;
     RootedValue value(cx);
     resultToCompletion(cx, ok, val, &status, &value);
     ac.destroy();
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -526,17 +526,18 @@ class Debugger : private mozilla::Linked
      *
      * Postcondition: we are in the debugger compartment, having called
      * ac.leave() even if an error occurred.
      *
      * On success, a completion value is in vp and ac.context does not have a
      * pending exception. (This ordinarily returns true even if the ok argument
      * is false.)
      */
-    bool receiveCompletionValue(mozilla::Maybe<AutoCompartment> &ac, bool ok, Value val,
+    bool receiveCompletionValue(mozilla::Maybe<AutoCompartment> &ac, bool ok,
+                                HandleValue val,
                                 MutableHandleValue vp);
 
     /*
      * Return the Debugger.Script object for |script|, or create a new one if
      * needed. The context |cx| must be in the debugger compartment; |script|
      * must be a script in a debuggee compartment.
      */
     JSObject *wrapScript(JSContext *cx, HandleScript script);
--- a/js/src/vm/ForkJoin.cpp
+++ b/js/src/vm/ForkJoin.cpp
@@ -141,16 +141,31 @@ js::InExclusiveParallelSection()
 }
 
 bool
 js::ParallelTestsShouldPass(JSContext *cx)
 {
     return false;
 }
 
+bool
+js::intrinsic_SetForkJoinTargetRegion(JSContext *cx, unsigned argc, Value *vp)
+{
+    return true;
+}
+
+static bool
+intrinsic_SetForkJoinTargetRegionPar(ForkJoinSlice *slice, unsigned argc, Value *vp)
+{
+    return true;
+}
+
+const JSJitInfo js::intrinsic_SetForkJoinTargetRegionInfo =
+    JS_JITINFO_NATIVE_PARALLEL(intrinsic_SetForkJoinTargetRegionPar);
+
 #endif // !JS_THREADSAFE || !JS_ION
 
 ///////////////////////////////////////////////////////////////////////////
 // All configurations
 //
 // Some code that is shared between degenerate and parallel configurations.
 
 static bool
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -1688,17 +1688,17 @@ DebugScopes::sweep(JSRuntime *rt)
          */
         if (IsObjectAboutToBeFinalized(&scope)) {
             e.removeFront();
             continue;
         }
     }
 }
 
-#if defined(DEBUG) && defined(JSGC_GENERATIONAL)
+#if defined(JSGC_GENERATIONAL) and defined(JS_GC_ZEAL)
 void
 DebugScopes::checkHashTablesAfterMovingGC(JSRuntime *runtime)
 {
     /*
      * This is called at the end of StoreBuffer::mark() to check that our
      * postbarriers have worked and that no hashtable keys (or values) are left
      * pointing into the nursery.
      */
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1655,17 +1655,17 @@ class InitialShapeSetRef : public Buffer
 
         /* Rekey the entry. */
         set->rekeyAs(lookup,
                      InitialShapeEntry::Lookup(clasp, proto, parent, metadata, nfixed, objectFlags),
                      *p);
     }
 };
 
-#ifdef DEBUG
+#ifdef JS_GC_ZEAL
 void
 JSCompartment::checkInitialShapesTableAfterMovingGC()
 {
     /*
      * Assert that the postbarriers have worked and that nothing is left in
      * initialShapes that points into the nursery, and that the hash table
      * entries are discoverable.
      */
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -358,23 +358,23 @@ AbstractFramePtr::setHookData(void *data
     }
 #ifdef JS_ION
     asBaselineFrame()->setHookData(data);
 #else
     MOZ_ASSUME_UNREACHABLE("Invalid frame");
 #endif
 }
 
-inline Value
+inline HandleValue
 AbstractFramePtr::returnValue() const
 {
     if (isStackFrame())
         return asStackFrame()->returnValue();
 #ifdef JS_ION
-    return *asBaselineFrame()->returnValue();
+    return asBaselineFrame()->returnValue();
 #else
     MOZ_ASSUME_UNREACHABLE("Invalid frame");
 #endif
 }
 
 inline void
 AbstractFramePtr::setReturnValue(const Value &rval) const
 {
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -370,17 +370,17 @@ StackFrame::mark(JSTracer *trc)
         gc::MarkObjectUnbarriered(trc, &exec.fun, "fun");
         if (isEvalFrame())
             gc::MarkScriptUnbarriered(trc, &u.evalScript, "eval script");
     } else {
         gc::MarkScriptUnbarriered(trc, &exec.script, "script");
     }
     if (IS_GC_MARKING_TRACER(trc))
         script()->compartment()->zone()->active = true;
-    gc::MarkValueUnbarriered(trc, &returnValue(), "rval");
+    gc::MarkValueUnbarriered(trc, returnValue().address(), "rval");
 }
 
 void
 StackFrame::markValues(JSTracer *trc, Value *sp)
 {
     JS_ASSERT(sp >= slots());
     gc::MarkValueRootRange(trc, sp - slots(), slots(), "vm_stack");
     if (hasArgs()) {
@@ -1135,17 +1135,17 @@ Value
 ScriptFrameIter::returnValue() const
 {
     switch (data_.state_) {
       case DONE:
         break;
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS())
-            return *data_.ionFrames_.baselineFrame()->returnValue();
+            return data_.ionFrames_.baselineFrame()->returnValue();
 #endif
         break;
       case SCRIPTED:
         return interpFrame()->returnValue();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -218,17 +218,17 @@ class AbstractFramePtr
 
     inline bool prevUpToDate() const;
     inline void setPrevUpToDate() const;
 
     JSObject *evalPrevScopeChain(JSContext *cx) const;
 
     inline void *maybeHookData() const;
     inline void setHookData(void *data) const;
-    inline Value returnValue() const;
+    inline HandleValue returnValue() const;
     inline void setReturnValue(const Value &rval) const;
 
     bool hasPushedSPSFrame() const;
 
     inline void popBlock(JSContext *cx) const;
     inline void popWith(JSContext *cx) const;
 };
 
@@ -768,20 +768,20 @@ class StackFrame
     }
 
     /* Return value */
 
     bool hasReturnValue() const {
         return !!(flags_ & HAS_RVAL);
     }
 
-    Value &returnValue() {
+    MutableHandleValue returnValue() {
         if (!(flags_ & HAS_RVAL))
             rval_.setUndefined();
-        return rval_;
+        return MutableHandleValue::fromMarkedLocation(&rval_);
     }
 
     void markReturnValue() {
         flags_ |= HAS_RVAL;
     }
 
     void setReturnValue(const Value &v) {
         rval_ = v;
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -21,17 +21,16 @@ class nsAXPCNativeCallContext;
 /***************************************************************************/
 
 // NB: jsval and jsid are declared in nsrootidl.idl
 
 [ptr] native JSContextPtr(JSContext);
 [ptr] native JSClassPtr(JSClass);
 [ptr] native JSFreeOpPtr(JSFreeOp);
 [ptr] native JSObjectPtr(JSObject);
-[ptr] native JSValPtr(JS::Value);
 [ptr] native JSValConstPtr(const JS::Value);
       native JSPropertyOp(JSPropertyOp);
       native JSEqualityOp(JSEqualityOp);
 [ptr] native JSScriptPtr(JSScript);
 [ptr] native voidPtrPtr(void*);
 [ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
 [ptr] native nsWrapperCachePtr(nsWrapperCache);
 [ref] native JSCompartmentOptions(JS::CompartmentOptions);
@@ -404,17 +403,17 @@ interface nsIXPConnect : nsISupports
            in JSObjectPtr  aJSObj,
            in nsIIDRef     aIID,
            [iid_is(aIID),retval] out nsQIResult result);
 
     /**
      * Wraps the given jsval in a nsIVariant and returns the new variant.
      */
     nsIVariant
-    jSValToVariant(in JSContextPtr cx, in JSValPtr aJSVal);
+    jSValToVariant(in JSContextPtr cx, in jsval aJSVal);
 
     /**
     * This only succeeds if the JSObject is a nsIXPConnectWrappedNative.
     * A new wrapper is *never* constructed.
     */
     nsIXPConnectWrappedNative
     getWrappedNativeOfJSObject(in JSContextPtr aJSContext,
                                in JSObjectPtr  aJSObj);
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -172,17 +172,17 @@ File(JSContext *cx, unsigned argc, Value
     }
 
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     JSObject* glob = CurrentGlobalOrNull(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
-                                true, args.rval().address());
+                                true, args.rval());
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
     return true;
 }
 
 static bool
@@ -207,17 +207,17 @@ Blob(JSContext *cx, unsigned argc, Value
     }
 
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     JSObject* glob = CurrentGlobalOrNull(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
-                                true, args.rval().address());
+                                true, args.rval());
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
     return true;
 }
 
 static const JSFunctionSpec gGlobalFun[] = {
@@ -1079,20 +1079,20 @@ mozJSComponentLoader::UnloadModules()
     JS_DestroyContextNoGC(mContext);
     mContext = nullptr;
 
     mRuntimeService = nullptr;
 }
 
 NS_IMETHODIMP
 mozJSComponentLoader::Import(const nsACString& registryLocation,
-                             const Value& targetValArg,
-                             JSContext* cx,
+                             HandleValue targetValArg,
+                             JSContext *cx,
                              uint8_t optionalArgc,
-                             Value* retval)
+                             MutableHandleValue retval)
 {
     MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 
     RootedValue targetVal(cx, targetValArg);
     RootedObject targetObject(cx, nullptr);
     if (optionalArgc) {
         // The caller passed in the optional second argument. Get it.
         if (targetVal.isObject()) {
@@ -1128,17 +1128,17 @@ mozJSComponentLoader::Import(const nsACS
     nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
 
     if (global) {
         if (!JS_WrapObject(cx, &global)) {
             NS_ERROR("can't wrap return value");
             return NS_ERROR_FAILURE;
         }
 
-        *retval = ObjectValue(*global);
+        retval.setObject(*global);
     }
     return rv;
 }
 
 /* [noscript] JSObjectPtr importInto(in AUTF8String registryLocation,
                                      in JSObjectPtr targetObj); */
 NS_IMETHODIMP
 mozJSComponentLoader::ImportInto(const nsACString & aLocation,
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -179,55 +179,58 @@ mozJSSubScriptLoader::ReadScript(nsIURI 
     /* repent for our evil deeds */
     JS_SetErrorReporter(cx, er);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
-                                    const Value& targetArg,
+                                    HandleValue target,
                                     const nsAString& charset,
-                                    JSContext* cx,
-                                    Value* retval)
+                                    JSContext *cx,
+                                    MutableHandleValue retval)
 {
     /*
      * Loads a local url and evals it into the current cx
      * Synchronous (an async version would be cool too.)
      *   url: The url to load.  Must be local so that it can be loaded
      *        synchronously.
      *   target_obj: Optional object to eval the script onto (defaults to context
      *               global)
      *   charset: Optional character set to use for reading
      *   returns: Whatever jsval the script pointed to by the url returns.
      * Should ONLY (O N L Y !) be called from JavaScript code.
      */
     LoadSubScriptOptions options(cx);
     options.charset = charset;
-    options.target = targetArg.isObject() ? &targetArg.toObject() : nullptr;
+    options.target = target.isObject() ? &target.toObject() : nullptr;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
 }
 
 
 NS_IMETHODIMP
-mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url, const Value& optionsVal,
-                                               JSContext* cx, Value* retval)
+mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url,
+                                               HandleValue optionsVal,
+                                               JSContext *cx,
+                                               MutableHandleValue retval)
 {
     if (!optionsVal.isObject())
         return NS_ERROR_INVALID_ARG;
     LoadSubScriptOptions options(cx, &optionsVal.toObject());
     if (!options.Parse())
         return NS_ERROR_INVALID_ARG;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
 }
 
 nsresult
 mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString& url,
                                                  LoadSubScriptOptions& options,
-                                                 JSContext* cx, Value* retval)
+                                                 JSContext *cx,
+                                                 MutableHandleValue retval)
 {
     nsresult rv = NS_OK;
 
     /* set the system principal if it's not here already */
     if (!mSystemPrincipal) {
         nsCOMPtr<nsIScriptSecurityManager> secman =
             do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
         if (!secman)
@@ -341,29 +344,28 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
         return rv;
 
     if (function) {
         script = JS_GetFunctionScript(cx, function);
     }
 
     loader->NoteSubScript(script, targetObj);
 
-    RootedValue rval(cx);
+
     bool ok = false;
     if (function) {
-        ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, rval.address());
+        ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, retval.address());
     } else {
-        ok = JS_ExecuteScriptVersion(cx, targetObj, script, rval.address(), version);
+        ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval.address(), version);
     }
 
     if (ok) {
         JSAutoCompartment rac(cx, result_obj);
-        if (!JS_WrapValue(cx, &rval))
+        if (!JS_WrapValue(cx, retval))
             return NS_ERROR_UNEXPECTED;
-        *retval = rval;
     }
 
     if (cache && ok && writeScript) {
         WriteCachedScript(cache, cachePath, cx, mSystemPrincipal, script);
     }
 
     return NS_OK;
 }
--- a/js/xpconnect/loader/mozJSSubScriptLoader.h
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.h
@@ -23,24 +23,25 @@ class nsIIOService;
 
 class mozJSSubScriptLoader : public mozIJSSubScriptLoader
 {
 public:
     mozJSSubScriptLoader();
     virtual ~mozJSSubScriptLoader();
 
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_MOZIJSSUBSCRIPTLOADER
 
 private:
     nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
                         const nsAString& charset, const char *uriStr,
                         nsIIOService *serv, nsIPrincipal *principal,
                         bool reuseGlobal, JSScript **scriptp,
                         JSFunction **functionp);
 
     nsresult DoLoadSubScriptWithOptions(const nsAString& url,
                                         LoadSubScriptOptions& options,
-                                        JSContext* cx, JS::Value* retval);
+                                        JSContext* cx,
+                                        JS::MutableHandle<JS::Value> retval);
 
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
 };
--- a/js/xpconnect/public/SandboxPrivate.h
+++ b/js/xpconnect/public/SandboxPrivate.h
@@ -20,17 +20,17 @@ class SandboxPrivate : public nsIGlobalO
 public:
     SandboxPrivate(nsIPrincipal *principal, JSObject *global)
         : mPrincipal(principal)
         , mGlobalJSObject(global)
     {
     }
     virtual ~SandboxPrivate() { }
 
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
 
     nsIPrincipal *GetPrincipal()
     {
         return mPrincipal;
     }
 
     JSObject *GetGlobalJSObject()
     {
--- a/js/xpconnect/public/xpc_map_end.h
+++ b/js/xpconnect/public/xpc_map_end.h
@@ -165,17 +165,17 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Call(ns
 #endif
 
 #ifndef XPC_MAP_WANT_CONSTRUCT
 NS_IMETHODIMP XPC_MAP_CLASSNAME::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const JS::CallArgs &args, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_HASINSTANCE
-NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const JS::Value &val, bool *bp, bool *_retval)
+NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JS::HandleValue val, bool *bp, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_OUTER_OBJECT
 NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
--- a/js/xpconnect/src/BackstagePass.h
+++ b/js/xpconnect/src/BackstagePass.h
@@ -14,17 +14,17 @@
 
 class BackstagePass : public nsIGlobalObject,
                       public nsIScriptObjectPrincipal,
                       public nsIXPCScriptable,
                       public nsIClassInfo,
                       public nsSupportsWeakReference
 {
 public:
-  NS_DECL_THREADSAFE_ISUPPORTS
+  NS_DECL_ISUPPORTS
   NS_DECL_NSIXPCSCRIPTABLE
   NS_DECL_NSICLASSINFO
 
   virtual nsIPrincipal* GetPrincipal() {
     return mPrincipal;
   }
 
   virtual JSObject* GetGlobalJSObject() {
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -50,17 +50,17 @@ NS_IMPL_ISUPPORTS3(SandboxPrivate,
 
 const char kScriptSecurityManagerContractID[] = NS_SCRIPTSECURITYMANAGER_CONTRACTID;
 
 class nsXPCComponents_utils_Sandbox : public nsIXPCComponents_utils_Sandbox,
                                       public nsIXPCScriptable
 {
 public:
     // Aren't macros nice?
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_UTILS_SANDBOX
     NS_DECL_NSIXPCSCRIPTABLE
 
 public:
     nsXPCComponents_utils_Sandbox();
     virtual ~nsXPCComponents_utils_Sandbox();
 
 private:
@@ -688,17 +688,17 @@ nsXPCComponents_utils_Sandbox::nsXPCComp
 nsXPCComponents_utils_Sandbox::~nsXPCComponents_utils_Sandbox()
 {
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_utils_Sandbox)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_utils_Sandbox)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_utils_Sandbox)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_utils_Sandbox)
 NS_IMPL_RELEASE(nsXPCComponents_utils_Sandbox)
 
 // We use the nsIXPScriptable macros to generate lots of stuff for us.
 #define XPC_MAP_CLASSNAME           nsXPCComponents_utils_Sandbox
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_utils_Sandbox"
 #define                             XPC_MAP_WANT_CALL
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -89,17 +89,17 @@ xpc::CheckAccessList(const char16_t *wid
 
 class nsXPCComponents_Interfaces :
             public nsIXPCComponents_Interfaces,
             public nsIXPCScriptable,
             public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_INTERFACES
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Interfaces();
     virtual ~nsXPCComponents_Interfaces();
 
@@ -211,17 +211,17 @@ nsXPCComponents_Interfaces::~nsXPCCompon
 }
 
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Interfaces)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Interfaces)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_Interfaces)
 NS_IMPL_RELEASE(nsXPCComponents_Interfaces)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_Interfaces
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Interfaces"
 #define                             XPC_MAP_WANT_NEWRESOLVE
@@ -299,18 +299,17 @@ nsXPCComponents_Interfaces::NewResolve(n
     // we only allow interfaces by name here
     if (name.encodeLatin1(cx, str) && name.ptr()[0] != '{') {
         nsCOMPtr<nsIInterfaceInfo> info;
         XPTInterfaceInfoManager::GetSingleton()->
             GetInfoForName(name.ptr(), getter_AddRefs(info));
         if (!info)
             return NS_OK;
 
-        nsCOMPtr<nsIJSIID> nsid =
-            dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
+        nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
 
         if (nsid) {
             nsXPConnect* xpc = nsXPConnect::XPConnect();
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSIID*>(nsid),
                                              NS_GET_IID(nsIJSIID),
                                              getter_AddRefs(holder)))) {
@@ -338,17 +337,17 @@ nsXPCComponents_Interfaces::NewResolve(n
 
 class nsXPCComponents_InterfacesByID :
             public nsIXPCComponents_InterfacesByID,
             public nsIXPCScriptable,
             public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_InterfacesByID();
     virtual ~nsXPCComponents_InterfacesByID();
 
@@ -460,17 +459,17 @@ nsXPCComponents_InterfacesByID::~nsXPCCo
     // empty
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_InterfacesByID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_InterfacesByID)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_InterfacesByID)
 NS_IMPL_RELEASE(nsXPCComponents_InterfacesByID)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_InterfacesByID
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_InterfacesByID"
 #define                             XPC_MAP_WANT_NEWRESOLVE
@@ -553,18 +552,17 @@ nsXPCComponents_InterfacesByID::NewResol
             return NS_OK;
 
         nsCOMPtr<nsIInterfaceInfo> info;
         XPTInterfaceInfoManager::GetSingleton()->
             GetInfoForIID(&iid, getter_AddRefs(info));
         if (!info)
             return NS_OK;
 
-        nsCOMPtr<nsIJSIID> nsid =
-            dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
+        nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
 
         if (!nsid)
             return NS_ERROR_OUT_OF_MEMORY;
 
         nsXPConnect* xpc = nsXPConnect::XPConnect();
         nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
         if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                          static_cast<nsIJSIID*>(nsid),
@@ -596,17 +594,17 @@ nsXPCComponents_InterfacesByID::NewResol
 
 class nsXPCComponents_Classes :
   public nsIXPCComponents_Classes,
   public nsIXPCScriptable,
   public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_CLASSES
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Classes();
     virtual ~nsXPCComponents_Classes();
 };
@@ -712,17 +710,17 @@ nsXPCComponents_Classes::~nsXPCComponent
     // empty
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_Classes)
 NS_IMPL_RELEASE(nsXPCComponents_Classes)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_Classes
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Classes"
 #define                             XPC_MAP_WANT_NEWRESOLVE
@@ -799,18 +797,17 @@ nsXPCComponents_Classes::NewResolve(nsIX
 {
     RootedId id(cx, idArg);
     RootedObject obj(cx, objArg);
 
     JSAutoByteString name;
     if (JSID_IS_STRING(id) &&
         name.encodeLatin1(cx, JSID_TO_STRING(id)) &&
         name.ptr()[0] != '{') { // we only allow contractids here
-        nsCOMPtr<nsIJSCID> nsid =
-            dont_AddRef(static_cast<nsIJSCID*>(nsJSCID::NewID(name.ptr())));
+        nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
         if (nsid) {
             nsXPConnect* xpc = nsXPConnect::XPConnect();
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSCID*>(nsid),
                                              NS_GET_IID(nsIJSCID),
                                              getter_AddRefs(holder)))) {
                 RootedObject idobj(cx);
@@ -837,17 +834,17 @@ nsXPCComponents_Classes::NewResolve(nsIX
 
 class nsXPCComponents_ClassesByID :
   public nsIXPCComponents_ClassesByID,
   public nsIXPCScriptable,
   public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_ClassesByID();
     virtual ~nsXPCComponents_ClassesByID();
 };
@@ -953,17 +950,17 @@ nsXPCComponents_ClassesByID::~nsXPCCompo
     // empty
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_ClassesByID)
 NS_IMPL_RELEASE(nsXPCComponents_ClassesByID)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_ClassesByID
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_ClassesByID"
 #define                             XPC_MAP_WANT_NEWRESOLVE
@@ -1060,18 +1057,17 @@ nsXPCComponents_ClassesByID::NewResolve(
     if (!JSID_IS_STRING(id))
         return NS_OK;
 
     JSAutoByteString name;
     RootedString str(cx, JSID_TO_STRING(id));
     if (name.encodeLatin1(cx, str) && name.ptr()[0] == '{' &&
         IsRegisteredCLSID(name.ptr())) // we only allow canonical CLSIDs here
     {
-        nsCOMPtr<nsIJSCID> nsid =
-            dont_AddRef(static_cast<nsIJSCID*>(nsJSCID::NewID(name.ptr())));
+        nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
         if (nsid) {
             nsXPConnect* xpc = nsXPConnect::XPConnect();
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSCID*>(nsid),
                                              NS_GET_IID(nsIJSCID),
                                              getter_AddRefs(holder)))) {
                 RootedObject idobj(cx);
@@ -1100,17 +1096,17 @@ nsXPCComponents_ClassesByID::NewResolve(
 
 class nsXPCComponents_Results :
   public nsIXPCComponents_Results,
   public nsIXPCScriptable,
   public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_RESULTS
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Results();
     virtual ~nsXPCComponents_Results();
 };
@@ -1218,17 +1214,17 @@ nsXPCComponents_Results::~nsXPCComponent
     // empty
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_Results)
 NS_IMPL_RELEASE(nsXPCComponents_Results)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_Results
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Results"
 #define                             XPC_MAP_WANT_NEWRESOLVE
@@ -1318,17 +1314,17 @@ nsXPCComponents_Results::NewResolve(nsIX
 
 class nsXPCComponents_ID :
   public nsIXPCComponents_ID,
   public nsIXPCScriptable,
   public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_ID
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 
 public:
     nsXPCComponents_ID();
     virtual ~nsXPCComponents_ID();
@@ -1440,17 +1436,17 @@ nsXPCComponents_ID::~nsXPCComponents_ID(
     // empty
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_ID)
 NS_IMPL_RELEASE(nsXPCComponents_ID)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_ID
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_ID"
 #define                             XPC_MAP_WANT_CALL
@@ -1519,35 +1515,34 @@ nsXPCComponents_ID::CallOrConstruct(nsIX
     args.rval().setObject(*newobj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                 JSContext *cx, JSObject *obj,
-                                const jsval &val, bool *bp, bool *_retval)
+                                HandleValue val, bool *bp, bool *_retval)
 {
-    RootedValue v(cx, val);
     if (bp)
-        *bp = JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIJSID));
+        *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
     return NS_OK;
 }
 
 /***************************************************************************/
 // JavaScript Constructor for nsIXPCException objects (Components.Exception)
 
 class nsXPCComponents_Exception :
   public nsIXPCComponents_Exception,
   public nsIXPCScriptable,
   public nsIClassInfo
 {
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_EXCEPTION
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 
 public:
     nsXPCComponents_Exception();
     virtual ~nsXPCComponents_Exception();
@@ -1659,17 +1654,17 @@ nsXPCComponents_Exception::~nsXPCCompone
     // empty
 }
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception)
-NS_INTERFACE_MAP_END_THREADSAFE
+NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsXPCComponents_Exception)
 NS_IMPL_RELEASE(nsXPCComponents_Exception)
 
 // The nsIXPCScriptable map declaration that will generate stubs for us...
 #define XPC_MAP_CLASSNAME           nsXPCComponents_Exception
 #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Exception"
 #define                             XPC_MAP_WANT_CALL
@@ -1885,17 +1880,17 @@ nsXPCComponents_Exception::CallOrConstru
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                        JSContext * cx, JSObject * obj,
-                                       const jsval &val, bool *bp,
+                                       HandleValue val, bool *bp,
                                        bool *_retval)
 {
     using namespace mozilla::dom;
 
     RootedValue v(cx, val);
     if (bp) {
         Exception* e;
         *bp = NS_SUCCEEDED(UNWRAP_OBJECT(Exception, v.toObjectOrNull(), e)) ||
@@ -1920,36 +1915,36 @@ class nsXPCConstructor :
   public nsIXPCConstructor,
   public nsIXPCScriptable,
   public nsIClassInfo
 {
 public:
     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID)
 public:
     // all the interface method declarations...
-    NS_DECL_THREADSAFE_ISUPPORTS
+    NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCONSTRUCTOR
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCConstructor(); // not implemented
     nsXPCConstructor(nsIJSCID* aClassID,
                      nsIJSIID* aInterfaceID,
                      const char* aInitializer);
     virtual ~nsXPCConstructor();
 
 private:
     nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,