Merge m-c to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 01 Oct 2015 14:16:12 +0200
changeset 265691 2cfe7f8440830f074c19c36a5aed3dca4725fbaa
parent 265690 d44a52b0faef48ef6d38df62eda63e78d391a7e7 (current diff)
parent 265532 2c1fb007137dcb68b1862a79553b53f1a34c99c3 (diff)
child 265692 7ac681cd9e4fadb5b6574d12d1a4126d24a67ef5
push id66003
push usercbook@mozilla.com
push dateFri, 02 Oct 2015 11:37:40 +0000
treeherdermozilla-inbound@3fd732d24f46 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone44.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
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
browser/themes/linux/browser.css
browser/themes/osx/browser.css
browser/themes/windows/browser.css
devtools/shared/heapsnapshot/tests/gtest/UniqueStringHashPolicy.cpp
js/src/jsapi-tests/testOps.cpp
layout/tools/reftest/print-manifest-dirs.py
testing/mozbase/Makefile.in
testing/mozharness/configs/builds/releng_sub_android_configs/64_api_11_partner_sample1.py
testing/taskcluster/tasks/builds/android_api_11_partner_sample1.yml
testing/testsuite-targets.mk
testing/web-platform/Makefile.in
testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-no-freshness-headers.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/onactivate-script-error.https.html.ini
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -34,16 +34,17 @@
 #include "nsIDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPropertyBag2.h"
 #include "nsIServiceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsReadableUtils.h"
 #include "nsFocusManager.h"
+#include "nsGlobalWindow.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #include "nsIXULWindow.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::a11y;
@@ -477,20 +478,19 @@ RootAccessible::Shutdown()
 }
 
 Relation
 RootAccessible::RelationByType(RelationType aType)
 {
   if (!mDocumentNode || aType != RelationType::EMBEDS)
     return DocAccessibleWrap::RelationByType(aType);
 
-  nsIDOMWindow* rootWindow = mDocumentNode->GetWindow();
+  nsPIDOMWindow* rootWindow = mDocumentNode->GetWindow();
   if (rootWindow) {
-    nsCOMPtr<nsIDOMWindow> contentWindow;
-    rootWindow->GetContent(getter_AddRefs(contentWindow));
+    nsCOMPtr<nsIDOMWindow> contentWindow = nsGlobalWindow::Cast(rootWindow)->GetContent();
     if (contentWindow) {
       nsCOMPtr<nsIDOMDocument> contentDOMDocument;
       contentWindow->GetDocument(getter_AddRefs(contentDOMDocument));
       nsCOMPtr<nsIDocument> contentDocumentNode =
         do_QueryInterface(contentDOMDocument);
       if (contentDocumentNode) {
         DocAccessible* contentDocument =
           GetAccService()->GetDocAccessible(contentDocumentNode);
--- a/b2g/components/MailtoProtocolHandler.js
+++ b/b2g/components/MailtoProtocolHandler.js
@@ -15,17 +15,17 @@ function MailtoProtocolHandler() {
 MailtoProtocolHandler.prototype = {
 
   scheme: "mailto",
   defaultPort: -1,
   protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
                  Ci.nsIProtocolHandler.URI_NOAUTH |
                  Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
                  Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA,
-  allowPort: function() false,
+  allowPort: () => false,
 
   newURI: function Proto_newURI(aSpec, aOriginCharset) {
     let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
     uri.spec = aSpec;
     return uri;
   },
 
   newChannel2: function Proto_newChannel2(aURI, aLoadInfo) {
--- a/b2g/components/SimulatorScreen.js
+++ b/b2g/components/SimulatorScreen.js
@@ -57,23 +57,23 @@ function hookScreen(window) {
 
   screen.mozUnlockOrientation = function() {
     debug('mozOrientationUnlock from', origin);
     GlobalSimulatorScreen.unlock();
     return true;
   };
 
   Object.defineProperty(screen, 'width', {
-    get: function () GlobalSimulatorScreen.width
+    get: () => GlobalSimulatorScreen.width
   });
   Object.defineProperty(screen, 'height', {
-    get: function () GlobalSimulatorScreen.height
+    get: () => GlobalSimulatorScreen.height
   });
   Object.defineProperty(screen, 'mozOrientation', {
-    get: function () GlobalSimulatorScreen.mozOrientation
+    get: () => GlobalSimulatorScreen.mozOrientation
   });
 }
 
 function SimulatorScreen() {}
 SimulatorScreen.prototype = {
   classID:         Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'),
   QueryInterface:  XPCOMUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsISupportsWeakReference]),
--- a/b2g/components/SmsProtocolHandler.js
+++ b/b2g/components/SmsProtocolHandler.js
@@ -24,17 +24,17 @@ function SmsProtocolHandler() {
 SmsProtocolHandler.prototype = {
 
   scheme: "sms",
   defaultPort: -1,
   protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
                  Ci.nsIProtocolHandler.URI_NOAUTH |
                  Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
                  Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA,
-  allowPort: function() false,
+  allowPort: () => false,
 
   newURI: function Proto_newURI(aSpec, aOriginCharset) {
     let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
     uri.spec = aSpec;
     return uri;
   },
 
   newChannel2: function Proto_newChannel2(aURI, aLoadInfo) {
--- a/b2g/components/TelProtocolHandler.js
+++ b/b2g/components/TelProtocolHandler.js
@@ -23,17 +23,17 @@ function TelProtocolHandler() {
 TelProtocolHandler.prototype = {
 
   scheme: "tel",
   defaultPort: -1,
   protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
                  Ci.nsIProtocolHandler.URI_NOAUTH |
                  Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
                  Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA,
-  allowPort: function() false,
+  allowPort: () => false,
 
   newURI: function Proto_newURI(aSpec, aOriginCharset) {
     let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
     uri.spec = aSpec;
     return uri;
   },
 
   newChannel2: function Proto_newChannel(aURI, aLoadInfo) {
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,20 +10,20 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,20 +10,20 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,18 +14,18 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12ff7481566587aa4198cf1287598acb3a999973"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,18 +12,18 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,19 +10,19 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,19 +10,19 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,18 +14,18 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12ff7481566587aa4198cf1287598acb3a999973"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,20 +10,20 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "be2da974ba076e06e2ff96cd3ac911769d3067a3", 
+        "git_revision": "bd8ff00faac97ad6a2df5a6217910b8d295d56a3", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "2194f873784f9366087ee7899640b58c7150dff4", 
+    "revision": "69bb3f2fc1245710dbca570a4dfaedf57d39f56b", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -10,20 +10,20 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -13,18 +13,18 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,20 +10,20 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd8ff00faac97ad6a2df5a6217910b8d295d56a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -180,16 +180,17 @@
 @RESPATH@/components/cookie.xpt
 @RESPATH@/components/devtools_security.xpt
 @RESPATH@/components/directory.xpt
 @RESPATH@/components/diskspacewatcher.xpt
 @RESPATH@/components/docshell.xpt
 @RESPATH@/components/dom.xpt
 @RESPATH@/components/dom_activities.xpt
 @RESPATH@/components/dom_apps.xpt
+@RESPATH@/components/dom_newapps.xpt
 @RESPATH@/components/dom_audiochannel.xpt
 @RESPATH@/components/dom_base.xpt
 @RESPATH@/components/dom_system.xpt
 #ifdef MOZ_WIDGET_GONK
 @RESPATH@/components/dom_wifi.xpt
 @RESPATH@/components/dom_system_gonk.xpt
 #endif
 #ifdef MOZ_B2G_RIL
@@ -724,16 +725,20 @@
 @RESPATH@/components/PrivateBrowsing.manifest
 @RESPATH@/components/PrivateBrowsingTrackingProtectionWhitelist.js
 
 ; GNOME hooks
 #ifdef MOZ_ENABLE_GNOME_COMPONENT
 @RESPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
 #endif
 
+; Signed Packaged Content
+@RESPATH@/components/InstallPackagedWebapp.manifest
+@RESPATH@/components/InstallPackagedWebapp.js
+
 ; ANGLE on Win32
 #ifdef XP_WIN32
 #ifndef HAVE_64BIT_BUILD
 @BINPATH@/libEGL.dll
 @BINPATH@/libGLESv2.dll
 #endif
 #endif
 
--- a/b2g/locales/Makefile.in
+++ b/b2g/locales/Makefile.in
@@ -52,17 +52,17 @@ include $(topsrcdir)/toolkit/locales/l10
 
 $(STAGEDIST): $(DIST)/branding
 
 $(DIST)/branding:
 	$(NSINSTALL) -D $@
 
 libs::
 	@if test -f '$(LOCALE_SRCDIR)/existing-profile-defaults.js'; then \
-	  $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
+	  $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) \
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js -o $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
 	fi
 
 NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
 
 libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$*
--- a/b2g/simulator/lib/simulator-process.js
+++ b/b2g/simulator/lib/simulator-process.js
@@ -16,34 +16,36 @@ const { Promise: promise } = Cu.import("
 const { EventEmitter } = Cu.import("resource://gre/modules/devtools/shared/event-emitter.js", {});
 
 
 // Log subprocess error and debug messages to the console.  This logs messages
 // for all consumers of the API.  We trim the messages because they sometimes
 // have trailing newlines.  And note that registerLogHandler actually registers
 // an error handler, despite its name.
 Subprocess.registerLogHandler(
-  function(s) console.error("subprocess: " + s.trim())
+  s => console.error("subprocess: " + s.trim())
 );
 Subprocess.registerDebugHandler(
-  function(s) console.debug("subprocess: " + s.trim())
+  s => console.debug("subprocess: " + s.trim())
 );
 
 function SimulatorProcess(options) {
   this.options = options;
 
   EventEmitter.decorate(this);
   this.on("stdout", (e, data) => { console.log(data.trim()) });
   this.on("stderr", (e, data) => { console.error(data.trim()) });
 }
 
 SimulatorProcess.prototype = {
 
   // check if b2g is running
-  get isRunning() !!this.process,
+  get isRunning() {
+    return !!this.process;
+  },
 
   /**
    * Start the process and connect the debugger client.
    */
   run: function() {
     // kill before start if already running
     if (this.process != null) {
       this.process
--- a/browser/base/content/browser-gestureSupport.js
+++ b/browser/base/content/browser-gestureSupport.js
@@ -49,17 +49,17 @@ var gGestureSupport = {
    */
   handleEvent: function GS_handleEvent(aEvent) {
     if (!Services.prefs.getBoolPref(
            "dom.debug.propagate_gesture_events_through_content")) {
       aEvent.stopPropagation();
     }
 
     // Create a preference object with some defaults
-    let def = function(aThreshold, aLatched)
+    let def = (aThreshold, aLatched) =>
       ({ threshold: aThreshold, latched: !!aLatched });
 
     switch (aEvent.type) {
       case "MozSwipeGestureMayStart":
         if (this._shouldDoSwipeGesture(aEvent)) {
           aEvent.preventDefault();
         }
         break;
--- a/browser/base/content/browser-loop.js
+++ b/browser/base/content/browser-loop.js
@@ -528,22 +528,20 @@ var LoopUI;
       let pageURI = gBrowser.selectedTab.linkedBrowser.currentURI.spec;
       // If the tab page’s url starts with http(s), fetch icon.
       if (!/^https?:/.test(pageURI)) {
         callback();
         return;
       }
 
       this.PlacesUtils.promiseFaviconLinkUrl(pageURI).then(uri => {
-        uri = this.PlacesUtils.getImageURLForResolution(window, uri.spec);
-
         // We XHR the favicon to get a File object, which we can pass to the FileReader
         // object. The FileReader turns the File object into a data-uri.
         let xhr = new XMLHttpRequest();
-        xhr.open("get", uri, true);
+        xhr.open("get", uri.spec, true);
         xhr.responseType = "blob";
         xhr.overrideMimeType("image/x-icon");
         xhr.onload = () => {
           if (xhr.status != 200) {
             callback(new Error("Invalid status code received for favicon XHR: " + xhr.status));
             return;
           }
 
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -25,17 +25,17 @@ var StarUI = {
     element.addEventListener("keypress", this, false);
     return this.panel = element;
   },
 
   // Array of command elements to disable when the panel is opened.
   get _blockedCommands() {
     delete this._blockedCommands;
     return this._blockedCommands =
-      ["cmd_close", "cmd_closeWindow"].map(function (id) this._element(id), this);
+      ["cmd_close", "cmd_closeWindow"].map(id => this._element(id));
   },
 
   _blockCommands: function SU__blockCommands() {
     this._blockedCommands.forEach(function (elt) {
       // make sure not to permanently disable this item (see bug 409155)
       if (elt.hasAttribute("wasDisabled"))
         return;
       if (elt.getAttribute("disabled") == "true") {
@@ -1493,17 +1493,17 @@ var BookmarkingUI = {
         Components.utils.reportError("BookmarkingUI did not receive current URI");
         return;
       }
 
       // It's possible that onItemAdded gets called before the async statement
       // calls back.  For such an edge case, retain all unique entries from both
       // arrays.
       this._itemIds = this._itemIds.filter(
-        function (id) aItemIds.indexOf(id) == -1
+        id => aItemIds.indexOf(id) == -1
       ).concat(aItemIds);
 
       this._updateStar();
 
       // Start observing bookmarks if needed.
       if (!this._hasBookmarksObserver) {
         try {
           PlacesUtils.addLazyBookmarkObserver(this);
--- a/browser/base/content/browser-syncui.js
+++ b/browser/base/content/browser-syncui.js
@@ -248,17 +248,17 @@ var gSyncUI = {
   },
 
   // Commands
   // doSync forces a sync - it *does not* return a promise as it is called
   // via the various UI components.
   doSync() {
     this._needsSetup().then(needsSetup => {
       if (!needsSetup) {
-        setTimeout(function () Weave.Service.errorHandler.syncAndReportErrors(), 0);
+        setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0);
       }
       Services.obs.notifyObservers(null, "cloudsync:user-sync", null);
     }).catch(err => {
       this.log.error("Failed to force a sync", err);
     });
   },
 
   // Handle clicking the toolbar button - which either opens the Sync setup
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -220,17 +220,17 @@ var TabView = {
         self._tabCloseEventListener = null;
       }
       if (self._SSWindowStateReadyListener) {
         window.removeEventListener(
           "SSWindowStateReady", self._SSWindowStateReadyListener, false);
         self._SSWindowStateReadyListener = null;
       }
 
-      self._initFrameCallbacks.forEach(function (cb) cb());
+      self._initFrameCallbacks.forEach(cb => cb());
       self._initFrameCallbacks = [];
     }, false);
 
     this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
     this._deck.appendChild(this._iframe);
 
     // ___ create tooltip
     let tooltip = document.createElement("tooltip");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3269,17 +3269,17 @@ function getMarkupDocumentViewer()
 
 // This function is obsolete. Newer code should use <tooltip page="true"/> instead.
 function FillInHTMLTooltip(tipElement)
 {
   document.getElementById("aHTMLTooltip").fillInPageTooltip(tipElement);
 }
 
 var browserDragAndDrop = {
-  canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
+  canDropLink: aEvent => Services.droppedLinkHandler.canDropLink(aEvent, true),
 
   dragOver: function (aEvent)
   {
     if (this.canDropLink(aEvent)) {
       aEvent.preventDefault();
     }
   },
 
@@ -3417,17 +3417,17 @@ const DOMLinkHandler = {
 
 const BrowserSearch = {
   addEngine: function(browser, engine, uri) {
     if (!this.searchBar)
       return;
 
     // Check to see whether we've already added an engine with this title
     if (browser.engines) {
-      if (browser.engines.some(function (e) e.title == engine.title))
+      if (browser.engines.some(e => e.title == engine.title))
         return;
     }
 
     var hidden = false;
     // If this engine (identified by title) is already in the list, add it
     // to the list of hidden engines rather than to the main list.
     // XXX This will need to be changed when engines are identified by URL;
     // see bug 335102.
@@ -3784,17 +3784,16 @@ function FillHistoryMenu(aParent) {
 
       // Cache this so that gotoHistoryIndex doesn't need the original index
       item.setAttribute("historyindex", j - index);
 
       if (j != index) {
         PlacesUtils.favicons.getFaviconURLForPage(entryURI, function (aURI) {
           if (aURI) {
             let iconURL = PlacesUtils.favicons.getFaviconLinkForIcon(aURI).spec;
-            iconURL = PlacesUtils.getImageURLForResolution(window, iconURL);
             item.style.listStyleImage = "url(" + iconURL + ")";
           }
         });
       }
 
       if (j < index) {
         item.className = "unified-nav-back menuitem-iconic menuitem-with-favicon";
         item.setAttribute("tooltiptext", tooltipBack);
@@ -4555,17 +4554,19 @@ var LinkTargetDisplay = {
   get DELAY_SHOW() {
      delete this.DELAY_SHOW;
      return this.DELAY_SHOW = Services.prefs.getIntPref("browser.overlink-delay");
   },
 
   DELAY_HIDE: 250,
   _timer: 0,
 
-  get _isVisible () XULBrowserWindow.statusTextField.label != "",
+  get _isVisible () {
+    return XULBrowserWindow.statusTextField.label != "";
+  },
 
   update: function () {
     clearTimeout(this._timer);
     window.removeEventListener("mousemove", this, true);
 
     if (!XULBrowserWindow.overLink) {
       if (XULBrowserWindow.hideOverLinkImmediately)
         this._hide();
@@ -4952,17 +4953,17 @@ nsBrowserAccess.prototype = {
                                         aParams.isPrivate, isExternal);
     if (browser)
       return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
 
     return null;
   },
 
   isTabContentWindow: function (aWindow) {
-    return gBrowser.browsers.some(function (browser) browser.contentWindow == aWindow);
+    return gBrowser.browsers.some(browser => browser.contentWindow == aWindow);
   },
 }
 
 function getTogglableToolbars() {
   let toolbarNodes = Array.slice(gNavToolbox.childNodes);
   toolbarNodes = toolbarNodes.concat(gNavToolbox.externalToolbars);
   toolbarNodes = toolbarNodes.filter(node => node.getAttribute("toolbarname"));
   return toolbarNodes;
@@ -5183,19 +5184,19 @@ var TabsInTitlebar = {
   _lastSizeMode: null,
 
   _readPref: function () {
     this.allowedBy("pref",
                    Services.prefs.getBoolPref(this._prefName));
   },
 
   _update: function (aForce=false) {
-    function $(id) document.getElementById(id);
-    function rect(ele) ele.getBoundingClientRect();
-    function verticalMargins(cstyle) parseFloat(cstyle.marginBottom) + parseFloat(cstyle.marginTop);
+    let $ = id => document.getElementById(id);
+    let rect = ele => ele.getBoundingClientRect();
+    let verticalMargins = cstyle => parseFloat(cstyle.marginBottom) + parseFloat(cstyle.marginTop);
 
     if (!this._initialized || window.fullScreen)
       return;
 
     let allowed = true;
 
     if (!aForce) {
       // _update is called on resize events, because the window is not ready
@@ -7393,18 +7394,22 @@ function getNotificationBox(aWindow) {
 function getTabModalPromptBox(aWindow) {
   var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
   if (foundBrowser)
     return gBrowser.getTabModalPromptBox(foundBrowser);
   return null;
 };
 
 /* DEPRECATED */
-function getBrowser() gBrowser;
-function getNavToolbox() gNavToolbox;
+function getBrowser() {
+  return gBrowser;
+}
+function getNavToolbox() {
+  return gNavToolbox;
+}
 
 var gPrivateBrowsingUI = {
   init: function PBUI_init() {
     // Do nothing for normal windows
     if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
       return;
     }
 
--- a/browser/base/content/chatWindow.xul
+++ b/browser/base/content/chatWindow.xul
@@ -123,17 +123,19 @@ chatBrowserAccess.prototype = {
     return browser ? browser.contentWindow : null;
   },
 
   openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aContext) {
     let browser = this._openURIInNewTab(aURI, aWhere);
     return browser ? browser.QueryInterface(Ci.nsIFrameLoaderOwner) : null;
   },
 
-  isTabContentWindow: function (aWindow) this.contentWindow == aWindow,
+  isTabContentWindow: function (aWindow) {
+    return this.contentWindow == aWindow;
+  },
 };
 
 </script>
 
 #include browser-sets.inc
 
 #ifdef XP_MACOSX
 #include browser-menubar.inc
--- a/browser/base/content/contentSearchUI.js
+++ b/browser/base/content/contentSearchUI.js
@@ -668,22 +668,20 @@ ContentSearchUIController.prototype = {
         entry.appendChild(document.createTextNode(" "));
       }
     }
 
     row.appendChild(entry);
     return row;
   },
 
-  // Converts favicon array buffer into data URI of the right size and dpi.
+  // Converts favicon array buffer into a data URI.
   _getFaviconURIFromBuffer: function (buffer) {
     let blob = new Blob([buffer]);
-    let dpiSize = Math.round(16 * window.devicePixelRatio);
-    let sizeStr = dpiSize + "," + dpiSize;
-    return URL.createObjectURL(blob) + "#-moz-resolution=" + sizeStr;
+    return URL.createObjectURL(blob);
   },
 
   // Adds "@2x" to the name of the given PNG url for "retina" screens.
   _getImageURIForCurrentResolution: function (uri) {
     if (window.devicePixelRatio > 1) {
       return uri.replace(/\.png$/, "@2x.png");
     }
     return uri;
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -430,18 +430,18 @@ Sanitizer.prototype = {
           if (findBarCanClear) {
             aCallback("formdata", true, aArg);
             return false;
           }
         }
 
         let count = 0;
         let countDone = {
-          handleResult : function(aResult) count = aResult,
-          handleError : function(aError) Components.utils.reportError(aError),
+          handleResult : aResult => count = aResult,
+          handleError : aError => Components.utils.reportError(aError),
           handleCompletion :
             function(aReason) { aCallback("formdata", aReason == 0 && count > 0, aArg); }
         };
         FormHistory.count({}, countDone);
         return false;
       }
     },
 
--- a/browser/base/content/sync/setup.js
+++ b/browser/base/content/sync/setup.js
@@ -46,17 +46,19 @@ var gSyncSetup = {
   _disabledSites: [],
 
   status: {
     password: false,
     email: false,
     server: false
   },
 
-  get _remoteSites() [Weave.Service.serverURL, RECAPTCHA_DOMAIN],
+  get _remoteSites() {
+    return [Weave.Service.serverURL, RECAPTCHA_DOMAIN];
+  },
 
   get _usingMainServers() {
     if (this._settingUpNew)
       return document.getElementById("server").selectedIndex == 0;
     return document.getElementById("existingServer").selectedIndex == 0;
   },
 
   init: function () {
@@ -74,17 +76,17 @@ var gSyncSetup = {
         //        of `this`. Fix in a followup. (bug 583347)
         if (add)
           Weave.Svc.Obs.add(topic, self[func], self);
         else
           Weave.Svc.Obs.remove(topic, self[func], self);
       });
     };
     addRem(true);
-    window.addEventListener("unload", function() addRem(false), false);
+    window.addEventListener("unload", () => addRem(false), false);
 
     window.setTimeout(function () {
       // Force Service to be loaded so that engines are registered.
       // See Bug 670082.
       Weave.Service;
     }, 0);
 
     this.captchaBrowser = document.getElementById("captcha");
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -45,17 +45,17 @@
       <field name="tabs" readonly="true">
         this.tabContainer.childNodes;
       </field>
 
       <property name="visibleTabs" readonly="true">
         <getter><![CDATA[
           if (!this._visibleTabs)
             this._visibleTabs = Array.filter(this.tabs,
-                                             function (tab) !tab.hidden && !tab.closing);
+                                             tab => !tab.hidden && !tab.closing);
           return this._visibleTabs;
         ]]></getter>
       </property>
 
       <field name="closingTabsEnum" readonly="true">({ ALL: 0, OTHER: 1, TO_END: 2 });</field>
 
       <field name="_visibleTabs">null</field>
 
@@ -899,19 +899,16 @@
               this.mFaviconService.setAndFetchFaviconForPage(browser.currentURI,
                                                              aURI, false,
                                                              PrivateBrowsingUtils.isWindowPrivate(window) ?
                                                                this.mFaviconService.FAVICON_LOAD_PRIVATE :
                                                                this.mFaviconService.FAVICON_LOAD_NON_PRIVATE);
             }
 
             let sizedIconUrl = browser.mIconURL || "";
-            if (sizedIconUrl) {
-              sizedIconUrl = this.PlacesUtils.getImageURLForResolution(window, sizedIconUrl);
-            }
             if (sizedIconUrl != aTab.getAttribute("image")) {
               if (sizedIconUrl)
                 aTab.setAttribute("image", sizedIconUrl);
               else
                 aTab.removeAttribute("image");
               this._tabAttrModified(aTab, ["image"]);
             }
 
@@ -2705,34 +2702,34 @@
         </body>
       </method>
 
       <method name="removeProgressListener">
         <parameter name="aListener"/>
         <body>
           <![CDATA[
             this.mProgressListeners =
-              this.mProgressListeners.filter(function (l) l != aListener);
+              this.mProgressListeners.filter(l => l != aListener);
          ]]>
         </body>
       </method>
 
       <method name="addTabsProgressListener">
         <parameter name="aListener"/>
         <body>
           this.mTabsProgressListeners.push(aListener);
         </body>
       </method>
 
       <method name="removeTabsProgressListener">
         <parameter name="aListener"/>
         <body>
         <![CDATA[
           this.mTabsProgressListeners =
-            this.mTabsProgressListeners.filter(function (l) l != aListener);
+            this.mTabsProgressListeners.filter(l => l != aListener);
         ]]>
         </body>
       </method>
 
       <method name="getBrowserForTab">
         <parameter name="aTab"/>
         <body>
         <![CDATA[
@@ -2836,17 +2833,17 @@
       <property name="selectedBrowser"
                 onget="return this.mCurrentBrowser;"
                 readonly="true"/>
 
       <property name="browsers" readonly="true">
        <getter>
           <![CDATA[
             return this._browsers ||
-                   (this._browsers = Array.map(this.tabs, function (tab) tab.linkedBrowser));
+                   (this._browsers = Array.map(this.tabs, tab => tab.linkedBrowser));
           ]]>
         </getter>
       </property>
       <field name="_browsers">null</field>
 
       <!-- Moves a tab to a new browser window, unless it's already the only tab
            in the current window, in which case this will do nothing. -->
       <method name="replaceTabWithWindow">
@@ -5525,17 +5522,19 @@
           toDrag = canvas;
         }
         dt.setDragImage(toDrag, -16 * scale, -16 * scale);
 
         // _dragData.offsetX/Y give the coordinates that the mouse should be
         // positioned relative to the corner of the new window created upon
         // dragend such that the mouse appears to have the same position
         // relative to the corner of the dragged tab.
-        function clientX(ele) ele.getBoundingClientRect().left;
+        function clientX(ele) {
+          return ele.getBoundingClientRect().left;
+        }
         let tabOffsetX = clientX(tab) - clientX(this);
         tab._dragData = {
           offsetX: event.screenX - window.screenX - tabOffsetX,
           offsetY: event.screenY - window.screenY,
           scrollX: this.mTabstrip.scrollPosition,
           screenX: event.screenX
         };
 
--- a/browser/base/content/test/general/browser_action_searchengine_alias.js
+++ b/browser/base/content/test/general/browser_action_searchengine_alias.js
@@ -32,17 +32,16 @@ add_task(function* () {
 
     return PlacesTestUtils.clearHistory();
   });
 
   yield promiseAutocompleteResultPopup("moz open a search");
 
   let result = gURLBar.popup.richlistbox.children[0];
   ok(result.hasAttribute("image"), "Result should have an image attribute");
-  // Image attribute gets a suffix (-moz-resolution) added in the value.
-  ok(result.getAttribute("image").startsWith(engine.iconURI.spec),
+  ok(result.getAttribute("image") === engine.iconURI.spec,
      "Image attribute should have the search engine's icon");
 
   EventUtils.synthesizeKey("VK_RETURN" , { });
   yield promiseTabLoaded(gBrowser.selectedTab);
 
   is(gBrowser.selectedBrowser.currentURI.spec, "http://example.com/?q=open+a+search");
 });
--- a/browser/base/content/test/general/browser_bug521216.js
+++ b/browser/base/content/test/general/browser_bug521216.js
@@ -1,12 +1,12 @@
 var expected = ["TabOpen", "onStateChange", "onLocationChange", "onLinkIconAvailable"];
 var actual = [];
 var tabIndex = -1;
-this.__defineGetter__("tab", function () gBrowser.tabs[tabIndex]);
+this.__defineGetter__("tab", () => gBrowser.tabs[tabIndex]);
 
 function test() {
   waitForExplicitFinish();
   tabIndex = gBrowser.tabs.length;
   gBrowser.addTabsProgressListener(progressListener);
   gBrowser.tabContainer.addEventListener("TabOpen", TabOpen, false);
   gBrowser.addTab("data:text/html,<html><head><link href='about:logo' rel='shortcut icon'>");
 }
--- a/browser/base/content/test/general/browser_bug537013.js
+++ b/browser/base/content/test/general/browser_bug537013.js
@@ -33,17 +33,17 @@ var newWindow;
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function () {
     while (tabs.length) {
       gBrowser.removeTab(tabs.pop());
     }
   });
-  texts.forEach(function(aText) addTabWithText(aText));
+  texts.forEach(aText => addTabWithText(aText));
 
   // Set up the first tab
   gBrowser.selectedTab = tabs[0];
 
   setFindString(texts[0]);
   // Turn on highlight for testing bug 891638
   gFindBar.getElement("highlight").checked = true;
 
--- a/browser/base/content/test/general/browser_bug580638.js
+++ b/browser/base/content/test/general/browser_bug580638.js
@@ -1,17 +1,19 @@
 /* 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/. */
 
 function test() {
   waitForExplicitFinish();
 
   function testState(aPinned) {
-    function elemAttr(id, attr) document.getElementById(id).getAttribute(attr);
+    function elemAttr(id, attr) {
+      return document.getElementById(id).getAttribute(attr);
+    }
 
     if (aPinned) {
       is(elemAttr("key_close", "disabled"), "true",
          "key_close should be disabled when a pinned-tab is selected");
       is(elemAttr("menu_close", "key"), "",
          "menu_close shouldn't have a key set when a pinned is selected");
     }
     else {
--- a/browser/base/content/test/general/browser_bug580956.js
+++ b/browser/base/content/test/general/browser_bug580956.js
@@ -1,10 +1,11 @@
-function numClosedTabs()
-  SessionStore.getClosedTabCount(window);
+function numClosedTabs() {
+  return SessionStore.getClosedTabCount(window);
+}
 
 function isUndoCloseEnabled() {
   updateTabContextMenu();
   return !document.getElementById("context_undoCloseTab").disabled;
 }
 
 function test() {
   waitForExplicitFinish();
--- a/browser/base/content/test/general/browser_bug624734.js
+++ b/browser/base/content/test/general/browser_bug624734.js
@@ -16,16 +16,16 @@ function finishTest() {
 function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   tab.linkedBrowser.addEventListener("load", (function(event) {
     tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
 
     if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING) {
-      waitForCondition(function() BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING, finishTest, "BookmarkingUI was updating for too long");
+      waitForCondition(() => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING, finishTest, "BookmarkingUI was updating for too long");
     } else {
       finishTest();
     }
   }), true);
 
   tab.linkedBrowser.loadURI("http://example.com/browser/browser/base/content/test/general/dummy_page.html");
 }
--- a/browser/base/content/test/general/browser_bug719271.js
+++ b/browser/base/content/test/general/browser_bug719271.js
@@ -64,17 +64,17 @@ function testNavigation() {
     yield waitForNextTurn(); // trying to fix orange bug 806046
     yield FullZoomHelper.navigate(FullZoomHelper.FORWARD);
     FullZoomHelper.zoomTest(gTab1, 1, "Zoom should be 1 again when navigating back to a video");
   }).then(finishTest, FullZoomHelper.failAndContinue(finish));
 }
 
 function waitForNextTurn() {
   let deferred = Promise.defer();
-  setTimeout(function () deferred.resolve(), 0);
+  setTimeout(() => deferred.resolve(), 0);
   return deferred.promise;
 }
 
 var finishTestStarted  = false;
 function finishTest() {
   Task.spawn(function () {
     ok(!finishTestStarted, "finishTest called more than once");
     finishTestStarted = true;
--- a/browser/base/content/test/general/browser_bug763468_perwindowpb.js
+++ b/browser/base/content/test/general/browser_bug763468_perwindowpb.js
@@ -30,17 +30,17 @@ function test() {
   };
 
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       windowsToClose.push(aWin);
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
-      executeSoon(function() aCallback(aWin));
+      executeSoon(() => aCallback(aWin));
     });
   };
 
    // this function is called after calling finish() on the test.
   registerCleanupFunction(function() {
     windowsToClose.forEach(function(aWin) {
       aWin.close();
     });
--- a/browser/base/content/test/general/browser_bug767836_perwindowpb.js
+++ b/browser/base/content/test/general/browser_bug767836_perwindowpb.js
@@ -40,17 +40,17 @@ function test() {
         aWindow.close();
         aCallback()
       });
     });
   }
 
   function testOnWindow(aIsPrivate, aCallback) {
     whenNewWindowLoaded({private: aIsPrivate}, function(win) {
-      executeSoon(function() aCallback(win));
+      executeSoon(() => aCallback(win));
     });
   }
 
   // check whether any custom new tab url has been configured
   ok(!NewTabURL.overridden, "No custom newtab url is set");
 
   // test normal mode
   testOnWindow(false, function(aWindow) {
--- a/browser/base/content/test/general/browser_bug822367.js
+++ b/browser/base/content/test/general/browser_bug822367.js
@@ -47,17 +47,17 @@ function MixedTest1A() {
   gTestBrowser.addEventListener("load", MixedTest1B, true);
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
 
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 function MixedTest1B() {
-  waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest1C, "Waited too long for mixed script to run in Test 1");
+  waitForCondition(() => content.document.getElementById('p1').innerHTML == "hello", MixedTest1C, "Waited too long for mixed script to run in Test 1");
 }
 function MixedTest1C() {
   ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 1");
   gTestBrowser.removeEventListener("load", MixedTest1B, true);
   MixedTest2();
 }
 
 //Mixed Display Test - Doorhanger should not appear
@@ -84,20 +84,20 @@ function MixedTest3A() {
   gTestBrowser.addEventListener("load", MixedTest3B, true);
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
 
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 function MixedTest3B() {
-  waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest3C, "Waited too long for mixed script to run in Test 3");
+  waitForCondition(() => content.document.getElementById('p1').innerHTML == "hello", MixedTest3C, "Waited too long for mixed script to run in Test 3");
 }
 function MixedTest3C() {
-  waitForCondition(function() content.document.getElementById('p2').innerHTML == "bye", MixedTest3D, "Waited too long for mixed image to load in Test 3");
+  waitForCondition(() => content.document.getElementById('p2').innerHTML == "bye", MixedTest3D, "Waited too long for mixed image to load in Test 3");
 }
 function MixedTest3D() {
   ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 3");
   ok(content.document.getElementById('p2').innerHTML == "bye","Mixed image didn't load in Test 3");
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: true});
   MixedTest4();
 }
 
@@ -113,25 +113,25 @@ function MixedTest4A() {
   gTestBrowser.addEventListener("load", MixedTest4B, true);
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
 
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 function MixedTest4B() {
-  waitForCondition(function() content.document.location == gHttpTestRoot + "file_bug822367_4B.html", MixedTest4C, "Waited too long for mixed script to run in Test 4");
+  waitForCondition(() => content.document.location == gHttpTestRoot + "file_bug822367_4B.html", MixedTest4C, "Waited too long for mixed script to run in Test 4");
 }
 function MixedTest4C() {
   ok(content.document.location == gHttpTestRoot + "file_bug822367_4B.html", "Location didn't change in test 4");
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
 
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
-  waitForCondition(function() content.document.getElementById('p1').innerHTML == "", MixedTest4D, "Mixed script loaded in test 4 after location change!");
+  waitForCondition(() => content.document.getElementById('p1').innerHTML == "", MixedTest4D, "Mixed script loaded in test 4 after location change!");
 }
 function MixedTest4D() {
   ok(content.document.getElementById('p1').innerHTML == "","p1.innerHTML changed; mixed script loaded after location change in Test 4");
   MixedTest5();
 }
 
 // Mixed script attempts to load in a document.open()
 function MixedTest5() {
@@ -145,17 +145,17 @@ function MixedTest5A() {
   gTestBrowser.addEventListener("load", MixedTest5B, true);
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
 
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 function MixedTest5B() {
-  waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest5C, "Waited too long for mixed script to run in Test 5");
+  waitForCondition(() => content.document.getElementById('p1').innerHTML == "hello", MixedTest5C, "Waited too long for mixed script to run in Test 5");
 }
 function MixedTest5C() {
   ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 5");
   MixedTest6();
 }
 
 // Mixed script attempts to load in a document.open() that is within an iframe.
 function MixedTest6() {
--- a/browser/base/content/test/general/browser_bug902156.js
+++ b/browser/base/content/test/general/browser_bug902156.js
@@ -55,17 +55,17 @@ function test1A() {
   // Disable Mixed Content Protection for the page (and reload)
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 
 function test1B() {
   var expected = "Mixed Content Blocker disabled";
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test1C, "Error: Waited too long for mixed script to run in Test 1B");
 }
 
 function test1C() {
   gTestBrowser.removeEventListener("load", test1B, true);
   var actual = content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1C");
 
@@ -110,17 +110,17 @@ function test2A() {
   // Disable Mixed Content Protection for the page (and reload)
   let {gIdentityHandler} = gTestBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 
 function test2B() {
   var expected = "Mixed Content Blocker disabled";
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test2C, "Error: Waited too long for mixed script to run in Test 2B");
 }
 
 function test2C() {
   gTestBrowser.removeEventListener("load", test2B, true);
   var actual = content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 2C");
 
--- a/browser/base/content/test/general/browser_bug906190.js
+++ b/browser/base/content/test/general/browser_bug906190.js
@@ -149,17 +149,17 @@ function checkPopUpNotification() {
   // Disable Mixed Content Protection for the page (which reloads the page)
   let {gIdentityHandler} = gTestWin.gBrowser.ownerGlobal;
   gIdentityHandler.disableMixedContentProtection();
 }
 
 function reloadedTabAfterDisablingMCB() {
   var expected = "Mixed Content Blocker disabled";
   waitForCondition(
-    function() gTestWin.content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => gTestWin.content.document.getElementById('mctestdiv').innerHTML == expected,
     makeSureMCBisDisabled, "Error: Waited too long for mixed script to run in " + curTestName + "!");
 }
 
 function makeSureMCBisDisabled() {
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Made sure MCB is disabled in " + curTestName + "!");
 
   // inject the provided link into the page, so we can test persistence of MCB
--- a/browser/base/content/test/general/browser_contentAreaClick.js
+++ b/browser/base/content/test/general/browser_contentAreaClick.js
@@ -213,17 +213,17 @@ var gClickHandler = {
     // Check that all required methods have been called.
     gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
       isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
             gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
     });
     
     if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
       ok(false, "Wrong number of invoked methods");
-      gInvokedMethods.forEach(function (method) info(method + " was invoked"));
+      gInvokedMethods.forEach(method => info(method + " was invoked"));
     }
 
     event.preventDefault();
     event.stopPropagation();
 
     executeSoon(runNextTest);
   }
 }
--- a/browser/base/content/test/general/browser_ctrlTab.js
+++ b/browser/base/content/test/general/browser_ctrlTab.js
@@ -85,24 +85,27 @@ function test() {
   }
 
   // cleanup
   if (gPrefService.prefHasUserValue("browser.ctrlTab.previews"))
     gPrefService.clearUserPref("browser.ctrlTab.previews");
 
   /* private utility functions */
 
-  function pressCtrlTab(aShiftKey)
+  function pressCtrlTab(aShiftKey) {
     EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: !!aShiftKey });
+  }
 
-  function releaseCtrl()
+  function releaseCtrl() {
     EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" });
+  }
 
-  function isOpen()
-    ctrlTab.isOpen;
+  function isOpen() {
+    return ctrlTab.isOpen;
+  }
 
   function checkTabs(aTabs) {
     var tabs = gBrowser.tabs.length;
     if (tabs != aTabs) {
       while (gBrowser.tabs.length > 1)
         gBrowser.removeCurrentTab();
       throw "expected " + aTabs + " open tabs, got " + tabs;
     }
--- a/browser/base/content/test/general/browser_discovery.js
+++ b/browser/base/content/test/general/browser_discovery.js
@@ -1,11 +1,13 @@
 var browser;
 
-function doc() browser.contentDocument;
+function doc() {
+  return browser.contentDocument;
+}
 
 function setHandlerFunc(aResultFunc) {
   gBrowser.addEventListener("DOMLinkAdded", function (event) {
     gBrowser.removeEventListener("DOMLinkAdded", arguments.callee, false);
     executeSoon(aResultFunc);
   }, false);
 }
 
--- a/browser/base/content/test/general/browser_gestureSupport.js
+++ b/browser/base/content/test/general/browser_gestureSupport.js
@@ -278,17 +278,17 @@ function test_emitLatchedEvents(eventPre
   let cumulativeDelta = 0;
   let isIncreasing = initialDelta > 0;
 
   let expect = {};
   // Reset the call counters and initialize expected values
   for (let dir in cmd)
     cmd[dir].callCount = expect[dir] = 0;
 
-  let check = function(aDir, aMsg) ok(cmd[aDir].callCount == expect[aDir], aMsg);
+  let check = (aDir, aMsg) => ok(cmd[aDir].callCount == expect[aDir], aMsg);
   let checkBoth = function(aNum, aInc, aDec) {
     let prefix = "Step " + aNum + ": ";
     check("inc", prefix + aInc);
     check("dec", prefix + aDec);
   };
 
   // Send the "Start" event.
   test_utils.sendSimpleGestureEvent(eventPrefix + "Start", 0, 0, 0, initialDelta, 0);
--- a/browser/base/content/test/general/browser_hide_removing.js
+++ b/browser/base/content/test/general/browser_hide_removing.js
@@ -19,17 +19,21 @@ function test() {
     // While the next tab is being selected, hide the removing tab
     numVisBeforeHide = gBrowser.visibleTabs.length;
     gBrowser.hideTab(testTab);
     numVisAfterHide = gBrowser.visibleTabs.length;
   }, false);
   gBrowser.removeTab(testTab, {animate: true});
 
   // Make sure the tab gets removed at the end of the animation by polling
-  (function checkRemoved() setTimeout(function() {
-    if (gBrowser.tabs.length != 1)
-      return checkRemoved();
+  (function checkRemoved() {
+    return setTimeout(function() {
+      if (gBrowser.tabs.length != 1) {
+        checkRemoved();
+        return;
+      }
 
-    is(numVisBeforeHide, 1, "animated remove has in 1 tab left");
-    is(numVisAfterHide, 1, "hiding a removing tab is also has 1 tab");
-    finish();
-  }, 50))();
+      is(numVisBeforeHide, 1, "animated remove has in 1 tab left");
+      is(numVisAfterHide, 1, "hiding a removing tab is also has 1 tab");
+      finish();
+    }, 50);
+  })();
 }
--- a/browser/base/content/test/general/browser_mcb_redirect.js
+++ b/browser/base/content/test/general/browser_mcb_redirect.js
@@ -107,17 +107,17 @@ function test1() {
 
 function checkUIForTest1() {
   gTestBrowser.removeEventListener("load", checkUIForTest1, true);
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
 
   var expected = "script blocked";
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test2, "Error: Waited too long for status in Test 1!",
     "OK: Expected result in innerHTML for Test1!");
 }
 
 //------------------------ Test 2 ------------------------------
 
 function test2() {
   gTestBrowser.addEventListener("load", checkUIForTest2, true);
@@ -127,17 +127,17 @@ function test2() {
 
 function checkUIForTest2() {
   gTestBrowser.removeEventListener("load", checkUIForTest2, true);
 
   assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
 
   var expected = "script executed";
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test3, "Error: Waited too long for status in Test 2!",
     "OK: Expected result in innerHTML for Test2!");
 }
 
 //------------------------ Test 3 ------------------------------
 // HTTPS page loading insecure image
 function test3() {
   gTestBrowser.addEventListener("load", checkLoadEventForTest3, true);
@@ -145,17 +145,17 @@ function test3() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest3() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest3, true);
 
   var expected = "image blocked"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test4, "Error: Waited too long for status in Test 3!",
     "OK: Expected result in innerHTML for Test3!");
 }
 
 //------------------------ Test 4 ------------------------------
 // HTTP page loading insecure image
 function test4() {
   gTestBrowser.addEventListener("load", checkLoadEventForTest4, true);
@@ -163,17 +163,17 @@ function test4() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest4() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest4, true);
 
   var expected = "image loaded"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test5, "Error: Waited too long for status in Test 4!",
     "OK: Expected result in innerHTML for Test4!");
 }
 
 //------------------------ Test 5 ------------------------------
 // HTTP page laoding insecure cached image
 // Assuming test 4 succeeded, the image has already been loaded once
 // and hence should be cached per the sjs cache-control header
@@ -186,17 +186,17 @@ function test5() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest5() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest5, true);
 
   var expected = "image loaded"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test6, "Error: Waited too long for status in Test 5!",
     "OK: Expected result in innerHTML for Test5!");
   // Go back online
   Services.io.offline = false;
 }
 
 //------------------------ Test 6 ------------------------------
 // HTTPS page loading insecure cached image
@@ -211,17 +211,17 @@ function test6() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest6() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest6, true);
 
   var expected = "image blocked"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test7, "Error: Waited too long for status in Test 6!",
     "OK: Expected result in innerHTML for Test6!");
   // Go back online
   Services.io.offline = false;
 }
 
 //------------------------ Test 7 ------------------------------
 // HTTP page loading insecure image that went through a double redirect
@@ -231,17 +231,17 @@ function test7() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest7() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest7, true);
 
   var expected = "image loaded"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test8, "Error: Waited too long for status in Test 7!",
     "OK: Expected result in innerHTML for Test7!");
 }
 
 //------------------------ Test 8 ------------------------------
 // HTTP page loading insecure cached image that went through a double redirect
 // Assuming test 7 succeeded, the image has already been loaded once
 // and hence should be cached per the sjs cache-control header
@@ -254,17 +254,17 @@ function test8() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest8() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest8, true);
 
   var expected = "image loaded"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     test9, "Error: Waited too long for status in Test 8!",
     "OK: Expected result in innerHTML for Test8!");
   // Go back online
   Services.io.offline = false;
 }
 
 //------------------------ Test 9 ------------------------------
 // HTTPS page loading insecure cached image that went through a double redirect
@@ -279,17 +279,17 @@ function test9() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function checkLoadEventForTest9() {
   gTestBrowser.removeEventListener("load", checkLoadEventForTest9, true);
 
   var expected = "image blocked"
   waitForCondition(
-    function() content.document.getElementById('mctestdiv').innerHTML == expected,
+    () => content.document.getElementById('mctestdiv').innerHTML == expected,
     cleanUpAfterTests, "Error: Waited too long for status in Test 9!",
     "OK: Expected result in innerHTML for Test9!");
   // Go back online
   Services.io.offline = false;
 }
 
 //------------------------ SETUP ------------------------------
 
--- a/browser/base/content/test/general/browser_no_mcb_on_http_site.js
+++ b/browser/base/content/test/general/browser_no_mcb_on_http_site.js
@@ -64,17 +64,17 @@ function waitForCondition(condition, nex
 //------------- TEST 1 -----------------------------------------
 
 function test1A() {
   gTestBrowser.removeEventListener("load", test1A, true);
 
   var expected = "Verifying MCB does not trigger warning/error for an http page ";
   expected += "with https css that includes http image";
   waitForCondition(
-    function() content.document.getElementById('testDiv').innerHTML == expected,
+    () => content.document.getElementById('testDiv').innerHTML == expected,
     test1B, "Error: Waited too long for status in Test 1!",
     "OK: Expected result in innerHTML!");
 }
 
 function test1B() {
   // set up test 2
   gTestBrowser.addEventListener("load", test2A, true);
   var url = gHttpTestRoot + "test_no_mcb_on_http_site_font.html";
@@ -84,17 +84,17 @@ function test1B() {
 //------------- TEST 2 -----------------------------------------
 
 function test2A() {
   gTestBrowser.removeEventListener("load", test2A, true);
 
   var expected = "Verifying MCB does not trigger warning/error for an http page ";
   expected += "with https css that includes http font";
   waitForCondition(
-    function() content.document.getElementById('testDiv').innerHTML == expected,
+    () => content.document.getElementById('testDiv').innerHTML == expected,
     test2B, "Error: Waited too long for status in Test 2!",
     "OK: Expected result in innerHTML!");
 }
 
 function test2B() {
   // set up test 3
   gTestBrowser.addEventListener("load", test3, true);
   var url = gHttpTestRoot + "test_no_mcb_on_http_site_font2.html";
@@ -104,17 +104,17 @@ function test2B() {
 //------------- TEST 3 -----------------------------------------
 
 function test3() {
   gTestBrowser.removeEventListener("load", test3, true);
 
   var expected = "Verifying MCB does not trigger warning/error for an http page "
   expected += "with https css that imports another http css which includes http font";
   waitForCondition(
-    function() content.document.getElementById('testDiv').innerHTML == expected,
+    () => content.document.getElementById('testDiv').innerHTML == expected,
     cleanUpAfterTests, "Error: Waited too long for status in Test 3!",
     "OK: Expected result in innerHTML!");
 }
 
 //------------------------------------------------------
 
 function test() {
   // Performing async calls, e.g. 'onload', we have to wait till all of them finished
--- a/browser/base/content/test/general/browser_overflowScroll.js
+++ b/browser/base/content/test/general/browser_overflowScroll.js
@@ -1,23 +1,23 @@
 var tabstrip = gBrowser.tabContainer.mTabstrip;
 var scrollbox = tabstrip._scrollbox;
 var originalSmoothScroll = tabstrip.smoothScroll;
 var tabs = gBrowser.tabs;
 
-function rect(ele)           ele.getBoundingClientRect();
-function width(ele)          rect(ele).width;
-function left(ele)           rect(ele).left;
-function right(ele)          rect(ele).right;
-function isLeft(ele, msg)    is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
-function isRight(ele, msg)   is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
-function elementFromPoint(x) tabstrip._elementFromPoint(x);
-function nextLeftElement()   elementFromPoint(left(scrollbox) - 1);
-function nextRightElement()  elementFromPoint(right(scrollbox) + 1);
-function firstScrollable()   tabs[gBrowser._numPinnedTabs];
+let rect = ele => ele.getBoundingClientRect();
+let width = ele => rect(ele).width;
+let left = ele => rect(ele).left;
+let right = ele => rect(ele).right;
+let isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
+let isRight = (ele, msg) => is(right(ele) - tabstrip._tabMarginRight, right(scrollbox), msg);
+let elementFromPoint = x => tabstrip._elementFromPoint(x);
+let nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
+let nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
+let firstScrollable = () => tabs[gBrowser._numPinnedTabs];
 
 function test() {
   requestLongerTimeout(2);
   waitForExplicitFinish();
 
   // If the previous (or more) test finished with cleaning up the tabs,
   // there may be some pending animations. That can cause a failure of
   // this tests, so, we should test this in another stack.
--- a/browser/base/content/test/general/browser_page_style_menu.js
+++ b/browser/base/content/test/general/browser_page_style_menu.js
@@ -27,17 +27,17 @@ function checkPageStyleMenu() {
   Array.forEach(content.document.getElementsByTagName("link"), function (link) {
     var title = link.getAttribute("title");
     var rel = link.getAttribute("rel");
     var media = link.getAttribute("media");
     var idstring = "link " + (title ? title : "without title and") +
                    " with rel=\"" + rel + "\"" +
                    (media ? " and media=\"" + media + "\"" : "");
 
-    var item = items.filter(function (item) item.getAttribute("label") == title);
+    var item = items.filter(item => item.getAttribute("label") == title);
     var found = item.length == 1;
     var checked = found && (item[0].getAttribute("checked") == "true");
 
     switch (link.getAttribute("data-state")) {
       case "0":
         ok(!found, idstring + " does not show up in page style menu");
         break;
       case "0-todo":
--- a/browser/base/content/test/general/browser_pinnedTabs.js
+++ b/browser/base/content/test/general/browser_pinnedTabs.js
@@ -1,11 +1,13 @@
 var tabs;
 
-function index(tab) Array.indexOf(gBrowser.tabs, tab);
+function index(tab) {
+  return Array.indexOf(gBrowser.tabs, tab);
+}
 
 function indexTest(tab, expectedIndex, msg) {
   var diag = "tab " + tab + " should be at index " + expectedIndex;
   if (msg)
     msg = msg + " (" + diag + ")";
   else
     msg = diag;
   is(index(tabs[tab]), expectedIndex, msg);
--- a/browser/base/content/test/general/browser_sanitize-timespans.js
+++ b/browser/base/content/test/general/browser_sanitize-timespans.js
@@ -54,17 +54,17 @@ function test() {
 function countEntries(name, message, check) {
   let deferred = Promise.defer();
 
   var obj = {};
   if (name !== null)
     obj.fieldname = name;
 
   let count;
-  FormHistory.count(obj, { handleResult: function (result) count = result,
+  FormHistory.count(obj, { handleResult: result => count = result,
                            handleError: function (error) {
                              do_throw("Error occurred searching form history: " + error);
                              deferred.reject(error)
                            },
                            handleCompletion: function (reason) {
                              if (!reason) {
                                check(count, message);
                                deferred.resolve();
@@ -467,31 +467,31 @@ function setupHistory() {
   today.setSeconds(1);
   addPlace(makeURI("http://today.com/"), "Today", today.getTime() * 1000);
 
   let lastYear = new Date();
   lastYear.setFullYear(lastYear.getFullYear() - 1);
   addPlace(makeURI("http://before-today.com/"), "Before Today", lastYear.getTime() * 1000);
 
   PlacesUtils.asyncHistory.updatePlaces(places, {
-    handleError: function () ok(false, "Unexpected error in adding visit."),
-    handleResult: function () { },
-    handleCompletion: function () deferred.resolve()
+    handleError: () => ok(false, "Unexpected error in adding visit."),
+    handleResult: () => { },
+    handleCompletion: () => deferred.resolve()
   });
 
   return deferred.promise;
 }
 
 function setupFormHistory() {
 
   function searchEntries(terms, params) {
     let deferred = Promise.defer();
 
     let results = [];
-    FormHistory.search(terms, params, { handleResult: function (result) results.push(result),
+    FormHistory.search(terms, params, { handleResult: result => results.push(result),
                                         handleError: function (error) {
                                           do_throw("Error occurred searching form history: " + error);
                                           deferred.reject(error);
                                         },
                                         handleCompletion: function (reason) { deferred.resolve(results); }
                                       });
     return deferred.promise;
   }
--- a/browser/base/content/test/general/browser_sanitizeDialog.js
+++ b/browser/base/content/test/general/browser_sanitizeDialog.js
@@ -972,17 +972,17 @@ function promiseAddFormEntryWithMinutesA
  * Checks if a form entry exists.
  */
 function formNameExists(name)
 {
   let deferred = Promise.defer();
 
   let count = 0;
   FormHistory.count({ fieldname: name },
-                    { handleResult: function (result) count = result,
+                    { handleResult: result => count = result,
                       handleError: function (error) {
                         do_throw("Error occurred searching form history: " + error);
                         deferred.reject(error);
                       },
                       handleCompletion: function (reason) {
                           if (!reason) deferred.resolve(count);
                       }
                     });
--- a/browser/base/content/test/general/browser_save_link-perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_link-perwindowpb.js
@@ -75,17 +75,17 @@ function triggerSave(aWindow, aCallback)
     event.target.hidePopup();
     info("popup hidden");
   }
 
   function onTransferComplete(aWindow, downloadSuccess, destDir) {
     ok(downloadSuccess, "Link should have been downloaded successfully");
     aWindow.close();
 
-    executeSoon(function() aCallback());
+    executeSoon(() => aCallback());
   }
 }
 
 function test() {
   info("Start the test");
   waitForExplicitFinish();
 
   var gNumSet = 0;
--- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
@@ -111,17 +111,17 @@ function test() {
   }
 
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       windowsToClose.push(aWin);
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
-      executeSoon(function() aCallback(aWin));
+      executeSoon(() => aCallback(aWin));
     });
   };
 
    // this function is called after calling finish() on the test.
   registerCleanupFunction(function() {
     windowsToClose.forEach(function(aWin) {
       aWin.close();
     });
--- a/browser/base/content/test/general/browser_tabMatchesInAwesomebar.js
+++ b/browser/base/content/test/general/browser_tabMatchesInAwesomebar.js
@@ -216,17 +216,17 @@ function checkAutocompleteResults(aExpec
       for (let entry in aExpected) {
         ok(false, "'" + entry + "' should be found in autocomplete");
       }
 
       executeSoon(aCallback);
     },
     setSelectedIndex: function() {},
     get searchCount() { return this.searches.length; },
-    getSearchAt: function(aIndex) this.searches[aIndex],
+    getSearchAt: function(aIndex) { return this.searches[aIndex]; },
     QueryInterface: XPCOMUtils.generateQI([
       Ci.nsIAutoCompleteInput,
       Ci.nsIAutoCompletePopup,
     ])
   };
 
   info("Searching open pages.");
   gController.startSearch(Services.prefs.getCharPref("browser.urlbar.restrict.openpage"));
--- a/browser/base/content/test/general/browser_tabMatchesInAwesomebar_perwindowpb.js
+++ b/browser/base/content/test/general/browser_tabMatchesInAwesomebar_perwindowpb.js
@@ -7,17 +7,17 @@ function test() {
 
   let testURL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
 
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
-      executeSoon(function() aCallback(aWin));
+      executeSoon(() => aCallback(aWin));
     });
   };
 
   testOnWindow({}, function(aNormalWindow) {
     testOnWindow({private: true}, function(aPrivateWindow) {
       runTest(aNormalWindow, aPrivateWindow, false, function() {
         aNormalWindow.close();
         aPrivateWindow.close();
--- a/browser/base/content/test/general/browser_tabfocus.js
+++ b/browser/base/content/test/general/browser_tabfocus.js
@@ -201,17 +201,17 @@ add_task(function*() {
                          "focusedWindow after blur in unfocused tab");
 
   focused = yield getFocusedElementForBrowser(browser1, true);
   is(focused, "Focus is <none>", "focusedElement in first browser after focus in unfocused tab");
   focused = yield getFocusedElementForBrowser(browser2, false);
   is(focused, "Focus is button2", "focusedElement in second browser after focus in unfocused tab");
 
   // When focus is in the tab bar, it should be retained there
-  yield expectFocusShift(function () gBrowser.selectedTab.focus(),
+  yield expectFocusShift(() => gBrowser.selectedTab.focus(),
                          "main-window", "tab2", true,
                          "focusing tab element");
   yield* expectFocusShiftAfterTabSwitch(tab1, "main-window", "tab1", true,
                                         "tab change when selected tab element was focused");
 
   let switchWaiter;
   if (gMultiProcessBrowser) {
     switchWaiter = new Promise((resolve, reject) => {
@@ -228,33 +228,33 @@ add_task(function*() {
   // When this a remote browser, wait for the paint on the second browser so that
   // any post tab-switching stuff has time to complete before blurring the tab.
   // Otherwise, the _adjustFocusAfterTabSwitch in tabbrowser gets confused and
   // isn't sure what tab is really focused.
   if (gMultiProcessBrowser) {
     yield switchWaiter;
   }
 
-  yield expectFocusShift(function () gBrowser.selectedTab.blur(),
+  yield expectFocusShift(() => gBrowser.selectedTab.blur(),
                          "main-window", null, true,
                          "blurring tab element");
 
   // focusing the url field should switch active focus away from the browser but
   // not clear what would be the focus in the browser
   focusElementInChild("button1", "focus");
 
-  yield expectFocusShift(function () gURLBar.focus(),
+  yield expectFocusShift(() => gURLBar.focus(),
                          "main-window", "urlbar", true,
                          "focusedWindow after url field focused");
   focused = yield getFocusedElementForBrowser(browser1, true);
   is(focused, "Focus is button1", "focusedElement after url field focused, first browser");
   focused = yield getFocusedElementForBrowser(browser2, true);
   is(focused, "Focus is button2", "focusedElement after url field focused, second browser");
 
-  yield expectFocusShift(function () gURLBar.blur(),
+  yield expectFocusShift(() => gURLBar.blur(),
                          "main-window", null, true,
                          "blurring url field");
 
   // when a chrome element is focused, switching tabs to a tab with a button
   // with the current focus should focus the button
   yield* expectFocusShiftAfterTabSwitch(tab1, "window1", "button1", true,
                                         "after tab change, focus in url field, button focused in new tab");
 
@@ -269,32 +269,32 @@ add_task(function*() {
                          "after blur in focused tab");
 
   focused = yield getFocusedElementForBrowser(browser1, false);
   is(focused, "Focus is <none>", "focusedWindow after blur in focused tab, child");
   focusedWindow = {};
   is(fm.getFocusedElementForWindow(window, false, focusedWindow), browser1, "focusedElement after blur in focused tab, parent");
 
   // blurring an non-focused url field should have no effect
-  yield expectFocusShift(function () gURLBar.blur(),
+  yield expectFocusShift(() => gURLBar.blur(),
                          "window1", null, false,
                          "after blur in unfocused url field");
 
   focusedWindow = {};
   is(fm.getFocusedElementForWindow(window, false, focusedWindow), browser1, "focusedElement after blur in unfocused url field");
 
   // switch focus to a tab with a currently focused element
   yield* expectFocusShiftAfterTabSwitch(tab2, "window2", "button2", true,
                                         "after switch from unfocused to focused tab");
   focused = yield getFocusedElementForBrowser(browser2, true);
   is(focused, "Focus is button2", "focusedElement after switch from unfocused to focused tab");
 
   // clearing focus on the chrome window should switch the focus to the
   // chrome window
-  yield expectFocusShift(function () fm.clearFocus(window),
+  yield expectFocusShift(() => fm.clearFocus(window),
                          "main-window", null, true,
                          "after switch to chrome with no focused element");
 
   focusedWindow = {};
   is(fm.getFocusedElementForWindow(window, false, focusedWindow), null, "focusedElement after switch to chrome with no focused element");
 
   // switch focus to another tab when neither have an active focus
   yield* expectFocusShiftAfterTabSwitch(tab1, "window1", null, true,
@@ -328,17 +328,17 @@ add_task(function*() {
 
   // Document navigation with F6 does not yet work in mutli-process browsers.
   if (!gMultiProcessBrowser) {
     gURLBar.focus();
     actualEvents = [];
     _browser_tabfocus_test_lastfocus = "urlbar";
     _browser_tabfocus_test_lastfocuswindow = "main-window";
 
-    yield expectFocusShift(function () EventUtils.synthesizeKey("VK_F6", { }),
+    yield expectFocusShift(() => EventUtils.synthesizeKey("VK_F6", { }),
                            "window1", "html1",
                            true, "switch document forward with f6");
 
     EventUtils.synthesizeKey("VK_F6", { });
     is(fm.focusedWindow, window, "switch document forward again with f6");
 
     browser1.style.MozUserFocus = "ignore";
     browser1.clientWidth;
--- a/browser/base/content/test/general/browser_windowopen_reflows.js
+++ b/browser/base/content/test/general/browser_windowopen_reflows.js
@@ -24,17 +24,17 @@ const EXPECTED_REFLOWS = [
   // (https://bugzilla.mozilla.org/show_bug.cgi?id=892154 will fix this)
   "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm",
 ];
 
 if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
   // TabsInTitlebar._update causes a reflow on OS X and Windows trying to do calculations
   // since layout info is already dirty. This doesn't seem to happen before
   // MozAfterPaint on Linux.
-  EXPECTED_REFLOWS.push("rect@chrome://browser/content/browser.js|" +
+  EXPECTED_REFLOWS.push("TabsInTitlebar._update/rect@chrome://browser/content/browser.js|" +
                           "TabsInTitlebar._update@chrome://browser/content/browser.js|" +
                           "updateAppearance@chrome://browser/content/browser.js|" +
                           "handleEvent@chrome://browser/content/tabbrowser.xml|");
 }
 
 if (Services.appinfo.OS == "Darwin") {
   // _onOverflow causes a reflow getting widths.
   EXPECTED_REFLOWS.push("OverflowableToolbar.prototype._onOverflow@resource:///modules/CustomizableUI.jsm|" +
--- a/browser/base/content/test/newtab/browser_newtab_bug722273.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug722273.js
@@ -41,17 +41,17 @@ function promiseAddFakeVisits() {
   }
   let place = {
     uri: makeURI(URL),
     title: "fake site",
     visits: visits
   };
   return new Promise((resolve, reject) => {
     PlacesUtils.asyncHistory.updatePlaces(place, {
-      handleError: function () reject(new Error("Couldn't add visit")),
+      handleError: () => reject(new Error("Couldn't add visit")),
       handleResult: function () {},
       handleCompletion: function () {
         NewTabUtils.links.populateCache(function () {
           NewTabUtils.allPages.update();
           resolve();
         }, true);
       }
     });
--- a/browser/base/content/test/newtab/head.js
+++ b/browser/base/content/test/newtab/head.js
@@ -305,17 +305,17 @@ function fillHistory(aLinks, aCallback =
       title: link.title,
       // Links are secondarily sorted by visit date descending, so decrease the
       // visit date as we progress through the array so that links appear in the
       // grid in the order they're present in the array.
       visits: [{visitDate: now - i, transitionType: transitionLink}]
     };
 
     PlacesUtils.asyncHistory.updatePlaces(place, {
-      handleError: function () ok(false, "couldn't add visit to history"),
+      handleError: () => ok(false, "couldn't add visit to history"),
       handleResult: function () {},
       handleCompletion: function () {
         if (--numLinks == 0 && aCallback)
           aCallback();
       }
     });
   }
 }
--- a/browser/base/content/test/plugins/browser_CTP_data_urls.js
+++ b/browser/base/content/test/plugins/browser_CTP_data_urls.js
@@ -63,17 +63,17 @@ add_task(function* () {
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
   yield promise;
 
   // Simulate clicking the "Allow Always" button.
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
     PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   // check plugin state
   pluginInfo = yield promiseForPluginInfo("test");
   ok(pluginInfo.activated, "Test 1b, plugin should be activated");
 });
@@ -180,17 +180,17 @@ add_task(function* () {
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
   yield promise;
 
   // Simulate clicking the "Allow Always" button.
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
     PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   // check plugin state
   pluginInfo = yield promiseForPluginInfo("test");
   ok(pluginInfo.activated, "Test 3a, plugin should be activated");
 
@@ -238,17 +238,17 @@ add_task(function* () {
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
   yield promise;
 
   // Simulate clicking the "Allow Always" button.
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
     PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   // check plugin state
   pluginInfo = yield promiseForPluginInfo("test");
   ok(pluginInfo.activated, "Test 4a, plugin should be activated");
 });
--- a/browser/base/content/test/plugins/browser_CTP_drag_drop.js
+++ b/browser/base/content/test/plugins/browser_CTP_drag_drop.js
@@ -78,17 +78,17 @@ add_task(function* () {
     let left = (bounds.left + bounds.right) / 2;
     let top = (bounds.top + bounds.bottom) / 2;
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
 
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed && gNewWindow.PopupNotifications.panel.firstChild;
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed && gNewWindow.PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
 });
 
 add_task(function* () {
   // Click the activate button on doorhanger to make sure it works
   gNewWindow.PopupNotifications.panel.firstChild._primaryButton.click();
 
   let pluginInfo = yield promiseForPluginInfo("test", gNewWindow.gBrowser.selectedBrowser);
--- a/browser/base/content/test/plugins/browser_bug787619.js
+++ b/browser/base/content/test/plugins/browser_bug787619.js
@@ -47,17 +47,17 @@ add_task(function* () {
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
   yield promise;
 
   // check plugin state
   pluginInfo = yield promiseForPluginInfo("plugin");
   ok(!pluginInfo.activated, "1b plugin should not be activated");
 
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
     PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   // check plugin state
   pluginInfo = yield promiseForPluginInfo("plugin");
   ok(pluginInfo.activated, "plugin should be activated");
 
--- a/browser/base/content/test/plugins/browser_pluginnotification.js
+++ b/browser/base/content/test/plugins/browser_pluginnotification.js
@@ -234,17 +234,17 @@ add_task(function* () {
     let left = (bounds.left + bounds.right) / 2;
     let top = (bounds.top + bounds.bottom) / 2;
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
 
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
   yield promiseForCondition(condition);
 });
 
 // Tests that clicking the text of the overlay activates the plugin
 add_task(function* () {
   yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
 
   // Work around for delayed PluginBindingAttached
@@ -264,17 +264,17 @@ add_task(function* () {
     let left = (bounds.left + bounds.right) / 2;
     let top = (bounds.top + bounds.bottom) / 2;
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
 
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
   yield promiseForCondition(condition);
 });
 
 // Tests that clicking the box of the overlay activates the doorhanger
 // (just to be thorough)
 add_task(function* () {
   yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
 
@@ -291,17 +291,17 @@ add_task(function* () {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", 50, 50, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", 50, 50, 0, 1, 0, false, 0, 0);
   });
 
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
+  let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed &&
     PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   pluginInfo = yield promiseForPluginInfo("test");
   ok(pluginInfo.activated, "Test 19e, Plugin should not be activated");
 
   clearAllPluginPermissions();
@@ -374,17 +374,17 @@ add_task(function* () {
     let left = (bounds.left + bounds.right) / 2;
     let top = (bounds.top + bounds.bottom) / 2;
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
   });
 
-  let condition = function() !notification.dismissed && !!PopupNotifications.panel.firstChild;
+  let condition = () => !notification.dismissed && !!PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   pluginInfo = yield promiseForPluginInfo("test");
   ok(pluginInfo.activated, "Test 20c, plugin should be activated");
 
   result = ContentTask.spawn(gTestBrowser, {}, function* () {
     let doc = content.document;
--- a/browser/base/content/test/plugins/browser_plugins_added_dynamically.js
+++ b/browser/base/content/test/plugins/browser_plugins_added_dynamically.js
@@ -109,17 +109,17 @@ add_task(function* () {
 
   yield promiseForNotificationShown(notification);
 
   is(notification.options.pluginData.size, 1, "Should be one plugin action");
 
   let pluginInfo = yield promiseForPluginInfo("pluginone");
   ok(!pluginInfo.activated, "Test 8, test plugin should be activated");
 
-  let condition = function() !notification.dismissed &&
+  let condition = () => !notification.dismissed &&
     PopupNotifications.panel.firstChild;
   yield promiseForCondition(condition);
 
   // "click" the button to activate the Test plugin
   PopupNotifications.panel.firstChild._primaryButton.click();
 
   pluginInfo = yield promiseForPluginInfo("pluginone");
   ok(pluginInfo.activated, "Test 9, test plugin should be activated");
--- a/browser/base/content/test/plugins/browser_private_clicktoplay.js
+++ b/browser/base/content/test/plugins/browser_private_clicktoplay.js
@@ -114,17 +114,17 @@ function test2a() {
 
   // Simulate clicking the "Allow Now" button.
   let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
                                                    "Shown");
   popupNotification.reshow();
   promiseShown.then(() => {
     PopupNotifications.panel.firstChild._secondaryButton.click();
 
-    let condition = function() objLoadingContent.activated;
+    let condition = () => objLoadingContent.activated;
     waitForCondition(condition, test2b, "Test 2a, Waited too long for plugin to activate");
   });
 }
 
 function test2b() {
   createPrivateWindow(test2c, gHttpTestRoot + "plugin_test.html");
 }
 
@@ -164,17 +164,17 @@ function test3a() {
 
   // Simulate clicking the "Allow Always" button.
   let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
                                                    "Shown");
   popupNotification.reshow();
   promiseShown.then(() => {
     PopupNotifications.panel.firstChild._secondaryButton.click();
 
-    let condition = function() objLoadingContent.activated;
+    let condition = () => objLoadingContent.activated;
     waitForCondition(condition, test3b, "Test 3a, Waited too long for plugin to activate");
   });
 }
 
 function test3b() {
   createPrivateWindow(test3c, gHttpTestRoot + "plugin_test.html");
 }
 
--- a/browser/base/content/test/social/browser_social_chatwindow.js
+++ b/browser/base/content/test/social/browser_social_chatwindow.js
@@ -248,22 +248,22 @@ var tests = {
   },
 
   testMultipleProviderChat: function(next) {
     // test incomming chats from all providers
     let port0 = openChat(Social.providers[0], function() {
       let port1 = openChat(Social.providers[1], function() {
         let port2 = openChat(Social.providers[2], function() {
           let chats = document.getElementById("pinnedchats");
-          waitForCondition(function() chats.children.length == Social.providers.length,
+          waitForCondition(() => chats.children.length == Social.providers.length,
             function() {
               ok(true, "one chat window per provider opened");
               // test logout of a single provider
               port2.postMessage({topic: "test-logout"});
-              waitForCondition(function() chats.children.length == Social.providers.length - 1,
+              waitForCondition(() => chats.children.length == Social.providers.length - 1,
                 function() {
                   Task.spawn(closeAllChats).then(next);
                 },
                 "chat window didn't close");
             }, "chat windows did not open");
         });
       });
     });
@@ -283,17 +283,17 @@ var tests = {
         case "test-init-done":
           info("open first chat window");
           port.postMessage({topic: "test-worker-chat", data: chatUrl});
           break;
         case "got-chatbox-message":
           ok(true, "got a chat window opened");
           if (opened) {
             port.postMessage({topic: "test-logout"});
-            waitForCondition(function() document.getElementById("pinnedchats").firstChild == null,
+            waitForCondition(() => document.getElementById("pinnedchats").firstChild == null,
                              function() {
                               next();
                              },
                              "chat windows didn't close");
           } else {
             // open a second chat window
             opened = true;
             port.postMessage({topic: "test-worker-chat", data: chatUrl+"?id=1"});
--- a/browser/base/content/test/social/browser_social_chatwindowfocus.js
+++ b/browser/base/content/test/social/browser_social_chatwindowfocus.js
@@ -30,17 +30,17 @@ function openChatViaSidebarMessage(port,
 }
 
 function openChatViaWorkerMessage(port, data, callback) {
   // sadly there is no message coming back to tell us when the chat has
   // been opened, so we wait until one appears.
   let chatbar = getChatBar();
   let numExpected = chatbar.childElementCount + 1;
   port.postMessage({topic: "test-worker-chat", data: data});
-  waitForCondition(function() chatbar.childElementCount == numExpected,
+  waitForCondition(() => chatbar.childElementCount == numExpected,
                    function() {
                       // so the child has been added, but we don't know if it
                       // has been intialized - re-request it and the callback
                       // means it's done.  Minimized, same as the worker.
                       chatbar.openChat(SocialSidebar.provider.origin,
                                        SocialSidebar.provider.name,
                                        data,
                                        "minimized",
@@ -102,17 +102,17 @@ function test() {
   tab.linkedBrowser.addEventListener("load", function tabLoad(event) {
     tab.linkedBrowser.removeEventListener("load", tabLoad, true);
     // before every test we focus the input field.
     let preSubTest = function(cb) {
       // XXX - when bug 604289 is fixed it should be possible to just do:
       // tab.linkedBrowser.contentWindow.focus()
       // but instead we must do:
       tab.linkedBrowser.contentDocument.getElementById("theinput").focus();
-      waitForCondition(function() isTabFocused(), cb, "tab should have focus");
+      waitForCondition(() => isTabFocused(), cb, "tab should have focus");
     }
     let postSubTest = function(cb) {
       Task.spawn(closeAllChats).then(cb);
     }
     // and run the tests.
     runSocialTestWithProvider(manifest, function (finishcb) {
       SocialSidebar.show();
       runSocialTests(tests, preSubTest, postSubTest, function () {
@@ -139,17 +139,17 @@ var tests = {
         is(chatbar.childElementCount, 1, "exactly 1 chat open");
         ok(isTabFocused(), "tab should still be focused");
         // re-request the same chat via a message.
         openChatViaSidebarMessage(port, {stealFocus: 1}, function() {
           is(chatbar.childElementCount, 1, "still exactly 1 chat open");
           ok(isTabFocused(), "tab should still be focused");
           // re-request the same chat via user event.
           openChatViaUser();
-          waitForCondition(function() isChatFocused(chatbar.selectedChat),
+          waitForCondition(() => isChatFocused(chatbar.selectedChat),
                            function() {
             is(chatbar.childElementCount, 1, "still exactly 1 chat open");
             is(chatbar.selectedChat, chatbar.firstElementChild, "chat should be selected");
             next();
           }, "chat should be focused");
         });
       });
     });
@@ -157,16 +157,16 @@ var tests = {
 
   // In this test we arrange for the sidebar to open the chat via a simulated
   // click.  This should cause the new chat to be opened and focused.
   testFocusWhenViaUser: function(next) {
     startTestAndWaitForSidebar(function(port) {
       let chatbar = getChatBar();
       openChatViaUser();
       ok(chatbar.firstElementChild, "chat opened");
-      waitForCondition(function() isChatFocused(chatbar.selectedChat),
+      waitForCondition(() => isChatFocused(chatbar.selectedChat),
                        function() {
         is(chatbar.selectedChat, chatbar.firstElementChild, "chat is selected");
         next();
       }, "chat should be focused");
     });
   },
 };
--- a/browser/base/content/test/social/browser_social_errorPage.js
+++ b/browser/base/content/test/social/browser_social_errorPage.js
@@ -129,17 +129,17 @@ var tests = {
       openChat(
         manifest.sidebarURL, /* empty html page */
         function() { // the panel api callback
           panelCallbackCount++;
         },
         function() { // the "load" callback.
           todo_is(panelCallbackCount, 0, "Bug 833207 - should be no callback when error page loads.");
           let chat = getChatBar().selectedChat;
-          waitForCondition(function() chat.content != null && chat.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly")==0,
+          waitForCondition(() => chat.content != null && chat.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly")==0,
                            function() {
                             chat.close();
                             next();
                             },
                            "error page didn't appear");
         }
       );
     });
@@ -157,24 +157,24 @@ var tests = {
       null,
       function() { // the "load" callback.
         let chat = getChatBar().selectedChat;
         is(chat.contentDocument.documentURI, url, "correct url loaded");
         // toggle to a detached window.
         chat.swapWindows().then(
           chat => {
             ok(!!chat.content, "we have chat content 1");
-            waitForCondition(function() chat.content != null && chat.contentDocument.readyState == "complete",
+            waitForCondition(() => chat.content != null && chat.contentDocument.readyState == "complete",
                              function() {
               // now go offline and reload the chat - about:socialerror should be loaded.
               goOffline().then(function() {
                 ok(!!chat.content, "we have chat content 2");
                 chat.contentDocument.location.reload();
                 info("chat reload called");
-                waitForCondition(function() chat.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly")==0,
+                waitForCondition(() => chat.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly")==0,
                                  function() {
                                   chat.close();
                                   next();
                                   },
                                  "error page didn't appear");
               });
             }, "swapped window loaded");
           }
--- a/browser/base/content/test/social/browser_social_marks.js
+++ b/browser/base/content/test/social/browser_social_marks.js
@@ -152,34 +152,34 @@ var tests = {
           case "test-init-done":
             ok(true, "test-init-done received");
             ok(provider.profile.userName, "profile was set by test worker");
             // first click marks the page, second click opens the page. We have to
             // synthesize so the command event happens
             EventUtils.synthesizeMouseAtCenter(btn, {});
             // wait for the button to be marked, click to open panel
             is(btn.panel.state, "closed", "panel should not be visible yet");
-            waitForCondition(function() btn.isMarked, function() {
+            waitForCondition(() => btn.isMarked, function() {
               EventUtils.synthesizeMouseAtCenter(btn, {});
             }, "button is marked");
             break;
           case "got-social-panel-visibility":
             ok(true, "got the panel message " + e.data.result);
             if (e.data.result == "shown") {
               // unmark the page via the button in the page
               ensureFrameLoaded(btn.content).then(() => {
                 let doc = btn.contentDocument;
                 let unmarkBtn = doc.getElementById("unmark");
                 ok(unmarkBtn, "testMarkPanel - got the panel unmark button");
                 EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
               });
             } else {
               // page should no longer be marked
               port.close();
-              waitForCondition(function() !btn.isMarked, function() {
+              waitForCondition(() => !btn.isMarked, function() {
                 // cleanup after the page has been unmarked
                 ensureBrowserTabClosed(tab).then(() => {
                   ok(btn.disabled, "button is disabled");
                   next();
                 });
               }, "button unmarked");
             }
             break;
@@ -240,17 +240,17 @@ var tests = {
       ok(!btn.disabled, "button is enabled");
       port.onmessage = function (e) {
         let topic = e.data.topic;
         switch (topic) {
           case "test-init-done":
             ok(true, "test-init-done received");
             ok(provider.profile.userName, "profile was set by test worker");
             port.postMessage({topic: "test-logout"});
-            waitForCondition(function() !provider.profile.userName,
+            waitForCondition(() => !provider.profile.userName,
                 function() {
                   // when the provider has not indicated to us that a user is
                   // logged in, the first click opens the page.
                   EventUtils.synthesizeMouseAtCenter(btn, {});
                 },
                 "profile was unset by test worker");
             break;
           case "got-social-panel-visibility":
@@ -263,17 +263,17 @@ var tests = {
                 let doc = btn.contentDocument;
                 let unmarkBtn = doc.getElementById("unmark");
                 ok(unmarkBtn, "testMarkPanelLoggedOut - got the panel unmark button");
                 EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
               });
             } else {
               // page should no longer be marked
               port.close();
-              waitForCondition(function() !btn.isMarked, function() {
+              waitForCondition(() => !btn.isMarked, function() {
                 // cleanup after the page has been unmarked
                 ensureBrowserTabClosed(tab).then(() => {
                   ok(btn.disabled, "button is disabled");
                   next();
                 });
               }, "button unmarked");
             }
             break;
--- a/browser/base/content/test/social/browser_social_multiworker.js
+++ b/browser/base/content/test/social/browser_social_multiworker.js
@@ -47,17 +47,17 @@ var tests = {
       };
       port.postMessage({topic: "test-init"});
     }
 
     for (let p of Social.providers) {
       oneWorkerTest(p);
     }
 
-    waitForCondition(function() messageReceived == Social.providers.length,
+    waitForCondition(() => messageReceived == Social.providers.length,
                      next, "received messages from all workers",
                      /* increase timeout because shutting down a child process is slow */ 60);
   },
 
    testMultipleWorkerEnabling: function(next) {
      // test that all workers are enabled when we allow multiple workers
      for (let p of Social.providers) {
        ok(p.enabled, "provider enabled");
--- a/browser/base/content/test/social/browser_social_window.js
+++ b/browser/base/content/test/social/browser_social_window.js
@@ -91,17 +91,17 @@ var tests = {
 
   // Check when providers are enabled and social is turned on at startup.
   testEnabledStartup: function(cbnext) {
     setManifestPref("social.manifest.test", manifest);
     ok(!SocialSidebar.opened, "sidebar is closed initially");
     SocialService.addProvider(manifest, function() {
       SocialService.addProvider(manifest2, function (provider) {
         SocialSidebar.show();
-        waitForCondition(function() SocialSidebar.opened,
+        waitForCondition(() => SocialSidebar.opened,
                      function() {
           ok(SocialSidebar.opened, "first window sidebar is open");
           openWindowAndWaitForInit(window, function(w1) {
             ok(w1.SocialSidebar.opened, "new window sidebar is open");
             ok(SocialService.hasEnabledProviders, "providers are enabled");
             checkSocialUI(w1);
             // now init is complete, open a second window
             openWindowAndWaitForInit(window, function(w2) {
@@ -135,17 +135,17 @@ var tests = {
     ok(!SocialSidebar.opened, "sidebar is closed initially");
     ok(!Services.prefs.prefHasUserValue("social.sidebar.provider"), "global state unset");
     // mimick no session state in opener so we exercise the global state via pref
     SessionStore.deleteWindowValue(window, "socialSidebar");
     ok(!SessionStore.getWindowValue(window, "socialSidebar"), "window state unset");
     SocialService.addProvider(manifest, function() {
       openWindowAndWaitForInit(window, function(w1) {
         w1.SocialSidebar.show();
-        waitForCondition(function() w1.SocialSidebar.opened,
+        waitForCondition(() => w1.SocialSidebar.opened,
                      function() {
           ok(Services.prefs.prefHasUserValue("social.sidebar.provider"), "global state set");
           ok(!SocialSidebar.opened, "1. main sidebar is still closed");
           ok(w1.SocialSidebar.opened, "1. window sidebar is open");
           closeWindow(w1, function() {
             // this time, the global state should cause the sidebar to be opened
             // in the new window
             openWindowAndWaitForInit(window, function(w1) {
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -149,17 +149,17 @@ function runSocialTestWithProvider(manif
       }
 
       // If we've added all the providers we need, call the callback to start
       // the tests (and give it a callback it can call to finish them)
       if (providersAdded == manifests.length) {
         registerCleanupFunction(function () {
           finishSocialTest(true);
         });
-        waitForCondition(function() provider.enabled,
+        waitForCondition(() => provider.enabled,
                          function() {
           info("provider has been enabled");
           callback(finishSocialTest);
         }, "providers added and enabled");
       }
     });
   });
 }
@@ -584,17 +584,17 @@ function resizeAndCheckWidths(first, sec
   let count = checks.length;
   let [width, numExpectedVisible, why] = checks.shift();
   info("<< Check " + count + ": " + why);
   info(count + ": " + "resizing window to " + width + ", expect " + numExpectedVisible + " visible items");
   resizeWindowToChatAreaWidth(width, function(sizedOk) {
     checkPopup();
     ok(sizedOk, count+": window resized correctly");
     function collapsedObserver(r, m) {
-      if ([first, second, third].filter(function(item) !item.collapsed).length == numExpectedVisible) {
+      if ([first, second, third].filter(item => !item.collapsed).length == numExpectedVisible) {
         if (m) {
           m.disconnect();
         }
         ok(true, count + ": " + "correct number of chats visible");
         info(">> Check " + count);
         executeSoon(function() {
           resizeAndCheckWidths(first, second, third, checks, cb);
         });
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -598,17 +598,17 @@ file, You can obtain one at http://mozil
           } catch (ex) {}
 
           // If the entire URL is selected, just use the actual loaded URI.
           if (inputVal == selectedVal) {
             // ... but only if  isn't a javascript: or data: URI, since those
             // are hard to read when encoded
             if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) {
               // Parentheses are known to confuse third-party applications (bug 458565).
-              selectedVal = uri.spec.replace(/[()]/g, function (c) escape(c));
+              selectedVal = uri.spec.replace(/[()]/g, c => escape(c));
             }
 
             return selectedVal;
           }
 
           // Just the beginning of the URL is selected, check for a trimmed
           // value
           let spec = uri.spec;
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -209,17 +209,17 @@ const CustomizableWidgets = [
               let item = doc.createElementNS(kNSXUL, "toolbarbutton");
               item.setAttribute("label", title || uri);
               item.setAttribute("targetURI", uri);
               item.setAttribute("class", "subviewbutton");
               item.addEventListener("click", function (aEvent) {
                 onHistoryVisit(uri, aEvent, item);
               });
               if (icon) {
-                let iconURL = PlacesUtils.getImageURLForResolution(win, "moz-anno:favicon:" + icon);
+                let iconURL = "moz-anno:favicon:" + icon;
                 item.setAttribute("image", iconURL);
               }
               fragment.appendChild(item);
             } catch (e) {
               ERROR("Error while showing history subview: " + e);
             }
           }
           items.appendChild(fragment);
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -383,18 +383,17 @@ PlacesViewBase.prototype = {
       }
       else
         throw "Unexpected node";
 
       element.setAttribute("label", PlacesUIUtils.getBestTitle(aPlacesNode));
 
       let icon = aPlacesNode.icon;
       if (icon)
-        element.setAttribute("image",
-                             PlacesUtils.getImageURLForResolution(window, icon));
+        element.setAttribute("image", icon);
     }
 
     element._placesNode = aPlacesNode;
     if (!this._domNodes.has(aPlacesNode))
       this._domNodes.set(aPlacesNode, element);
 
     return element;
   },
@@ -522,18 +521,17 @@ PlacesViewBase.prototype = {
     // Here we need the <menu>.
     if (elt.localName == "menupopup")
       elt = elt.parentNode;
 
     let icon = aPlacesNode.icon;
     if (!icon)
       elt.removeAttribute("image");
     else if (icon != elt.getAttribute("image"))
-      elt.setAttribute("image",
-                       PlacesUtils.getImageURLForResolution(window, icon));
+      elt.setAttribute("image", icon);
   },
 
   nodeAnnotationChanged:
   function PVB_nodeAnnotationChanged(aPlacesNode, aAnno) {
     let elt = this._getDOMNodeForPlacesNode(aPlacesNode);
 
     // All livemarks have a feedURI, so use it as our indicator of a livemark
     // being modified.
@@ -1053,18 +1051,17 @@ PlacesToolbar.prototype = {
       button = document.createElement("toolbarseparator");
     }
     else {
       button = document.createElement("toolbarbutton");
       button.className = "bookmark-item";
       button.setAttribute("label", aChild.title || "");
       let icon = aChild.icon;
       if (icon)
-        button.setAttribute("image",
-                            PlacesUtils.getImageURLForResolution(window, icon));
+        button.setAttribute("image", icon);
 
       if (PlacesUtils.containerTypes.indexOf(type) != -1) {
         button.setAttribute("type", "menu");
         button.setAttribute("container", "true");
 
         if (PlacesUtils.nodeIsQuery(aChild)) {
           button.setAttribute("query", "true");
           if (PlacesUtils.nodeIsTagQuery(aChild))
@@ -1881,18 +1878,17 @@ PlacesPanelMenuView.prototype = {
     else {
       button = document.createElement("toolbarbutton");
       button.className = "bookmark-item";
       if (typeof this.options.extraClasses.entry == "string")
         button.classList.add(this.options.extraClasses.entry);
       button.setAttribute("label", aChild.title || "");
       let icon = aChild.icon;
       if (icon)
-        button.setAttribute("image",
-                            PlacesUtils.getImageURLForResolution(window, icon));
+        button.setAttribute("image", icon);
 
       if (PlacesUtils.containerTypes.indexOf(type) != -1) {
         button.setAttribute("container", "true");
 
         if (PlacesUtils.nodeIsQuery(aChild)) {
           button.setAttribute("query", "true");
           if (PlacesUtils.nodeIsTagQuery(aChild))
             button.setAttribute("tagContainer", "true");
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -1409,19 +1409,16 @@ PlacesTreeView.prototype = {
   },
 
   getImageSrc: function PTV_getImageSrc(aRow, aColumn) {
     // Only the title column has an image.
     if (this._getColumnType(aColumn) != this.COLUMN_TYPE_TITLE)
       return "";
 
     let node = this._getNodeForRow(aRow);
-    if (PlacesUtils.nodeIsURI(node) && node.icon)
-      return PlacesUtils.getImageURLForResolution(window, node.icon);
-
     return node.icon;
   },
 
   getProgressMode: function(aRow, aColumn) { },
   getCellValue: function(aRow, aColumn) { },
 
   getCellText: function PTV_getCellText(aRow, aColumn) {
     let node = this._getNodeForRow(aRow);
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -1,17 +1,16 @@
 /* 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/. */
 
 // Load DownloadUtils module for convertByteUnits
 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
 Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
 
 var gAdvancedPane = {
   _inited: false,
 
   /**
    * Brings the appropriate tab to the front and initializes various bits of UI.
    */
   init: function ()
@@ -567,17 +566,17 @@ var gAdvancedPane = {
     }
   },
 
   removeOfflineApp: function()
   {
     var list = document.getElementById("offlineAppsList");
     var item = list.selectedItem;
     var origin = item.getAttribute("origin");
-    var principal = BrowserUtils.principalFromOrigin(origin);
+    var principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
 
     var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                             .getService(Components.interfaces.nsIPromptService);
     var flags = prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_0 +
                 prompts.BUTTON_TITLE_CANCEL * prompts.BUTTON_POS_1;
 
     var bundle = document.getElementById("bundlePreferences");
     var title = bundle.getString("offlineAppRemoveTitle");
--- a/browser/components/preferences/in-content/search.js
+++ b/browser/components/preferences/in-content/search.js
@@ -111,18 +111,17 @@ var gSearchPane = {
       currentEngine = engines[0].name;
 
     // Now clean-up and rebuild the list.
     list.removeAllItems();
     gEngineView._engineStore._engines.forEach(e => {
       let item = list.appendItem(e.name);
       item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon");
       if (e.iconURI) {
-        let uri = PlacesUtils.getImageURLForResolution(window, e.iconURI.spec);
-        item.setAttribute("image", uri);
+        item.setAttribute("image", e.iconURI.spec);
       }
       item.engine = e;
       if (e.name == currentEngine)
         list.selectedItem = item;
     });
   },
 
   handleEvent: function(aEvent) {
@@ -483,18 +482,17 @@ EngineView.prototype = {
 
   // nsITreeView
   get rowCount() {
     return this._engineStore.engines.length;
   },
 
   getImageSrc: function(index, column) {
     if (column.id == "engineName" && this._engineStore.engines[index].iconURI) {
-      let uri = this._engineStore.engines[index].iconURI.spec;
-      return PlacesUtils.getImageURLForResolution(window, uri);
+      return this._engineStore.engines[index].iconURI.spec;
     }
     return "";
   },
 
   getCellText: function(index, column) {
     if (column.id == "engineName")
       return this._engineStore.engines[index].name;
     else if (column.id == "engineKeyword")
--- a/browser/components/preferences/translation.js
+++ b/browser/components/preferences/translation.js
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/BrowserUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "gLangBundle", () =>
   Services.strings.createBundle("chrome://global/locale/languageNames.properties"));
 
 const kPermissionType = "translate";
 const kLanguagesPref = "browser.translation.neverForLanguages";
 
 function Tree(aId, aData)
@@ -209,30 +208,30 @@ var gTranslationExceptions = {
 
   onAllLanguagesDeleted: function() {
     Services.prefs.setCharPref(kLanguagesPref, "");
   },
 
   onSiteDeleted: function() {
     let removedSites = this._siteTree.getSelectedItems();
     for (let origin of removedSites) {
-      let principal = BrowserUtils.principalFromOrigin(origin);
+      let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
       Services.perms.removeFromPrincipal(principal, kPermissionType);
     }
   },
 
   onAllSitesDeleted: function() {
     if (this._siteTree.isEmpty)
       return;
 
     let removedSites = this._sites.splice(0, this._sites.length);
     this._siteTree.boxObject.rowCountChanged(0, -removedSites.length);
 
     for (let origin of removedSites) {
-      let principal = BrowserUtils.principalFromOrigin(origin);
+      let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
       Services.perms.removeFromPrincipal(principal, kPermissionType);
     }
 
     this.onSiteSelected();
   },
 
   onSiteKeyPress: function(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE)
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -260,19 +260,16 @@
           BrowserSearch.updateOpenSearchBadge();
         ]]></body>
       </method>
 
       <method name="setIcon">
         <parameter name="element"/>
         <parameter name="uri"/>
         <body><![CDATA[
-          if (uri) {
-            uri = this.PlacesUtils.getImageURLForResolution(window, uri);
-          }
           element.setAttribute("src", uri);
         ]]></body>
       </method>
 
       <method name="updateDisplay">
         <body><![CDATA[
           var uri = this.currentEngine.iconURI;
           this.setIcon(this, uri ? uri.spec : "");
@@ -1086,18 +1083,17 @@
         </getter>
       </property>
 
       <method name="updateHeader">
         <body><![CDATA[
           let currentEngine = Services.search.currentEngine;
           let uri = currentEngine.iconURI;
           if (uri) {
-            uri = uri.spec;
-            this.setAttribute("src", PlacesUtils.getImageURLForResolution(window, uri));
+            this.setAttribute("src", uri.spec);
           }
           else {
             // If the default has just been changed to a provider without icon,
             // avoid showing the icon of the previous default provider.
             this.removeAttribute("src");
           }
 
           let headerText = this.bundle.formatStringFromName("searchHeader",
@@ -1249,18 +1245,17 @@
             button.setAttribute("class", "addengine-item");
             button.setAttribute("label", label);
             button.setAttribute("pack", "start");
 
             button.setAttribute("crop", "end");
             button.setAttribute("tooltiptext", engine.uri);
             button.setAttribute("uri", engine.uri);
             if (engine.icon) {
-              let uri = PlacesUtils.getImageURLForResolution(window, engine.icon);
-              button.setAttribute("image", uri);
+              button.setAttribute("image", engine.icon);
             }
             button.setAttribute("title", engine.title);
             addEngineList.appendChild(button);
           }
         }
 
         // Finally, build the list of one-off buttons.
         while (list.firstChild)
@@ -1323,17 +1318,17 @@
 
         let dummyItems = enginesPerRow - (engines.length % enginesPerRow || enginesPerRow);
         for (let i = 0; i < engines.length; ++i) {
           let engine = engines[i];
           let button = document.createElementNS(kXULNS, "button");
           button.id = "searchbar-engine-one-off-item-" + engine.name.replace(/ /g, '-');
           let uri = "chrome://browser/skin/search-engine-placeholder.png";
           if (engine.iconURI) {
-            uri = PlacesUtils.getImageURLForResolution(window, engine.iconURI.spec);
+            uri = engine.iconURI.spec;
           }
           button.setAttribute("image", uri);
           button.setAttribute("class", "searchbar-engine-one-off-item");
           button.setAttribute("tooltiptext", engine.name);
           button.setAttribute("width", buttonWidth);
           button.engine = engine;
 
           if ((i + 1) % enginesPerRow == 0)
--- a/browser/components/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm
+++ b/browser/components/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm
@@ -164,15 +164,15 @@ this.RecentlyClosedTabsAndWindowsMenuUti
       return;
 
     aEvent.view.undoCloseTab(aEvent.originalTarget.getAttribute("value"));
     aEvent.view.gBrowser.moveTabToEnd();
   },
 };
 
 function setImage(aWindow, aItem, aElement) {
-  let iconURL = PlacesUtils.getImageURLForResolution(aWindow, aItem.image);
+  let iconURL = aItem.image;
   // don't initiate a connection just to fetch a favicon (see bug 467828)
   if (/^https?:/.test(iconURL))
     iconURL = "moz-anno:favicon:" + iconURL;
 
   aElement.setAttribute("image", iconURL);
 }
--- a/browser/components/sessionstore/SessionStorage.jsm
+++ b/browser/components/sessionstore/SessionStorage.jsm
@@ -4,17 +4,16 @@
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["SessionStorage"];
 
 const Cu = Components.utils;
 const Ci = Components.interfaces;
 
-Cu.import("resource://gre/modules/BrowserUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "console",
   "resource://gre/modules/devtools/shared/Console.jsm");
 
 // Returns the principal for a given |frame| contained in a given |docShell|.
 function getPrincipalForFrame(docShell, frame) {
@@ -100,17 +99,17 @@ var SessionStorageInternal = {
    * @param aStorageData
    *        A nested object with storage data to be restored that has hosts as
    *        keys and per-host session storage data as values. For example:
    *        {"example.com": {"key": "value", "my_number": 123}}
    */
   restore: function (aDocShell, aStorageData) {
     for (let origin of Object.keys(aStorageData)) {
       let data = aStorageData[origin];
-      let principal = BrowserUtils.principalFromOrigin(origin);
+      let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
       let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
       let window = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
 
       // There is no need to pass documentURI, it's only used to fill documentURI property of
       // domstorage event, which in this case has no consumer. Prevention of events in case
       // of missing documentURI will be solved in a followup bug to bug 600307.
       let storage = storageManager.createStorage(window, principal, "", aDocShell.usePrivateBrowsing);
 
--- a/browser/components/tabview/favicons.js
+++ b/browser/components/tabview/favicons.js
@@ -86,34 +86,29 @@ var FavIcons = {
 
     // If the tab image's url starts with http(s), fetch icon from favicon
     // service via the moz-anno protocol.
     if (/^https?:/.test(tabImage)) {
       let tabImageURI = gWindow.makeURI(tabImage);
       tabImage = this._favIconService.getFaviconLinkForIcon(tabImageURI).spec;
     }
 
-    if (tabImage) {
-      tabImage = PlacesUtils.getImageURLForResolution(window, tabImage);
-    }
-
     callback(tabImage);
   },
 
   // ----------
   // Function: _getFavIconForHttpDocument
   // Retrieves the favicon for tab containg a http(s) document.
   _getFavIconForHttpDocument:
     function FavIcons_getFavIconForHttpDocument(tab, callback) {
 
     let {currentURI} = tab.linkedBrowser;
     this._favIconService.getFaviconURLForPage(currentURI, function (uri) {
       if (uri) {
-        let icon = PlacesUtils.getImageURLForResolution(window,
-                     this._favIconService.getFaviconLinkForIcon(uri).spec);
+        let icon = this._favIconService.getFaviconLinkForIcon(uri).spec;
         callback(icon);
       } else {
         callback(this.defaultFavicon);
       }
     }.bind(this));
   },
 
   // ----------
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -2218,17 +2218,17 @@ this.Experiments.PreviousExperimentProvi
   this._experiments = experiments;
   this._experimentList = [];
   this._log = Log.repository.getLoggerWithMessagePrefix(
     "Browser.Experiments.Experiments",
     "PreviousExperimentProvider #" + gPreviousProviderCounter++ + "::");
 }
 
 this.Experiments.PreviousExperimentProvider.prototype = Object.freeze({
-  get name() "PreviousExperimentProvider",
+  name: "PreviousExperimentProvider",
 
   startup: function () {
     this._log.trace("startup()");
     Services.obs.addObserver(this, EXPERIMENTS_CHANGED_TOPIC, false);
   },
 
   shutdown: function () {
     this._log.trace("shutdown()");
--- a/browser/fuel/fuelApplication.js
+++ b/browser/fuel/fuelApplication.js
@@ -13,44 +13,44 @@ const APPLICATION_CID = Components.ID("f
 const APPLICATION_CONTRACTID = "@mozilla.org/fuel/application;1";
 
 //=================================================
 // Singleton that holds services and utilities
 var Utilities = {
   get bookmarks() {
     let bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
                     getService(Ci.nsINavBookmarksService);
-    this.__defineGetter__("bookmarks", function() bookmarks);
+    this.__defineGetter__("bookmarks", () => bookmarks);
     return this.bookmarks;
   },
 
   get bookmarksObserver() {
     let bookmarksObserver = new BookmarksObserver();
-    this.__defineGetter__("bookmarksObserver", function() bookmarksObserver);
+    this.__defineGetter__("bookmarksObserver", () => bookmarksObserver);
     return this.bookmarksObserver;
   },
 
   get annotations() {
     let annotations = Cc["@mozilla.org/browser/annotation-service;1"].
                       getService(Ci.nsIAnnotationService);
-    this.__defineGetter__("annotations", function() annotations);
+    this.__defineGetter__("annotations", () => annotations);
     return this.annotations;
   },
 
   get history() {
     let history = Cc["@mozilla.org/browser/nav-history-service;1"].
                   getService(Ci.nsINavHistoryService);
-    this.__defineGetter__("history", function() history);
+    this.__defineGetter__("history", () => history);
     return this.history;
   },
 
   get windowMediator() {
     let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
                          getService(Ci.nsIWindowMediator);
-    this.__defineGetter__("windowMediator", function() windowMediator);
+    this.__defineGetter__("windowMediator", () => windowMediator);
     return this.windowMediator;
   },
 
   makeURI: function fuelutil_makeURI(aSpec) {
     if (!aSpec)
       return null;
     var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
     return ios.newURI(aSpec, null, null);
--- a/browser/fuel/test/browser_Bookmarks.js
+++ b/browser/fuel/test/browser_Bookmarks.js
@@ -131,20 +131,20 @@ function test() {
   testBookmark.annotations.set("testing/bookmark/double", 3.333, 0);
   ok(testBookmark.annotations.has("testing/bookmark/double"), "Checking existence of added double annotation");
   is(testBookmark.annotations.get("testing/bookmark/double"), 3.333, "Checking value of added double annotation");
   is(gLastBookmarkAction, "testing/bookmark/double", "Check event handler for setting annotation");
   gLastBookmarkAction = "";
 
   // test names array - NOTE: "bookmarkProperties/description" is an annotation too
   var names = testBookmark.annotations.names;
-  ok(names.some(function (f) f == "bookmarkProperties/description"), "Checking for description annotation");
-  ok(names.some(function (f) f == "testing/bookmark/string"), "Checking for string test annotation");
-  ok(names.some(function (f) f == "testing/bookmark/int"), "Checking for int test annotation");
-  ok(names.some(function (f) f == "testing/bookmark/double"), "Checking for double test annotation");
+  ok(names.some(f => f == "bookmarkProperties/description"), "Checking for description annotation");
+  ok(names.some(f => f == "testing/bookmark/string"), "Checking for string test annotation");
+  ok(names.some(f => f == "testing/bookmark/int"), "Checking for int test annotation");
+  ok(names.some(f => f == "testing/bookmark/double"), "Checking for double test annotation");
 
   // test adding a separator
   var testSeparator = testFolder.addSeparator();
   ok(testSeparator, "Check bookmark creation");
   ok(testSeparator.parent, "Check parent after separator creation");
   is(gLastFolderAction, "addchild", "Check event handler for adding a child separator to a folder");
   is(testSeparator.type, "separator", "Check 'bookmark.type' after separator creation");
 
--- a/browser/fuel/test/browser_Browser.js
+++ b/browser/fuel/test/browser_Browser.js
@@ -80,20 +80,20 @@ function test() {
         const complete = Ci.nsIWebProgressListener.STATE_IS_WINDOW +
                          Ci.nsIWebProgressListener.STATE_IS_NETWORK +
                          Ci.nsIWebProgressListener.STATE_STOP;
         if ((stateFlags & complete) == complete) {
           gBrowser.removeProgressListener(this);
           onPageBLoadComplete();
         }
       },
-      onLocationChange: function () 0,
-      onProgressChange: function () 0,
-      onStatusChange: function () 0,
-      onSecurityChange: function () 0
+      onLocationChange: () => 0,
+      onProgressChange: () => 0,
+      onStatusChange: () => 0,
+      onSecurityChange: () => 0
     });
 
     // test loading new content with a frame into a tab
     // the event will be checked in onPageBLoadComplete
     gPageB.events.addListener("load", onPageBLoadWithFrames);
     gPageB.load(makeURI(CHROMEROOT + "ContentWithFrames.html"));
   }
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -188,16 +188,17 @@
 @RESPATH@/components/directory.xpt
 @RESPATH@/components/docshell.xpt
 @RESPATH@/components/dom.xpt
 #ifdef MOZ_ACTIVITIES
 @RESPATH@/components/dom_activities.xpt
 @RESPATH@/components/dom_messages.xpt
 #endif
 @RESPATH@/components/dom_apps.xpt
+@RESPATH@/components/dom_newapps.xpt
 @RESPATH@/components/dom_base.xpt
 @RESPATH@/components/dom_system.xpt
 #ifdef MOZ_B2G_BT
 @RESPATH@/components/dom_bluetooth.xpt
 #endif
 @RESPATH@/components/dom_canvas.xpt
 @RESPATH@/components/dom_alarm.xpt
 @RESPATH@/components/dom_core.xpt
@@ -633,16 +634,20 @@
 @RESPATH@/components/url-classifier.xpt
 #endif
 
 ; Private Browsing
 @RESPATH@/components/privatebrowsing.xpt
 @RESPATH@/components/PrivateBrowsing.manifest
 @RESPATH@/components/PrivateBrowsingTrackingProtectionWhitelist.js
 
+; Signed Packaged Content
+@RESPATH@/components/InstallPackagedWebapp.manifest
+@RESPATH@/components/InstallPackagedWebapp.js
+
 ; ANGLE GLES-on-D3D rendering library
 #ifdef MOZ_ANGLE_RENDERER
 @BINPATH@/libEGL.dll
 @BINPATH@/libGLESv2.dll
 
 #ifdef MOZ_D3DCOMPILER_VISTA_DLL
 @BINPATH@/@MOZ_D3DCOMPILER_VISTA_DLL@
 #endif
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -147,19 +147,17 @@
     locale/browser/syncSetup.dtd                (%chrome/browser/syncSetup.dtd)
     locale/browser/syncSetup.properties         (%chrome/browser/syncSetup.properties)
     locale/browser/syncGenericChange.properties         (%chrome/browser/syncGenericChange.properties)
     locale/browser/syncKey.dtd                  (%chrome/browser/syncKey.dtd)
     locale/browser/syncQuota.dtd                (%chrome/browser/syncQuota.dtd)
     locale/browser/syncQuota.properties         (%chrome/browser/syncQuota.properties)
 #endif
 % resource search-plugins chrome://browser/locale/searchplugins/
-# little trick to make the test below work
-#define en_US en-US
-#if AB_CD == en_US
+#if BUILD_FASTER
     locale/browser/searchplugins/list.txt       (%searchplugins/list.txt)
     locale/browser/searchplugins/               (%searchplugins/*.xml)
 #else
     locale/browser/searchplugins/list.txt       (.deps/generated_@AB_CD@/list.txt)
     locale/browser/searchplugins/               (.deps/generated_@AB_CD@/*.xml)
 #endif
 % locale browser-region @AB_CD@ %locale/browser-region/
     locale/browser-region/region.properties        (%chrome/browser-region/region.properties)
--- a/browser/modules/BrowserUITelemetry.jsm
+++ b/browser/modules/BrowserUITelemetry.jsm
@@ -708,28 +708,34 @@ this.BrowserUITelemetry = {
   },
 
   _bucket: BUCKET_DEFAULT,
   _bucketTimer: null,
 
   /**
    * Default bucket name, when no other bucket is active.
    */
-  get BUCKET_DEFAULT() BUCKET_DEFAULT,
+  get BUCKET_DEFAULT() {
+    return BUCKET_DEFAULT;
+  },
 
   /**
    * Bucket prefix, for named buckets.
    */
-  get BUCKET_PREFIX() BUCKET_PREFIX,
+  get BUCKET_PREFIX() {
+    return BUCKET_PREFIX;
+  },
 
   /**
    * Standard separator to use between different parts of a bucket name, such
    * as primary name and the time step string.
    */
-  get BUCKET_SEPARATOR() BUCKET_SEPARATOR,
+  get BUCKET_SEPARATOR() {
+    return BUCKET_SEPARATOR;
+  },
 
   get currentBucket() {
     return this._bucket;
   },
 
   /**
    * Sets a named bucket for all countable events and select durections to be
    * put into.
--- a/browser/modules/ContentLinkHandler.jsm
+++ b/browser/modules/ContentLinkHandler.jsm
@@ -139,17 +139,17 @@ this.ContentLinkHandler = {
     // Verify that the load of this icon is legal.
     // Some error or special pages can load their favicon.
     // To be on the safe side, only allow chrome:// favicons.
     var isAllowedPage = [
       /^about:neterror\?/,
       /^about:blocked\?/,
       /^about:certerror\?/,
       /^about:home$/,
-    ].some(function (re) re.test(targetDoc.documentURI));
+    ].some(re => re.test(targetDoc.documentURI));
 
     if (!isAllowedPage || !uri.schemeIs("chrome")) {
       var ssm = Services.scriptSecurityManager;
       try {
         ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
                                       Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
       } catch(e) {
         return null;
--- a/browser/modules/DirectoryLinksProvider.jsm
+++ b/browser/modules/DirectoryLinksProvider.jsm
@@ -154,22 +154,24 @@ var DirectoryLinksProvider = {
   _avoidInadjacentSites: false,
 
   /**
    * This flag is set if _avoidInadjacentSites is true and there is
    * an inadjacent site in the new tab
    */
   _newTabHasInadjacentSite: false,
 
-  get _observedPrefs() Object.freeze({
-    enhanced: PREF_NEWTAB_ENHANCED,
-    linksURL: PREF_DIRECTORY_SOURCE,
-    matchOSLocale: PREF_MATCH_OS_LOCALE,
-    prefSelectedLocale: PREF_SELECTED_LOCALE,
-  }),
+  get _observedPrefs() {
+    return Object.freeze({
+      enhanced: PREF_NEWTAB_ENHANCED,
+      linksURL: PREF_DIRECTORY_SOURCE,
+      matchOSLocale: PREF_MATCH_OS_LOCALE,
+      prefSelectedLocale: PREF_SELECTED_LOCALE,
+    });
+  },
 
   get _linksURL() {
     if (!this.__linksURL) {
       try {
         this.__linksURL = Services.prefs.getCharPref(this._observedPrefs["linksURL"]);
         this.__linksURLModified = Services.prefs.prefHasUserValue(this._observedPrefs["linksURL"]);
       }
       catch (e) {
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -208,17 +208,17 @@ this.Social = {
       let place = {
         uri: aURI,
         visits: [{
           visitDate: Date.now() + 1000,
           transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
         }]
       };
       PlacesUtils.asyncHistory.updatePlaces(place, {
-        handleError: function () Cu.reportError("couldn't update history for socialmark annotation"),
+        handleError: () => Cu.reportError("couldn't update history for socialmark annotation"),
         handleResult: function () {},
         handleCompletion: function () {
           promiseSetAnnotation(aURI, providerList).then(function() {
             if (aCallback)
               schedule(function() { aCallback(true); } );
           }).then(null, Cu.reportError);
         }
       });
--- a/browser/modules/Windows8WindowFrameColor.jsm
+++ b/browser/modules/Windows8WindowFrameColor.jsm
@@ -26,17 +26,17 @@ const Windows8WindowFrameColor = {
       // Seems to be the default color (hardcoded because of bug 1065998)
       return [158, 158, 158];
     }
     // The color returned from the Registry is in decimal form.
     let customizationColorHex = customizationColor.toString(16);
     // Zero-pad the number just to make sure that it is 8 digits.
     customizationColorHex = ("00000000" + customizationColorHex).substr(-8);
     let customizationColorArray = customizationColorHex.match(/../g);
-    let [unused, fgR, fgG, fgB] = customizationColorArray.map(function(val) parseInt(val, 16));
+    let [unused, fgR, fgG, fgB] = customizationColorArray.map(val => parseInt(val, 16));
     let colorizationColorBalance = Registry.readRegKey(HKCU, dwmKey,
                                                        "ColorizationColorBalance") || 78;
      // Window frame base color when Color Intensity is at 0, see bug 1004576.
     let frameBaseColor = 217;
     let alpha = colorizationColorBalance / 100;
 
     // Alpha-blend the foreground color with the frame base color.
     let r = Math.round(fgR * alpha + frameBaseColor * (1 - alpha));
--- a/browser/modules/WindowsJumpLists.jsm
+++ b/browser/modules/WindowsJumpLists.jsm
@@ -97,41 +97,41 @@ var tasksCfg = [
    * args        - Command line args to invoke the task.
    * iconIndex   - Optional win icon index into the main application for the
    *               list item.
    * open        - Boolean indicates if the command should be visible after the browser opens.
    * close       - Boolean indicates if the command should be visible after the browser closes.
    */
   // Open new tab
   {
-    get title()       _getString("taskbar.tasks.newTab.label"),
-    get description() _getString("taskbar.tasks.newTab.description"),
+    get title()       { return _getString("taskbar.tasks.newTab.label"); },
+    get description() { return _getString("taskbar.tasks.newTab.description"); },
     args:             "-new-tab about:blank",
     iconIndex:        3, // New window icon
     open:             true,
     close:            true, // The jump list already has an app launch icon, but
                             // we don't always update the list on shutdown.
                             // Thus true for consistency.
   },
 
   // Open new window
   {
-    get title()       _getString("taskbar.tasks.newWindow.label"),
-    get description() _getString("taskbar.tasks.newWindow.description"),
+    get title()       { return _getString("taskbar.tasks.newWindow.label"); },
+    get description() { return _getString("taskbar.tasks.newWindow.description"); },
     args:             "-browser",
     iconIndex:        2, // New tab icon
     open:             true,
     close:            true, // No point, but we don't always update the list on
                             // shutdown. Thus true for consistency.
   },
 
   // Open new private window
   {
-    get title()       _getString("taskbar.tasks.newPrivateWindow.label"),
-    get description() _getString("taskbar.tasks.newPrivateWindow.description"),
+    get title()       { return _getString("taskbar.tasks.newPrivateWindow.label"); },
+    get description() { return _getString("taskbar.tasks.newPrivateWindow.description"); },
     args:             "-private-window",
     iconIndex:        4, // Private browsing mode icon
     open:             true,
     close:            true, // No point, but we don't always update the list on
                             // shutdown. Thus true for consistency.
   },
 ];
 
--- a/browser/modules/WindowsPreviewPerTab.jsm
+++ b/browser/modules/WindowsPreviewPerTab.jsm
@@ -310,18 +310,17 @@ PreviewController.prototype = {
     // Avoid returning 0
     let tabWidth = boxObject.width || 1;
     // Avoid divide by 0
     let tabHeight = boxObject.height || 1;
     return tabWidth / tabHeight;
   },
 
   drawPreview: function (ctx) {
-    let self = this;
-    this.win.tabbrowser.previewTab(this.tab, function () self.previewTabCallback(ctx));
+    this.win.tabbrowser.previewTab(this.tab, () => this.previewTabCallback(ctx));
 
     // We must avoid having the frame drawn around the window. See bug 520807
     return false;
   },
 
   previewTabCallback: function (ctx) {
     // This will extract the resolution-scale component of the scaling we need,
     // which should be applied to both chrome and content;
@@ -744,17 +743,17 @@ this.AeroPeek = {
           let controller = preview.controller.wrappedJSObject;
           controller.resetCanvasPreview();
         });
         break;
     }
   }
 };
 
-XPCOMUtils.defineLazyGetter(AeroPeek, "cacheTimer", function ()
+XPCOMUtils.defineLazyGetter(AeroPeek, "cacheTimer", () =>
   Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
 );
 
 XPCOMUtils.defineLazyServiceGetter(AeroPeek, "prefs",
                                    "@mozilla.org/preferences-service;1",
                                    "nsIPrefBranch");
 
 AeroPeek.initialize();
--- a/browser/modules/test/browser_taskbar_preview.js
+++ b/browser/modules/test/browser_taskbar_preview.js
@@ -101,24 +101,27 @@ function test() {
 
   function checkPreviews(aPreviews, msg) {
     let nPreviews = AeroPeek.previews.length;
     is(aPreviews, gBrowser.tabs.length, "Browser has expected number of tabs");
     is(nPreviews, gBrowser.tabs.length, "Browser has one preview per tab");
     is(nPreviews, aPreviews, msg || "Got expected number of previews");
   }
 
-  function getPreviewForTab(tab)
-    window.gTaskbarTabGroup.previewFromTab(tab);
+  function getPreviewForTab(tab) {
+    return window.gTaskbarTabGroup.previewFromTab(tab);
+  }
 
-  function checkSelectedTab()
-    getPreviewForTab(gBrowser.selectedTab).active;
+  function checkSelectedTab() {
+    return getPreviewForTab(gBrowser.selectedTab).active;
+  }
 
-  function isTabSelected(idx)
-    gBrowser.tabs[idx].selected;
+  function isTabSelected(idx) {
+    return gBrowser.tabs[idx].selected;
+  }
 
   function createThumbnailSurface(p) {
     let thumbnailWidth = 200,
         thumbnailHeight = 120;
     let ratio = p.controller.thumbnailAspectRatio;
 
     if (thumbnailWidth/thumbnailHeight > ratio)
       thumbnailWidth = thumbnailHeight * ratio;
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1632,21 +1632,29 @@ richlistitem[type~="action"][actiontype=
 }
 
 .alltabs-item[tabIsVisible] {
   /* box-shadow instead of background-color to work around native styling */
   box-shadow: inset -5px 0 ThreeDShadow;
 }
 
 .alltabs-endimage[muted] {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted);
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-muted);
 }
 
 .alltabs-endimage[soundplaying] {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio);
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu);
+}
+
+menuitem:hover > hbox > .alltabs-endimage[muted] {
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-muted-hover);
+}
+
+menuitem:hover > hbox > .alltabs-endimage[soundplaying] {
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-hover);
 }
 
 /* Sidebar */
 #sidebar-throbber[loading="true"] {
   list-style-image: url("chrome://global/skin/icons/loading_16.png");
   -moz-margin-end: 4px;
 }
 
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -2954,21 +2954,29 @@ toolbarbutton.chevron > .toolbarbutton-m
 }
 
 .alltabs-item[tabIsVisible] {
   /* box-shadow instead of background-color to work around native styling */
   box-shadow: inset -5px 0 ThreeDShadow;
 }
 
 .alltabs-endimage[muted] {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted);
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-muted);
 }
 
 .alltabs-endimage[soundplaying] {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio);
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu);
+}
+
+menuitem:hover > hbox > .alltabs-endimage[muted] {
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-muted-hover);
+}
+
+menuitem:hover > hbox > .alltabs-endimage[soundplaying] {
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-hover);
 }
 
 /* Bookmarks toolbar */
 #PlacesToolbarDropIndicator {
   list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
 }
 
 /* Bookmark drag and drop styles */
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -94,17 +94,17 @@
   skin/classic/browser/search-history-icon.svg                 (../shared/search/history-icon.svg)
   skin/classic/browser/search-indicator-magnifying-glass.svg   (../shared/search/search-indicator-magnifying-glass.svg)
   skin/classic/browser/search-arrow-go.svg                     (../shared/search/search-arrow-go.svg)
   skin/classic/browser/social/chat-icons.svg                   (../shared/social/chat-icons.svg)
   skin/classic/browser/social/gear_default.png                 (../shared/social/gear_default.png)
   skin/classic/browser/social/gear_clicked.png                 (../shared/social/gear_clicked.png)
   skin/classic/browser/tabbrowser/crashed.svg                  (../shared/tabbrowser/crashed.svg)
   skin/classic/browser/tabbrowser/pendingpaint.png             (../shared/tabbrowser/pendingpaint.png)
-  skin/classic/browser/tabbrowser/tab-audio.svg                (../shared/tabbrowser/tab-audio.svg)
+* skin/classic/browser/tabbrowser/tab-audio.svg                (../shared/tabbrowser/tab-audio.svg)
   skin/classic/browser/tabbrowser/tab-audio-small.svg          (../shared/tabbrowser/tab-audio-small.svg)
   skin/classic/browser/tabbrowser/tab-overflow-indicator.png   (../shared/tabbrowser/tab-overflow-indicator.png)
   skin/classic/browser/theme-switcher-icon.png                 (../shared/theme-switcher-icon.png)
   skin/classic/browser/theme-switcher-icon@2x.png              (../shared/theme-switcher-icon@2x.png)
   skin/classic/browser/translating-16.png                      (../shared/translation/translating-16.png)
   skin/classic/browser/translating-16@2x.png                   (../shared/translation/translating-16@2x.png)
   skin/classic/browser/translation-16.png                      (../shared/translation/translation-16.png)
   skin/classic/browser/translation-16@2x.png                   (../shared/translation/translation-16@2x.png)
--- a/browser/themes/shared/tabbrowser/tab-audio.svg
+++ b/browser/themes/shared/tabbrowser/tab-audio.svg
@@ -30,16 +30,27 @@
     .icon.white.pressed {
       opacity: 1;
     }
     .icon.white > .outline {
       fill: #000;
       fill-opacity: .5;
     }
 
+    .icon.menu {
+      fill: MenuText;
+    }
+    .icon.menu.hover {
+#ifdef XP_MACOSX
+      fill: -moz-mac-menutextselect;
+#else
+      fill: -moz-menuhovertext;
+#endif
+    }
+
     .icon.backgroundTab,
     .icon.backgroundTab.hover,
     .icon.backgroundTab.pressed {
       fill: -moz-MenuBarText;
     }
   </style>
 
   <path id="tab-audio" class="icon" d="M4,5C2.9,5,2,5.9,2,7v2c0,1.1,0.9,2,2,2h1.2L9,14V2L5.2,5H4z M11,8c0-0.6-0.4-1-1-1v2C10.6,9,11,8.6,11,8z M13,8 c0-1.4-1-2.6-2.3-2.9L10.4,6C11.3,6.2,12,7,12,8s-0.7,1.8-1.6,2l0.4,0.9C12,10.6,13,9.4,13,8z M11.4,3.2l-0.4,0.9 C12.8,4.6,14,6.2,14,8s-1.2,3.4-2.9,3.8l0.4,0.9C13.5,12.2,15,10.3,15,8S13.5,3.8,11.4,3.2z"/>
@@ -79,9 +90,14 @@
     <path class="outline" d="M9,2v4.3l3.5-2.9l0.9,1.2l-11,9l-1-1.2l1.9-1.5C2.6,10.6,2,9.9,2,9V7c0-1.1,0.9-2,2-2h1.2L9,2 M9,10v4l-2.5-2L9,10 M10-0.1 L8.4,1.2L4.9,4H4C2.3,4,1,5.3,1,7v2c0,0.7,0.3,1.4,0.7,2l-0.8,0.7l-0.8,0.6l0.6,0.8l1,1.2L2.3,15l0.8-0.6l2.3-1.9l0.4,0.3l2.5,2 l1.6,1.3V14v-4V8.7l4.1-3.4l0.8-0.6l-0.6-0.8l-0.9-1.2L12.7,2l-0.8,0.6L10,4.2V2V-0.1L10-0.1z"/>
     <path d="M12.5,3.4L9,6.3V2L5.2,5H4C2.9,5,2,5.9,2,7v2c0,0.9,0.6,1.6,1.4,1.9l-1.9,1.5l1,1.2l11-9L12.5,3.4z M9,14v-4l-2.5,2L9,14z"/>
   </g>
   <g id="tab-audio-muted-white-pressed" class="icon muted white pressed">
     <path class="outline" d="M9,2v4.3l3.5-2.9l0.9,1.2l-11,9l-1-1.2l1.9-1.5C2.6,10.6,2,9.9,2,9V7c0-1.1,0.9-2,2-2h1.2L9,2 M9,10v4l-2.5-2L9,10 M10-0.1 L8.4,1.2L4.9,4H4C2.3,4,1,5.3,1,7v2c0,0.7,0.3,1.4,0.7,2l-0.8,0.7l-0.8,0.6l0.6,0.8l1,1.2L2.3,15l0.8-0.6l2.3-1.9l0.4,0.3l2.5,2 l1.6,1.3V14v-4V8.7l4.1-3.4l0.8-0.6l-0.6-0.8l-0.9-1.2L12.7,2l-0.8,0.6L10,4.2V2V-0.1L10-0.1z"/>
     <path d="M12.5,3.4L9,6.3V2L5.2,5H4C2.9,5,2,5.9,2,7v2c0,0.9,0.6,1.6,1.4,1.9l-1.9,1.5l1,1.2l11-9L12.5,3.4z M9,14v-4l-2.5,2L9,14z"/>
   </g>
 
+  <path id="tab-audio-menu" class="icon menu" d="M4,5C2.9,5,2,5.9,2,7v2c0,1.1,0.9,2,2,2h1.2L9,14V2L5.2,5H4z M11,8c0-0.6-0.4-1-1-1v2C10.6,9,11,8.6,11,8z M13,8 c0-1.4-1-2.6-2.3-2.9L10.4,6C11.3,6.2,12,7,12,8s-0.7,1.8-1.6,2l0.4,0.9C12,10.6,13,9.4,13,8z M11.4,3.2l-0.4,0.9 C12.8,4.6,14,6.2,14,8s-1.2,3.4-2.9,3.8l0.4,0.9C13.5,12.2,15,10.3,15,8S13.5,3.8,11.4,3.2z"/>
+  <path id="tab-audio-menu-muted" class="icon menu" d="M12.5,3.4L9,6.3V2L5.2,5H4C2.9,5,2,5.9,2,7v2c0,0.9,0.6,1.6,1.4,1.9l-1.9,1.5l1,1.2l11-9L12.5,3.4z M9,14v-4l-2.5,2L9,14z"/>
+  <path id="tab-audio-menu-hover" class="icon menu hover" d="M4,5C2.9,5,2,5.9,2,7v2c0,1.1,0.9,2,2,2h1.2L9,14V2L5.2,5H4z M11,8c0-0.6-0.4-1-1-1v2C10.6,9,11,8.6,11,8z M13,8 c0-1.4-1-2.6-2.3-2.9L10.4,6C11.3,6.2,12,7,12,8s-0.7,1.8-1.6,2l0.4,0.9C12,10.6,13,9.4,13,8z M11.4,3.2l-0.4,0.9 C12.8,4.6,14,6.2,14,8s-1.2,3.4-2.9,3.8l0.4,0.9C13.5,12.2,15,10.3,15,8S13.5,3.8,11.4,3.2z"/>
+  <path id="tab-audio-menu-muted-hover" class="icon menu hover" d="M12.5,3.4L9,6.3V2L5.2,5H4C2.9,5,2,5.9,2,7v2c0,0.9,0.6,1.6,1.4,1.9l-1.9,1.5l1,1.2l11-9L12.5,3.4z M9,14v-4l-2.5,2L9,14z"/>
+
 </svg>
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2190,21 +2190,29 @@ richlistitem[type~="action"][actiontype=
 }
 
 .alltabs-item[tabIsVisible] {
   /* box-shadow instead of background-color to work around native styling */
   box-shadow: inset -5px 0 ThreeDShadow;
 }
 
 .alltabs-endimage[muted] {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted);
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-muted);
 }
 
 .alltabs-endimage[soundplaying] {
-  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio);
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu);
+}
+
+menuitem:hover > hbox > .alltabs-endimage[muted] {
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-muted-hover);
+}
+
+menuitem:hover > hbox > .alltabs-endimage[soundplaying] {
+  list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-menu-hover);
 }
 
 toolbarbutton.chevron {
   list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
 }
 
 toolbar[brighttext] toolbarbutton.chevron {
   list-style-image: url("chrome://global/skin/toolbar/chevron-inverted.png") !important;
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -132,33 +132,37 @@ MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -DTRACING
 MOZ_ARG_WITH_STRING(debug-label,
 [  --with-debug-label=LABELS
                           Define DEBUG_<value> for each comma-separated
                           value given.],
 [ for option in `echo $withval | sed 's/,/ /g'`; do
     MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${option}"
 done])
 
-MOZ_DEBUG_DISABLE_DEFS="-DNDEBUG -DTRIMMED"
-
 if test -n "$MOZ_DEBUG"; then
     AC_MSG_CHECKING([for valid debug flags])
     _SAVE_CFLAGS=$CFLAGS
     CFLAGS="$CFLAGS $MOZ_DEBUG_FLAGS"
     AC_TRY_COMPILE([#include <stdio.h>],
         [printf("Hello World\n");],
         _results=yes,
         _results=no)
     AC_MSG_RESULT([$_results])
     if test "$_results" = "no"; then
         AC_MSG_ERROR([These compiler flags are invalid: $MOZ_DEBUG_FLAGS])
     fi
     CFLAGS=$_SAVE_CFLAGS
+
+    MOZ_DEBUG_DEFINES="$MOZ_DEBUG_ENABLE_DEFS"
+else
+    MOZ_DEBUG_DEFINES="-DNDEBUG -DTRIMMED"
 fi
 
+AC_SUBST(MOZ_DEBUG_DEFINES)
+
 dnl ========================================================
 dnl = Enable generation of debug symbols
 dnl ========================================================
 MOZ_ARG_ENABLE_STRING(debug-symbols,
 [  --enable-debug-symbols[=DBG]
                           Enable debugging symbols (using compiler flags DBG)],
 [ if test "$enableval" != "no"; then
       MOZ_DEBUG_SYMBOLS=1
--- a/build/macosx/cross-mozconfig.common
+++ b/build/macosx/cross-mozconfig.common
@@ -41,11 +41,14 @@ export DMG_TOOL=$topsrcdir/dmg/dmg
 export HOST_CC="$topsrcdir/clang/bin/clang"
 export HOST_CXX="$topsrcdir/clang/bin/clang++"
 export HOST_CPP="$topsrcdir/clang/bin/clang -E"
 export HOST_LDFLAGS="-g"
 
 ac_add_options --target=x86_64-apple-darwin
 ac_add_options --with-macos-private-frameworks=$CROSS_PRIVATE_FRAMEWORKS
 
+# Enable static analysis checks by default on OSX cross builds.
+ac_add_options --enable-clang-plugin
+
 . "$topsrcdir/build/mozconfig.cache"
 
 export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -48,18 +48,16 @@ bool OriginAttributes::CopyFromLoadConte
   mUserContextId = attrs.mUserContextId;
   mSignedPkg = attrs.mSignedPkg;
   return true;
 }
 
 void
 OriginAttributes::CreateSuffix(nsACString& aStr) const
 {
-  MOZ_RELEASE_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
-
   UniquePtr<URLParams> params(new URLParams());
   nsAutoString value;
 
   //
   // Important: While serializing any string-valued attributes, perform a
   // release-mode assertion to make sure that they don't contain characters that
   // will break the quota manager when it uses the serialization for file
   // naming (see addonId below).
@@ -122,20 +120,16 @@ public:
   {
     if (aName.EqualsLiteral("appId")) {
       nsresult rv;
       mOriginAttributes->mAppId = aValue.ToInteger(&rv);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return false;
       }
 
-      if (mOriginAttributes->mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
-        return false;
-      }
-
       return true;
     }
 
     if (aName.EqualsLiteral("inBrowser")) {
       if (!aValue.EqualsLiteral("1")) {
         return false;
       }
 
@@ -217,24 +211,16 @@ BasePrincipal::~BasePrincipal()
 {}
 
 NS_IMETHODIMP
 BasePrincipal::GetOrigin(nsACString& aOrigin)
 {
   nsresult rv = GetOriginInternal(aOrigin);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // OriginAttributes::CreateSuffix asserts against UNKNOWN_APP_ID. It's trivial
-  // to trigger this getter from script on such a principal, so we handle it
-  // here at the API entry point.
-  if (mOriginAttributes.mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
-    NS_WARNING("Refusing to provide canonical origin string to principal with UNKNOWN_APP_ID");
-    return NS_ERROR_FAILURE;
-  }
-
   nsAutoCString suffix;
   mOriginAttributes.CreateSuffix(suffix);
   aOrigin.Append(suffix);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
@@ -320,18 +306,16 @@ BasePrincipal::GetIsNullPrincipal(bool* 
 {
   *aIsNullPrincipal = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetJarPrefix(nsACString& aJarPrefix)
 {
-  MOZ_ASSERT(AppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID);
-
   mozilla::GetJarPrefix(mOriginAttributes.mAppId, mOriginAttributes.mInBrowser, aJarPrefix);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
 {
   if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
@@ -421,16 +405,38 @@ BasePrincipal::CreateCodebasePrincipal(n
 
   // Mint a codebase principal.
   nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
   rv = codebase->Init(aURI, aAttrs);
   NS_ENSURE_SUCCESS(rv, nullptr);
   return codebase.forget();
 }
 
+already_AddRefed<BasePrincipal>
+BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
+{
+  MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
+             "CreateCodebasePrincipal does not support System and Expanded principals");
+
+  MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
+             "CreateCodebasePrincipal does not support nsNullPrincipal");
+
+  nsAutoCString originNoSuffix;
+  mozilla::OriginAttributes attrs;
+  if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
+}
+
 bool
 BasePrincipal::AddonAllowsLoad(nsIURI* aURI)
 {
   if (mOriginAttributes.mAddonId.IsEmpty()) {
     return false;
   }
 
   nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -155,16 +155,17 @@ public:
   NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
 
   virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
 
   virtual bool IsCodebasePrincipal() const { return false; };
 
   static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
   static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(nsIURI* aURI, OriginAttributes& aAttrs);
+  static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
 
   const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
   uint32_t AppId() const { return mOriginAttributes.mAppId; }
   uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
   bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
 
 protected:
   virtual ~BasePrincipal();
--- a/caps/nsIScriptSecurityManager.idl
+++ b/caps/nsIScriptSecurityManager.idl
@@ -21,17 +21,17 @@ class DomainPolicyClone;
 }
 }
 %}
 
 [ptr] native JSContextPtr(JSContext);
 [ptr] native JSObjectPtr(JSObject);
 [ptr] native DomainPolicyClonePtr(mozilla::dom::DomainPolicyClone);
 
-[scriptable, uuid(6e8a4d1e-d9c6-4d86-bf53-d73f58f36148)]
+[scriptable, uuid(b7ae2310-576e-11e5-a837-0800200c9a66)]
 interface nsIScriptSecurityManager : nsISupports
 {
     /**
      * For each of these hooks returning NS_OK means 'let the action continue'.
      * Returning an error code means 'veto the action'. XPConnect will return
      * false to the js engine if the action is vetoed. The implementor of this
      * interface is responsible for setting a JS exception into the JSContext
      * if that is appropriate.
@@ -193,16 +193,23 @@ interface nsIScriptSecurityManager : nsI
      * Returns a principal whose origin is composed of |uri| and |originAttributes|.
      * See nsIPrincipal.idl for a description of origin attributes, and
      * ChromeUtils.webidl for a list of origin attributes and their defaults.
      */
     [implicit_jscontext]
     nsIPrincipal createCodebasePrincipal(in nsIURI uri, in jsval originAttributes);
 
     /**
+     * Returns a principal whose origin is the one we pass in.
+     * See nsIPrincipal.idl for a description of origin attributes, and
+     * ChromeUtils.webidl for a list of origin attributes and their defaults.
+     */
+    nsIPrincipal createCodebasePrincipalFromOrigin(in ACString origin);
+
+    /**
      * Returns a unique nonce principal with |originAttributes|.
      * See nsIPrincipal.idl for a description of origin attributes, and
      * ChromeUtils.webidl for a list of origin attributes and their defaults.
      */
     [implicit_jscontext]
     nsIPrincipal createNullPrincipal(in jsval originAttributes);
 
     /**
--- a/caps/nsNullPrincipal.cpp
+++ b/caps/nsNullPrincipal.cpp
@@ -52,17 +52,16 @@ nsNullPrincipal::Create(const OriginAttr
 
   return nullPrin.forget();
 }
 
 nsresult
 nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes)
 {
   mOriginAttributes = aOriginAttributes;
-  MOZ_ASSERT(AppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID);
 
   mURI = nsNullPrincipalURI::Create();
   NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
 
   return NS_OK;
 }
 
 void
@@ -168,19 +167,16 @@ nsNullPrincipal::Read(nsIObjectInputStre
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNullPrincipal::Write(nsIObjectOutputStream* aStream)
 {
-  NS_ENSURE_TRUE(mOriginAttributes.mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
-                 NS_ERROR_INVALID_ARG);
-
   nsAutoCString suffix;
   OriginAttributesRef().CreateSuffix(suffix);
 
   nsresult rv = aStream->WriteStringZ(suffix.get());
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsPrincipal.cpp
@@ -422,19 +422,16 @@ nsPrincipal::Read(nsIObjectInputStream* 
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPrincipal::Write(nsIObjectOutputStream* aStream)
 {
   NS_ENSURE_STATE(mCodebase);
-  NS_ENSURE_TRUE(mOriginAttributes.mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
-                 NS_ERROR_INVALID_ARG);
-
   nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
                                                true);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
                                       true);
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -62,16 +62,17 @@
 #include "mozilla/dom/BindingUtils.h"
 #include <stdint.h>
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "nsILoadInfo.h"
+#include "nsXPCOMStrings.h"
 
 // This should be probably defined on some other place... but I couldn't find it
 #define WEBAPPS_PERM_NAME "webapps-manage"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsIIOService    *nsScriptSecurityManager::sIOService = nullptr;
@@ -1039,16 +1040,33 @@ nsScriptSecurityManager::CreateCodebaseP
       return NS_ERROR_INVALID_ARG;
   }
   nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
   prin.forget(aPrincipal);
   return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
+nsScriptSecurityManager::CreateCodebasePrincipalFromOrigin(const nsACString& aOrigin,
+                                                           nsIPrincipal** aPrincipal)
+{
+  if (StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("["))) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  if (StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":"))) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aOrigin);
+  prin.forget(aPrincipal);
+  return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
 nsScriptSecurityManager::CreateNullPrincipal(JS::Handle<JS::Value> aOriginAttributes,
                                              JSContext* aCx, nsIPrincipal** aPrincipal)
 {
   OriginAttributes attrs;
   if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
       return NS_ERROR_INVALID_ARG;
   }
   nsCOMPtr<nsIPrincipal> prin = nsNullPrincipal::Create(attrs);
--- a/caps/tests/unit/test_origin.js
+++ b/caps/tests/unit/test_origin.js
@@ -1,14 +1,13 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/BrowserUtils.jsm");
 var ssm = Services.scriptSecurityManager;
 function makeURI(uri) { return Services.io.newURI(uri, null, null); }
 
 function checkThrows(f) {
   var threw = false;
   try { f(); } catch (e) { threw = true }
   do_check_true(threw);
 }
@@ -23,19 +22,19 @@ function checkCrossOrigin(a, b) {
 }
 
 function checkOriginAttributes(prin, attrs, suffix) {
   attrs = attrs || {};
   do_check_eq(prin.originAttributes.appId, attrs.appId || 0);
   do_check_eq(prin.originAttributes.inBrowser, attrs.inBrowser || false);
   do_check_eq(prin.originSuffix, suffix || '');
   if (!prin.isNullPrincipal && !prin.origin.startsWith('[')) {
-    do_check_true(BrowserUtils.principalFromOrigin(prin.origin).equals(prin));
+    do_check_true(ssm.createCodebasePrincipalFromOrigin(prin.origin).equals(prin));
   } else {
-    checkThrows(() => BrowserUtils.principalFromOrigin(prin.origin));
+    checkThrows(() => ssm.createCodebasePrincipalFromOrigin(prin.origin));
   }
 }
 
 function run_test() {
   // Attributeless origins.
   do_check_eq(ssm.getSystemPrincipal().origin, '[System Principal]');
   checkOriginAttributes(ssm.getSystemPrincipal());
   var exampleOrg = ssm.createCodebasePrincipal(makeURI('http://example.org'), {});
@@ -94,21 +93,17 @@ function run_test() {
   checkOriginAttributes(exampleCom_appBrowser, {appId: 42, inBrowser: true}, '^appId=42&inBrowser=1');
   do_check_eq(exampleCom_appBrowser.origin, 'https://www.example.com:123^appId=42&inBrowser=1');
 
   // Addon.
   var exampleOrg_addon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy'});
   checkOriginAttributes(exampleOrg_addon, { addonId: "dummy" }, '^addonId=dummy');
   do_check_eq(exampleOrg_addon.origin, 'http://example.org^addonId=dummy');
 
-  // Make sure that we refuse to create .origin for principals with UNKNOWN_APP_ID.
-  var simplePrin = ssm.getSimpleCodebasePrincipal(makeURI('http://example.com'));
-  try { simplePrin.origin; do_check_true(false); } catch (e) { do_check_true(true); }
-
-  // Make sure we don't crash when serializing them either.
+  // Make sure we don't crash when serializing principals with UNKNOWN_APP_ID.
   try {
     let binaryStream = Cc["@mozilla.org/binaryoutputstream;1"].
                        createInstance(Ci.nsIObjectOutputStream);
     let pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
     pipe.init(false, false, 0, 0xffffffff, null);
     binaryStream.setOutputStream(pipe.outputStream);
     binaryStream.writeCompoundObject(simplePrin, Ci.nsISupports, true);
     binaryStream.close();
--- a/chrome/test/unit/test_no_remote_registration.js
+++ b/chrome/test/unit/test_no_remote_registration.js
@@ -46,17 +46,17 @@ function ProtocolHandler(aScheme, aFlags
   this.scheme = aScheme;
   this.protocolFlags = aFlags;
   this.contractID = "@mozilla.org/network/protocol;1?name=" + aScheme;
 }
 
 ProtocolHandler.prototype =
 {
   defaultPort: -1,
-  allowPort: function() false,
+  allowPort: () => false,
   newURI: function(aSpec, aCharset, aBaseURI)
   {
     let uri = Cc["@mozilla.org/network/standard-url;1"].
               createInstance(Ci.nsIURI);
     uri.spec = aSpec;
     if (!uri.scheme) {
       // We got a partial uri, so let's resolve it with the base one
       uri.spec = aBaseURI.resolve(aSpec);
--- a/config/config.mk
+++ b/config/config.mk
@@ -157,23 +157,17 @@ TOUCH ?= touch
 
 PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py
 
 # determine debug-related options
 _DEBUG_ASFLAGS :=
 _DEBUG_CFLAGS :=
 _DEBUG_LDFLAGS :=
 
-ifdef MOZ_DEBUG
-  _DEBUG_CFLAGS += $(MOZ_DEBUG_ENABLE_DEFS)
-  XULPPFLAGS += $(MOZ_DEBUG_ENABLE_DEFS)
-else
-  _DEBUG_CFLAGS += $(MOZ_DEBUG_DISABLE_DEFS)
-  XULPPFLAGS += $(MOZ_DEBUG_DISABLE_DEFS)
-endif
+_DEBUG_CFLAGS += $(MOZ_DEBUG_DEFINES)
 
 ifneq (,$(MOZ_DEBUG)$(MOZ_DEBUG_SYMBOLS))
   ifeq ($(AS),yasm)
     ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_)
       _DEBUG_ASFLAGS += -g cv8
     else
       ifneq ($(OS_ARCH),Darwin)
         _DEBUG_ASFLAGS += -g dwarf2
--- a/config/external/nss/Makefile.in
+++ b/config/external/nss/Makefile.in
@@ -349,17 +349,17 @@ nss3.def: $(nss_def_file) $(DEPTH)/db/sq
 	mv $@.tmp $@
 else
 ifdef GCC_USE_GNU_LD
 sqlite_def_file := $(topsrcdir)/db/sqlite3/src/sqlite.def
 nspr_def_file := $(srcdir)/nspr-dummy.def
 
 nss3.def: $(nss_def_file) $(sqlite_def_file) $(nspr_def_file) $(NSS_EXTRA_SYMBOLS_FILE)
 	@$(call py_action,convert_def_file, \
-	  $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) -o $@ $^)
+	  $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) -o $@ $^)
 
 GARBAGE += \
   nss3.def \
   $(NULL)
 endif # GCC_USE_GNU_LD
 endif # WINNT
 
 IMPORT_LIB_FILES = $(IMPORT_LIBRARY)
--- a/config/external/sqlite/Makefile.in
+++ b/config/external/sqlite/Makefile.in
@@ -16,13 +16,13 @@ ifdef GCC_USE_GNU_LD
 
 GARBAGE += \
   $(LD_VERSION_SCRIPT) \
   $(NULL)
 
 # Convert to the format we need for ld.
 $(LD_VERSION_SCRIPT): $(topsrcdir)/db/sqlite3/src/sqlite.def
 	@$(call py_action,convert_def_file, \
-	  $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) -o $@ $^)
+	  $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) -o $@ $^)
 
 endif
 endif
 endif
--- a/config/faster/rules.mk
+++ b/config/faster/rules.mk
@@ -54,18 +54,18 @@ default: $(TOPOBJDIR)/dist/bin/platform.
 default: $(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini
 
 # Targets from the recursive make backend to be built for a default build
 default: $(TOPOBJDIR)/config/makefiles/xpidl/xpidl
 
 .PHONY: FORCE
 
 # Extra define to trigger some workarounds. We should strive to limit the
-# use of those. As of writing the only one is in
-# toolkit/content/buildconfig.html.
+# use of those. As of writing the only ones are in
+# toolkit/content/buildconfig.html and browser/locales/jar.mn.
 ACDEFINES += -DBUILD_FASTER
 
 # Generic rule to fall back to the recursive make backend
 $(TOPOBJDIR)/%: FORCE
 	$(MAKE) -C $(dir $@) $(notdir $@)
 
 # Files under the faster/ sub-directory, however, are not meant to use the
 # fallback
@@ -88,18 +88,16 @@ ACDEFINES += -DBUILD_FASTER
 		--no-remove \
 		--no-remove-empty-directories \
 		$(TOPOBJDIR)/$* \
 		install_$(subst /,_,$*)
 
 # Preprocessed files. Ideally they would be using install manifests but
 # right now, it's not possible because of things like APP_BUILDID or
 # nsURLFormatter.js.
-# Things missing:
-# - XULPPFLAGS
 #
 # The list of preprocessed files is defined in PP_TARGETS. The list is
 # relative to TOPOBJDIR.
 # The source file for each of those preprocessed files is defined as a Make
 # dependency for the $(TOPOBJDIR)/path target. For example:
 #   PP_TARGETS = foo/bar
 #   $(TOPOBJDIR)/foo/bar: /path/to/source/for/foo/bar.in
 # The file name for the source doesn't need to be different.
@@ -109,28 +107,28 @@ ACDEFINES += -DBUILD_FASTER
 #   $(TOPOBJDIR)/foo/bar: defines = -Dqux=foobar
 $(addprefix $(TOPOBJDIR)/,$(PP_TARGETS)): Makefile
 $(addprefix $(TOPOBJDIR)/,$(PP_TARGETS)): $(TOPOBJDIR)/%:
 	$(PYTHON) -m mozbuild.action.preprocessor \
 		--depend $(TOPOBJDIR)/faster/.deps/$(subst /,_,$*) \
 		-DAB_CD=en-US \
 		$(defines) \
 		$(ACDEFINES) \
+		$(MOZ_DEBUG_DEFINES) \
 		$< \
 		-o $@
 
 # Include the dependency files from the above preprocessed files rule.
 $(foreach pp_target,$(PP_TARGETS), \
 	$(eval -include $(TOPOBJDIR)/faster/.deps/$(subst /,_,$(pp_target))))
 
 # Install files from jar manifests. Ideally, they would be using install
 # manifests, but the code to read jar manifests and emit appropriate
 # install manifests is not there yet.
 # Things missing:
-# - XULPPFLAGS
 # - DEFINES from config/config.mk
 # - L10N
 # - -e when USE_EXTENSION_MANIFEST is set in moz.build
 #
 # The list given in JAR_MN_TARGETS corresponds to the list of `jar-%` targets
 # to be processed, with the `jar-` prefix stripped.
 # The Makefile is expected to specify the source jar manifest as a dependency
 # to each target. There is no expectation that the `jar-%` target name matches
@@ -160,16 +158,17 @@ jar-%:
 	$(PYTHON) -m mozbuild.action.jar_maker \
 		-j $(TOPOBJDIR)/$(install_target)/chrome \
 		-t $(TOPSRCDIR) \
 		-f $(MOZ_CHROME_FILE_FORMAT) \
 		-c $(dir $<)/en-US \
 		-DAB_CD=en-US \
 		$(defines) \
 		$(ACDEFINES) \
+		$(MOZ_DEBUG_DEFINES) \
 		$<
 
 # Create some chrome manifests
 # This rule is forced to run every time because it may be updating files that
 # already exit.
 #
 # The list of chrome manifests is given in MANIFEST_TARGETS, relative to the
 # top object directory. The content for those manifests is given in the
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1257,17 +1257,17 @@ ifndef XPI_ROOT_APPID
 $(error XPI_ROOT_APPID is not defined - langpacks will break.)
 endif
 endif
 endif
 
 libs realchrome:: $(FINAL_TARGET)/chrome
 	$(call py_action,jar_maker,\
 	  $(QUIET) -j $(FINAL_TARGET)/chrome \
-	  $(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
+	  $(MAKE_JARS_FLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) \
 	  $(JAR_MANIFEST))
 
 endif
 
 # This is a temporary check to ensure patches relying on the old behavior
 # of silently picking up jar.mn files continue to work.
 else # No JAR_MANIFEST
 ifneq (,$(wildcard $(srcdir)/jar.mn))
@@ -1511,17 +1511,17 @@ pp_target_results = $(foreach file,$($(1
 $(foreach tier,$(PP_TARGETS_TIERS), \
   $(eval $(tier):: $(PP_TARGETS_RESULTS_$(tier))) \
 )
 
 PP_TARGETS_ALL_RESULTS := $(sort $(foreach tier,$(PP_TARGETS_TIERS),$(PP_TARGETS_RESULTS_$(tier))))
 $(PP_TARGETS_ALL_RESULTS):
 	$(if $(filter-out $(notdir $@),$(notdir $(<:.in=))),$(error Looks like $@ has an unexpected dependency on $< which breaks PP_TARGETS))
 	$(RM) '$@'
-	$(call py_action,preprocessor,--depend $(MDDEPDIR)/$(@F).pp $(PP_TARGET_FLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) '$<' -o '$@')
+	$(call py_action,preprocessor,--depend $(MDDEPDIR)/$(@F).pp $(PP_TARGET_FLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) '$<' -o '$@')
 
 # The depfile is based on the filename, and we don't want conflicts. So check
 # there's only one occurrence of any given filename in PP_TARGETS_ALL_RESULTS.
 PP_TARGETS_ALL_RESULT_NAMES := $(notdir $(PP_TARGETS_ALL_RESULTS))
 $(foreach file,$(sort $(PP_TARGETS_ALL_RESULT_NAMES)), \
   $(if $(filter-out 1,$(words $(filter $(file),$(PP_TARGETS_ALL_RESULT_NAMES)))), \
     $(error Multiple preprocessing rules are creating a $(file) file) \
   ) \
--- a/configure.in
+++ b/configure.in
@@ -8552,18 +8552,16 @@ AC_SUBST(IMPLIB)
 AC_SUBST(FILTER)
 AC_SUBST(BIN_FLAGS)
 AC_SUBST(MOZ_WIDGET_TOOLKIT)
 AC_SUBST(MOZ_UPDATE_XTERM)
 AC_SUBST(MOZ_AUTH_EXTENSION)
 AC_SUBST(MOZ_PREF_EXTENSIONS)
 AC_SUBST(MOZ_DEBUG)
 AC_SUBST(MOZ_DEBUG_SYMBOLS)
-AC_SUBST(MOZ_DEBUG_ENABLE_DEFS)
-AC_SUBST(MOZ_DEBUG_DISABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_LDFLAGS)
 AC_SUBST(WARNINGS_AS_ERRORS)
 AC_SUBST_SET(MOZ_EXTENSIONS)
 AC_SUBST(MOZ_ENABLE_PROFILER_SPS)
 AC_SUBST(MOZ_JPROF)
 AC_SUBST(MOZ_INSTRUMENTS)
 AC_SUBST(MOZ_CALLGRIND)
 AC_SUBST(MOZ_VTUNE)
--- a/db/sqlite3/src/Makefile.in
+++ b/db/sqlite3/src/Makefile.in
@@ -10,11 +10,11 @@ DEFFILE = $(CURDIR)/sqlite-processed.def
 
 GARBAGE += \
   $(DEFFILE) \
   $(NULL)
 
 # We have to preprocess our def file because we need different symbols in debug
 # builds exposed that are not built in non-debug builds.
 $(DEFFILE): sqlite.def
-	@$(call py_action,preprocessor,$(DEFINES) $(XULPPFLAGS) \
+	@$(call py_action,preprocessor,$(DEFINES) $(MOZ_DEBUG_DEFINES) \
 	  $(srcdir)/sqlite.def -o $(DEFFILE))
 endif
--- a/devtools/client/app-manager/app-projects.js
+++ b/devtools/client/app-manager/app-projects.js
@@ -203,17 +203,17 @@ const AppProjects = {
       return store.object.projects[store.object.projects.length - 1];
     });
   },
 
   update: function (project) {
     return IDB.update(project);
   },
 
-  updateLocation: function(project, newLocation) {
+  updateLocation: function(project, newLocation) {
     return IDB.remove(project.location)
               .then(() => {
                 project.location = newLocation;
                 return IDB.add(project);
               });
   },
 
   remove: function(location) {
--- a/devtools/client/responsivedesign/responsivedesign.jsm
+++ b/devtools/client/responsivedesign/responsivedesign.jsm
@@ -228,17 +228,19 @@ function ResponsiveUI(aWindow, aTab)
     window: this.mainWindow,
     type: "deveditionpromo",
     anchor: this.chromeDoc.querySelector("#content")
   });
 }
 
 ResponsiveUI.prototype = {
   _transitionsEnabled: true,
-  get transitionsEnabled() this._transitionsEnabled,
+  get transitionsEnabled() {
+    return this._transitionsEnabled;
+  },
   set transitionsEnabled(aValue) {
     this._transitionsEnabled = aValue;
     if (aValue && !this._resizing && this.stack.hasAttribute("responsivemode")) {
       this.stack.removeAttribute("notransition");
     } else if (!aValue) {
       this.stack.setAttribute("notransition", "true");
     }
   },
--- a/devtools/client/shared/AppCacheUtils.jsm
+++ b/devtools/client/shared/AppCacheUtils.jsm
@@ -611,17 +611,17 @@ ManifestParser.prototype = {
           this._addError(this.currentLine,
                          "invalidSectionName", text, this.currentLine);
           return false;
       }
     }
   },
 };
 
-XPCOMUtils.defineLazyGetter(this, "l10n", function() Services.strings
+XPCOMUtils.defineLazyGetter(this, "l10n", () => Services.strings
   .createBundle("chrome://browser/locale/devtools/appcacheutils.properties"));
 
 XPCOMUtils.defineLazyGetter(this, "appcacheservice", function() {
   return Cc["@mozilla.org/network/application-cache-service;1"]
            .getService(Ci.nsIApplicationCacheService);
 
 });
 
--- a/devtools/client/shared/SplitView.jsm
+++ b/devtools/client/shared/SplitView.jsm
@@ -81,31 +81,40 @@ this.SplitView = function SplitView(aRoo
 }
 
 SplitView.prototype = {
   /**
     * Retrieve whether the UI currently has a landscape orientation.
     *
     * @return boolean
     */
-  get isLandscape() this._mql.matches,
+  get isLandscape()
+  {
+    return this._mql.matches;
+  },
 
   /**
     * Retrieve the root element.
     *
     * @return DOMElement
     */
-  get rootElement() this._root,
+  get rootElement()
+  {
+    return this._root;
+  },
 
   /**
     * Retrieve the active item's summary element or null if there is none.
     *
     * @return DOMElement
     */
-  get activeSummary() this._activeSummary,
+  get activeSummary()
+  {
+    return this._activeSummary;
+  },
 
   /**
     * Set the active item's summary element.
     *
     * @param DOMElement aSummary
     */
   set activeSummary(aSummary)
   {
--- a/devtools/client/shared/widgets/SideMenuWidget.jsm
+++ b/devtools/client/shared/widgets/SideMenuWidget.jsm
@@ -71,17 +71,17 @@ SideMenuWidget.prototype = {
   /**
    * Specifies if groups in this container should be sorted.
    */
   sortedGroups: true,
 
   /**
    * The comparator used to sort groups.
    */
-  groupSortPredicate: function(a, b) a.localeCompare(b),
+  groupSortPredicate: (a, b) => a.localeCompare(b),
 
   /**
    * Inserts an item in this container at the specified index, optionally
    * grouping by name.
    *
    * @param number aIndex
    *        The position in the container intended for this item.
    * @param nsIDOMNode aContents
@@ -483,18 +483,22 @@ function SideMenuGroup(aWidget, aName, a
   else {
     let target = this._target = this._list = this.document.createElement("vbox");
     target.className = "side-menu-widget-group side-menu-widget-group-list";
     target.setAttribute("merged-group-contents", "");
   }
 }
 
 SideMenuGroup.prototype = {
-  get _orderedGroupElementsArray() this.ownerView._orderedGroupElementsArray,
-  get _orderedMenuElementsArray() this.ownerView._orderedMenuElementsArray,
+  get _orderedGroupElementsArray() {
+    return this.ownerView._orderedGroupElementsArray;
+  },
+  get _orderedMenuElementsArray() {
+    return this.ownerView._orderedMenuElementsArray;
+  },
   get _itemsByElement() { return this.ownerView._itemsByElement; },
 
   /**
    * Inserts this group in the parent container at the specified index.
    *
    * @param number aIndex
    *        The position in the container intended for this group.
    */
@@ -590,18 +594,22 @@ function SideMenuItem(aGroup, aContents,
     target.setAttribute("merged-item-contents", "");
   }
 
   this._target.setAttribute("flex", "1");
   this.contents = aContents;
 }
 
 SideMenuItem.prototype = {
-  get _orderedGroupElementsArray() this.ownerView._orderedGroupElementsArray,
-  get _orderedMenuElementsArray() this.ownerView._orderedMenuElementsArray,
+  get _orderedGroupElementsArray() {
+    return this.ownerView._orderedGroupElementsArray;
+  },
+  get _orderedMenuElementsArray() {
+    return this.ownerView._orderedMenuElementsArray;
+  },
   get _itemsByElement() { return this.ownerView._itemsByElement; },
 
   /**
    * Inserts this item in the parent group at the specified index.
    *
    * @param number aIndex
    *        The position in the container intended for this item.
    * @return nsIDOMNode
--- a/devtools/client/shared/widgets/VariablesView.jsm
+++ b/devtools/client/shared/widgets/VariablesView.jsm
@@ -397,40 +397,46 @@ VariablesView.prototype = {
       this.nonEnumVisible = true;
     }
   },
 
   /**
    * Sets if the variable and property searching is enabled.
    * @param boolean aFlag
    */
-  set searchEnabled(aFlag) aFlag ? this._enableSearch() : this._disableSearch(),
+  set searchEnabled(aFlag) {
+    aFlag ? this._enableSearch() : this._disableSearch();
+  },
 
   /**
    * Gets if the variable and property searching is enabled.
    * @return boolean
    */
-  get searchEnabled() !!this._searchboxContainer,
+  get searchEnabled() {
+    return !!this._searchboxContainer;
+  },
 
   /**
    * Sets the text displayed for the searchbox in this container.
    * @param string aValue
    */
   set searchPlaceholder(aValue) {
     if (this._searchboxNode) {
       this._searchboxNode.setAttribute("placeholder", aValue);
     }
     this._searchboxPlaceholder = aValue;
   },
 
   /**
    * Gets the text displayed for the searchbox in this container.
    * @return string
    */
-  get searchPlaceholder() this._searchboxPlaceholder,
+  get searchPlaceholder() {
+    return this._searchboxPlaceholder;
+  },
 
   /**
    * Enables variable and property searching in this view.
    * Use the "searchEnabled" setter to enable searching.
    */
   _enableSearch: function() {
     // If searching was already enabled, no need to re-enable it again.
     if (this._searchboxContainer) {
@@ -992,35 +998,43 @@ VariablesView.prototype = {
       this._parent.removeAttribute("actions-first");
     }
   },
 
   /**
    * Gets the parent node holding this view.
    * @return nsIDOMNode
    */
-  get boxObject() this._list.boxObject,
+  get boxObject() {
+    return this._list.boxObject;
+  },
 
   /**
    * Gets the parent node holding this view.
    * @return nsIDOMNode
    */
-  get parentNode() this._parent,
+  get parentNode() {
+    return this._parent;
+  },
 
   /**
    * Gets the owner document holding this view.
    * @return nsIHTMLDocument
    */
-  get document() this._document || (this._document = this._parent.ownerDocument),
+  get document() {
+    return this._document || (this._document = this._parent.ownerDocument);
+  },
 
   /**
    * Gets the default window holding this view.
    * @return nsIDOMWindow
    */
-  get window() this._window || (this._window = this.document.defaultView),
+  get window() {
+    return this._window || (this._window = this.document.defaultView);
+  },
 
   _document: null,
   _window: null,
 
   _store: null,
   _itemsByElement: null,
   _prevHierarchy: null,
   _currHierarchy: null,
@@ -1582,71 +1596,91 @@ Scope.prototype = {
     this._arrow.setAttribute("invisible", "");
     this._isArrowVisible = false;
   },
 
   /**
    * Gets the visibility state.
    * @return boolean
    */
-  get visible() this._isContentVisible,
+  get visible() {
+    return this._isContentVisible;
+  },
 
   /**
    * Gets the expanded state.
    * @return boolean
    */
-  get expanded() this._isExpanded,
+  get expanded() {
+    return this._isExpanded;
+  },
 
   /**
    * Gets the header visibility state.
    * @return boolean
    */
-  get header() this._isHeaderVisible,
+  get header() {
+    return this._isHeaderVisible;
+  },
 
   /**
    * Gets the twisty visibility state.
    * @return boolean
    */
-  get twisty() this._isArrowVisible,
+  get twisty() {
+    return this._isArrowVisible;
+  },
 
   /**
    * Gets the expand lock state.
    * @return boolean
    */
-  get locked() this._isLocked,
+  get locked() {
+    return this._isLocked;
+  },
 
   /**
    * Sets the visibility state.
    * @param boolean aFlag
    */
-  set visible(aFlag) aFlag ? this.show() : this.hide(),
+  set visible(aFlag) {
+    aFlag ? this.show() : this.hide();
+  },
 
   /**
    * Sets the expanded state.
    * @param boolean aFlag
    */
-  set expanded(aFlag) aFlag ? this.expand() : this.collapse(),
+  set expanded(aFlag) {
+    aFlag ? this.expand() : this.collapse();
+  },
 
   /**
    * Sets the header visibility state.
    * @param boolean aFlag
    */
-  set header(aFlag) aFlag ? this.showHeader() : this.hideHeader(),
+  set header(aFlag) {
+    aFlag ? this.showHeader() : this.hideHeader();
+  },
 
   /**
    * Sets the twisty visibility state.
    * @param boolean aFlag
    */
-  set twisty(aFlag) aFlag ? this.showArrow() : this.hideArrow(),
+  set twisty(aFlag) {
+    aFlag ? this.showArrow() : this.hideArrow();
+  },
 
   /**
    * Sets the expand lock state.
    * @param boolean aFlag
    */
-  set locked(aFlag) this._isLocked = aFlag,
+  set locked(aFlag) {
+    this._isLocked = aFlag;
+  },
 
   /**
    * Specifies if this target node may be focused.
    * @return boolean
    */
   get focusable() {
     // Check if this target node is actually visibile.
     if (!this._nameString ||
@@ -1693,41 +1727,51 @@ Scope.prototype = {
   removeEventListener: function(aName, aCallback, aCapture) {
     this._title.removeEventListener(aName, aCallback, aCapture);
   },
 
   /**
    * Gets the id associated with this item.
    * @return string
    */
-  get id() this._idString,
+  get id() {
+    return this._idString;
+  },
 
   /**
    * Gets the name associated with this item.
    * @return string
    */
-  get name() this._nameString,
+  get name() {
+    return this._nameString;
+  },
 
   /**
    * Gets the displayed value for this item.
    * @return string
    */
-  get displayValue() this._valueString,
+  get displayValue() {
+    return this._valueString;
+  },
 
   /**
    * Gets the class names used for the displayed value.
    * @return string
    */
-  get displayValueClassName() this._valueClassName,
+  get displayValueClassName() {
+    return this._valueClassName;
+  },
 
   /**
    * Gets the element associated with this item.
    * @return nsIDOMNode
    */
-  get target() this._target,
+  get target() {
+    return this._target;
+  },
 
   /**
    * Initializes this scope's id, view and binds event listeners.
    *
    * @param string aName
    *        The scope's name.
    * @param object aFlags [optional]
    *        Additional options or flags for this scope.
@@ -1999,43 +2043,51 @@ Scope.prototype = {
 
     return null;
   },
 
   /**
    * Gets top level variables view instance.
    * @return VariablesView
    */
-  get _variablesView() this._topView || (this._topView = (function(self) {
-    let parentView = self.ownerView;
-    let topView;
-
-    while ((topView = parentView.ownerView)) {
-      parentView = topView;
-    }
-    return parentView;
-  })(this)),
+  get _variablesView() {
+    return this._topView || (this._topView = (() => {
+      let parentView = this.ownerView;
+      let topView;
+
+      while ((topView = parentView.ownerView)) {
+        parentView = topView;
+      }
+      return parentView;
+    })());
+  },
 
   /**
    * Gets the parent node holding this scope.
    * @return nsIDOMNode
    */
-  get parentNode() this.ownerView._list,
+  get parentNode() {
+    return this.ownerView._list;
+  },
 
   /**
    * Gets the owner document holding this scope.
    * @return nsIHTMLDocument
    */
-  get document() this._document || (this._document = this.ownerView.document),
+  get document() {
+    return this._document || (this._document = this.ownerView.document);
+  },
 
   /**
    * Gets the default window holding this scope.
    * @return nsIDOMWindow
    */
-  get window() this._window || (this._window = this.ownerView.window),
+  get window() {
+    return this._window || (this._window = this.ownerView.window);
+  },
 
   _topView: null,
   _document: null,
   _window: null,
 
   ownerView: null,
   eval: null,
   switch: null,
@@ -2328,29 +2380,35 @@ Variable.prototype = Heritage.extend(Sco
     }
     return path;
   },
 
   /**
    * Returns this variable's value from the descriptor if available.
    * @return any
    */
-  get value() this._initialDescriptor.value,
+  get value() {
+    return this._initialDescriptor.value;
+  },
 
   /**
    * Returns this variable's getter from the descriptor if available.
    * @return object
    */
-  get getter() this._initialDescriptor.get,
+  get getter() {
+    return this._initialDescriptor.get;
+  },
 
   /**
    * Returns this variable's getter from the descriptor if available.
    * @return object
    */
-  get setter() this._initialDescriptor.set,
+  get setter() {
+    return this._initialDescriptor.set;
+  },
 
   /**
    * Sets the specific grip for this variable (applies the text content and
    * class name to the value label).
    *
    * The grip should contain the value or the type & class, as defined in the
    * remote debugger protocol. For convenience, undefined and null are
    * both considered types.
--- a/devtools/client/shared/widgets/ViewHelpers.jsm
+++ b/devtools/client/shared/widgets/ViewHelpers.jsm
@@ -766,17 +766,19 @@ this.WidgetMethods = {
       aWidget.on("mousePress", this._onWidgetMousePress.bind(this));
     }
   },
 
   /**
    * Gets the element node or widget associated with this container.
    * @return nsIDOMNode | object
    */
-  get widget() this._widget,
+  get widget() {
+    return this._widget;
+  },
 
   /**
    * Prepares an item to be added to this container. This allows, for example,
    * for a large number of items to be batched up before being sorted & added.
    *
    * If the "staged" flag is *not* set to true, the item will be immediately
    * inserted at the correct position in this container, so that all the items
    * still remain sorted. This can (possibly) be much slower than batching up
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -995,17 +995,17 @@ var NodeFront = protocol.FrontClass(Node
     return this._form.props ? this._form.props[name] : null;
   },
 
   hasFormProperty: function(name) {
     return this._form.props ? (name in this._form.props) : null;
   },
 
   get formProperties() {
-    return this._form.props
+    return this._form.props;
   },
 
   /**
    * Return a new AttributeModificationList for this node.
    */
   startModifyingAttributes: function() {
     return AttributeModificationList(this);
   },
new file mode 100644
--- /dev/null
+++ b/devtools/shared/heapsnapshot/.gitattributes
@@ -0,0 +1,1 @@
+CoreDump.pb.* binary
--- a/devtools/shared/heapsnapshot/AutoMemMap.h
+++ b/devtools/shared/heapsnapshot/AutoMemMap.h
@@ -1,14 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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_devtools_AutoMemMap_h
+#define mozilla_devtools_AutoMemMap_h
+
 #include <prio.h>
 #include "mozilla/GuardObjects.h"
 
 namespace mozilla {
 namespace devtools {
 
 // # AutoMemMap
 //
@@ -63,8 +66,10 @@ public:
 
   // Get the mapped memory.
   void* address() { MOZ_ASSERT(addr); return addr; }
   const void* address() const { MOZ_ASSERT(addr); return addr; }
 };
 
 } // namespace devtools
 } // namespace mozilla
+
+#endif // mozilla_devtools_AutoMemMap_h
--- a/devtools/shared/heapsnapshot/CoreDump.pb.cc
+++ b/devtools/shared/heapsnapshot/CoreDump.pb.cc
@@ -30,22 +30,38 @@ const ::google::protobuf::internal::Gene
   StackFrame_reflection_ = NULL;
 struct StackFrameOneofInstance {
   const ::mozilla::devtools::protobuf::StackFrame_Data* data_;
   ::google::protobuf::uint64 ref_;
 }* StackFrame_default_oneof_instance_ = NULL;
 const ::google::protobuf::Descriptor* StackFrame_Data_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   StackFrame_Data_reflection_ = NULL;
+struct StackFrame_DataOneofInstance {
+  const ::std::string* source_;
+  ::google::protobuf::uint64 sourceref_;
+  const ::std::string* functiondisplayname_;
+  ::google::protobuf::uint64 functiondisplaynameref_;
+}* StackFrame_Data_default_oneof_instance_ = NULL;
 const ::google::protobuf::Descriptor* Node_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   Node_reflection_ = NULL;
+struct NodeOneofInstance {
+  const ::std::string* typename__;
+  ::google::protobuf::uint64 typenameref_;
+  const ::std::string* jsobjectclassname_;
+  ::google::protobuf::uint64 jsobjectclassnameref_;
+}* Node_default_oneof_instance_ = NULL;
 const ::google::protobuf::Descriptor* Edge_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   Edge_reflection_ = NULL;
+struct EdgeOneofInstance {
+  const ::std::string* name_;
+  ::google::protobuf::uint64 nameref_;
+}* Edge_default_oneof_instance_ = NULL;
 
 }  // namespace
 
 
 void protobuf_AssignDesc_CoreDump_2eproto() {
   protobuf_AddDesc_CoreDump_2eproto();
   const ::google::protobuf::FileDescriptor* file =
     ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
@@ -81,71 +97,87 @@ void protobuf_AssignDesc_CoreDump_2eprot
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame, _unknown_fields_),
       -1,
       StackFrame_default_oneof_instance_,
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame, _oneof_case_[0]),
       ::google::protobuf::DescriptorPool::generated_pool(),
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(StackFrame));
   StackFrame_Data_descriptor_ = StackFrame_descriptor_->nested_type(0);
-  static const int StackFrame_Data_offsets_[8] = {
+  static const int StackFrame_Data_offsets_[12] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, id_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, parent_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, line_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, column_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, source_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, functiondisplayname_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, source_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, sourceref_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, functiondisplayname_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, functiondisplaynameref_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, issystem_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, isselfhosted_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, SourceOrRef_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, FunctionDisplayNameOrRef_),
   };
   StackFrame_Data_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
       StackFrame_Data_descriptor_,
       StackFrame_Data::default_instance_,
       StackFrame_Data_offsets_,
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _has_bits_[0]),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _unknown_fields_),
       -1,
+      StackFrame_Data_default_oneof_instance_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _oneof_case_[0]),
       ::google::protobuf::DescriptorPool::generated_pool(),
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(StackFrame_Data));
   Node_descriptor_ = file->message_type(2);
-  static const int Node_offsets_[7] = {
+  static const int Node_offsets_[11] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, id_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, typename__),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typename__),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typenameref_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, size_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, edges_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, allocationstack_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, jsobjectclassname_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassname_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassnameref_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, coarsetype_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, TypeNameOrRef_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, JSObjectClassNameOrRef_),
   };
   Node_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
       Node_descriptor_,
       Node::default_instance_,
       Node_offsets_,
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _has_bits_[0]),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _unknown_fields_),
       -1,
+      Node_default_oneof_instance_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _oneof_case_[0]),
       ::google::protobuf::DescriptorPool::generated_pool(),
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(Node));
   Edge_descriptor_ = file->message_type(3);
-  static const int Edge_offsets_[2] = {
+  static const int Edge_offsets_[4] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, referent_),
-    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, name_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Edge_default_oneof_instance_, name_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Edge_default_oneof_instance_, nameref_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, EdgeNameOrRef_),
   };
   Edge_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
       Edge_descriptor_,
       Edge::default_instance_,
       Edge_offsets_,
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _has_bits_[0]),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _unknown_fields_),
       -1,
+      Edge_default_oneof_instance_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _oneof_case_[0]),
       ::google::protobuf::DescriptorPool::generated_pool(),
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(Edge));
 }
 
 namespace {
 
 GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
@@ -172,54 +204,66 @@ void protobuf_RegisterTypes(const ::std:
 
 void protobuf_ShutdownFile_CoreDump_2eproto() {
   delete Metadata::default_instance_;
   delete Metadata_reflection_;
   delete StackFrame::default_instance_;
   delete StackFrame_default_oneof_instance_;
   delete StackFrame_reflection_;
   delete StackFrame_Data::default_instance_;
+  delete StackFrame_Data_default_oneof_instance_;
   delete StackFrame_Data_reflection_;
   delete Node::default_instance_;
+  delete Node_default_oneof_instance_;
   delete Node_reflection_;
   delete Edge::default_instance_;
+  delete Edge_default_oneof_instance_;
   delete Edge_reflection_;
 }
 
 void protobuf_AddDesc_CoreDump_2eproto() {
   static bool already_here = false;
   if (already_here) return;
   already_here = true;
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
     "\n\016CoreDump.proto\022\031mozilla.devtools.proto"
-    "buf\"\035\n\010Metadata\022\021\n\ttimeStamp\030\001 \001(\004\"\250\002\n\nS"
+    "buf\"\035\n\010Metadata\022\021\n\ttimeStamp\030\001 \001(\004\"\216\003\n\nS"
     "tackFrame\022:\n\004data\030\001 \001(\0132*.mozilla.devtoo"
     "ls.protobuf.StackFrame.DataH\000\022\r\n\003ref\030\002 \001"
-    "(\004H\000\032\274\001\n\004Data\022\n\n\002id\030\001 \001(\004\0225\n\006parent\030\002 \001("
+    "(\004H\000\032\242\002\n\004Data\022\n\n\002id\030\001 \001(\004\0225\n\006parent\030\002 \001("
     "\0132%.mozilla.devtools.protobuf.StackFrame"
-    "\022\014\n\004line\030\003 \001(\r\022\016\n\006column\030\004 \001(\r\022\016\n\006source"
-    "\030\005 \001(\014\022\033\n\023functionDisplayName\030\006 \001(\014\022\020\n\010i"
-    "sSystem\030\007 \001(\010\022\024\n\014isSelfHosted\030\010 \001(\010B\020\n\016S"
-    "tackFrameType\"\324\001\n\004Node\022\n\n\002id\030\001 \001(\004\022\020\n\010ty"
-    "peName\030\002 \001(\014\022\014\n\004size\030\003 \001(\004\022.\n\005edges\030\004 \003("
-    "\0132\037.mozilla.devtools.protobuf.Edge\022>\n\017al"
-    "locationStack\030\005 \001(\0132%.mozilla.devtools.p"
-    "rotobuf.StackFrame\022\031\n\021jsObjectClassName\030"
-    "\006 \001(\014\022\025\n\ncoarseType\030\007 \001(\r:\0010\"&\n\004Edge\022\020\n\010"
-    "referent\030\001 \001(\004\022\014\n\004name\030\002 \001(\014", 628);
+    "\022\014\n\004line\030\003 \001(\r\022\016\n\006column\030\004 \001(\r\022\020\n\006source"
+    "\030\005 \001(\014H\000\022\023\n\tsourceRef\030\006 \001(\004H\000\022\035\n\023functio"
+    "nDisplayName\030\007 \001(\014H\001\022 \n\026functionDisplayN"
+    "ameRef\030\010 \001(\004H\001\022\020\n\010isSystem\030\t \001(\010\022\024\n\014isSe"
+    "lfHosted\030\n \001(\010B\r\n\013SourceOrRefB\032\n\030Functio"
+    "nDisplayNameOrRefB\020\n\016StackFrameType\"\272\002\n\004"
+    "Node\022\n\n\002id\030\001 \001(\004\022\022\n\010typeName\030\002 \001(\014H\000\022\025\n\013"
+    "typeNameRef\030\003 \001(\004H\000\022\014\n\004size\030\004 \001(\004\022.\n\005edg"
+    "es\030\005 \003(\0132\037.mozilla.devtools.protobuf.Edg"
+    "e\022>\n\017allocationStack\030\006 \001(\0132%.mozilla.dev"
+    "tools.protobuf.StackFrame\022\033\n\021jsObjectCla"
+    "ssName\030\007 \001(\014H\001\022\036\n\024jsObjectClassNameRef\030\010"
+    " \001(\004H\001\022\025\n\ncoarseType\030\t \001(\r:\0010B\017\n\rTypeNam"
+    "eOrRefB\030\n\026JSObjectClassNameOrRef\"L\n\004Edge"
+    "\022\020\n\010referent\030\001 \001(\004\022\016\n\004name\030\002 \001(\014H\000\022\021\n\007na"
+    "meRef\030\003 \001(\004H\000B\017\n\rEdgeNameOrRef", 870);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "CoreDump.proto", &protobuf_RegisterTypes);
   Metadata::default_instance_ = new Metadata();
   StackFrame::default_instance_ = new StackFrame();
   StackFrame_default_oneof_instance_ = new StackFrameOneofInstance;
   StackFrame_Data::default_instance_ = new StackFrame_Data();
+  StackFrame_Data_default_oneof_instance_ = new StackFrame_DataOneofInstance;
   Node::default_instance_ = new Node();
+  Node_default_oneof_instance_ = new NodeOneofInstance;
   Edge::default_instance_ = new Edge();
+  Edge_default_oneof_instance_ = new EdgeOneofInstance;
   Metadata::default_instance_->InitAsDefaultInstance();
   StackFrame::default_instance_->InitAsDefaultInstance();
   StackFrame_Data::default_instance_->InitAsDefaultInstance();
   Node::default_instance_->InitAsDefaultInstance();
   Edge::default_instance_->InitAsDefaultInstance();
   ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_CoreDump_2eproto);
 }
 
@@ -455,63 +499,69 @@ void Metadata::Swap(Metadata* other) {
 // ===================================================================
 
 #ifndef _MSC_VER
 const int StackFrame_Data::kIdFieldNumber;
 const int StackFrame_Data::kParentFieldNumber;
 const int StackFrame_Data::kLineFieldNumber;
 const int StackFrame_Data::kColumnFieldNumber;
 const int StackFrame_Data::kSourceFieldNumber;
+const int StackFrame_Data::kSourceRefFieldNumber;
 const int StackFrame_Data::kFunctionDisplayNameFieldNumber;
+const int StackFrame_Data::kFunctionDisplayNameRefFieldNumber;
 const int StackFrame_Data::kIsSystemFieldNumber;
 const int StackFrame_Data::kIsSelfHostedFieldNumber;
 #endif  // !_MSC_VER
 
 StackFrame_Data::StackFrame_Data()
   : ::google::protobuf::Message() {
   SharedCtor();
   // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.StackFrame.Data)
 }
 
 void StackFrame_Data::InitAsDefaultInstance() {
   parent_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance());
+  StackFrame_Data_default_oneof_instance_->source_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
+  StackFrame_Data_default_oneof_instance_->sourceref_ = GOOGLE_ULONGLONG(0);
+  StackFrame_Data_default_oneof_instance_->functiondisplayname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
+  StackFrame_Data_default_oneof_instance_->functiondisplaynameref_ = GOOGLE_ULONGLONG(0);
 }
 
 StackFrame_Data::StackFrame_Data(const StackFrame_Data& from)
   : ::google::protobuf::Message() {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.StackFrame.Data)
 }
 
 void StackFrame_Data::SharedCtor() {
   ::google::protobuf::internal::GetEmptyString();
   _cached_size_ = 0;
   id_ = GOOGLE_ULONGLONG(0);
   parent_ = NULL;
   line_ = 0u;
   column_ = 0u;
-  source_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  functiondisplayname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   issystem_ = false;
   isselfhosted_ = false;
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  clear_has_SourceOrRef();
+  clear_has_FunctionDisplayNameOrRef();
 }
 
 StackFrame_Data::~StackFrame_Data() {
   // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.StackFrame.Data)
   SharedDtor();
 }
 
 void StackFrame_Data::SharedDtor() {
-  if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete source_;
+  if (has_SourceOrRef()) {
+    clear_SourceOrRef();
   }
-  if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete functiondisplayname_;
+  if (has_FunctionDisplayNameOrRef()) {
+    clear_FunctionDisplayNameOrRef();
   }
   if (this != default_instance_) {
     delete parent_;
   }
 }
 
 void StackFrame_Data::SetCachedSize(int size) const {
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -529,49 +579,76 @@ const StackFrame_Data& StackFrame_Data::
 }
 
 StackFrame_Data* StackFrame_Data::default_instance_ = NULL;
 
 StackFrame_Data* StackFrame_Data::New() const {
   return new StackFrame_Data;
 }
 
+void StackFrame_Data::clear_SourceOrRef() {
+  switch(SourceOrRef_case()) {
+    case kSource: {
+      delete SourceOrRef_.source_;
+      break;
+    }
+    case kSourceRef: {
+      // No need to clear
+      break;
+    }
+    case SOURCEORREF_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = SOURCEORREF_NOT_SET;
+}
+
+void StackFrame_Data::clear_FunctionDisplayNameOrRef() {
+  switch(FunctionDisplayNameOrRef_case()) {
+    case kFunctionDisplayName: {
+      delete FunctionDisplayNameOrRef_.functiondisplayname_;
+      break;
+    }
+    case kFunctionDisplayNameRef: {
+      // No need to clear
+      break;
+    }
+    case FUNCTIONDISPLAYNAMEORREF_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[1] = FUNCTIONDISPLAYNAMEORREF_NOT_SET;
+}
+
+
 void StackFrame_Data::Clear() {
 #define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
   &reinterpret_cast<StackFrame_Data*>(16)->f) - \
    reinterpret_cast<char*>(16))
 
 #define ZR_(first, last) do {                              \
     size_t f = OFFSET_OF_FIELD_(first);                    \
     size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
     ::memset(&first, 0, n);                                \
   } while (0)
 
-  if (_has_bits_[0 / 32] & 255) {
+  if (_has_bits_[0 / 32] & 15) {
     ZR_(line_, column_);
-    ZR_(issystem_, isselfhosted_);
     id_ = GOOGLE_ULONGLONG(0);
     if (has_parent()) {
       if (parent_ != NULL) parent_->::mozilla::devtools::protobuf::StackFrame::Clear();
     }
-    if (has_source()) {
-      if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        source_->clear();
-      }
-    }
-    if (has_functiondisplayname()) {
-      if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        functiondisplayname_->clear();
-      }
-    }
   }
+  ZR_(issystem_, isselfhosted_);
 
 #undef OFFSET_OF_FIELD_
 #undef ZR_
 
+  clear_SourceOrRef();
+  clear_FunctionDisplayNameOrRef();
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   mutable_unknown_fields()->Clear();
 }
 
 bool StackFrame_Data::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
 #define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
@@ -642,51 +719,83 @@ bool StackFrame_Data::MergePartialFromCo
       case 5: {
         if (tag == 42) {
          parse_source:
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_source()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(50)) goto parse_functionDisplayName;
+        if (input->ExpectTag(48)) goto parse_sourceRef;
         break;
       }
 
-      // optional bytes functionDisplayName = 6;
+      // optional uint64 sourceRef = 6;
       case 6: {
-        if (tag == 50) {
+        if (tag == 48) {
+         parse_sourceRef:
+          clear_SourceOrRef();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &SourceOrRef_.sourceref_)));
+          set_has_sourceref();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(58)) goto parse_functionDisplayName;
+        break;
+      }
+
+      // optional bytes functionDisplayName = 7;
+      case 7: {
+        if (tag == 58) {
          parse_functionDisplayName:
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_functiondisplayname()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(56)) goto parse_isSystem;
+        if (input->ExpectTag(64)) goto parse_functionDisplayNameRef;
         break;
       }
 
-      // optional bool isSystem = 7;
-      case 7: {
-        if (tag == 56) {
+      // optional uint64 functionDisplayNameRef = 8;
+      case 8: {
+        if (tag == 64) {
+         parse_functionDisplayNameRef:
+          clear_FunctionDisplayNameOrRef();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &FunctionDisplayNameOrRef_.functiondisplaynameref_)));
+          set_has_functiondisplaynameref();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(72)) goto parse_isSystem;
+        break;
+      }
+
+      // optional bool isSystem = 9;
+      case 9: {
+        if (tag == 72) {
          parse_isSystem:
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &issystem_)));
           set_has_issystem();
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(64)) goto parse_isSelfHosted;
+        if (input->ExpectTag(80)) goto parse_isSelfHosted;
         break;
       }
 
-      // optional bool isSelfHosted = 8;
-      case 8: {
-        if (tag == 64) {
+      // optional bool isSelfHosted = 10;
+      case 10: {
+        if (tag == 80) {
          parse_isSelfHosted:
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &isselfhosted_)));
           set_has_isselfhosted();
         } else {
           goto handle_unusual;
         }
@@ -741,30 +850,40 @@ void StackFrame_Data::SerializeWithCache
   }
 
   // optional bytes source = 5;
   if (has_source()) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
       5, this->source(), output);
   }
 
-  // optional bytes functionDisplayName = 6;
+  // optional uint64 sourceRef = 6;
+  if (has_sourceref()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->sourceref(), output);
+  }
+
+  // optional bytes functionDisplayName = 7;
   if (has_functiondisplayname()) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
-      6, this->functiondisplayname(), output);
+      7, this->functiondisplayname(), output);
   }
 
-  // optional bool isSystem = 7;
-  if (has_issystem()) {
-    ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->issystem(), output);
+  // optional uint64 functionDisplayNameRef = 8;
+  if (has_functiondisplaynameref()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->functiondisplaynameref(), output);
   }
 
-  // optional bool isSelfHosted = 8;
+  // optional bool isSystem = 9;
+  if (has_issystem()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(9, this->issystem(), output);
+  }
+
+  // optional bool isSelfHosted = 10;
   if (has_isselfhosted()) {
-    ::google::protobuf::internal::WireFormatLite::WriteBool(8, this->isselfhosted(), output);
+    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->isselfhosted(), output);
   }
 
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.StackFrame.Data)
 }
@@ -796,31 +915,41 @@ void StackFrame_Data::SerializeWithCache
 
   // optional bytes source = 5;
   if (has_source()) {
     target =
       ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
         5, this->source(), target);
   }
 
-  // optional bytes functionDisplayName = 6;
+  // optional uint64 sourceRef = 6;
+  if (has_sourceref()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(6, this->sourceref(), target);
+  }
+
+  // optional bytes functionDisplayName = 7;
   if (has_functiondisplayname()) {
     target =
       ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
-        6, this->functiondisplayname(), target);
+        7, this->functiondisplayname(), target);
+  }
+
+  // optional uint64 functionDisplayNameRef = 8;
+  if (has_functiondisplaynameref()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->functiondisplaynameref(), target);
   }
 
-  // optional bool isSystem = 7;
+  // optional bool isSystem = 9;
   if (has_issystem()) {
-    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->issystem(), target);
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(9, this->issystem(), target);
   }
 
-  // optional bool isSelfHosted = 8;
+  // optional bool isSelfHosted = 10;
   if (has_isselfhosted()) {
-    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(8, this->isselfhosted(), target);
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->isselfhosted(), target);
   }
 
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.StackFrame.Data)
   return target;
@@ -853,41 +982,67 @@ int StackFrame_Data::ByteSize() const {
 
     // optional uint32 column = 4;
     if (has_column()) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::UInt32Size(
           this->column());
     }
 
-    // optional bytes source = 5;
-    if (has_source()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::BytesSize(
-          this->source());
-    }
-
-    // optional bytes functionDisplayName = 6;
-    if (has_functiondisplayname()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::BytesSize(
-          this->functiondisplayname());
-    }
-
-    // optional bool isSystem = 7;
+  }
+  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+    // optional bool isSystem = 9;
     if (has_issystem()) {
       total_size += 1 + 1;
     }
 
-    // optional bool isSelfHosted = 8;
+    // optional bool isSelfHosted = 10;
     if (has_isselfhosted()) {
       total_size += 1 + 1;
     }
 
   }
+  switch (SourceOrRef_case()) {
+    // optional bytes source = 5;
+    case kSource: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::BytesSize(
+          this->source());
+      break;
+    }
+    // optional uint64 sourceRef = 6;
+    case kSourceRef: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->sourceref());
+      break;
+    }
+    case SOURCEORREF_NOT_SET: {
+      break;
+    }
+  }
+  switch (FunctionDisplayNameOrRef_case()) {
+    // optional bytes functionDisplayName = 7;
+    case kFunctionDisplayName: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::BytesSize(
+          this->functiondisplayname());
+      break;
+    }
+    // optional uint64 functionDisplayNameRef = 8;
+    case kFunctionDisplayNameRef: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->functiondisplaynameref());
+      break;
+    }
+    case FUNCTIONDISPLAYNAMEORREF_NOT_SET: {
+      break;
+    }
+  }
   if (!unknown_fields().empty()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         unknown_fields());
   }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -903,35 +1058,57 @@ void StackFrame_Data::MergeFrom(const ::
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
 }
 
 void StackFrame_Data::MergeFrom(const StackFrame_Data& from) {
   GOOGLE_CHECK_NE(&from, this);
+  switch (from.SourceOrRef_case()) {
+    case kSource: {
+      set_source(from.source());
+      break;
+    }
+    case kSourceRef: {
+      set_sourceref(from.sourceref());
+      break;
+    }
+    case SOURCEORREF_NOT_SET: {
+      break;
+    }
+  }
+  switch (from.FunctionDisplayNameOrRef_case()) {
+    case kFunctionDisplayName: {
+      set_functiondisplayname(from.functiondisplayname());
+      break;
+    }
+    case kFunctionDisplayNameRef: {
+      set_functiondisplaynameref(from.functiondisplaynameref());
+      break;
+    }
+    case FUNCTIONDISPLAYNAMEORREF_NOT_SET: {
+      break;
+    }
+  }
   if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
     if (from.has_id()) {
       set_id(from.id());
     }
     if (from.has_parent()) {
       mutable_parent()->::mozilla::devtools::protobuf::StackFrame::MergeFrom(from.parent());
     }
     if (from.has_line()) {
       set_line(from.line());
     }
     if (from.has_column()) {
       set_column(from.column());
     }
-    if (from.has_source()) {
-      set_source(from.source());
-    }
-    if (from.has_functiondisplayname()) {
-      set_functiondisplayname(from.functiondisplayname());
-    }
+  }
+  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
     if (from.has_issystem()) {
       set_issystem(from.issystem());
     }
     if (from.has_isselfhosted()) {
       set_isselfhosted(from.isselfhosted());
     }
   }
   mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -955,20 +1132,22 @@ bool StackFrame_Data::IsInitialized() co
 }
 
 void StackFrame_Data::Swap(StackFrame_Data* other) {
   if (other != this) {
     std::swap(id_, other->id_);
     std::swap(parent_, other->parent_);
     std::swap(line_, other->line_);
     std::swap(column_, other->column_);
-    std::swap(source_, other->source_);
-    std::swap(functiondisplayname_, other->functiondisplayname_);
     std::swap(issystem_, other->issystem_);
     std::swap(isselfhosted_, other->isselfhosted_);
+    std::swap(SourceOrRef_, other->SourceOrRef_);
+    std::swap(_oneof_case_[0], other->_oneof_case_[0]);
+    std::swap(FunctionDisplayNameOrRef_, other->FunctionDisplayNameOrRef_);
+    std::swap(_oneof_case_[1], other->_oneof_case_[1]);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);
   }
 }
 
 ::google::protobuf::Metadata StackFrame_Data::GetMetadata() const {
   protobuf_AssignDescriptorsOnce();
@@ -1271,63 +1450,69 @@ void StackFrame::Swap(StackFrame* other)
 }
 
 
 // ===================================================================
 
 #ifndef _MSC_VER
 const int Node::kIdFieldNumber;
 const int Node::kTypeNameFieldNumber;
+const int Node::kTypeNameRefFieldNumber;
 const int Node::kSizeFieldNumber;
 const int Node::kEdgesFieldNumber;
 const int Node::kAllocationStackFieldNumber;
 const int Node::kJsObjectClassNameFieldNumber;
+const int Node::kJsObjectClassNameRefFieldNumber;
 const int Node::kCoarseTypeFieldNumber;
 #endif  // !_MSC_VER
 
 Node::Node()
   : ::google::protobuf::Message() {
   SharedCtor();
   // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Node)
 }
 
 void Node::InitAsDefaultInstance() {
+  Node_default_oneof_instance_->typename__ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
+  Node_default_oneof_instance_->typenameref_ = GOOGLE_ULONGLONG(0);
   allocationstack_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance());
+  Node_default_oneof_instance_->jsobjectclassname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
+  Node_default_oneof_instance_->jsobjectclassnameref_ = GOOGLE_ULONGLONG(0);
 }
 
 Node::Node(const Node& from)
   : ::google::protobuf::Message() {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Node)
 }
 
 void Node::SharedCtor() {
   ::google::protobuf::internal::GetEmptyString();
   _cached_size_ = 0;
   id_ = GOOGLE_ULONGLONG(0);
-  typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   size_ = GOOGLE_ULONGLONG(0);
   allocationstack_ = NULL;
-  jsobjectclassname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   coarsetype_ = 0u;
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  clear_has_TypeNameOrRef();
+  clear_has_JSObjectClassNameOrRef();
 }
 
 Node::~Node() {
   // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Node)
   SharedDtor();
 }
 
 void Node::SharedDtor() {
-  if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete typename__;
+  if (has_TypeNameOrRef()) {
+    clear_TypeNameOrRef();
   }
-  if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete jsobjectclassname_;
+  if (has_JSObjectClassNameOrRef()) {
+    clear_JSObjectClassNameOrRef();
   }
   if (this != default_instance_) {
     delete allocationstack_;
   }
 }
 
 void Node::SetCachedSize(int size) const {
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -1345,36 +1530,76 @@ const Node& Node::default_instance() {
 }
 
 Node* Node::default_instance_ = NULL;
 
 Node* Node::New() const {
   return new Node;
 }
 
+void Node::clear_TypeNameOrRef() {
+  switch(TypeNameOrRef_case()) {
+    case kTypeName: {
+      delete TypeNameOrRef_.typename__;
+      break;
+    }
+    case kTypeNameRef: {
+      // No need to clear
+      break;
+    }
+    case TYPENAMEORREF_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = TYPENAMEORREF_NOT_SET;
+}
+
+void Node::clear_JSObjectClassNameOrRef() {
+  switch(JSObjectClassNameOrRef_case()) {
+    case kJsObjectClassName: {
+      delete JSObjectClassNameOrRef_.jsobjectclassname_;
+      break;
+    }
+    case kJsObjectClassNameRef: {
+      // No need to clear
+      break;
+    }
+    case JSOBJECTCLASSNAMEORREF_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET;
+}
+
+
 void Node::Clear() {
-  if (_has_bits_[0 / 32] & 119) {
-    id_ = GOOGLE_ULONGLONG(0);
-    if (has_typename_()) {
-      if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        typename__->clear();
-      }
-    }
-    size_ = GOOGLE_ULONGLONG(0);
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<Node*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  if (_has_bits_[0 / 32] & 41) {
+    ZR_(id_, size_);
     if (has_allocationstack()) {
       if (allocationstack_ != NULL) allocationstack_->::mozilla::devtools::protobuf::StackFrame::Clear();
     }
-    if (has_jsobjectclassname()) {
-      if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        jsobjectclassname_->clear();
-      }
-    }
-    coarsetype_ = 0u;
   }
+  coarsetype_ = 0u;
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
   edges_.Clear();
+  clear_TypeNameOrRef();
+  clear_JSObjectClassNameOrRef();
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   mutable_unknown_fields()->Clear();
 }
 
 bool Node::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
 #define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
@@ -1402,78 +1627,110 @@ bool Node::MergePartialFromCodedStream(
       case 2: {
         if (tag == 18) {
          parse_typeName:
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_typename_()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(24)) goto parse_size;
+        if (input->ExpectTag(24)) goto parse_typeNameRef;
         break;
       }
 
-      // optional uint64 size = 3;
+      // optional uint64 typeNameRef = 3;
       case 3: {
         if (tag == 24) {
+         parse_typeNameRef:
+          clear_TypeNameOrRef();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &TypeNameOrRef_.typenameref_)));
+          set_has_typenameref();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(32)) goto parse_size;
+        break;
+      }
+
+      // optional uint64 size = 4;
+      case 4: {
+        if (tag == 32) {
          parse_size:
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                  input, &size_)));
           set_has_size();
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(34)) goto parse_edges;
+        if (input->ExpectTag(42)) goto parse_edges;
         break;
       }
 
-      // repeated .mozilla.devtools.protobuf.Edge edges = 4;
-      case 4: {
-        if (tag == 34) {
+      // repeated .mozilla.devtools.protobuf.Edge edges = 5;
+      case 5: {
+        if (tag == 42) {
          parse_edges:
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                 input, add_edges()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(34)) goto parse_edges;
-        if (input->ExpectTag(42)) goto parse_allocationStack;
+        if (input->ExpectTag(42)) goto parse_edges;
+        if (input->ExpectTag(50)) goto parse_allocationStack;
         break;
       }
 
-      // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5;
-      case 5: {
-        if (tag == 42) {
+      // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
+      case 6: {
+        if (tag == 50) {
          parse_allocationStack:
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, mutable_allocationstack()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(50)) goto parse_jsObjectClassName;
+        if (input->ExpectTag(58)) goto parse_jsObjectClassName;
         break;
       }
 
-      // optional bytes jsObjectClassName = 6;
-      case 6: {
-        if (tag == 50) {
+      // optional bytes jsObjectClassName = 7;
+      case 7: {
+        if (tag == 58) {
          parse_jsObjectClassName:
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_jsobjectclassname()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(56)) goto parse_coarseType;
+        if (input->ExpectTag(64)) goto parse_jsObjectClassNameRef;
         break;
       }
 
-      // optional uint32 coarseType = 7 [default = 0];
-      case 7: {
-        if (tag == 56) {
+      // optional uint64 jsObjectClassNameRef = 8;
+      case 8: {
+        if (tag == 64) {
+         parse_jsObjectClassNameRef:
+          clear_JSObjectClassNameOrRef();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &JSObjectClassNameOrRef_.jsobjectclassnameref_)));
+          set_has_jsobjectclassnameref();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(72)) goto parse_coarseType;
+        break;
+      }
+
+      // optional uint32 coarseType = 9 [default = 0];
+      case 9: {
+        if (tag == 72) {
          parse_coarseType:
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                  input, &coarsetype_)));
           set_has_coarsetype();
         } else {
           goto handle_unusual;
         }
@@ -1512,42 +1769,52 @@ void Node::SerializeWithCachedSizes(
   }
 
   // optional bytes typeName = 2;
   if (has_typename_()) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
       2, this->typename_(), output);
   }
 
-  // optional uint64 size = 3;
-  if (has_size()) {
-    ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->size(), output);
+  // optional uint64 typeNameRef = 3;
+  if (has_typenameref()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->typenameref(), output);
   }
 
-  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
+  // optional uint64 size = 4;
+  if (has_size()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->size(), output);
+  }
+
+  // repeated .mozilla.devtools.protobuf.Edge edges = 5;
   for (int i = 0; i < this->edges_size(); i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->edges(i), output);
+      5, this->edges(i), output);
   }
 
-  // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5;
+  // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
   if (has_allocationstack()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->allocationstack(), output);
+      6, this->allocationstack(), output);
   }
 
-  // optional bytes jsObjectClassName = 6;
+  // optional bytes jsObjectClassName = 7;
   if (has_jsobjectclassname()) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
-      6, this->jsobjectclassname(), output);
+      7, this->jsobjectclassname(), output);
   }
 
-  // optional uint32 coarseType = 7 [default = 0];
+  // optional uint64 jsObjectClassNameRef = 8;
+  if (has_jsobjectclassnameref()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->jsobjectclassnameref(), output);
+  }
+
+  // optional uint32 coarseType = 9 [default = 0];
   if (has_coarsetype()) {
-    ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->coarsetype(), output);
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->coarsetype(), output);
   }
 
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Node)
 }
@@ -1562,45 +1829,55 @@ void Node::SerializeWithCachedSizes(
 
   // optional bytes typeName = 2;
   if (has_typename_()) {
     target =
       ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
         2, this->typename_(), target);
   }
 
-  // optional uint64 size = 3;
-  if (has_size()) {
-    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->size(), target);
+  // optional uint64 typeNameRef = 3;
+  if (has_typenameref()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->typenameref(), target);
   }
 
-  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
+  // optional uint64 size = 4;
+  if (has_size()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->size(), target);
+  }
+
+  // repeated .mozilla.devtools.protobuf.Edge edges = 5;
   for (int i = 0; i < this->edges_size(); i++) {
     target = ::google::protobuf::internal::WireFormatLite::
       WriteMessageNoVirtualToArray(
-        4, this->edges(i), target);
+        5, this->edges(i), target);
   }
 
-  // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5;
+  // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
   if (has_allocationstack()) {
     target = ::google::protobuf::internal::WireFormatLite::
       WriteMessageNoVirtualToArray(
-        5, this->allocationstack(), target);
+        6, this->allocationstack(), target);
   }
 
-  // optional bytes jsObjectClassName = 6;
+  // optional bytes jsObjectClassName = 7;
   if (has_jsobjectclassname()) {
     target =
       ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
-        6, this->jsobjectclassname(), target);
+        7, this->jsobjectclassname(), target);
   }
 
-  // optional uint32 coarseType = 7 [default = 0];
+  // optional uint64 jsObjectClassNameRef = 8;
+  if (has_jsobjectclassnameref()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->jsobjectclassnameref(), target);
+  }
+
+  // optional uint32 coarseType = 9 [default = 0];
   if (has_coarsetype()) {
-    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->coarsetype(), target);
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->coarsetype(), target);
   }
 
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Node)
   return target;
@@ -1612,60 +1889,86 @@ int Node::ByteSize() const {
   if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
     // optional uint64 id = 1;
     if (has_id()) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::UInt64Size(
           this->id());
     }
 
-    // optional bytes typeName = 2;
-    if (has_typename_()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::BytesSize(
-          this->typename_());
-    }
-
-    // optional uint64 size = 3;
+    // optional uint64 size = 4;
     if (has_size()) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::UInt64Size(
           this->size());
     }
 
-    // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5;
+    // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
     if (has_allocationstack()) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
           this->allocationstack());
     }
 
-    // optional bytes jsObjectClassName = 6;
-    if (has_jsobjectclassname()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::BytesSize(
-          this->jsobjectclassname());
-    }
-
-    // optional uint32 coarseType = 7 [default = 0];
+  }
+  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+    // optional uint32 coarseType = 9 [default = 0];
     if (has_coarsetype()) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::UInt32Size(
           this->coarsetype());
     }
 
   }
-  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
+  // repeated .mozilla.devtools.protobuf.Edge edges = 5;
   total_size += 1 * this->edges_size();
   for (int i = 0; i < this->edges_size(); i++) {
     total_size +=
       ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
         this->edges(i));
   }
 
+  switch (TypeNameOrRef_case()) {
+    // optional bytes typeName = 2;
+    case kTypeName: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::BytesSize(
+          this->typename_());
+      break;
+    }
+    // optional uint64 typeNameRef = 3;
+    case kTypeNameRef: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->typenameref());
+      break;
+    }
+    case TYPENAMEORREF_NOT_SET: {
+      break;
+    }
+  }
+  switch (JSObjectClassNameOrRef_case()) {
+    // optional bytes jsObjectClassName = 7;
+    case kJsObjectClassName: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::BytesSize(
+          this->jsobjectclassname());
+      break;
+    }
+    // optional uint64 jsObjectClassNameRef = 8;
+    case kJsObjectClassNameRef: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->jsobjectclassnameref());
+      break;
+    }
+    case JSOBJECTCLASSNAMEORREF_NOT_SET: {
+      break;
+    }
+  }
   if (!unknown_fields().empty()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         unknown_fields());
   }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -1682,32 +1985,54 @@ void Node::MergeFrom(const ::google::pro
   } else {
     MergeFrom(*source);
   }
 }
 
 void Node::MergeFrom(const Node& from) {
   GOOGLE_CHECK_NE(&from, this);
   edges_.MergeFrom(from.edges_);
+  switch (from.TypeNameOrRef_case()) {
+    case kTypeName: {
+      set_typename_(from.typename_());
+      break;
+    }
+    case kTypeNameRef: {
+      set_typenameref(from.typenameref());
+      break;
+    }
+    case TYPENAMEORREF_NOT_SET: {
+      break;
+    }
+  }
+  switch (from.JSObjectClassNameOrRef_case()) {
+    case kJsObjectClassName: {
+      set_jsobjectclassname(from.jsobjectclassname());
+      break;
+    }
+    case kJsObjectClassNameRef: {
+      set_jsobjectclassnameref(from.jsobjectclassnameref());
+      break;
+    }
+    case JSOBJECTCLASSNAMEORREF_NOT_SET: {
+      break;
+    }
+  }
   if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
     if (from.has_id()) {
       set_id(from.id());
     }
-    if (from.has_typename_()) {
-      set_typename_(from.typename_());
-    }
     if (from.has_size()) {
       set_size(from.size());
     }
     if (from.has_allocationstack()) {
       mutable_allocationstack()->::mozilla::devtools::protobuf::StackFrame::MergeFrom(from.allocationstack());
     }
-    if (from.has_jsobjectclassname()) {
-      set_jsobjectclassname(from.jsobjectclassname());
-    }
+  }
+  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
     if (from.has_coarsetype()) {
       set_coarsetype(from.coarsetype());
     }
   }
   mutable_unknown_fields()->MergeFrom(from.unknown_fields());
 }
 
 void Node::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1725,22 +2050,24 @@ void Node::CopyFrom(const Node& from) {
 bool Node::IsInitialized() const {
 
   return true;
 }
 
 void Node::Swap(Node* other) {
   if (other != this) {
     std::swap(id_, other->id_);
-    std::swap(typename__, other->typename__);
     std::swap(size_, other->size_);
     edges_.Swap(&other->edges_);
     std::swap(allocationstack_, other->allocationstack_);
-    std::swap(jsobjectclassname_, other->jsobjectclassname_);
     std::swap(coarsetype_, other->coarsetype_);
+    std::swap(TypeNameOrRef_, other->TypeNameOrRef_);
+    std::swap(_oneof_case_[0], other->_oneof_case_[0]);
+    std::swap(JSObjectClassNameOrRef_, other->JSObjectClassNameOrRef_);
+    std::swap(_oneof_case_[1], other->_oneof_case_[1]);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);
   }
 }
 
 ::google::protobuf::Metadata Node::GetMetadata() const {
   protobuf_AssignDescriptorsOnce();
@@ -1751,50 +2078,53 @@ void Node::Swap(Node* other) {
 }
 
 
 // ===================================================================
 
 #ifndef _MSC_VER
 const int Edge::kReferentFieldNumber;
 const int Edge::kNameFieldNumber;
+const int Edge::kNameRefFieldNumber;
 #endif  // !_MSC_VER
 
 Edge::Edge()
   : ::google::protobuf::Message() {
   SharedCtor();
   // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Edge)
 }
 
 void Edge::InitAsDefaultInstance() {
+  Edge_default_oneof_instance_->name_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
+  Edge_default_oneof_instance_->nameref_ = GOOGLE_ULONGLONG(0);
 }
 
 Edge::Edge(const Edge& from)
   : ::google::protobuf::Message() {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Edge)
 }
 
 void Edge::SharedCtor() {
   ::google::protobuf::internal::GetEmptyString();
   _cached_size_ = 0;
   referent_ = GOOGLE_ULONGLONG(0);
-  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  clear_has_EdgeNameOrRef();
 }
 
 Edge::~Edge() {
   // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Edge)
   SharedDtor();
 }
 
 void Edge::SharedDtor() {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete name_;
+  if (has_EdgeNameOrRef()) {
+    clear_EdgeNameOrRef();
   }
   if (this != default_instance_) {
   }
 }
 
 void Edge::SetCachedSize(int size) const {
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = size;
@@ -1811,25 +2141,37 @@ const Edge& Edge::default_instance() {
 }
 
 Edge* Edge::default_instance_ = NULL;
 
 Edge* Edge::New() const {
   return new Edge;
 }
 
-void Edge::Clear() {
-  if (_has_bits_[0 / 32] & 3) {
-    referent_ = GOOGLE_ULONGLONG(0);
-    if (has_name()) {
-      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        name_->clear();
-      }
+void Edge::clear_EdgeNameOrRef() {
+  switch(EdgeNameOrRef_case()) {
+    case kName: {
+      delete EdgeNameOrRef_.name_;
+      break;
+    }
+    case kNameRef: {
+      // No need to clear
+      break;
+    }
+    case EDGENAMEORREF_NOT_SET: {
+      break;
     }
   }
+  _oneof_case_[0] = EDGENAMEORREF_NOT_SET;
+}
+
+
+void Edge::Clear() {
+  referent_ = GOOGLE_ULONGLONG(0);
+  clear_EdgeNameOrRef();
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   mutable_unknown_fields()->Clear();
 }
 
 bool Edge::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
 #define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
@@ -1857,16 +2199,32 @@ bool Edge::MergePartialFromCodedStream(
       case 2: {
         if (tag == 18) {
          parse_name:
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_name()));
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(24)) goto parse_nameRef;
+        break;
+      }
+
+      // optional uint64 nameRef = 3;
+      case 3: {
+        if (tag == 24) {
+         parse_nameRef:
+          clear_EdgeNameOrRef();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &EdgeNameOrRef_.nameref_)));
+          set_has_nameref();
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
 
       default: {
       handle_unusual:
         if (tag == 0 ||
             ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
@@ -1897,16 +2255,21 @@ void Edge::SerializeWithCachedSizes(
   }
 
   // optional bytes name = 2;
   if (has_name()) {
     ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
       2, this->name(), output);
   }
 
+  // optional uint64 nameRef = 3;
+  if (has_nameref()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->nameref(), output);
+  }
+
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Edge)
 }
 
 ::google::protobuf::uint8* Edge::SerializeWithCachedSizesToArray(
@@ -1919,16 +2282,21 @@ void Edge::SerializeWithCachedSizes(
 
   // optional bytes name = 2;
   if (has_name()) {
     target =
       ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
         2, this->name(), target);
   }
 
+  // optional uint64 nameRef = 3;
+  if (has_nameref()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->nameref(), target);
+  }
+
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Edge)
   return target;
 }
 
@@ -1938,23 +2306,35 @@ int Edge::ByteSize() const {
   if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
     // optional uint64 referent = 1;
     if (has_referent()) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::UInt64Size(
           this->referent());
     }
 
+  }
+  switch (EdgeNameOrRef_case()) {
     // optional bytes name = 2;
-    if (has_name()) {
+    case kName: {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::BytesSize(
           this->name());
+      break;
     }
-
+    // optional uint64 nameRef = 3;
+    case kNameRef: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->nameref());
+      break;
+    }
+    case EDGENAMEORREF_NOT_SET: {
+      break;
+    }
   }
   if (!unknown_fields().empty()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         unknown_fields());
   }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
@@ -1971,23 +2351,33 @@ void Edge::MergeFrom(const ::google::pro
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
     MergeFrom(*source);
   }
 }
 
 void Edge::MergeFrom(const Edge& from) {
   GOOGLE_CHECK_NE(&from, this);
+  switch (from.EdgeNameOrRef_case()) {
+    case kName: {
+      set_name(from.name());
+      break;
+    }
+    case kNameRef: {
+      set_nameref(from.nameref());
+      break;
+    }
+    case EDGENAMEORREF_NOT_SET: {
+      break;
+    }
+  }
   if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
     if (from.has_referent()) {
       set_referent(from.referent());
     }
-    if (from.has_name()) {
-      set_name(from.name());
-    }
   }
   mutable_unknown_fields()->MergeFrom(from.unknown_fields());
 }
 
 void Edge::CopyFrom(const ::google::protobuf::Message& from) {
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -2002,17 +2392,18 @@ void Edge::CopyFrom(const Edge& from) {
 bool Edge::IsInitialized() const {
 
   return true;
 }
 
 void Edge::Swap(Edge* other) {
   if (other != this) {
     std::swap(referent_, other->referent_);
-    std::swap(name_, other->name_);
+    std::swap(EdgeNameOrRef_, other->EdgeNameOrRef_);
+    std::swap(_oneof_case_[0], other->_oneof_case_[0]);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);
   }
 }
 
 ::google::protobuf::Metadata Edge::GetMetadata() const {
   protobuf_AssignDescriptorsOnce();
--- a/devtools/shared/heapsnapshot/CoreDump.pb.h
+++ b/devtools/shared/heapsnapshot/CoreDump.pb.h
@@ -140,16 +140,28 @@ class StackFrame_Data : public ::google:
 
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
     return &_unknown_fields_;
   }
 
   static const ::google::protobuf::Descriptor* descriptor();
   static const StackFrame_Data& default_instance();
 
+  enum SourceOrRefCase {
+    kSource = 5,
+    kSourceRef = 6,
+    SOURCEORREF_NOT_SET = 0,
+  };
+
+  enum FunctionDisplayNameOrRefCase {
+    kFunctionDisplayName = 7,
+    kFunctionDisplayNameRef = 8,
+    FUNCTIONDISPLAYNAMEORREF_NOT_SET = 0,
+  };
+
   void Swap(StackFrame_Data* other);
 
   // implements Message ----------------------------------------------
 
   StackFrame_Data* New() const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const StackFrame_Data& from);
@@ -212,73 +224,105 @@ class StackFrame_Data : public ::google:
   inline const ::std::string& source() const;
   inline void set_source(const ::std::string& value);
   inline void set_source(const char* value);
   inline void set_source(const void* value, size_t size);
   inline ::std::string* mutable_source();
   inline ::std::string* release_source();
   inline void set_allocated_source(::std::string* source);
 
-  // optional bytes functionDisplayName = 6;
+  // optional uint64 sourceRef = 6;
+  inline bool has_sourceref() const;
+  inline void clear_sourceref();
+  static const int kSourceRefFieldNumber = 6;
+  inline ::google::protobuf::uint64 sourceref() const;
+  inline void set_sourceref(::google::protobuf::uint64 value);
+
+  // optional bytes functionDisplayName = 7;
   inline bool has_functiondisplayname() const;
   inline void clear_functiondisplayname();
-  static const int kFunctionDisplayNameFieldNumber = 6;
+  static const int kFunctionDisplayNameFieldNumber = 7;
   inline const ::std::string& functiondisplayname() const;
   inline void set_functiondisplayname(const ::std::string& value);
   inline void set_functiondisplayname(const char* value);
   inline void set_functiondisplayname(const void* value, size_t size);
   inline ::std::string* mutable_functiondisplayname();
   inline ::std::string* release_functiondisplayname();
   inline void set_allocated_functiondisplayname(::std::string* functiondisplayname);
 
-  // optional bool isSystem = 7;
+  // optional uint64 functionDisplayNameRef = 8;
+  inline bool has_functiondisplaynameref() const;
+  inline void clear_functiondisplaynameref();
+  static const int kFunctionDisplayNameRefFieldNumber = 8;
+  inline ::google::protobuf::uint64 functiondisplaynameref() const;
+  inline void set_functiondisplaynameref(::google::protobuf::uint64 value);
+
+  // optional bool isSystem = 9;
   inline bool has_issystem() const;
   inline void clear_issystem();
-  static const int kIsSystemFieldNumber = 7;
+  static const int kIsSystemFieldNumber = 9;
   inline bool issystem() const;
   inline void set_issystem(bool value);
 
-  // optional bool isSelfHosted = 8;
+  // optional bool isSelfHosted = 10;
   inline bool has_isselfhosted() const;
   inline void clear_isselfhosted();
-  static const int kIsSelfHostedFieldNumber = 8;
+  static const int kIsSelfHostedFieldNumber = 10;
   inline bool isselfhosted() const;
   inline void set_isselfhosted(bool value);
 
+  inline SourceOrRefCase SourceOrRef_case() const;
+  inline FunctionDisplayNameOrRefCase FunctionDisplayNameOrRef_case() const;
   // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.StackFrame.Data)
  private:
   inline void set_has_id();
   inline void clear_has_id();
   inline void set_has_parent();
   inline void clear_has_parent();
   inline void set_has_line();
   inline void clear_has_line();
   inline void set_has_column();
   inline void clear_has_column();
   inline void set_has_source();
-  inline void clear_has_source();
+  inline void set_has_sourceref();
   inline void set_has_functiondisplayname();
-  inline void clear_has_functiondisplayname();
+  inline void set_has_functiondisplaynameref();
   inline void set_has_issystem();
   inline void clear_has_issystem();
   inline void set_has_isselfhosted();
   inline void clear_has_isselfhosted();
 
+  inline bool has_SourceOrRef();
+  void clear_SourceOrRef();
+  inline void clear_has_SourceOrRef();
+
+  inline bool has_FunctionDisplayNameOrRef();
+  void clear_FunctionDisplayNameOrRef();
+  inline void clear_has_FunctionDisplayNameOrRef();
+
   ::google::protobuf::UnknownFieldSet _unknown_fields_;
 
   ::google::protobuf::uint32 _has_bits_[1];
   mutable int _cached_size_;
   ::google::protobuf::uint64 id_;
   ::mozilla::devtools::protobuf::StackFrame* parent_;
   ::google::protobuf::uint32 line_;
   ::google::protobuf::uint32 column_;
-  ::std::string* source_;
-  ::std::string* functiondisplayname_;
   bool issystem_;
   bool isselfhosted_;
+  union SourceOrRefUnion {
+    ::std::string* source_;
+    ::google::protobuf::uint64 sourceref_;
+  } SourceOrRef_;
+  union FunctionDisplayNameOrRefUnion {
+    ::std::string* functiondisplayname_;
+    ::google::protobuf::uint64 functiondisplaynameref_;
+  } FunctionDisplayNameOrRef_;
+  ::google::protobuf::uint32 _oneof_case_[2];
+
   friend void  protobuf_AddDesc_CoreDump_2eproto();
   friend void protobuf_AssignDesc_CoreDump_2eproto();
   friend void protobuf_ShutdownFile_CoreDump_2eproto();
 
   void InitAsDefaultInstance();
   static StackFrame_Data* default_instance_;
 };
 // -------------------------------------------------------------------
@@ -407,16 +451,28 @@ class Node : public ::google::protobuf::
 
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
     return &_unknown_fields_;
   }
 
   static const ::google::protobuf::Descriptor* descriptor();
   static const Node& default_instance();
 
+  enum TypeNameOrRefCase {
+    kTypeName = 2,
+    kTypeNameRef = 3,
+    TYPENAMEORREF_NOT_SET = 0,
+  };
+
+  enum JSObjectClassNameOrRefCase {
+    kJsObjectClassName = 7,
+    kJsObjectClassNameRef = 8,
+    JSOBJECTCLASSNAMEORREF_NOT_SET = 0,
+  };
+
   void Swap(Node* other);
 
   // implements Message ----------------------------------------------
 
   Node* New() const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Node& from);
@@ -456,89 +512,121 @@ class Node : public ::google::protobuf::
   inline const ::std::string& typename_() const;
   inline void set_typename_(const ::std::string& value);
   inline void set_typename_(const char* value);
   inline void set_typename_(const void* value, size_t size);
   inline ::std::string* mutable_typename_();
   inline ::std::string* release_typename_();
   inline void set_allocated_typename_(::std::string* typename_);
 
-  // optional uint64 size = 3;
+  // optional uint64 typeNameRef = 3;
+  inline bool has_typenameref() const;
+  inline void clear_typenameref();
+  static const int kTypeNameRefFieldNumber = 3;
+  inline ::google::protobuf::uint64 typenameref() const;
+  inline void set_typenameref(::google::protobuf::uint64 value);
+
+  // optional uint64 size = 4;
   inline bool has_size() const;
   inline void clear_size();
-  static const int kSizeFieldNumber = 3;
+  static const int kSizeFieldNumber = 4;
   inline ::google::protobuf::uint64 size() const;
   inline void set_size(::google::protobuf::uint64 value);
 
-  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
+  // repeated .mozilla.devtools.protobuf.Edge edges = 5;
   inline int edges_size() const;
   inline void clear_edges();
-  static const int kEdgesFieldNumber = 4;
+  static const int kEdgesFieldNumber = 5;
   inline const ::mozilla::devtools::protobuf::Edge& edges(int index) const;
   inline ::mozilla::devtools::protobuf::Edge* mutable_edges(int index);
   inline ::mozilla::devtools::protobuf::Edge* add_edges();
   inline const ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >&
       edges() const;
   inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >*
       mutable_edges();
 
-  // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5;
+  // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
   inline bool has_allocationstack() const;
   inline void clear_allocationstack();
-  static const int kAllocationStackFieldNumber = 5;
+  static const int kAllocationStackFieldNumber = 6;
   inline const ::mozilla::devtools::protobuf::StackFrame& allocationstack() const;
   inline ::mozilla::devtools::protobuf::StackFrame* mutable_allocationstack();
   inline ::mozilla::devtools::protobuf::StackFrame* release_allocationstack();
   inline void set_allocated_allocationstack(::mozilla::devtools::protobuf::StackFrame* allocationstack);
 
-  // optional bytes jsObjectClassName = 6;
+  // optional bytes jsObjectClassName = 7;
   inline bool has_jsobjectclassname() const;
   inline void clear_jsobjectclassname();
-  static const int kJsObjectClassNameFieldNumber = 6;
+  static const int kJsObjectClassNameFieldNumber = 7;
   inline const ::std::string& jsobjectclassname() const;
   inline void set_jsobjectclassname(const ::std::string& value);
   inline void set_jsobjectclassname(const char* value);
   inline void set_jsobjectclassname(const void* value, size_t size);
   inline ::std::string* mutable_jsobjectclassname();
   inline ::std::string* release_jsobjectclassname();
   inline void set_allocated_jsobjectclassname(::std::string* jsobjectclassname);
 
-  // optional uint32 coarseType = 7 [default = 0];
+  // optional uint64 jsObjectClassNameRef = 8;
+  inline bool has_jsobjectclassnameref() const;
+  inline void clear_jsobjectclassnameref();
+  static const int kJsObjectClassNameRefFieldNumber = 8;
+  inline ::google::protobuf::uint64 jsobjectclassnameref() const;
+  inline void set_jsobjectclassnameref(::google::protobuf::uint64 value);
+
+  // optional uint32 coarseType = 9 [default = 0];
   inline bool has_coarsetype() const;
   inline void clear_coarsetype();
-  static const int kCoarseTypeFieldNumber = 7;
+  static const int kCoarseTypeFieldNumber = 9;
   inline ::google::protobuf::uint32 coarsetype() const;
   inline void set_coarsetype(::google::protobuf::uint32 value);
 
+  inline TypeNameOrRefCase TypeNameOrRef_case() const;
+  inline JSObjectClassNameOrRefCase JSObjectClassNameOrRef_case() const;
   // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Node)
  private:
   inline void set_has_id();
   inline void clear_has_id();
   inline void set_has_typename_();
-  inline void clear_has_typename_();
+  inline void set_has_typenameref();
   inline void set_has_size();
   inline void clear_has_size();
   inline void set_has_allocationstack();
   inline void clear_has_allocationstack();
   inline void set_has_jsobjectclassname();
-  inline void clear_has_jsobjectclassname();
+  inline void set_has_jsobjectclassnameref();
   inline void set_has_coarsetype();
   inline void clear_has_coarsetype();
 
+  inline bool has_TypeNameOrRef();
+  void clear_TypeNameOrRef();
+  inline void clear_has_TypeNameOrRef();
+
+  inline bool has_JSObjectClassNameOrRef();
+  void clear_JSObjectClassNameOrRef();
+  inline void clear_has_JSObjectClassNameOrRef();
+
   ::google::protobuf::UnknownFieldSet _unknown_fields_;
 
   ::google::protobuf::uint32 _has_bits_[1];
   mutable int _cached_size_;
   ::google::protobuf::uint64 id_;
-  ::std::string* typename__;
   ::google::protobuf::uint64 size_;
   ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge > edges_;
   ::mozilla::devtools::protobuf::StackFrame* allocationstack_;
-  ::std::string* jsobjectclassname_;
   ::google::protobuf::uint32 coarsetype_;
+  union TypeNameOrRefUnion {
+    ::std::string* typename__;
+    ::google::protobuf::uint64 typenameref_;
+  } TypeNameOrRef_;
+  union JSObjectClassNameOrRefUnion {
+    ::std::string* jsobjectclassname_;
+    ::google::protobuf::uint64 jsobjectclassnameref_;
+  } JSObjectClassNameOrRef_;
+  ::google::protobuf::uint32 _oneof_case_[2];
+
   friend void  protobuf_AddDesc_CoreDump_2eproto();
   friend void protobuf_AssignDesc_CoreDump_2eproto();
   friend void protobuf_ShutdownFile_CoreDump_2eproto();
 
   void InitAsDefaultInstance();
   static Node* default_instance_;
 };
 // -------------------------------------------------------------------
@@ -561,16 +649,22 @@ class Edge : public ::google::protobuf::
 
   inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
     return &_unknown_fields_;
   }
 
   static const ::google::protobuf::Descriptor* descriptor();
   static const Edge& default_instance();
 
+  enum EdgeNameOrRefCase {
+    kName = 2,
+    kNameRef = 3,
+    EDGENAMEORREF_NOT_SET = 0,
+  };
+
   void Swap(Edge* other);
 
   // implements Message ----------------------------------------------
 
   Edge* New() const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Edge& from);
@@ -610,29 +704,46 @@ class Edge : public ::google::protobuf::
   inline const ::std::string& name() const;
   inline void set_name(const ::std::string& value);
   inline void set_name(const char* value);
   inline void set_name(const void* value, size_t size);
   inline ::std::string* mutable_name();
   inline ::std::string* release_name();
   inline void set_allocated_name(::std::string* name);
 
+  // optional uint64 nameRef = 3;
+  inline bool has_nameref() const;
+  inline void clear_nameref();
+  static const int kNameRefFieldNumber = 3;
+  inline ::google::protobuf::uint64 nameref() const;
+  inline void set_nameref(::google::protobuf::uint64 value);
+
+  inline EdgeNameOrRefCase EdgeNameOrRef_case() const;
   // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Edge)
  private:
   inline void set_has_referent();
   inline void clear_has_referent();
   inline void set_has_name();
-  inline void clear_has_name();
+  inline void set_has_nameref();
+
+  inline bool has_EdgeNameOrRef();
+  void clear_EdgeNameOrRef();
+  inline void clear_has_EdgeNameOrRef();
 
   ::google::protobuf::UnknownFieldSet _unknown_fields_;
 
   ::google::protobuf::uint32 _has_bits_[1];
   mutable int _cached_size_;
   ::google::protobuf::uint64 referent_;
-  ::std::string* name_;
+  union EdgeNameOrRefUnion {
+    ::std::string* name_;
+    ::google::protobuf::uint64 nameref_;
+  } EdgeNameOrRef_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
   friend void  protobuf_AddDesc_CoreDump_2eproto();
   friend void protobuf_AssignDesc_CoreDump_2eproto();
   friend void protobuf_ShutdownFile_CoreDump_2eproto();
 
   void InitAsDefaultInstance();
   static Edge* default_instance_;
 };
 // ===================================================================
@@ -780,214 +891,274 @@ inline ::google::protobuf::uint32 StackF
 inline void StackFrame_Data::set_column(::google::protobuf::uint32 value) {
   set_has_column();
   column_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.column)
 }
 
 // optional bytes source = 5;
 inline bool StackFrame_Data::has_source() const {
-  return (_has_bits_[0] & 0x00000010u) != 0;
+  return SourceOrRef_case() == kSource;
 }
 inline void StackFrame_Data::set_has_source() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void StackFrame_Data::clear_has_source() {
-  _has_bits_[0] &= ~0x00000010u;
+  _oneof_case_[0] = kSource;
 }
 inline void StackFrame_Data::clear_source() {
-  if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    source_->clear();
+  if (has_source()) {
+    delete SourceOrRef_.source_;
+    clear_has_SourceOrRef();
   }
-  clear_has_source();
 }
 inline const ::std::string& StackFrame_Data::source() const {
-  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.source)
-  return *source_;
+  if (has_source()) {
+    return *SourceOrRef_.source_;
+  }
+  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
 }
 inline void StackFrame_Data::set_source(const ::std::string& value) {
-  set_has_source();
-  if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    source_ = new ::std::string;
+  if (!has_source()) {
+    clear_SourceOrRef();
+    set_has_source();
+    SourceOrRef_.source_ = new ::std::string;
   }
-  source_->assign(value);
-  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.source)
+  SourceOrRef_.source_->assign(value);
 }
 inline void StackFrame_Data::set_source(const char* value) {
-  set_has_source();
-  if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    source_ = new ::std::string;
+  if (!has_source()) {
+    clear_SourceOrRef();
+    set_has_source();
+    SourceOrRef_.source_ = new ::std::string;
   }
-  source_->assign(value);
-  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.StackFrame.Data.source)
+  SourceOrRef_.source_->assign(value);
 }
 inline void StackFrame_Data::set_source(const void* value, size_t size) {
-  set_has_source();
-  if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    source_ = new ::std::string;
+  if (!has_source()) {
+    clear_SourceOrRef();
+    set_has_source();
+    SourceOrRef_.source_ = new ::std::string;
   }
-  source_->assign(reinterpret_cast<const char*>(value), size);
-  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.StackFrame.Data.source)
+  SourceOrRef_.source_->assign(
+      reinterpret_cast<const char*>(value), size);
 }
 inline ::std::string* StackFrame_Data::mutable_source() {
-  set_has_source();
-  if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    source_ = new ::std::string;
+  if (!has_source()) {
+    clear_SourceOrRef();
+    set_has_source();
+    SourceOrRef_.source_ = new ::std::string;
   }
-  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.StackFrame.Data.source)
-  return source_;
+  return SourceOrRef_.source_;
 }
 inline ::std::string* StackFrame_Data::release_source() {
-  clear_has_source();
-  if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    return NULL;
+  if (has_source()) {
+    clear_has_SourceOrRef();
+    ::std::string* temp = SourceOrRef_.source_;
+    SourceOrRef_.source_ = NULL;
+    return temp;
   } else {
-    ::std::string* temp = source_;
-    source_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-    return temp;
+    return NULL;
   }
 }
 inline void StackFrame_Data::set_allocated_source(::std::string* source) {
-  if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete source_;
-  }
+  clear_SourceOrRef();
   if (source) {
     set_has_source();
-    source_ = source;
-  } else {
-    clear_has_source();
-    source_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    SourceOrRef_.source_ = source;
   }
-  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.StackFrame.Data.source)
 }
 
-// optional bytes functionDisplayName = 6;
+// optional uint64 sourceRef = 6;
+inline bool StackFrame_Data::has_sourceref() const {
+  return SourceOrRef_case() == kSourceRef;
+}
+inline void StackFrame_Data::set_has_sourceref() {
+  _oneof_case_[0] = kSourceRef;
+}
+inline void StackFrame_Data::clear_sourceref() {
+  if (has_sourceref()) {
+    SourceOrRef_.sourceref_ = GOOGLE_ULONGLONG(0);
+    clear_has_SourceOrRef();
+  }
+}
+inline ::google::protobuf::uint64 StackFrame_Data::sourceref() const {
+  if (has_sourceref()) {
+    return SourceOrRef_.sourceref_;
+  }
+  return GOOGLE_ULONGLONG(0);
+}
+inline void StackFrame_Data::set_sourceref(::google::protobuf::uint64 value) {
+  if (!has_sourceref()) {
+    clear_SourceOrRef();
+    set_has_sourceref();
+  }
+  SourceOrRef_.sourceref_ = value;
+}
+
+// optional bytes functionDisplayName = 7;
 inline bool StackFrame_Data::has_functiondisplayname() const {
-  return (_has_bits_[0] & 0x00000020u) != 0;
+  return FunctionDisplayNameOrRef_case() == kFunctionDisplayName;
 }
 inline void StackFrame_Data::set_has_functiondisplayname() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void StackFrame_Data::clear_has_functiondisplayname() {
-  _has_bits_[0] &= ~0x00000020u;
+  _oneof_case_[1] = kFunctionDisplayName;
 }
 inline void StackFrame_Data::clear_functiondisplayname() {
-  if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    functiondisplayname_->clear();
+  if (has_functiondisplayname()) {
+    delete FunctionDisplayNameOrRef_.functiondisplayname_;
+    clear_has_FunctionDisplayNameOrRef();
   }
-  clear_has_functiondisplayname();
 }
 inline const ::std::string& StackFrame_Data::functiondisplayname() const {
-  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName)
-  return *functiondisplayname_;
+  if (has_functiondisplayname()) {
+    return *FunctionDisplayNameOrRef_.functiondisplayname_;
+  }
+  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
 }
 inline void StackFrame_Data::set_functiondisplayname(const ::std::string& value) {
-  set_has_functiondisplayname();
-  if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    functiondisplayname_ = new ::std::string;
+  if (!has_functiondisplayname()) {
+    clear_FunctionDisplayNameOrRef();
+    set_has_functiondisplayname();
+    FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
   }
-  functiondisplayname_->assign(value);
-  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName)
+  FunctionDisplayNameOrRef_.functiondisplayname_->assign(value);
 }
 inline void StackFrame_Data::set_functiondisplayname(const char* value) {
-  set_has_functiondisplayname();
-  if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    functiondisplayname_ = new ::std::string;
+  if (!has_functiondisplayname()) {
+    clear_FunctionDisplayNameOrRef();
+    set_has_functiondisplayname();
+    FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
   }
-  functiondisplayname_->assign(value);
-  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName)
+  FunctionDisplayNameOrRef_.functiondisplayname_->assign(value);
 }
 inline void StackFrame_Data::set_functiondisplayname(const void* value, size_t size) {
-  set_has_functiondisplayname();
-  if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    functiondisplayname_ = new ::std::string;
+  if (!has_functiondisplayname()) {
+    clear_FunctionDisplayNameOrRef();
+    set_has_functiondisplayname();
+    FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
   }
-  functiondisplayname_->assign(reinterpret_cast<const char*>(value), size);
-  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName)
+  FunctionDisplayNameOrRef_.functiondisplayname_->assign(
+      reinterpret_cast<const char*>(value), size);
 }
 inline ::std::string* StackFrame_Data::mutable_functiondisplayname() {
-  set_has_functiondisplayname();
-  if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    functiondisplayname_ = new ::std::string;
+  if (!has_functiondisplayname()) {
+    clear_FunctionDisplayNameOrRef();
+    set_has_functiondisplayname();
+    FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string;
   }
-  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName)
-  return functiondisplayname_;
+  return FunctionDisplayNameOrRef_.functiondisplayname_;
 }
 inline ::std::string* StackFrame_Data::release_functiondisplayname() {
-  clear_has_functiondisplayname();
-  if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    return NULL;
+  if (has_functiondisplayname()) {
+    clear_has_FunctionDisplayNameOrRef();
+    ::std::string* temp = FunctionDisplayNameOrRef_.functiondisplayname_;
+    FunctionDisplayNameOrRef_.functiondisplayname_ = NULL;
+    return temp;
   } else {
-    ::std::string* temp = functiondisplayname_;
-    functiondisplayname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-    return temp;
+    return NULL;
   }
 }
 inline void StackFrame_Data::set_allocated_functiondisplayname(::std::string* functiondisplayname) {
-  if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete functiondisplayname_;
-  }
+  clear_FunctionDisplayNameOrRef();
   if (functiondisplayname) {
     set_has_functiondisplayname();
-    functiondisplayname_ = functiondisplayname;
-  } else {
-    clear_has_functiondisplayname();
-    functiondisplayname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    FunctionDisplayNameOrRef_.functiondisplayname_ = functiondisplayname;
   }
-  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName)
 }
 
-// optional bool isSystem = 7;
+// optional uint64 functionDisplayNameRef = 8;
+inline bool StackFrame_Data::has_functiondisplaynameref() const {
+  return FunctionDisplayNameOrRef_case() == kFunctionDisplayNameRef;
+}
+inline void StackFrame_Data::set_has_functiondisplaynameref() {
+  _oneof_case_[1] = kFunctionDisplayNameRef;
+}
+inline void StackFrame_Data::clear_functiondisplaynameref() {
+  if (has_functiondisplaynameref()) {
+    FunctionDisplayNameOrRef_.functiondisplaynameref_ = GOOGLE_ULONGLONG(0);
+    clear_has_FunctionDisplayNameOrRef();
+  }
+}
+inline ::google::protobuf::uint64 StackFrame_Data::functiondisplaynameref() const {
+  if (has_functiondisplaynameref()) {
+    return FunctionDisplayNameOrRef_.functiondisplaynameref_;
+  }
+  return GOOGLE_ULONGLONG(0);
+}
+inline void StackFrame_Data::set_functiondisplaynameref(::google::protobuf::uint64 value) {
+  if (!has_functiondisplaynameref()) {
+    clear_FunctionDisplayNameOrRef();
+    set_has_functiondisplaynameref();
+  }
+  FunctionDisplayNameOrRef_.functiondisplaynameref_ = value;
+}
+
+// optional bool isSystem = 9;
 inline bool StackFrame_Data::has_issystem() const {
-  return (_has_bits_[0] & 0x00000040u) != 0;
+  return (_has_bits_[0] & 0x00000100u) != 0;
 }
 inline void StackFrame_Data::set_has_issystem() {
-  _has_bits_[0] |= 0x00000040u;
+  _has_bits_[0] |= 0x00000100u;
 }
 inline void StackFrame_Data::clear_has_issystem() {
-  _has_bits_[0] &= ~0x00000040u;
+  _has_bits_[0] &= ~0x00000100u;
 }
 inline void StackFrame_Data::clear_issystem() {
   issystem_ = false;
   clear_has_issystem();
 }
 inline bool StackFrame_Data::issystem() const {
   // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.isSystem)
   return issystem_;
 }
 inline void StackFrame_Data::set_issystem(bool value) {
   set_has_issystem();
   issystem_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.isSystem)
 }
 
-// optional bool isSelfHosted = 8;
+// optional bool isSelfHosted = 10;
 inline bool StackFrame_Data::has_isselfhosted() const {
-  return (_has_bits_[0] & 0x00000080u) != 0;
+  return (_has_bits_[0] & 0x00000200u) != 0;
 }
 inline void StackFrame_Data::set_has_isselfhosted() {
-  _has_bits_[0] |= 0x00000080u;
+  _has_bits_[0] |= 0x00000200u;
 }
 inline void StackFrame_Data::clear_has_isselfhosted() {
-  _has_bits_[0] &= ~0x00000080u;
+  _has_bits_[0] &= ~0x00000200u;
 }
 inline void StackFrame_Data::clear_isselfhosted() {
   isselfhosted_ = false;
   clear_has_isselfhosted();
 }
 inline bool StackFrame_Data::isselfhosted() const {
   // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.isSelfHosted)
   return isselfhosted_;
 }
 inline void StackFrame_Data::set_isselfhosted(bool value) {
   set_has_isselfhosted();
   isselfhosted_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.isSelfHosted)
 }
 
+inline bool StackFrame_Data::has_SourceOrRef() {
+  return SourceOrRef_case() != SOURCEORREF_NOT_SET;
+}
+inline void StackFrame_Data::clear_has_SourceOrRef() {
+  _oneof_case_[0] = SOURCEORREF_NOT_SET;
+}
+inline bool StackFrame_Data::has_FunctionDisplayNameOrRef() {
+  return FunctionDisplayNameOrRef_case() != FUNCTIONDISPLAYNAMEORREF_NOT_SET;
+}
+inline void StackFrame_Data::clear_has_FunctionDisplayNameOrRef() {
+  _oneof_case_[1] = FUNCTIONDISPLAYNAMEORREF_NOT_SET;
+}
+inline StackFrame_Data::SourceOrRefCase StackFrame_Data::SourceOrRef_case() const {
+  return StackFrame_Data::SourceOrRefCase(_oneof_case_[0]);
+}
+inline StackFrame_Data::FunctionDisplayNameOrRefCase StackFrame_Data::FunctionDisplayNameOrRef_case() const {
+  return StackFrame_Data::FunctionDisplayNameOrRefCase(_oneof_case_[1]);
+}
 // -------------------------------------------------------------------
 
 // StackFrame
 
 // optional .mozilla.devtools.protobuf.StackFrame.Data data = 1;
 inline bool StackFrame::has_data() const {
   return StackFrameType_case() == kData;
 }
@@ -1091,115 +1262,136 @@ inline ::google::protobuf::uint64 Node::
 inline void Node::set_id(::google::protobuf::uint64 value) {
   set_has_id();
   id_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.id)
 }
 
 // optional bytes typeName = 2;
 inline bool Node::has_typename_() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+  return TypeNameOrRef_case() == kTypeName;
 }
 inline void Node::set_has_typename_() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void Node::clear_has_typename_() {
-  _has_bits_[0] &= ~0x00000002u;
+  _oneof_case_[0] = kTypeName;
 }
 inline void Node::clear_typename_() {
-  if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    typename__->clear();
+  if (has_typename_()) {
+    delete TypeNameOrRef_.typename__;
+    clear_has_TypeNameOrRef();
   }
-  clear_has_typename_();
 }
 inline const ::std::string& Node::typename_() const {
-  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.typeName)
-  return *typename__;
+  if (has_typename_()) {
+    return *TypeNameOrRef_.typename__;
+  }
+  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
 }
 inline void Node::set_typename_(const ::std::string& value) {
-  set_has_typename_();
-  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    typename__ = new ::std::string;
+  if (!has_typename_()) {
+    clear_TypeNameOrRef();
+    set_has_typename_();
+    TypeNameOrRef_.typename__ = new ::std::string;
   }
-  typename__->assign(value);
-  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.typeName)
+  TypeNameOrRef_.typename__->assign(value);
 }
 inline void Node::set_typename_(const char* value) {
-  set_has_typename_();
-  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    typename__ = new ::std::string;
+  if (!has_typename_()) {
+    clear_TypeNameOrRef();
+    set_has_typename_();
+    TypeNameOrRef_.typename__ = new ::std::string;
   }
-  typename__->assign(value);
-  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.typeName)
+  TypeNameOrRef_.typename__->assign(value);
 }
 inline void Node::set_typename_(const void* value, size_t size) {
-  set_has_typename_();
-  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    typename__ = new ::std::string;
+  if (!has_typename_()) {
+    clear_TypeNameOrRef();
+    set_has_typename_();
+    TypeNameOrRef_.typename__ = new ::std::string;
   }
-  typename__->assign(reinterpret_cast<const char*>(value), size);
-  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.typeName)
+  TypeNameOrRef_.typename__->assign(
+      reinterpret_cast<const char*>(value), size);
 }
 inline ::std::string* Node::mutable_typename_() {
-  set_has_typename_();
-  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    typename__ = new ::std::string;
+  if (!has_typename_()) {
+    clear_TypeNameOrRef();
+    set_has_typename_();
+    TypeNameOrRef_.typename__ = new ::std::string;
   }
-  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.typeName)
-  return typename__;
+  return TypeNameOrRef_.typename__;
 }
 inline ::std::string* Node::release_typename_() {
-  clear_has_typename_();
-  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    return NULL;
+  if (has_typename_()) {
+    clear_has_TypeNameOrRef();
+    ::std::string* temp = TypeNameOrRef_.typename__;
+    TypeNameOrRef_.typename__ = NULL;
+    return temp;
   } else {
-    ::std::string* temp = typename__;
-    typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-    return temp;
+    return NULL;
   }
 }
 inline void Node::set_allocated_typename_(::std::string* typename_) {
-  if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete typename__;
-  }
+  clear_TypeNameOrRef();
   if (typename_) {
     set_has_typename_();
-    typename__ = typename_;
-  } else {
-    clear_has_typename_();
-    typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    TypeNameOrRef_.typename__ = typename_;
   }
-  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.typeName)
 }
 
-// optional uint64 size = 3;
+// optional uint64 typeNameRef = 3;
+inline bool Node::has_typenameref() const {
+  return TypeNameOrRef_case() == kTypeNameRef;
+}
+inline void Node::set_has_typenameref() {
+  _oneof_case_[0] = kTypeNameRef;
+}
+inline void Node::clear_typenameref() {
+  if (has_typenameref()) {
+    TypeNameOrRef_.typenameref_ = GOOGLE_ULONGLONG(0);
+    clear_has_TypeNameOrRef();
+  }
+}
+inline ::google::protobuf::uint64 Node::typenameref() const {
+  if (has_typenameref()) {
+    return TypeNameOrRef_.typenameref_;
+  }
+  return GOOGLE_ULONGLONG(0);
+}
+inline void Node::set_typenameref(::google::protobuf::uint64 value) {
+  if (!has_typenameref()) {
+    clear_TypeNameOrRef();
+    set_has_typenameref();
+  }
+  TypeNameOrRef_.typenameref_ = value;
+}
+
+// optional uint64 size = 4;
 inline bool Node::has_size() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000008u) != 0;
 }
 inline void Node::set_has_size() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000008u;
 }
 inline void Node::clear_has_size() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline void Node::clear_size() {
   size_ = GOOGLE_ULONGLONG(0);
   clear_has_size();
 }
 inline ::google::protobuf::uint64 Node::size() const {
   // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.size)
   return size_;
 }
 inline void Node::set_size(::google::protobuf::uint64 value) {
   set_has_size();
   size_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.size)
 }
 
-// repeated .mozilla.devtools.protobuf.Edge edges = 4;
+// repeated .mozilla.devtools.protobuf.Edge edges = 5;
 inline int Node::edges_size() const {
   return edges_.size();
 }
 inline void Node::clear_edges() {
   edges_.Clear();
 }
 inline const ::mozilla::devtools::protobuf::Edge& Node::edges(int index) const {
   // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.edges)
@@ -1219,25 +1411,25 @@ Node::edges() const {
   return edges_;
 }
 inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >*
 Node::mutable_edges() {
   // @@protoc_insertion_point(field_mutable_list:mozilla.devtools.protobuf.Node.edges)
   return &edges_;
 }
 
-// optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5;
+// optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6;
 inline bool Node::has_allocationstack() const {
-  return (_has_bits_[0] & 0x00000010u) != 0;
+  return (_has_bits_[0] & 0x00000020u) != 0;
 }
 inline void Node::set_has_allocationstack() {
-  _has_bits_[0] |= 0x00000010u;
+  _has_bits_[0] |= 0x00000020u;
 }
 inline void Node::clear_has_allocationstack() {
-  _has_bits_[0] &= ~0x00000010u;
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline void Node::clear_allocationstack() {
   if (allocationstack_ != NULL) allocationstack_->::mozilla::devtools::protobuf::StackFrame::Clear();
   clear_has_allocationstack();
 }
 inline const ::mozilla::devtools::protobuf::StackFrame& Node::allocationstack() const {
   // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.allocationStack)
   return allocationstack_ != NULL ? *allocationstack_ : *default_instance_->allocationstack_;
@@ -1260,116 +1452,155 @@ inline void Node::set_allocated_allocati
   if (allocationstack) {
     set_has_allocationstack();
   } else {
     clear_has_allocationstack();
   }
   // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.allocationStack)
 }
 
-// optional bytes jsObjectClassName = 6;
+// optional bytes jsObjectClassName = 7;
 inline bool Node::has_jsobjectclassname() const {
-  return (_has_bits_[0] & 0x00000020u) != 0;
+  return JSObjectClassNameOrRef_case() == kJsObjectClassName;
 }
 inline void Node::set_has_jsobjectclassname() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void Node::clear_has_jsobjectclassname() {
-  _has_bits_[0] &= ~0x00000020u;
+  _oneof_case_[1] = kJsObjectClassName;
 }
 inline void Node::clear_jsobjectclassname() {
-  if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    jsobjectclassname_->clear();
+  if (has_jsobjectclassname()) {
+    delete JSObjectClassNameOrRef_.jsobjectclassname_;
+    clear_has_JSObjectClassNameOrRef();
   }
-  clear_has_jsobjectclassname();
 }
 inline const ::std::string& Node::jsobjectclassname() const {
-  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.jsObjectClassName)
-  return *jsobjectclassname_;
+  if (has_jsobjectclassname()) {
+    return *JSObjectClassNameOrRef_.jsobjectclassname_;
+  }
+  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
 }
 inline void Node::set_jsobjectclassname(const ::std::string& value) {
-  set_has_jsobjectclassname();
-  if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    jsobjectclassname_ = new ::std::string;
+  if (!has_jsobjectclassname()) {
+    clear_JSObjectClassNameOrRef();
+    set_has_jsobjectclassname();
+    JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
   }
-  jsobjectclassname_->assign(value);
-  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.jsObjectClassName)
+  JSObjectClassNameOrRef_.jsobjectclassname_->assign(value);
 }
 inline void Node::set_jsobjectclassname(const char* value) {
-  set_has_jsobjectclassname();
-  if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    jsobjectclassname_ = new ::std::string;
+  if (!has_jsobjectclassname()) {
+    clear_JSObjectClassNameOrRef();
+    set_has_jsobjectclassname();
+    JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
   }
-  jsobjectclassname_->assign(value);
-  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.jsObjectClassName)
+  JSObjectClassNameOrRef_.jsobjectclassname_->assign(value);
 }
 inline void Node::set_jsobjectclassname(const void* value, size_t size) {
-  set_has_jsobjectclassname();
-  if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    jsobjectclassname_ = new ::std::string;
+  if (!has_jsobjectclassname()) {
+    clear_JSObjectClassNameOrRef();
+    set_has_jsobjectclassname();
+    JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
   }
-  jsobjectclassname_->assign(reinterpret_cast<const char*>(value), size);
-  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.jsObjectClassName)
+  JSObjectClassNameOrRef_.jsobjectclassname_->assign(
+      reinterpret_cast<const char*>(value), size);
 }
 inline ::std::string* Node::mutable_jsobjectclassname() {
-  set_has_jsobjectclassname();
-  if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    jsobjectclassname_ = new ::std::string;
+  if (!has_jsobjectclassname()) {
+    clear_JSObjectClassNameOrRef();
+    set_has_jsobjectclassname();
+    JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string;
   }
-  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.jsObjectClassName)
-  return jsobjectclassname_;
+  return JSObjectClassNameOrRef_.jsobjectclassname_;
 }
 inline ::std::string* Node::release_jsobjectclassname() {
-  clear_has_jsobjectclassname();
-  if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    return NULL;
+  if (has_jsobjectclassname()) {
+    clear_has_JSObjectClassNameOrRef();
+    ::std::string* temp = JSObjectClassNameOrRef_.jsobjectclassname_;
+    JSObjectClassNameOrRef_.jsobjectclassname_ = NULL;
+    return temp;
   } else {
-    ::std::string* temp = jsobjectclassname_;
-    jsobjectclassname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-    return temp;
+    return NULL;
   }
 }
 inline void Node::set_allocated_jsobjectclassname(::std::string* jsobjectclassname) {
-  if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete jsobjectclassname_;
-  }
+  clear_JSObjectClassNameOrRef();
   if (jsobjectclassname) {
     set_has_jsobjectclassname();
-    jsobjectclassname_ = jsobjectclassname;
-  } else {
-    clear_has_jsobjectclassname();
-    jsobjectclassname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    JSObjectClassNameOrRef_.jsobjectclassname_ = jsobjectclassname;
   }
-  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.jsObjectClassName)
 }
 
-// optional uint32 coarseType = 7 [default = 0];
+// optional uint64 jsObjectClassNameRef = 8;
+inline bool Node::has_jsobjectclassnameref() const {
+  return JSObjectClassNameOrRef_case() == kJsObjectClassNameRef;
+}
+inline void Node::set_has_jsobjectclassnameref() {
+  _oneof_case_[1] = kJsObjectClassNameRef;
+}
+inline void Node::clear_jsobjectclassnameref() {
+  if (has_jsobjectclassnameref()) {
+    JSObjectClassNameOrRef_.jsobjectclassnameref_ = GOOGLE_ULONGLONG(0);
+    clear_has_JSObjectClassNameOrRef();
+  }
+}
+inline ::google::protobuf::uint64 Node::jsobjectclassnameref() const {
+  if (has_jsobjectclassnameref()) {
+    return JSObjectClassNameOrRef_.jsobjectclassnameref_;
+  }
+  return GOOGLE_ULONGLONG(0);
+}
+inline void Node::set_jsobjectclassnameref(::google::protobuf::uint64 value) {
+  if (!has_jsobjectclassnameref()) {
+    clear_JSObjectClassNameOrRef();
+    set_has_jsobjectclassnameref();
+  }
+  JSObjectClassNameOrRef_.jsobjectclassnameref_ = value;
+}
+
+// optional uint32 coarseType = 9 [default = 0];
 inline bool Node::has_coarsetype() const {
-  return (_has_bits_[0] & 0x00000040u) != 0;
+  return (_has_bits_[0] & 0x00000100u) != 0;
 }
 inline void Node::set_has_coarsetype() {
-  _has_bits_[0] |= 0x00000040u;
+  _has_bits_[0] |= 0x00000100u;
 }
 inline void Node::clear_has_coarsetype() {
-  _has_bits_[0] &= ~0x00000040u;
+  _has_bits_[0] &= ~0x00000100u;
 }
 inline void Node::clear_coarsetype() {
   coarsetype_ = 0u;
   clear_has_coarsetype();
 }
 inline ::google::protobuf::uint32 Node::coarsetype() const {
   // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.coarseType)
   return coarsetype_;
 }
 inline void Node::set_coarsetype(::google::protobuf::uint32 value) {
   set_has_coarsetype();
   coarsetype_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.coarseType)
 }
 
+inline bool Node::has_TypeNameOrRef() {
+  return TypeNameOrRef_case() != TYPENAMEORREF_NOT_SET;
+}
+inline void Node::clear_has_TypeNameOrRef() {
+  _oneof_case_[0] = TYPENAMEORREF_NOT_SET;
+}
+inline bool Node::has_JSObjectClassNameOrRef() {
+  return JSObjectClassNameOrRef_case() != JSOBJECTCLASSNAMEORREF_NOT_SET;
+}
+inline void Node::clear_has_JSObjectClassNameOrRef() {
+  _oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET;
+}
+inline Node::TypeNameOrRefCase Node::TypeNameOrRef_case() const {
+  return Node::TypeNameOrRefCase(_oneof_case_[0]);
+}
+inline Node::JSObjectClassNameOrRefCase Node::JSObjectClassNameOrRef_case() const {
+  return Node::JSObjectClassNameOrRefCase(_oneof_case_[1]);
+}
 // -------------------------------------------------------------------
 
 // Edge
 
 // optional uint64 referent = 1;
 inline bool Edge::has_referent() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
@@ -1390,90 +1621,120 @@ inline ::google::protobuf::uint64 Edge::
 inline void Edge::set_referent(::google::protobuf::uint64 value) {
   set_has_referent();
   referent_ = value;
   // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Edge.referent)
 }
 
 // optional bytes name = 2;
 inline bool Edge::has_name() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+  return EdgeNameOrRef_case() == kName;
 }
 inline void Edge::set_has_name() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void Edge::clear_has_name() {
-  _has_bits_[0] &= ~0x00000002u;
+  _oneof_case_[0] = kName;
 }
 inline void Edge::clear_name() {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    name_->clear();
+  if (has_name()) {
+    delete EdgeNameOrRef_.name_;
+    clear_has_EdgeNameOrRef();
   }
-  clear_has_name();
 }
 inline const ::std::string& Edge::name() const {
-  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Edge.name)
-  return *name_;
+  if (has_name()) {
+    return *EdgeNameOrRef_.name_;
+  }
+  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
 }
 inline void Edge::set_name(const ::std::string& value) {
-  set_has_name();
-  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    name_ = new ::std::string;
+  if (!has_name()) {
+    clear_EdgeNameOrRef();
+    set_has_name();
+    EdgeNameOrRef_.name_ = new ::std::string;
   }
-  name_->assign(value);
-  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Edge.name)
+  EdgeNameOrRef_.name_->assign(value);
 }
 inline void Edge::set_name(const char* value) {
-  set_has_name();
-  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    name_ = new ::std::string;
+  if (!has_name()) {
+    clear_EdgeNameOrRef();
+    set_has_name();
+    EdgeNameOrRef_.name_ = new ::std::string;
   }
-  name_->assign(value);
-  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Edge.name)
+  EdgeNameOrRef_.name_->assign(value);
 }
 inline void Edge::set_name(const void* value, size_t size) {
-  set_has_name();
-  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    name_ = new ::std::string;
+  if (!has_name()) {
+    clear_EdgeNameOrRef();
+    set_has_name();
+    EdgeNameOrRef_.name_ = new ::std::string;
   }
-  name_->assign(reinterpret_cast<const char*>(value), size);
-  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Edge.name)
+  EdgeNameOrRef_.name_->assign(
+      reinterpret_cast<const char*>(value), size);
 }
 inline ::std::string* Edge::mutable_name() {
-  set_has_name();
-  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    name_ = new ::std::string;
+  if (!has_name()) {
+    clear_EdgeNameOrRef();
+    set_has_name();
+    EdgeNameOrRef_.name_ = new ::std::string;
   }
-  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Edge.name)
-  return name_;
+  return EdgeNameOrRef_.name_;
 }
 inline ::std::string* Edge::release_name() {
-  clear_has_name();
-  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    return NULL;
+  if (has_name()) {
+    clear_has_EdgeNameOrRef();
+    ::std::string* temp = EdgeNameOrRef_.name_;
+    EdgeNameOrRef_.name_ = NULL;
+    return temp;
   } else {
-    ::std::string* temp = name_;
-    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-    return temp;
+    return NULL;
   }
 }
 inline void Edge::set_allocated_name(::std::string* name) {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete name_;
-  }
+  clear_EdgeNameOrRef();
   if (name) {
     set_has_name();
-    name_ = name;
-  } else {
-    clear_has_name();
-    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    EdgeNameOrRef_.name_ = name;
   }
-  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Edge.name)
 }
 
+// optional uint64 nameRef = 3;
+inline bool Edge::has_nameref() const {
+  return EdgeNameOrRef_case() == kNameRef;
+}
+inline void Edge::set_has_nameref() {
+  _oneof_case_[0] = kNameRef;
+}
+inline void Edge::clear_nameref() {
+  if (has_nameref()) {
+    EdgeNameOrRef_.nameref_ = GOOGLE_ULONGLONG(0);
+    clear_has_EdgeNameOrRef();
+  }
+}
+inline ::google::protobuf::uint64 Edge::nameref() const {
+  if (has_nameref()) {
+    return EdgeNameOrRef_.nameref_;
+  }
+  return GOOGLE_ULONGLONG(0);
+}
+inline void Edge::set_nameref(::google::protobuf::uint64 value) {
+  if (!has_nameref()) {
+    clear_EdgeNameOrRef();
+    set_has_nameref();
+  }
+  EdgeNameOrRef_.nameref_ = value;
+}
+
+inline bool Edge::has_EdgeNameOrRef() {
+  return EdgeNameOrRef_case() != EDGENAMEORREF_NOT_SET;
+}
+inline void Edge::clear_has_EdgeNameOrRef() {
+  _oneof_case_[0] = EDGENAMEORREF_NOT_SET;
+}
+inline Edge::EdgeNameOrRefCase Edge::EdgeNameOrRef_case() const {
+  return Edge::EdgeNameOrRefCase(_oneof_case_[0]);
+}
 
 // @@protoc_insertion_point(namespace_scope)
 
 }  // namespace protobuf
 }  // namespace devtools
 }  // namespace mozilla
 
 #ifndef SWIG
--- a/devtools/shared/heapsnapshot/CoreDump.proto
+++ b/devtools/shared/heapsnapshot/CoreDump.proto
@@ -33,21 +33,35 @@
 //     +-----------------------------------------------------------------------+
 //     | message: A `Node` message.                                            |
 //     +-----------------------------------------------------------------------+
 //     | .                                                                     |
 //     | .                                                                     |
 //     | .                                                                     |
 //     +-----------------------------------------------------------------------+
 //
-// In practice, certain message fields have a lot of duplication (such as type
-// or edge name strings). Rather than try and de-duplicate this information at
-// the protobuf message and field level, core dumps should be written with
-// `google::protobuf::io::GzipOutputStream` and read from
+// Core dumps should always be written with a
+// `google::protobuf::io::GzipOutputStream` and read from a
 // `google::protobuf::io::GzipInputStream`.
+//
+// Note that all strings are de-duplicated. The first time the N^th unique
+// string is encountered, the full string is serialized. Subsequent times that
+// same string is encountered, it is referenced by N. This de-duplication
+// happens across string properties, not on a per-property basis. For example,
+// if the same K^th unique string is first used as an Edge::EdgeNameOrRef and
+// then as a StackFrame::Data::FunctionDisplayNameOrRef, the first will be the
+// actual string as the functionDisplayName oneof property, and the second will
+// be a reference to the first as the edgeNameRef oneof property whose value is
+// K.
+//
+// We would ordinarily abstract these de-duplicated strings with messages of
+// their own, but unfortunately, the protobuf compiler does not have a way to
+// inline a messsage within another message and the child message must be
+// referenced by pointer. This leads to extra mallocs that we wish to avoid.
+
 
 package mozilla.devtools.protobuf;
 
 // A collection of metadata about this core dump.
 message Metadata {
     // Number of microseconds since midnight (00:00:00) 1 January 1970 UTC.
     optional uint64 timeStamp = 1;
 }
@@ -60,41 +74,64 @@ message StackFrame {
         // here is all of its data.
         Data   data = 1;
         // A reference to a stack frame that has already been serialized and has
         // the given number as its id.
         uint64 ref  = 2;
     }
 
     message Data {
-        optional uint64 id = 1;
-        optional StackFrame parent = 2;
-        optional uint32 line = 3;
-        optional uint32 column = 4;
-        // char16_t[]
-        optional bytes source = 5;
-        // char16_t[]
-        optional bytes functionDisplayName = 6;
-        optional bool isSystem = 7;
-        optional bool isSelfHosted = 8;
+        optional uint64        id           = 1;
+        optional StackFrame    parent       = 2;
+        optional uint32        line         = 3;
+        optional uint32        column       = 4;
+
+        // De-duplicated two-byte string.
+        oneof SourceOrRef {
+            bytes  source                   = 5;
+            uint64 sourceRef                = 6;
+        }
+
+        // De-duplicated two-byte string.
+        oneof FunctionDisplayNameOrRef {
+            bytes  functionDisplayName      = 7;
+            uint64 functionDisplayNameRef   = 8;
+        }
+
+        optional bool          isSystem     = 9;
+        optional bool          isSelfHosted = 10;
     }
 }
 
 // A serialized version of `JS::ubi::Node` and its outgoing edges.
 message Node {
-    optional uint64     id                = 1;
-    // char16_t[]
-    optional bytes      typeName          = 2;
-    optional uint64     size              = 3;
-    repeated Edge       edges             = 4;
-    optional StackFrame allocationStack   = 5;
-    // char[]
-    optional bytes      jsObjectClassName = 6;
+    optional uint64     id                   = 1;
+
+    // De-duplicated two-byte string.
+    oneof TypeNameOrRef {
+        bytes           typeName             = 2;
+        uint64          typeNameRef          = 3;
+    }
+    
+    optional uint64     size                 = 4;
+    repeated Edge       edges                = 5;
+    optional StackFrame allocationStack      = 6;
+
+    // De-duplicated one-byte string.
+    oneof JSObjectClassNameOrRef {
+        bytes           jsObjectClassName    = 7;
+        uint64          jsObjectClassNameRef = 8;
+    }
+
     // JS::ubi::CoarseType. Defaults to Other.
-    optional uint32     coarseType        = 7 [default = 0];
+    optional uint32     coarseType           = 9 [default = 0];
 }
 
 // A serialized edge from the heap graph.
 message Edge {
-    optional uint64 referent = 1;
-    // char16_t[]
-    optional bytes  name     = 2;
+    optional uint64 referent    = 1;
+
+    // De-duplicated two-byte string.
+    oneof EdgeNameOrRef {
+        bytes       name    = 2;
+        uint64      nameRef = 3;
+    }
 }
--- a/devtools/shared/heapsnapshot/DeserializedNode.cpp
+++ b/devtools/shared/heapsnapshot/DeserializedNode.cpp
@@ -5,55 +5,30 @@
 
 #include "mozilla/devtools/DeserializedNode.h"
 #include "mozilla/devtools/HeapSnapshot.h"
 #include "nsCRTGlue.h"
 
 namespace mozilla {
 namespace devtools {
 
-DeserializedEdge::DeserializedEdge()
-  : referent(0)
-  , name(nullptr)
-{ }
-
 DeserializedEdge::DeserializedEdge(DeserializedEdge&& rhs)
 {
   referent = rhs.referent;
   name = rhs.name;
 }
 
 DeserializedEdge& DeserializedEdge::operator=(DeserializedEdge&& rhs)
 {
   MOZ_ASSERT(&rhs != this);
   this->~DeserializedEdge();
   new(this) DeserializedEdge(Move(rhs));
   return *this;
 }
 
-bool
-DeserializedEdge::init(const protobuf::Edge& edge, HeapSnapshot& owner)
-{
-  // Although the referent property is optional in the protobuf format for
-  // future compatibility, we can't semantically have an edge to nowhere and
-  // require a referent here.
-  if (!edge.has_referent())
-    return false;
-  referent = edge.referent();
-
-  if (edge.has_name()) {
-    const char16_t* duplicateEdgeName = reinterpret_cast<const char16_t*>(edge.name().c_str());
-    name = owner.borrowUniqueString(duplicateEdgeName, edge.name().length() / sizeof(char16_t));
-    if (!name)
-      return false;
-  }
-
-  return true;
-}
-
 JS::ubi::Node
 DeserializedNode::getEdgeReferent(const DeserializedEdge& edge)
 {
   auto ptr = owner->nodes.lookup(edge.referent);
   MOZ_ASSERT(ptr);
 
   // `HashSets` only provide const access to their values, because mutating a
   // value might change its hash, rendering it unfindable in the set.
--- a/devtools/shared/heapsnapshot/DeserializedNode.h
+++ b/devtools/shared/heapsnapshot/DeserializedNode.h
@@ -35,23 +35,23 @@ using StackFrameId = uint64_t;
 // A `DeserializedEdge` represents an edge in the heap graph pointing to the
 // node with id equal to `DeserializedEdge::referent` that we deserialized from
 // a core dump.
 struct DeserializedEdge {
   NodeId         referent;
   // A borrowed reference to a string owned by this node's owning HeapSnapshot.
   const char16_t* name;
 
-  explicit DeserializedEdge();
+  explicit DeserializedEdge(NodeId referent, const char16_t* edgeName = nullptr)
+    : referent(referent)
+    , name(edgeName)
+  { }
   DeserializedEdge(DeserializedEdge&& rhs);
   DeserializedEdge& operator=(DeserializedEdge&& rhs);
 
-  // Initialize this `DeserializedEdge` from the given `protobuf::Edge` message.
-  bool init(const protobuf::Edge& edge, HeapSnapshot& owner);
-
 private:
   DeserializedEdge(const DeserializedEdge&) = delete;
   DeserializedEdge& operator=(const DeserializedEdge&) = delete;
 };
 
 // A `DeserializedNode` is a node in the heap graph that we deserialized from a
 // core dump.
 struct DeserializedNode {
@@ -60,48 +60,49 @@ struct DeserializedNode {
 
   NodeId              id;
   JS::ubi::CoarseType coarseType;
   // A borrowed reference to a string owned by this node's owning HeapSnapshot.
   const char16_t*     typeName;
   uint64_t            size;
   EdgeVector          edges;
   Maybe<StackFrameId> allocationStack;
-  UniquePtr<char[]>   jsObjectClassName;
+  // A borrowed reference to a string owned by this node's owning HeapSnapshot.
+  const char*         jsObjectClassName;
   // A weak pointer to this node's owning `HeapSnapshot`. Safe without
   // AddRef'ing because this node's lifetime is equal to that of its owner.
   HeapSnapshot*       owner;
 
   DeserializedNode(NodeId id,
                    JS::ubi::CoarseType coarseType,
                    const char16_t* typeName,
                    uint64_t size,
                    EdgeVector&& edges,
                    Maybe<StackFrameId> allocationStack,
-                   UniquePtr<char[]>&& className,
+                   const char* className,
                    HeapSnapshot& owner)
     : id(id)
     , coarseType(coarseType)
     , typeName(typeName)
     , size(size)
     , edges(Move(edges))
     , allocationStack(allocationStack)
-    , jsObjectClassName(Move(className))
+    , jsObjectClassName(className)
     , owner(&owner)
   { }
   virtual ~DeserializedNode() { }
 
   DeserializedNode(DeserializedNode&& rhs)
     : id(rhs.id)
     , coarseType(rhs.coarseType)
     , typeName(rhs.typeName)
     , size(rhs.size)
     , edges(Move(rhs.edges))
     , allocationStack(rhs.allocationStack)
-    , jsObjectClassName(Move(rhs.jsObjectClassName))
+    , jsObjectClassName(rhs.jsObjectClassName)
     , owner(rhs.owner)
   { }
 
   DeserializedNode& operator=(DeserializedNode&& rhs)
   {
     MOZ_ASSERT(&rhs != this);
     this->~DeserializedNode();
     new(this) DeserializedNode(Move(rhs));
@@ -253,17 +254,17 @@ public:
     new (storage) Concrete(ptr);
   }
 
   CoarseType coarseType() const final { return get().coarseType; }
   Id identifier() const override { return get().id; }
   bool isLive() const override { return false; }
   const char16_t* typeName() const override;
   Node::Size size(mozilla::MallocSizeOf mallocSizeof) const override;
-  const char* jsObjectClassName() const override { return get().jsObjectClassName.get(); }
+  const char* jsObjectClassName() const override { return get().jsObjectClassName; }
 
   bool hasAllocationStack() const override { return get().allocationStack.isSome(); }
   StackFrame allocationStack() const override;
 
   // We ignore the `bool wantNames` parameter because we can't control whether
   // the core dump was serialized with edge names or not.
   UniquePtr<EdgeRange> edges(JSRuntime* rt, bool) const override;
 };
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
@@ -45,16 +45,18 @@ namespace devtools {
 using namespace JS;
 using namespace dom;
 
 using ::google::protobuf::io::ArrayInputStream;
 using ::google::protobuf::io::CodedInputStream;
 using ::google::protobuf::io::GzipInputStream;
 using ::google::protobuf::io::ZeroCopyInputStream;
 
+using JS::ubi::AtomOrTwoByteChars;
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(HeapSnapshot)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HeapSnapshot)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HeapSnapshot)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -117,86 +119,169 @@ parseMessage(ZeroCopyInputStream& stream
   {
     return false;
   }
 
   codedStream.PopLimit(limit);
   return true;
 }
 
+template<typename CharT, typename InternedStringSet>
+struct GetOrInternStringMatcher
+{
+  using ReturnType = const CharT*;
+
+  InternedStringSet& internedStrings;
+
+  explicit GetOrInternStringMatcher(InternedStringSet& strings) : internedStrings(strings) { }
+
+  const CharT* match(const std::string* str) {
+    MOZ_ASSERT(str);
+    size_t length = str->length() / sizeof(CharT);
+    auto tempString = reinterpret_cast<const CharT*>(str->data());
+
+    UniquePtr<CharT[], NSFreePolicy> owned(NS_strndup(tempString, length));
+    if (!owned || !internedStrings.append(Move(owned)))
+      return nullptr;
+
+    return internedStrings.back().get();
+  }
+
+  const CharT* match(uint64_t ref) {
+    if (MOZ_LIKELY(ref < internedStrings.length())) {
+      auto& string = internedStrings[ref];
+      MOZ_ASSERT(string);
+      return string.get();
+    }
+
+    return nullptr;
+  }
+};
+
+template<
+  // Either char or char16_t.
+  typename CharT,
+  // A reference to either `internedOneByteStrings` or `internedTwoByteStrings`
+  // if CharT is char or char16_t respectively.
+  typename InternedStringSet>
+const CharT*
+HeapSnapshot::getOrInternString(InternedStringSet& internedStrings,
+                                Maybe<StringOrRef>& maybeStrOrRef)
+{
+  // Incomplete message: has neither a string nor a reference to an already
+  // interned string.
+  if (MOZ_UNLIKELY(maybeStrOrRef.isNothing()))
+    return nullptr;
+
+  GetOrInternStringMatcher<CharT, InternedStringSet> m(internedStrings);
+  return maybeStrOrRef->match(m);
+}
+
+// Get a de-duplicated string as a Maybe<StringOrRef> from the given `msg`.
+#define GET_STRING_OR_REF_WITH_PROP_NAMES(msg, strPropertyName, refPropertyName) \
+  (msg.has_##refPropertyName()                                                   \
+    ? Some(StringOrRef(msg.refPropertyName()))                                   \
+    : msg.has_##strPropertyName()                                                \
+      ? Some(StringOrRef(&msg.strPropertyName()))                                \
+      : Nothing())
+
+#define GET_STRING_OR_REF(msg, property)      \
+  (msg.has_##property##ref()                  \
+     ? Some(StringOrRef(msg.property##ref())) \
+     : msg.has_##property()                   \
+       ? Some(StringOrRef(&msg.property()))   \
+       : Nothing())
+
 bool
 HeapSnapshot::saveNode(const protobuf::Node& node)
 {
-  if (!node.has_id())
+  // NB: de-duplicated string properties must be read back and interned in the
+  // same order here as they are written and serialized in
+  // `CoreDumpWriter::writeNode` or else indices in references to already
+  // serialized strings will be off.
+
+  if (NS_WARN_IF(!node.has_id()))
     return false;
   NodeId id = node.id();
 
   // Should only deserialize each node once.
-  if (nodes.has(id))
+  if (NS_WARN_IF(nodes.has(id)))
     return false;
 
-  if (!JS::ubi::Uint32IsValidCoarseType(node.coarsetype()))
+  if (NS_WARN_IF(!JS::ubi::Uint32IsValidCoarseType(node.coarsetype())))
     return false;
   auto coarseType = JS::ubi::Uint32ToCoarseType(node.coarsetype());
 
-  if (!node.has_typename_())
+  Maybe<StringOrRef> typeNameOrRef = GET_STRING_OR_REF_WITH_PROP_NAMES(node, typename_, typenameref);
+  auto typeName = getOrInternString<char16_t>(internedTwoByteStrings, typeNameOrRef);
+  if (NS_WARN_IF(!typeName))
     return false;
 
-  auto duplicatedTypeName = reinterpret_cast<const char16_t*>(
-    node.typename_().data());
-  auto length = node.typename_().length() / sizeof(char16_t);
-  auto typeName = borrowUniqueString(duplicatedTypeName, length);
-  if (!typeName)
-    return false;
-
-  if (!node.has_size())
+  if (NS_WARN_IF(!node.has_size()))
     return false;
   uint64_t size = node.size();
 
   auto edgesLength = node.edges_size();
   DeserializedNode::EdgeVector edges;
-  if (!edges.reserve(edgesLength))
+  if (NS_WARN_IF(!edges.reserve(edgesLength)))
     return false;
   for (decltype(edgesLength) i = 0; i < edgesLength; i++) {
-    DeserializedEdge edge;
-    if (!edge.init(node.edges(i), *this))
+    auto& protoEdge = node.edges(i);
+
+    if (NS_WARN_IF(!protoEdge.has_referent()))
       return false;
-    edges.infallibleAppend(Move(edge));
+    NodeId referent = protoEdge.referent();
+
+    const char16_t* edgeName = nullptr;
+    if (protoEdge.EdgeNameOrRef_case() != protobuf::Edge::EDGENAMEORREF_NOT_SET) {
+      Maybe<StringOrRef> edgeNameOrRef = GET_STRING_OR_REF(protoEdge, name);
+      edgeName = getOrInternString<char16_t>(internedTwoByteStrings, edgeNameOrRef);
+      if (NS_WARN_IF(!edgeName))
+        return false;
+    }
+
+    edges.infallibleAppend(DeserializedEdge(referent, edgeName));
   }
 
   Maybe<StackFrameId> allocationStack;
   if (node.has_allocationstack()) {
     StackFrameId id = 0;
-    if (!saveStackFrame(node.allocationstack(), id))
+    if (NS_WARN_IF(!saveStackFrame(node.allocationstack(), id)))
       return false;
     allocationStack.emplace(id);
   }
   MOZ_ASSERT(allocationStack.isSome() == node.has_allocationstack());
 
-  UniquePtr<char[]> jsObjectClassName;
-  if (node.has_jsobjectclassname()) {
-    auto length = node.jsobjectclassname().length();
-    jsObjectClassName.reset(static_cast<char*>(malloc(length + 1)));
-    if (!jsObjectClassName)
+  const char* jsObjectClassName = nullptr;
+  if (node.JSObjectClassNameOrRef_case() != protobuf::Node::JSOBJECTCLASSNAMEORREF_NOT_SET) {
+    Maybe<StringOrRef> clsNameOrRef = GET_STRING_OR_REF(node, jsobjectclassname);
+    jsObjectClassName = getOrInternString<char>(internedOneByteStrings, clsNameOrRef);
+    if (NS_WARN_IF(!jsObjectClassName))
       return false;
-    strncpy(jsObjectClassName.get(), node.jsobjectclassname().data(),
-            length);
-    jsObjectClassName.get()[length] = '\0';
   }
 
-  return nodes.putNew(id, DeserializedNode(id, coarseType, typeName, size,
-                                           Move(edges), allocationStack,
-                                           Move(jsObjectClassName),
-                                           *this));
+  if (NS_WARN_IF(!nodes.putNew(id, DeserializedNode(id, coarseType, typeName,
+                                                    size, Move(edges),
+                                                    allocationStack,
+                                                    jsObjectClassName, *this))))
+  {
+    return false;
+  };
+
+  return true;
 }
 
 bool
 HeapSnapshot::saveStackFrame(const protobuf::StackFrame& frame,
                              StackFrameId& outFrameId)
 {
+  // NB: de-duplicated string properties must be read in the same order here as
+  // they are written in `CoreDumpWriter::getProtobufStackFrame` or else indices
+  // in references to already serialized strings will be off.
+
   if (frame.has_ref()) {
     // We should only get a reference to the previous frame if we have already
     // seen the previous frame.
     if (!frames.has(frame.ref()))
       return false;
 
     outFrameId = frame.ref();
     return true;
@@ -211,59 +296,55 @@ HeapSnapshot::saveStackFrame(const proto
   if (!data.has_id())
     return false;
   StackFrameId id = data.id();
 
   // This should be the first and only time we see this frame.
   if (frames.has(id))
     return false;
 
-  Maybe<StackFrameId> parent;
-  if (data.has_parent()) {
-    StackFrameId parentId = 0;
-    if (!saveStackFrame(data.parent(), parentId))
-      return false;
-    parent = Some(parentId);
-  }
-
   if (!data.has_line())
     return false;
   uint32_t line = data.line();
 
   if (!data.has_column())
     return false;
   uint32_t column = data.column();
 
-  auto duplicatedSource = reinterpret_cast<const char16_t*>(
-    data.source().data());
-  size_t sourceLength = data.source().length() / sizeof(char16_t);
-  const char16_t* source = borrowUniqueString(duplicatedSource, sourceLength);
-  if (!source)
-    return false;
-
-  const char16_t* functionDisplayName = nullptr;
-  if (data.has_functiondisplayname() && data.functiondisplayname().length() > 0) {
-    auto duplicatedName = reinterpret_cast<const char16_t*>(
-      data.functiondisplayname().data());
-    size_t nameLength = data.functiondisplayname().length() / sizeof(char16_t);
-    functionDisplayName = borrowUniqueString(duplicatedName, nameLength);
-    if (!functionDisplayName)
-      return false;
-  }
-  MOZ_ASSERT(!!functionDisplayName == (data.has_functiondisplayname() &&
-                                       data.functiondisplayname().length() > 0));
-
   if (!data.has_issystem())
     return false;
   bool isSystem = data.issystem();
 
   if (!data.has_isselfhosted())
     return false;
   bool isSelfHosted = data.isselfhosted();
 
+  Maybe<StringOrRef> sourceOrRef = GET_STRING_OR_REF(data, source);
+  auto source = getOrInternString<char16_t>(internedTwoByteStrings, sourceOrRef);
+  if (!source)
+    return false;
+
+  const char16_t* functionDisplayName = nullptr;
+  if (data.FunctionDisplayNameOrRef_case() !=
+      protobuf::StackFrame_Data::FUNCTIONDISPLAYNAMEORREF_NOT_SET)
+  {
+    Maybe<StringOrRef> nameOrRef = GET_STRING_OR_REF(data, functiondisplayname);
+    functionDisplayName = getOrInternString<char16_t>(internedTwoByteStrings, nameOrRef);
+    if (!functionDisplayName)
+      return false;
+  }
+
+  Maybe<StackFrameId> parent;
+  if (data.has_parent()) {
+    StackFrameId parentId = 0;
+    if (!saveStackFrame(data.parent(), parentId))
+      return false;
+    parent = Some(parentId);
+  }
+
   if (!frames.putNew(id, DeserializedStackFrame(id, parent, line, column,
                                                 source, functionDisplayName,
                                                 isSystem, isSelfHosted, *this)))
   {
     return false;
   }
 
   outFrameId = id;
@@ -291,17 +372,17 @@ StreamHasData(GzipInputStream& stream)
   // to the stream and let the parser get at it.
   stream.BackUp(size);
   return true;
 }
 
 bool
 HeapSnapshot::init(const uint8_t* buffer, uint32_t size)
 {
-  if (!nodes.init() || !frames.init() || !strings.init())
+  if (!nodes.init() || !frames.init())
     return false;
 
   ArrayInputStream stream(buffer, size);
   GzipInputStream gzipStream(&stream);
 
   // First is the metadata.
 
   protobuf::Metadata metadata;
@@ -333,32 +414,16 @@ HeapSnapshot::init(const uint8_t* buffer
       return false;
     if (NS_WARN_IF(!saveNode(node)))
       return false;
   }
 
   return true;
 }
 
-const char16_t*
-HeapSnapshot::borrowUniqueString(const char16_t* duplicateString, size_t length)
-{
-  MOZ_ASSERT(duplicateString);
-  UniqueStringHashPolicy::Lookup lookup(duplicateString, length);
-  auto ptr = strings.lookupForAdd(lookup);
-
-  if (!ptr) {
-    UniqueString owned(NS_strndup(duplicateString, length));
-    if (!owned || !strings.add(ptr, Move(owned)))
-      return nullptr;
-  }
-
-  MOZ_ASSERT(ptr->get() != duplicateString);
-  return ptr->get();
-}
 
 /*** Heap Snapshot Analyses ***********************************************************************/
 
 void
 HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options,
                          JS::MutableHandleValue rval, ErrorResult& rv)
 {
   JS::ubi::Census census(cx);
@@ -402,16 +467,20 @@ HeapSnapshot::TakeCensus(JSContext* cx, 
   }
 
   if (NS_WARN_IF(!handler.report(rval))) {
     rv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 }
 
+#undef GET_STRING_OR_REF_WITH_PROP_NAMES
+#undef GET_STRING_OR_REF
+
+
 /*** Saving Heap Snapshots ************************************************************************/
 
 // If we are only taking a snapshot of the heap affected by the given set of
 // globals, find the set of zones the globals are allocated within. Returns
 // false on OOM failure.
 static bool
 PopulateZonesWithGlobals(ZoneSet& zones, AutoObjectVector& globals)
 {
@@ -544,41 +613,306 @@ EstablishBoundaries(JSContext* cx,
 
   MOZ_ASSERT(roots.initialized());
   MOZ_ASSERT_IF(boundaries.mDebugger.WasPassed(), zones.initialized());
   MOZ_ASSERT_IF(boundaries.mGlobals.WasPassed(), zones.initialized());
   return true;
 }
 
 
+// A variant covering all the various two-byte strings that we can get from the
+// ubi::Node API.
+class TwoByteString : public Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName>
+{
+  using Base = Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName>;
+
+  struct AsTwoByteStringMatcher
+  {
+    using ReturnType = TwoByteString;
+
+    TwoByteString match(JSAtom* atom) {
+      return TwoByteString(atom);
+    }
+
+    TwoByteString match(const char16_t* chars) {
+      return TwoByteString(chars);
+    }
+  };
+
+  struct IsNonNullMatcher
+  {
+    using ReturnType = bool;
+
+    template<typename T>
+    bool match(const T& t) { return t != nullptr; }
+  };
+
+  struct LengthMatcher
+  {
+    using ReturnType = size_t;
+
+    size_t match(JSAtom* atom) {
+      MOZ_ASSERT(atom);
+      JS::ubi::AtomOrTwoByteChars s(atom);
+      return s.length();
+    }
+
+    size_t match(const char16_t* chars) {
+      MOZ_ASSERT(chars);
+      return NS_strlen(chars);
+    }
+
+    size_t match(const JS::ubi::EdgeName& ptr) {
+      MOZ_ASSERT(ptr);
+      return NS_strlen(ptr.get());
+    }
+  };
+
+  struct CopyToBufferMatcher
+  {
+    using ReturnType = size_t;
+
+    RangedPtr<char16_t> destination;
+    size_t              maxLength;
+
+    CopyToBufferMatcher(RangedPtr<char16_t> destination, size_t maxLength)
+      : destination(destination)
+      , maxLength(maxLength)
+    { }
+
+    size_t match(JS::ubi::EdgeName& ptr) {
+      return ptr ? match(ptr.get()) : 0;
+    }
+
+    size_t match(JSAtom* atom) {
+      MOZ_ASSERT(atom);
+      JS::ubi::AtomOrTwoByteChars s(atom);
+      return s.copyToBuffer(destination, maxLength);
+    }
+
+    size_t match(const char16_t* chars) {
+      MOZ_ASSERT(chars);
+      JS::ubi::AtomOrTwoByteChars s(chars);
+      return s.copyToBuffer(destination, maxLength);
+    }
+  };
+
+public:
+  template<typename T>
+  MOZ_IMPLICIT TwoByteString(T&& rhs) : Base(Forward<T>(rhs)) { }
+
+  template<typename T>
+  TwoByteString& operator=(T&& rhs) {
+    MOZ_ASSERT(this != &rhs, "self-move disallowed");
+    this->~TwoByteString();
+    new (this) TwoByteString(Forward<T>(rhs));
+    return *this;
+  }
+
+  TwoByteString(const TwoByteString&) = delete;
+  TwoByteString& operator=(const TwoByteString&) = delete;
+
+  // Rewrap the inner value of a JS::ubi::AtomOrTwoByteChars as a TwoByteString.
+  static TwoByteString from(JS::ubi::AtomOrTwoByteChars&& s) {
+    AsTwoByteStringMatcher m;
+    return s.match(m);
+  }
+
+  // Returns true if the given TwoByteString is non-null, false otherwise.
+  bool isNonNull() const {
+    IsNonNullMatcher m;
+    return match(m);
+  }
+
+  // Return the length of the string, 0 if it is null.
+  size_t length() const {
+    LengthMatcher m;
+    return match(m);
+  }
+
+  // Copy the contents of a TwoByteString into the provided buffer. The buffer
+  // is NOT null terminated. The number of characters written is returned.
+  size_t copyToBuffer(RangedPtr<char16_t> destination, size_t maxLength) {
+    CopyToBufferMatcher m(destination, maxLength);
+    return match(m);
+  }
+
+  struct HashPolicy;
+};
+
+// A hashing policy for TwoByteString.
+//
+// Atoms are pointer hashed and use pointer equality, which means that we
+// tolerate some duplication across atoms and the other two types of two-byte
+// strings. In practice, we expect the amount of this duplication to be very low
+// because each type is generally a different semantic thing in addition to
+// having a slightly different representation. For example, the set of edge
+// names and the set stack frames' source names naturally tend not to overlap
+// very much if at all.
+struct TwoByteString::HashPolicy {
+  using Lookup = TwoByteString;
+
+  struct HashingMatcher {
+    using ReturnType  = js::HashNumber;
+
+    js::HashNumber match(const JSAtom* atom) {
+      return js::DefaultHasher<const JSAtom*>::hash(atom);
+    }
+
+    js::HashNumber match(const char16_t* chars) {
+      MOZ_ASSERT(chars);
+      auto length = NS_strlen(chars);
+      return HashString(chars, length);
+    }
+
+    js::HashNumber match(const JS::ubi::EdgeName& ptr) {
+      MOZ_ASSERT(ptr);
+      return match(ptr.get());
+    }
+  };
+
+  static js::HashNumber hash(const Lookup& l) {
+    HashingMatcher hasher;
+    return l.match(hasher);
+  }
+
+  struct EqualityMatcher {
+    using ReturnType = bool;
+    const TwoByteString& rhs;
+    explicit EqualityMatcher(const TwoByteString& rhs) : rhs(rhs) { }
+
+    bool match(const JSAtom* atom) {
+      return rhs.is<JSAtom*>() && rhs.as<JSAtom*>() == atom;
+    }
+
+    bool match(const char16_t* chars) {
+      MOZ_ASSERT(chars);
+
+      const char16_t* rhsChars = nullptr;
+      if (rhs.is<const char16_t*>())
+        rhsChars = rhs.as<const char16_t*>();
+      else if (rhs.is<JS::ubi::EdgeName>())
+        rhsChars = rhs.as<JS::ubi::EdgeName>().get();
+      else
+        return false;
+      MOZ_ASSERT(rhsChars);
+
+      auto length = NS_strlen(chars);
+      if (NS_strlen(rhsChars) != length)
+        return false;
+
+      return memcmp(chars, rhsChars, length * sizeof(char16_t)) == 0;
+    }
+
+    bool match(const JS::ubi::EdgeName& ptr) {
+      MOZ_ASSERT(ptr);
+      return match(ptr.get());
+    }
+  };
+
+  static bool match(const TwoByteString& k, const Lookup& l) {
+    EqualityMatcher eq(l);
+    return k.match(eq);
+  }
+
+  static void rekey(TwoByteString& k, TwoByteString&& newKey) {
+    k = Move(newKey);
+  }
+};
+
 // A `CoreDumpWriter` that serializes nodes to protobufs and writes them to the
 // given `ZeroCopyOutputStream`.
 class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter
 {
-  using Set = js::HashSet<uint64_t>;
+  using FrameSet         = js::HashSet<uint64_t>;
+  using TwoByteStringMap = js::HashMap<TwoByteString, uint64_t, TwoByteString::HashPolicy>;
+  using OneByteStringMap = js::HashMap<const char*, uint64_t>;
 
-  JSContext* cx;
-  bool       wantNames;
+  JSContext*       cx;
+  bool             wantNames;
   // The set of |JS::ubi::StackFrame::identifier()|s that have already been
   // serialized and written to the core dump.
-  Set        framesAlreadySerialized;
+  FrameSet         framesAlreadySerialized;
+  // The set of two-byte strings that have already been serialized and written
+  // to the core dump.
+  TwoByteStringMap twoByteStringsAlreadySerialized;
+  // The set of one-byte strings that have already been serialized and written
+  // to the core dump.
+  OneByteStringMap oneByteStringsAlreadySerialized;
 
   ::google::protobuf::io::ZeroCopyOutputStream& stream;
 
   bool writeMessage(const ::google::protobuf::MessageLite& message) {
     // We have to create a new CodedOutputStream when writing each message so
     // that the 64MB size limit used by Coded{Output,Input}Stream to prevent
     // integer overflow is enforced per message rather than on the whole stream.
     ::google::protobuf::io::CodedOutputStream codedStream(&stream);
     codedStream.WriteVarint32(message.ByteSize());
     message.SerializeWithCachedSizes(&codedStream);
     return !codedStream.HadError();
   }
 
+  // Attach the full two-byte string or a reference to a two-byte string that
+  // has already been serialized to a protobuf message.
+  template <typename SetStringFunction,
+            typename SetRefFunction>
+  bool attachTwoByteString(TwoByteString& string, SetStringFunction setString,
+                           SetRefFunction setRef) {
+    auto ptr = twoByteStringsAlreadySerialized.lookupForAdd(string);
+    if (ptr) {
+      setRef(ptr->value());
+      return true;
+    }
+
+    auto length = string.length();
+    auto stringData = MakeUnique<std::string>(length * sizeof(char16_t), '\0');
+    if (!stringData)
+      return false;
+
+    auto buf = const_cast<char16_t*>(reinterpret_cast<const char16_t*>(stringData->data()));
+    string.copyToBuffer(RangedPtr<char16_t>(buf, length), length);
+
+    uint64_t ref = twoByteStringsAlreadySerialized.count();
+    if (!twoByteStringsAlreadySerialized.add(ptr, Move(string), ref))
+      return false;
+
+    setString(stringData.release());
+    return true;
+  }
+
+  // Attach the full one-byte string or a reference to a one-byte string that
+  // has already been serialized to a protobuf message.
+  template <typename SetStringFunction,
+            typename SetRefFunction>
+  bool attachOneByteString(const char* string, SetStringFunction setString,
+                           SetRefFunction setRef) {
+    auto ptr = oneByteStringsAlreadySerialized.lookupForAdd(string);
+    if (ptr) {
+      setRef(ptr->value());
+      return true;
+    }
+
+    auto length = strlen(string);
+    auto stringData = MakeUnique<std::string>(string, length);
+    if (!stringData)
+      return false;
+
+    uint64_t ref = oneByteStringsAlreadySerialized.count();
+    if (!oneByteStringsAlreadySerialized.add(ptr, string, ref))
+      return false;
+
+    setString(stringData.release());
+    return true;
+  }
+
   protobuf::StackFrame* getProtobufStackFrame(JS::ubi::StackFrame& frame) {
+    // NB: de-duplicated string properties must be written in the same order
+    // here as they are read in `HeapSnapshot::saveStackFrame` or else indices
+    // in references to already serialized strings will be off.
+
     MOZ_ASSERT(frame,
                "null frames should be represented as the lack of a serialized "
                "stack frame");
 
     auto id = frame.identifier();
     auto protobufStackFrame = MakeUnique<protobuf::StackFrame>();
     if (!protobufStackFrame)
       return nullptr;
@@ -593,34 +927,32 @@ class MOZ_STACK_CLASS StreamWriter : pub
       return nullptr;
 
     data->set_id(id);
     data->set_line(frame.line());
     data->set_column(frame.column());
     data->set_issystem(frame.isSystem());
     data->set_isselfhosted(frame.isSelfHosted());
 
-    auto source = MakeUnique<std::string>(frame.sourceLength() * sizeof(char16_t),
-                                          '\0');
-    if (!source)
+    auto dupeSource = TwoByteString::from(frame.source());
+    if (!attachTwoByteString(dupeSource,
+                             [&] (std::string* source) { data->set_allocated_source(source); },
+                             [&] (uint64_t ref) { data->set_sourceref(ref); }))
+    {
       return nullptr;
-    auto buf = const_cast<char16_t*>(reinterpret_cast<const char16_t*>(source->data()));
-    frame.source(RangedPtr<char16_t>(buf, frame.sourceLength()),
-                 frame.sourceLength());
-    data->set_allocated_source(source.release());
+    }
 
-    auto nameLength = frame.functionDisplayNameLength();
-    if (nameLength > 0) {
-      auto functionDisplayName = MakeUnique<std::string>(nameLength * sizeof(char16_t),
-                                                         '\0');
-      if (!functionDisplayName)
+    auto dupeName = TwoByteString::from(frame.functionDisplayName());
+    if (dupeName.isNonNull()) {
+      if (!attachTwoByteString(dupeName,
+                               [&] (std::string* name) { data->set_allocated_functiondisplayname(name); },
+                               [&] (uint64_t ref) { data->set_functiondisplaynameref(ref); }))
+      {
         return nullptr;
-      auto buf = const_cast<char16_t*>(reinterpret_cast<const char16_t*>(functionDisplayName->data()));
-      frame.functionDisplayName(RangedPtr<char16_t>(buf, nameLength), nameLength);
-      data->set_allocated_functiondisplayname(functionDisplayName.release());
+      }
     }
 
     auto parent = frame.parent();
     if (parent) {
       auto protobufParent = getProtobufStackFrame(parent);
       if (!protobufParent)
         return nullptr;
       data->set_allocated_parent(protobufParent);
@@ -636,77 +968,100 @@ class MOZ_STACK_CLASS StreamWriter : pub
 
 public:
   StreamWriter(JSContext* cx,
                ::google::protobuf::io::ZeroCopyOutputStream& stream,
                bool wantNames)
     : cx(cx)
     , wantNames(wantNames)
     , framesAlreadySerialized(cx)
+    , twoByteStringsAlreadySerialized(cx)
+    , oneByteStringsAlreadySerialized(cx)
     , stream(stream)
   { }
 
-  bool init() { return framesAlreadySerialized.init(); }
+  bool init() {
+    return framesAlreadySerialized.init() &&
+           twoByteStringsAlreadySerialized.init() &&
+           oneByteStringsAlreadySerialized.init();
+  }
 
   ~StreamWriter() override { }
 
-  virtual bool writeMetadata(uint64_t timestamp) override {
+  virtual bool writeMetadata(uint64_t timestamp) final {
     protobuf::Metadata metadata;
     metadata.set_timestamp(timestamp);
     return writeMessage(metadata);
   }
 
   virtual bool writeNode(const JS::ubi::Node& ubiNode,
                          EdgePolicy includeEdges) final {
+    // NB: de-duplicated string properties must be written in the same order
+    // here as they are read in `HeapSnapshot::saveNode` or else indices in
+    // references to already serialized strings will be off.
+
     protobuf::Node protobufNode;
     protobufNode.set_id(ubiNode.identifier());
 
     protobufNode.set_coarsetype(JS::ubi::CoarseTypeToUint32(ubiNode.coarseType()));
 
-    const char16_t* typeName = ubiNode.typeName();
-    size_t length = NS_strlen(typeName) * sizeof(char16_t);
-    protobufNode.set_typename_(typeName, length);
+    auto typeName = TwoByteString(ubiNode.typeName());
+    if (NS_WARN_IF(!attachTwoByteString(typeName,
+                                        [&] (std::string* name) { protobufNode.set_allocated_typename_(name); },
+                                        [&] (uint64_t ref) { protobufNode.set_typenameref(ref); })))
+    {
+      return false;
+    }
 
     JSRuntime* rt = JS_GetRuntime(cx);
     mozilla::MallocSizeOf mallocSizeOf = dbg::GetDebuggerMallocSizeOf(rt);
     MOZ_ASSERT(mallocSizeOf);
     protobufNode.set_size(ubiNode.size(mallocSizeOf));
 
+    if (includeEdges) {
+      auto edges = ubiNode.edges(JS_GetRuntime(cx), wantNames);
+      if (NS_WARN_IF(!edges))
+        return false;
+
+      for ( ; !edges->empty(); edges->popFront()) {
+        ubi::Edge& ubiEdge = edges->front();
+
+        protobuf::Edge* protobufEdge = protobufNode.add_edges();
+        if (NS_WARN_IF(!protobufEdge)) {
+          return false;
+        }
+
+        protobufEdge->set_referent(ubiEdge.referent.identifier());
+
+        if (wantNames && ubiEdge.name) {
+          TwoByteString edgeName(Move(ubiEdge.name));
+          if (NS_WARN_IF(!attachTwoByteString(edgeName,
+                                              [&] (std::string* name) { protobufEdge->set_allocated_name(name); },
+                                              [&] (uint64_t ref) { protobufEdge->set_nameref(ref); })))
+          {
+            return false;
+          }
+        }
+      }
+    }
+
     if (ubiNode.hasAllocationStack()) {
       auto ubiStackFrame = ubiNode.allocationStack();
       auto protoStackFrame = getProtobufStackFrame(ubiStackFrame);
       if (NS_WARN_IF(!protoStackFrame))
         return false;
       protobufNode.set_allocated_allocationstack(protoStackFrame);
     }
 
     if (auto className = ubiNode.jsObjectClassName()) {
-      size_t length = strlen(className);
-      protobufNode.set_jsobjectclassname(className, length);
-    }
-
-    if (includeEdges) {
-      auto edges = ubiNode.edges(JS_GetRuntime(cx), wantNames);
-      if (NS_WARN_IF(!edges))
+      if (NS_WARN_IF(!attachOneByteString(className,
+                                          [&] (std::string* name) { protobufNode.set_allocated_jsobjectclassname(name); },
+                                          [&] (uint64_t ref) { protobufNode.set_jsobjectclassnameref(ref); })))
+      {
         return false;
-
-      for ( ; !edges->empty(); edges->popFront()) {
-        const ubi::Edge& ubiEdge = edges->front();
-
-        protobuf::Edge* protobufEdge = protobufNode.add_edges();
-        if (NS_WARN_IF(!protobufEdge)) {
-          return false;
-        }
-
-        protobufEdge->set_referent(ubiEdge.referent.identifier());
-
-        if (wantNames && ubiEdge.name) {
-          size_t length = NS_strlen(ubiEdge.name) * sizeof(char16_t);
-          protobufEdge->set_name(ubiEdge.name, length);
-        }
       }
     }
 
     return writeMessage(protobufNode);
   }
 };
 
 // A JS::ubi::BreadthFirst handler that serializes a snapshot of the heap into a
--- a/devtools/shared/heapsnapshot/HeapSnapshot.h
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.h
@@ -29,55 +29,32 @@ namespace mozilla {
 namespace devtools {
 
 struct NSFreePolicy {
   void operator()(void* ptr) {
     NS_Free(ptr);
   }
 };
 
-using UniqueString = UniquePtr<char16_t[], NSFreePolicy>;
-
-struct UniqueStringHashPolicy {
-  struct Lookup {
-    const char16_t* str;
-    size_t          length;
-
-    Lookup(const char16_t* str, size_t length)
-      : str(str)
-      , length(length)
-    { }
-  };
-
-  static js::HashNumber hash(const Lookup& lookup) {
-    MOZ_ASSERT(lookup.str);
-    return HashString(lookup.str, lookup.length);
-  }
-
-  static bool match(const UniqueString& existing, const Lookup& lookup) {
-    MOZ_ASSERT(lookup.str);
-    if (NS_strlen(existing.get()) != lookup.length)
-      return false;
-    return memcmp(existing.get(), lookup.str, lookup.length * sizeof(char16_t)) == 0;
-  }
-};
+using UniqueTwoByteString = UniquePtr<char16_t[], NSFreePolicy>;
+using UniqueOneByteString = UniquePtr<char[], NSFreePolicy>;
 
 class HeapSnapshot final : public nsISupports
                          , public nsWrapperCache
 {
   friend struct DeserializedNode;
+  friend struct DeserializedEdge;
   friend struct DeserializedStackFrame;
   friend struct JS::ubi::Concrete<JS::ubi::DeserializedNode>;
 
   explicit HeapSnapshot(JSContext* cx, nsISupports* aParent)
     : timestamp(Nothing())
     , rootId(0)
     , nodes(cx)
     , frames(cx)
-    , strings(cx)
     , mParent(aParent)
   {
     MOZ_ASSERT(aParent);
   };
 
   // Initialize this HeapSnapshot from the given buffer that contains a
   // serialized core dump. Do NOT take ownership of the buffer, only borrow it
   // for the duration of the call. Return false on failure.
@@ -103,24 +80,25 @@ class HeapSnapshot final : public nsISup
   using NodeSet = js::HashSet<DeserializedNode, DeserializedNode::HashPolicy>;
   NodeSet nodes;
 
   // The set of stack frames in this deserialized heap graph, keyed by id.
   using FrameSet = js::HashSet<DeserializedStackFrame,
                                DeserializedStackFrame::HashPolicy>;
   FrameSet frames;
 
-  // Core dump files have many duplicate strings: type names are repeated for
-  // each node, and although in theory edge names are highly customizable for
-  // specific edges, in practice they are also highly duplicated. Rather than
-  // make each Deserialized{Node,Edge} malloc their own copy of their edge and
-  // type names, we de-duplicate the strings here and Deserialized{Node,Edge}
-  // get borrowed pointers into this set.
-  using UniqueStringSet = js::HashSet<UniqueString, UniqueStringHashPolicy>;
-  UniqueStringSet strings;
+  Vector<UniqueTwoByteString> internedTwoByteStrings;
+  Vector<UniqueOneByteString> internedOneByteStrings;
+
+  using StringOrRef = Variant<const std::string*, uint64_t>;
+
+  template<typename CharT,
+           typename InternedStringSet>
+  const CharT* getOrInternString(InternedStringSet& internedStrings,
+                                 Maybe<StringOrRef>& maybeStrOrRef);
 
 protected:
   nsCOMPtr<nsISupports> mParent;
 
   virtual ~HeapSnapshot() { }
 
 public:
   // Create a `HeapSnapshot` from the given buffer that contains a serialized
--- a/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp
+++ b/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp
@@ -38,64 +38,60 @@ size_t fakeMallocSizeOf(const void*) {
 
 DEF_TEST(DeserializedNodeUbiNodes, {
     const char16_t* typeName = MOZ_UTF16("TestTypeName");
     const char* className = "MyObjectClassName";
 
     NodeId id = uint64_t(1) << 33;
     uint64_t size = uint64_t(1) << 60;
     MockDeserializedNode mocked(id, typeName, size);
-    mocked.jsObjectClassName = mozilla::UniquePtr<char[]>(strdup(className));
-    ASSERT_TRUE(!!mocked.jsObjectClassName);
     mocked.coarseType = JS::ubi::CoarseType::Script;
+    mocked.jsObjectClassName = className;
 
     DeserializedNode& deserialized = mocked;
     JS::ubi::Node ubi(&deserialized);
 
     // Test the ubi::Node accessors.
 
     EXPECT_EQ(size, ubi.size(fakeMallocSizeOf));
     EXPECT_EQ(typeName, ubi.typeName());
     EXPECT_EQ(JS::ubi::CoarseType::Script, ubi.coarseType());
     EXPECT_EQ(id, ubi.identifier());
     EXPECT_FALSE(ubi.isLive());
-    EXPECT_EQ(strcmp(ubi.jsObjectClassName(), className), 0);
+    EXPECT_EQ(ubi.jsObjectClassName(), className);
 
     // Test the ubi::Node's edges.
 
     UniquePtr<DeserializedNode> referent1(new MockDeserializedNode(1,
                                                                    nullptr,
                                                                    10));
-    DeserializedEdge edge1;
-    edge1.referent = referent1->id;
+    DeserializedEdge edge1(referent1->id);
     mocked.addEdge(Move(edge1));
     EXPECT_CALL(mocked,
                 getEdgeReferent(Field(&DeserializedEdge::referent,
                                       referent1->id)))
       .Times(1)
       .WillOnce(Return(JS::ubi::Node(referent1.get())));
 
     UniquePtr<DeserializedNode> referent2(new MockDeserializedNode(2,
                                                                    nullptr,
                                                                    20));
-    DeserializedEdge edge2;
-    edge2.referent = referent2->id;
+    DeserializedEdge edge2(referent2->id);
     mocked.addEdge(Move(edge2));
     EXPECT_CALL(mocked,
                 getEdgeReferent(Field(&DeserializedEdge::referent,
                                       referent2->id)))
       .Times(1)
       .WillOnce(Return(JS::ubi::Node(referent2.get())));
 
     UniquePtr<DeserializedNode> referent3(new MockDeserializedNode(3,
                                                                    nullptr,
                                                                    30));
-    DeserializedEdge edge3;
-    edge3.referent = referent3->id;
+    DeserializedEdge edge3(referent3->id);
     mocked.addEdge(Move(edge3));
     EXPECT_CALL(mocked,
                 getEdgeReferent(Field(&DeserializedEdge::referent,
                                       referent3->id)))
       .Times(1)
       .WillOnce(Return(JS::ubi::Node(referent3.get())));
 
-    ubi.edges(JS_GetRuntime(cx));
+    ubi.edges(rt);
   });
--- a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h
+++ b/devtools/shared/heapsnapshot/tests/gtest/DevTools.h
@@ -97,17 +97,17 @@ struct DevTools : public ::testing::Test
     return JS_NewContext(rt, 8192);
   }
 
   static const JSClass* getGlobalClass() {
     static const JSClass globalClass = {
       "global", JSCLASS_GLOBAL_FLAGS,
       nullptr, nullptr, nullptr, nullptr,
       nullptr, nullptr, nullptr, nullptr,
-      nullptr, nullptr, nullptr, nullptr,
+      nullptr, nullptr, nullptr,
       JS_GlobalObjectTraceHook
     };
     return &globalClass;
   }
 
   JSObject* createGlobal()
   {
     /* Create the global object. */
@@ -177,17 +177,17 @@ using mozilla::UniquePtr;
 
 template<>
 class Concrete<FakeNode> : public Base
 {
   const char16_t* typeName() const override {
     return concreteTypeName;
   }
 
-  UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override {
+  UniquePtr<EdgeRange> edges(JSRuntime*, bool) const override {
     return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
   }
 
   Size size(mozilla::MallocSizeOf) const override {
     return get().size;
   }
 
   JS::Zone* zone() const override {
@@ -265,16 +265,24 @@ MATCHER_P3(Edge, rt, n, matcher, "") {
   return false;
 }
 
 // Ensures that two char16_t* strings are equal.
 MATCHER_P(UTF16StrEq, str, "") {
   return NS_strcmp(arg, str) == 0;
 }
 
+MATCHER_P(UniqueUTF16StrEq, str, "") {
+  return NS_strcmp(arg.get(), str) == 0;
+}
+
+MATCHER(UniqueIsNull, "") {
+  return arg.get() == nullptr;
+}
+
 } // namespace testing
 
 
 // A mock `Writer` class to be used with testing `WriteHeapGraph`.
 class MockWriter : public CoreDumpWriter
 {
 public:
   virtual ~MockWriter() override { }
--- a/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp
+++ b/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp
@@ -25,21 +25,21 @@ DEF_TEST(SerializesEdgeNames, {
 
     ::testing::NiceMock<MockWriter> writer;
 
     // Should get the node with edges once.
     EXPECT_CALL(
       writer,
       writeNode(AllOf(EdgesLength(rt, 3),
                       Edge(rt, 0, Field(&JS::ubi::Edge::name,
-                                        UTF16StrEq(edgeName))),
+                                        UniqueUTF16StrEq(edgeName))),
                       Edge(rt, 1, Field(&JS::ubi::Edge::name,
-                                        UTF16StrEq(emptyStr))),
+                                        UniqueUTF16StrEq(emptyStr))),
                       Edge(rt, 2, Field(&JS::ubi::Edge::name,
-                                        IsNull()))),
+                                        UniqueIsNull()))),
                 _)
     )
       .Times(1)
       .WillOnce(Return(true));
 
     // Should get the referent node that doesn't have any edges once.
     ExpectWriteNode(writer, referent);
 
deleted file mode 100644
--- a/devtools/shared/heapsnapshot/tests/gtest/UniqueStringHashPolicy.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*-  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/. */
-
-// Bug 1171226 - Test UniqueStringHashPolicy::match
-
-#include "DevTools.h"
-#include "mozilla/devtools/HeapSnapshot.h"
-
-using mozilla::devtools::UniqueString;
-using mozilla::devtools::UniqueStringHashPolicy;
-
-DEF_TEST(UniqueStringHashPolicy_match, {
-    //                                               1
-    //                                     01234567890123456
-    UniqueString str1(NS_strdup(MOZ_UTF16("some long string and a tail")));
-    ASSERT_TRUE(!!str1);
-
-    UniqueStringHashPolicy::Lookup lookup(MOZ_UTF16("some long string with same prefix"), 16);
-
-    // str1 is longer than Lookup.length, so they shouldn't match, even though
-    // the first 16 chars are equal!
-    ASSERT_FALSE(UniqueStringHashPolicy::match(str1, lookup));
-  });
--- a/devtools/shared/heapsnapshot/tests/gtest/moz.build
+++ b/devtools/shared/heapsnapshot/tests/gtest/moz.build
@@ -13,17 +13,16 @@ LOCAL_INCLUDES += [
 UNIFIED_SOURCES = [
     'DeserializedNodeUbiNodes.cpp',
     'DeserializedStackFrameUbiStackFrames.cpp',
     'DoesCrossZoneBoundaries.cpp',
     'DoesntCrossZoneBoundaries.cpp',
     'SerializesEdgeNames.cpp',
     'SerializesEverythingInHeapGraphOnce.cpp',
     'SerializesTypeNames.cpp',
-    'UniqueStringHashPolicy.cpp',
 ]
 
 # THE MOCK_METHOD2 macro from gtest triggers this clang warning and it's hard
 # to work around, so we just ignore it.
 if CONFIG['CLANG_CXX']:
   CXXFLAGS += ['-Wno-inconsistent-missing-override']
 
 FINAL_LIBRARY = 'xul-gtest'
--- a/docshell/test/chrome/bug293235_window.xul
+++ b/docshell/test/chrome/bug293235_window.xul
@@ -59,17 +59,19 @@
           is(aTopic, URI_VISITED_RESOLUTION_TOPIC, "Unexpected topic");
           this.notified = true;
 
           // Cleanup after ourselves...
           os.removeObserver(this, URI_VISITED_RESOLUTION_TOPIC);
         },
       };
       os.addObserver(observer, URI_VISITED_RESOLUTION_TOPIC, false);
-      function notified() observer.notified;
+      function notified() {
+        return observer.notified;
+      }
 
       // Load a test page containing a link that should be initially
       // blue, per the :link style.
       doPageNavigation({
         uri: getHttpUrl("bug293235.html"),
         onNavComplete: nextTest
       });
       yield undefined;
--- a/dom/apps/PermissionsInstaller.jsm
+++ b/dom/apps/PermissionsInstaller.jsm
@@ -159,17 +159,18 @@ this.PermissionsInstaller = {
             // work even on a system update, with the caveat that if a
             // ALLOW/DENY permission is changed to PROMPT then the system should
             // inform the user that he can now change a permission that he could
             // not change before.
             permValue =
               PermissionSettingsModule.getPermission(expandedPermNames[idx],
                                                      aApp.manifestURL,
                                                      aApp.origin,
-                                                     false);
+                                                     false,
+                                                     aApp.isCachedPackage);
             if (permValue === "unknown") {
               permValue = PERM_TO_STRING[permission];
             }
           }
 
           this._setPermission(expandedPermNames[idx], permValue, aApp);
         }
       }
@@ -187,21 +188,23 @@ this.PermissionsInstaller = {
   /**
    * Set a permission value.
    * @param string aPermName
    *        The permission name.
    * @param string aPermValue
    *        The permission value.
    * @param object aApp
    *        The just-installed app configuration.
-   *        The properties used are manifestURL and origin.
+   *        The properties used are manifestURL, origin, appId, isCachedPackage.
    * @returns void
    **/
   _setPermission: function setPermission(aPermName, aPermValue, aApp) {
     PermissionSettingsModule.addPermission({
       type: aPermName,
       origin: aApp.origin,
       manifestURL: aApp.manifestURL,
       value: aPermValue,
-      browserFlag: false
+      browserFlag: false,
+      localId: aApp.localId,
+      isCachedPackage: aApp.isCachedPackage,
     });
   }
 };
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -3937,17 +3937,17 @@ nsGlobalWindow::GetRealTop(nsIDOMWindow*
 
 void
 nsGlobalWindow::GetContentOuter(JSContext* aCx,
                                 JS::MutableHandle<JSObject*> aRetval,
                                 ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
-  nsCOMPtr<nsIDOMWindow> content = GetContentInternal(aError);
+  nsCOMPtr<nsIDOMWindow> content = GetContentInternal(aError, !nsContentUtils::IsCallerChrome());
   if (aError.Failed()) {
     return;
   }
 
   if (content) {
     JS::Rooted<JS::Value> val(aCx);
     aError = nsContentUtils::WrapNative(aCx, content, &val);
     if (aError.Failed()) {
@@ -3966,17 +3966,17 @@ void
 nsGlobalWindow::GetContent(JSContext* aCx,
                            JS::MutableHandle<JSObject*> aRetval,
                            ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetContentOuter, (aCx, aRetval, aError), aError, );
 }
 
 already_AddRefed<nsIDOMWindow>
-nsGlobalWindow::GetContentInternal(ErrorResult& aError)
+nsGlobalWindow::GetContentInternal(ErrorResult& aError, bool aUnprivilegedCaller)
 {
   MOZ_ASSERT(IsOuterWindow());
 
   // First check for a named frame named "content"
   nsCOMPtr<nsIDOMWindow> domWindow =
     GetChildWindow(NS_LITERAL_STRING("content"));
   if (domWindow) {
     return domWindow.forget();
@@ -3984,17 +3984,17 @@ nsGlobalWindow::GetContentInternal(Error
 
   // If we're contained in <iframe mozbrowser> or <iframe mozapp>, then
   // GetContent is the same as window.top.
   if (mDocShell && mDocShell->GetIsInBrowserOrApp()) {
     return GetTopOuter(aError);
   }
 
   nsCOMPtr<nsIDocShellTreeItem> primaryContent;
-  if (!nsContentUtils::IsCallerChrome()) {
+  if (aUnprivilegedCaller) {
     // If we're called by non-chrome code, make sure we don't return
     // the primary content window if the calling tab is hidden. In
     // such a case we return the same-type root in the hidden tab,
     // which is "good enough", for now.
     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mDocShell));
 
     if (baseWin) {
       bool visible = false;
@@ -4019,27 +4019,16 @@ nsGlobalWindow::GetContentInternal(Error
   if (!primaryContent) {
     return nullptr;
   }
 
   domWindow = primaryContent->GetWindow();
   return domWindow.forget();
 }
 
-NS_IMETHODIMP
-nsGlobalWindow::GetContent(nsIDOMWindow** aContent)
-{
-  FORWARD_TO_OUTER(GetContent, (aContent), NS_ERROR_UNEXPECTED);
-
-  ErrorResult rv;
-  *aContent = GetContentInternal(rv).take();
-
-  return rv.StealNSResult();
-}
-
 MozSelfSupport*
 nsGlobalWindow::GetMozSelfSupport(ErrorResult& aError)
 {
   MOZ_ASSERT(IsInnerWindow());
 
   if (mMozSelfSupport) {
     return mMozSelfSupport;
   }
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -35,16 +35,17 @@
 #include "mozilla/EventListenerManager.h"
 #include "nsIPrincipal.h"
 #include "nsSize.h"
 #include "mozFlushType.h"
 #include "prclist.h"
 #include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/StorageEventBinding.h"
 #include "mozilla/dom/UnionTypes.h"
+#include "mozilla/ErrorResult.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/TimeStamp.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIIdleObserver.h"
 #include "nsIDocument.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/WindowBinding.h"
@@ -333,16 +334,18 @@ public:
   static void
   AssertIsOnMainThread()
 #ifdef DEBUG
   ;
 #else
   { }
 #endif
 
+  static nsGlobalWindow* Cast(nsPIDOMWindow* aPIWin) { return static_cast<nsGlobalWindow*>(aPIWin); }
+
   // public methods
   nsPIDOMWindow* GetPrivateParent();
 
   // callback for close event
   void ReallyCloseWindow();
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -1111,22 +1114,32 @@ public:
                                                  const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
                                                  mozilla::ErrorResult& aError);
   already_AddRefed<nsIDOMWindow> OpenDialog(JSContext* aCx,
                                             const nsAString& aUrl,
                                             const nsAString& aName,
                                             const nsAString& aOptions,
                                             const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
                                             mozilla::ErrorResult& aError);
+
+  already_AddRefed<nsIDOMWindow>
+    GetContentInternal(mozilla::ErrorResult& aError, bool aUnprivilegedCaller);
   void GetContentOuter(JSContext* aCx,
                        JS::MutableHandle<JSObject*> aRetval,
                        mozilla::ErrorResult& aError);
   void GetContent(JSContext* aCx,
                   JS::MutableHandle<JSObject*> aRetval,
                   mozilla::ErrorResult& aError);
+  already_AddRefed<nsIDOMWindow> GetContent()
+  {
+    MOZ_ASSERT(IsOuterWindow());
+    mozilla::ErrorResult ignored;
+    return GetContentInternal(ignored, /* aUnprivilegedCaller = */ false);
+  }
+
   void Get_content(JSContext* aCx,
                    JS::MutableHandle<JSObject*> aRetval,
                    mozilla::ErrorResult& aError)
   {
     if (mDoc) {
       mDoc->WarnOnceAbout(nsIDocument::eWindow_Content);
     }
     GetContent(aCx, aRetval, aError);
@@ -1612,19 +1625,16 @@ protected:
   already_AddRefed<nsIVariant>
     ShowModalDialogOuter(const nsAString& aUrl, nsIVariant* aArgument,
                          const nsAString& aOptions, mozilla::ErrorResult& aError);
 
   already_AddRefed<nsIVariant>
     ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
                     const nsAString& aOptions, mozilla::ErrorResult& aError);
 
-  already_AddRefed<nsIDOMWindow>
-    GetContentInternal(mozilla::ErrorResult& aError);
-
   // Ask the user if further dialogs should be blocked, if dialogs are currently
   // being abused. This is used in the cases where we have no modifiable UI to
   // show, in that case we show a separate dialog to ask this question.
   bool ConfirmDialogIfNeeded();
 
 private:
   // Fire the JS engine's onNewGlobalObject hook.  Only used on inner windows.
   void FireOnNewGlobalObject();
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -480,17 +480,16 @@ class CGDOMJSClass(CGThing):
                 ${flags},
                 ${addProperty}, /* addProperty */
                 nullptr,               /* delProperty */
                 nullptr,               /* getProperty */
                 nullptr,               /* setProperty */
                 ${enumerate}, /* enumerate */
                 ${resolve}, /* resolve */
                 ${mayResolve}, /* mayResolve */
-                nullptr,               /* convert */
                 ${finalize}, /* finalize */
                 ${call}, /* call */
                 nullptr,               /* hasInstance */
                 nullptr,               /* construct */
                 ${trace}, /* trace */
                 JS_NULL_CLASS_SPEC,
                 $*{classExtensionAndObjectOps}
               },
@@ -623,17 +622,16 @@ class CGPrototypeJSClass(CGThing):
                 JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(${slotCount}),
                 nullptr,               /* addProperty */
                 nullptr,               /* delProperty */
                 nullptr,               /* getProperty */
                 nullptr,               /* setProperty */
                 nullptr,               /* enumerate */
                 nullptr,               /* resolve */
                 nullptr,               /* mayResolve */
-                nullptr,               /* convert */
                 nullptr,               /* finalize */
                 nullptr,               /* call */
                 nullptr,               /* hasInstance */
                 nullptr,               /* construct */
                 nullptr,               /* trace */
                 JS_NULL_CLASS_SPEC,
                 JS_NULL_CLASS_EXT,
                 JS_NULL_OBJECT_OPS
@@ -720,17 +718,16 @@ class CGInterfaceObjectJSClass(CGThing):
                 JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(${slotCount}),
                 nullptr,               /* addProperty */
                 nullptr,               /* delProperty */
                 nullptr,               /* getProperty */
                 nullptr,               /* setProperty */
                 nullptr,               /* enumerate */
                 nullptr,               /* resolve */
                 nullptr,               /* mayResolve */
-                nullptr,               /* convert */
                 nullptr,               /* finalize */
                 ${ctorname}, /* call */
                 ${hasInstance}, /* hasInstance */
                 ${ctorname}, /* construct */
                 nullptr,               /* trace */
                 JS_NULL_CLASS_SPEC,
                 JS_NULL_CLASS_EXT,
                 JS_NULL_OBJECT_OPS
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -145,18 +145,16 @@ using mozilla::gl::GLContextProvider;
 using namespace mozilla;
 using namespace mozilla::CanvasUtils;
 using namespace mozilla::css;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 
-namespace mgfx = mozilla::gfx;
-
 namespace mozilla {
 namespace dom {
 
 // Cap sigma to avoid overly large temp surfaces.
 const Float SIGMA_MAX = 100;
 
 /* Memory reporter stuff */
 static int64_t gCanvasAzureMemoryUsed = 0;
@@ -290,20 +288,20 @@ public:
  */
 class AdjustedTargetForFilter
 {
 public:
   typedef CanvasRenderingContext2D::ContextState ContextState;
 
   AdjustedTargetForFilter(CanvasRenderingContext2D *ctx,
                           DrawTarget *aFinalTarget,
-                          const mgfx::IntPoint& aFilterSpaceToTargetOffset,
-                          const mgfx::IntRect& aPreFilterBounds,
-                          const mgfx::IntRect& aPostFilterBounds,
-                          mgfx::CompositionOp aCompositionOp)
+                          const gfx::IntPoint& aFilterSpaceToTargetOffset,
+                          const gfx::IntRect& aPreFilterBounds,
+                          const gfx::IntRect& aPostFilterBounds,
+                          gfx::CompositionOp aCompositionOp)
     : mCtx(nullptr)
     , mCompositionOp(aCompositionOp)
   {
     mCtx = ctx;
     mFinalTarget = aFinalTarget;
     mPostFilterBounds = aPostFilterBounds;
     mOffset = aFilterSpaceToTargetOffset;
 
@@ -341,17 +339,17 @@ public:
     }
 
     mTarget->SetTransform(
       mFinalTarget->GetTransform().PostTranslate(-mSourceGraphicRect.TopLeft() + mOffset));
   }
 
   // Return a SourceSurface that contains the FillPaint or StrokePaint source.
   already_AddRefed<SourceSurface>
-  DoSourcePaint(mgfx::IntRect& aRect, CanvasRenderingContext2D::Style aStyle)
+  DoSourcePaint(gfx::IntRect& aRect, CanvasRenderingContext2D::Style aStyle)
   {
     if (aRect.IsEmpty()) {
       return nullptr;
     }
 
     RefPtr<DrawTarget> dt =
       mFinalTarget->CreateSimilarDrawTarget(aRect.Size(), SurfaceFormat::B8G8R8A8);
     if (!dt) {
@@ -360,18 +358,18 @@ public:
     }
 
     Matrix transform =
       mFinalTarget->GetTransform().PostTranslate(-aRect.TopLeft() + mOffset);
 
     dt->SetTransform(transform);
 
     if (transform.Invert()) {
-      mgfx::Rect dtBounds(0, 0, aRect.width, aRect.height);
-      mgfx::Rect fillRect = transform.TransformBounds(dtBounds);
+      gfx::Rect dtBounds(0, 0, aRect.width, aRect.height);
+      gfx::Rect fillRect = transform.TransformBounds(dtBounds);
       dt->FillRect(fillRect, CanvasGeneralPattern().ForStyle(mCtx, aStyle, dt));
     }
     return dt->Snapshot();
   }
 
   ~AdjustedTargetForFilter()
   {
     if (!mCtx) {
@@ -383,19 +381,19 @@ public:
     RefPtr<SourceSurface> fillPaint =
       DoSourcePaint(mFillPaintRect, CanvasRenderingContext2D::Style::FILL);
     RefPtr<SourceSurface> strokePaint =
       DoSourcePaint(mStrokePaintRect, CanvasRenderingContext2D::Style::STROKE);
 
     AutoRestoreTransform autoRestoreTransform(mFinalTarget);
     mFinalTarget->SetTransform(Matrix());
 
-    mgfx::FilterSupport::RenderFilterDescription(
+    gfx::FilterSupport::RenderFilterDescription(
       mFinalTarget, mCtx->CurrentState().filter,
-      mgfx::Rect(mPostFilterBounds),
+      gfx::Rect(mPostFilterBounds),
       snapshot, mSourceGraphicRect,
       fillPaint, mFillPaintRect,
       strokePaint, mStrokePaintRect,
       mCtx->CurrentState().filterAdditionalImages,
       mPostFilterBounds.TopLeft() - mOffset,
       DrawOptions(1.0f, mCompositionOp));
   }
 
@@ -403,48 +401,48 @@ public:
   {
     return mTarget;
   }
 
 private:
   RefPtr<DrawTarget> mTarget;
   RefPtr<DrawTarget> mFinalTarget;
   CanvasRenderingContext2D *mCtx;
-  mgfx::IntRect mSourceGraphicRect;
-  mgfx::IntRect mFillPaintRect;
-  mgfx::IntRect mStrokePaintRect;
-  mgfx::IntRect mPostFilterBounds;
-  mgfx::IntPoint mOffset;
-  mgfx::CompositionOp mCompositionOp;
+  gfx::IntRect mSourceGraphicRect;
+  gfx::IntRect mFillPaintRect;
+  gfx::IntRect mStrokePaintRect;
+  gfx::IntRect mPostFilterBounds;
+  gfx::IntPoint mOffset;
+  gfx::CompositionOp mCompositionOp;
 };
 
 /* This is an RAII based class that can be used as a drawtarget for
  * operations that need to have a shadow applied to their results.
  * All coordinates passed to the constructor are in device space.
  */
 class AdjustedTargetForShadow
 {
 public:
   typedef CanvasRenderingContext2D::ContextState ContextState;
 
   AdjustedTargetForShadow(CanvasRenderingContext2D *ctx,
                           DrawTarget *aFinalTarget,
-                          const mgfx::Rect& aBounds,
-                          mgfx::CompositionOp aCompositionOp)
+                          const gfx::Rect& aBounds,
+                          gfx::CompositionOp aCompositionOp)
     : mCtx(nullptr)
     , mCompositionOp(aCompositionOp)
   {
     mCtx = ctx;
     mFinalTarget = aFinalTarget;
 
     const ContextState &state = mCtx->CurrentState();
 
     mSigma = state.ShadowBlurSigma();
 
-    mgfx::Rect bounds = aBounds;
+    gfx::Rect bounds = aBounds;
 
     int32_t blurRadius = state.ShadowBlurRadius();
 
     // We actually include the bounds of the shadow blur, this makes it
     // easier to execute the actual blur on hardware, and shouldn't affect
     // the amount of pixels that need to be touched.
     bounds.Inflate(blurRadius);
 
@@ -481,28 +479,28 @@ public:
                                         mCompositionOp);
   }
 
   DrawTarget* DT()
   {
     return mTarget;
   }
 
-  mgfx::IntPoint OffsetToFinalDT()
+  gfx::IntPoint OffsetToFinalDT()
   {
     return mTempRect.TopLeft();
   }
 
 private:
   RefPtr<DrawTarget> mTarget;
   RefPtr<DrawTarget> mFinalTarget;
   CanvasRenderingContext2D *mCtx;
   Float mSigma;
-  mgfx::IntRect mTempRect;
-  mgfx::CompositionOp mCompositionOp;
+  gfx::IntRect mTempRect;
+  gfx::CompositionOp mCompositionOp;
 };
 
 /* This is an RAII based class that can be used as a drawtarget for
  * operations that need a shadow or a filter drawn. It will automatically
  * provide a temporary target when needed, and if so blend it back with a
  * shadow, filter, or both.
  * If both a shadow and a filter are needed, the filter is applied first,
  * and the shadow is applied to the filtered results.
@@ -512,67 +510,67 @@ private:
  * drawing operation will be assumed to cover the whole canvas.
  */
 class AdjustedTarget
 {
 public:
   typedef CanvasRenderingContext2D::ContextState ContextState;
 
   explicit AdjustedTarget(CanvasRenderingContext2D* ctx,
-                          const mgfx::Rect *aBounds = nullptr)
+                          const gfx::Rect *aBounds = nullptr)
   {
     mTarget = ctx->mTarget;
 
     // All rects in this function are in the device space of ctx->mTarget.
 
     // In order to keep our temporary surfaces as small as possible, we first
     // calculate what their maximum required bounds would need to be if we
     // were to fill the whole canvas. Everything outside those bounds we don't
     // need to render.
-    mgfx::Rect r(0, 0, ctx->mWidth, ctx->mHeight);
-    mgfx::Rect maxSourceNeededBoundsForShadow =
+    gfx::Rect r(0, 0, ctx->mWidth, ctx->mHeight);
+    gfx::Rect maxSourceNeededBoundsForShadow =
       MaxSourceNeededBoundsForShadow(r, ctx);
-    mgfx::Rect maxSourceNeededBoundsForFilter =
+    gfx::Rect maxSourceNeededBoundsForFilter =
       MaxSourceNeededBoundsForFilter(maxSourceNeededBoundsForShadow, ctx);
 
-    mgfx::Rect bounds = maxSourceNeededBoundsForFilter;
+    gfx::Rect bounds = maxSourceNeededBoundsForFilter;
     if (aBounds) {
       bounds = bounds.Intersect(*aBounds);
     }
-    mgfx::Rect boundsAfterFilter = BoundsAfterFilter(bounds, ctx);
+    gfx::Rect boundsAfterFilter = BoundsAfterFilter(bounds, ctx);
 
     mozilla::gfx::CompositionOp op = ctx->CurrentState().op;
 
-    mgfx::IntPoint offsetToFinalDT;
+    gfx::IntPoint offsetToFinalDT;
 
     // First set up the shadow draw target, because the shadow goes outside.
     // It applies to the post-filter results, if both a filter and a shadow
     // are used.
     if (ctx->NeedToDrawShadow()) {
       mShadowTarget = MakeUnique<AdjustedTargetForShadow>(
         ctx, mTarget, boundsAfterFilter, op);
       mTarget = mShadowTarget->DT();
       offsetToFinalDT = mShadowTarget->OffsetToFinalDT();
 
       // If we also have a filter, the filter needs to be drawn with OP_OVER
       // because shadow drawing already applies op on the result.
-      op = mgfx::CompositionOp::OP_OVER;
+      op = gfx::CompositionOp::OP_OVER;
     }
 
     // Now set up the filter draw target.
     if (ctx->NeedToApplyFilter()) {
       bounds.RoundOut();
 
-      mgfx::IntRect intBounds;
+      gfx::IntRect intBounds;
       if (!bounds.ToIntRect(&intBounds)) {
         return;
       }
       mFilterTarget = MakeUnique<AdjustedTargetForFilter>(
         ctx, mTarget, offsetToFinalDT, intBounds,
-        mgfx::RoundedToInt(boundsAfterFilter), op);
+        gfx::RoundedToInt(boundsAfterFilter), op);
       mTarget = mFilterTarget->DT();
     }
   }
 
   ~AdjustedTarget()
   {
     // The order in which the targets are finalized is important.
     // Filters are inside, any shadow applies to the post-filter results.
@@ -587,69 +585,69 @@ public:
 
   DrawTarget* operator->() MOZ_NO_ADDREF_RELEASE_ON_RETURN
   {
     return mTarget;
   }
 
 private:
 
-  mgfx::Rect
-  MaxSourceNeededBoundsForFilter(const mgfx::Rect& aDestBounds, CanvasRenderingContext2D *ctx)
+  gfx::Rect
+  MaxSourceNeededBoundsForFilter(const gfx::Rect& aDestBounds, CanvasRenderingContext2D *ctx)
   {
     if (!ctx->NeedToApplyFilter()) {
       return aDestBounds;
     }
 
     nsIntRegion sourceGraphicNeededRegion;
     nsIntRegion fillPaintNeededRegion;
     nsIntRegion strokePaintNeededRegion;
 
     FilterSupport::ComputeSourceNeededRegions(
-      ctx->CurrentState().filter, mgfx::RoundedToInt(aDestBounds),
+      ctx->CurrentState().filter, gfx::RoundedToInt(aDestBounds),
       sourceGraphicNeededRegion, fillPaintNeededRegion, strokePaintNeededRegion);
 
-    return mgfx::Rect(sourceGraphicNeededRegion.GetBounds());
-  }
-
-  mgfx::Rect
-  MaxSourceNeededBoundsForShadow(const mgfx::Rect& aDestBounds, CanvasRenderingContext2D *ctx)
+    return gfx::Rect(sourceGraphicNeededRegion.GetBounds());
+  }
+
+  gfx::Rect
+  MaxSourceNeededBoundsForShadow(const gfx::Rect& aDestBounds, CanvasRenderingContext2D *ctx)
   {
     if (!ctx->NeedToDrawShadow()) {
       return aDestBounds;
     }
 
     const ContextState &state = ctx->CurrentState();
-    mgfx::Rect sourceBounds = aDestBounds - state.shadowOffset;
+    gfx::Rect sourceBounds = aDestBounds - state.shadowOffset;
     sourceBounds.Inflate(state.ShadowBlurRadius());
 
     // Union the shadow source with the original rect because we're going to
     // draw both.
     return sourceBounds.Union(aDestBounds);
   }
 
-  mgfx::Rect
-  BoundsAfterFilter(const mgfx::Rect& aBounds, CanvasRenderingContext2D *ctx)
+  gfx::Rect
+  BoundsAfterFilter(const gfx::Rect& aBounds, CanvasRenderingContext2D *ctx)
   {
     if (!ctx->NeedToApplyFilter()) {
       return aBounds;
     }
 
-    mgfx::Rect bounds(aBounds);
+    gfx::Rect bounds(aBounds);
     bounds.RoundOut();
 
-    mgfx::IntRect intBounds;
+    gfx::IntRect intBounds;
     if (!bounds.ToIntRect(&intBounds)) {
-      return mgfx::Rect();
+      return gfx::Rect();
     }
 
     nsIntRegion extents =
-      mgfx::FilterSupport::ComputePostFilterExtents(ctx->CurrentState().filter,
-                                                    intBounds);
-    return mgfx::Rect(extents.GetBounds());
+      gfx::FilterSupport::ComputePostFilterExtents(ctx->CurrentState().filter,
+                                                   intBounds);
+    return gfx::Rect(extents.GetBounds());
   }
 
   RefPtr<DrawTarget> mTarget;
   UniquePtr<AdjustedTargetForShadow> mShadowTarget;
   UniquePtr<AdjustedTargetForFilter> mFilterTarget;
 };
 
 void
@@ -1133,17 +1131,17 @@ CanvasRenderingContext2D::Redraw()
   nsSVGEffects::InvalidateDirectRenderingObservers(mCanvasElement);
 
   mCanvasElement->InvalidateCanvasContent(nullptr);
 
   return NS_OK;
 }
 
 void
-CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
+CanvasRenderingContext2D::Redraw(const gfx::Rect &r)
 {
   mIsCapturedFrameInvalid = true;
 
   ++mInvalidateCount;
 
   if (mIsEntireFrameInvalid) {
     return;
   }
@@ -1181,18 +1179,17 @@ CanvasRenderingContext2D::RedrawUser(con
 {
   mIsCapturedFrameInvalid = true;
 
   if (mIsEntireFrameInvalid) {
     ++mInvalidateCount;
     return;
   }
 
-  mgfx::Rect newr =
-    mTarget->GetTransform().TransformBounds(ToRect(r));
+  gfx::Rect newr = mTarget->GetTransform().TransformBounds(ToRect(r));
   Redraw(newr);
 }
 
 bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
 {
   if (!IsTargetValid() || mRenderingMode == aRenderingMode) {
     return false;
   }
@@ -1229,17 +1226,17 @@ bool CanvasRenderingContext2D::SwitchRen
   RenderingMode attemptedMode = EnsureTarget(aRenderingMode);
   if (!IsTargetValid())
     return false;
 
   // We succeeded, so update mRenderingMode to reflect reality
   mRenderingMode = attemptedMode;
 
   // Restore the content from the old DrawTarget
-  mgfx::Rect r(0, 0, mWidth, mHeight);
+  gfx::Rect r(0, 0, mWidth, mHeight);
   mTarget->DrawSurface(snapshot, r, r);
 
   // Restore the clips and transform
   for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) {
     mTarget->PushClip(CurrentState().clipsPushed[i]);
   }
 
   mTarget->SetTransform(transform);
@@ -1444,25 +1441,25 @@ CanvasRenderingContext2D::EnsureTarget(R
     }
 
     gCanvasAzureMemoryUsed += mWidth * mHeight * 4;
     JSContext* context = nsContentUtils::GetCurrentJSContext();
     if (context) {
       JS_updateMallocCounter(context, mWidth * mHeight * 4);
     }
 
-    mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
-    if (mTarget->GetBackendType() == mgfx::BackendType::CAIRO) {
+    mTarget->ClearRect(gfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
+    if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) {
       // Cairo doesn't play well with huge clips. When given a very big clip it
       // will try to allocate big mask surface without taking the target
       // size into account which can cause OOM. See bug 1034593.
       // This limits the clip extents to the size of the canvas.
       // A fix in Cairo would probably be preferable, but requires somewhat
       // invasive changes.
-      mTarget->PushClipRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
+      mTarget->PushClipRect(gfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
     }
     // Force a full layer transaction since we didn't have a layer before
     // and now we might need one.
     if (mCanvasElement) {
       mCanvasElement->InvalidateCanvas();
     }
     // Calling Redraw() tells our invalidation machinery that the entire
     // canvas is already invalid, which can speed up future drawing.
@@ -1575,19 +1572,19 @@ CanvasRenderingContext2D::InitializeWith
   mTarget = gfxPlatform::GetPlatform()->
     CreateDrawTargetForSurface(surface, IntSize(width, height));
 
   if (!mTarget) {
     EnsureErrorTarget();
     mTarget = sErrorTarget;
   }
 
-  if (mTarget->GetBackendType() == mgfx::BackendType::CAIRO) {
+  if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) {
     // Cf comment in EnsureTarget
-    mTarget->PushClipRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
+    mTarget->PushClipRect(gfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetIsOpaque(bool isOpaque)
 {
@@ -2515,17 +2512,17 @@ NormalizeRect(double& aX, double& aY, do