Merge m-c to oak
authorRobert Strong <robert.bugzilla@gmail.com>
Sun, 05 Jul 2015 00:08:36 -0700
changeset 491437 5f977a5e2d5e89b882e6746102ddb15dcc36de82
parent 491436 702bff9373fdd634da6f24df78e801667a4102de (current diff)
parent 275753 136c41fca8538192642e3a71534967525a9bae9a (diff)
child 491438 19e465c824f160898d0e4ae960f0732a33ff1496
push id47343
push userbmo:dothayer@mozilla.com
push dateWed, 01 Mar 2017 22:58:58 +0000
milestone42.0a1
Merge m-c to oak
CLOBBER
dom/bluetooth/BluetoothUtils.cpp
dom/bluetooth/BluetoothUtils.h
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/xre/nsAppRunner.cpp
tools/profiler/AutoObjectMapper.cpp
tools/profiler/AutoObjectMapper.h
tools/profiler/EHABIStackWalk.cpp
tools/profiler/EHABIStackWalk.h
tools/profiler/GeckoProfiler.h
tools/profiler/GeckoProfilerFunc.h
tools/profiler/GeckoProfilerImpl.h
tools/profiler/GeckoTaskTracer.cpp
tools/profiler/GeckoTaskTracer.h
tools/profiler/GeckoTaskTracerImpl.h
tools/profiler/IntelPowerGadget.cpp
tools/profiler/IntelPowerGadget.h
tools/profiler/LulCommon.cpp
tools/profiler/LulCommonExt.h
tools/profiler/LulDwarf.cpp
tools/profiler/LulDwarfExt.h
tools/profiler/LulDwarfInt.h
tools/profiler/LulDwarfSummariser.cpp
tools/profiler/LulDwarfSummariser.h
tools/profiler/LulElf.cpp
tools/profiler/LulElfExt.h
tools/profiler/LulElfInt.h
tools/profiler/LulMain.cpp
tools/profiler/LulMain.h
tools/profiler/LulMainInt.h
tools/profiler/LulPlatformMacros.h
tools/profiler/PlatformMacros.h
tools/profiler/ProfileEntry.cpp
tools/profiler/ProfileEntry.h
tools/profiler/ProfileGatherer.cpp
tools/profiler/ProfileGatherer.h
tools/profiler/ProfileJSONWriter.cpp
tools/profiler/ProfileJSONWriter.h
tools/profiler/Profiler.jsm
tools/profiler/ProfilerBacktrace.cpp
tools/profiler/ProfilerBacktrace.h
tools/profiler/ProfilerIOInterposeObserver.cpp
tools/profiler/ProfilerIOInterposeObserver.h
tools/profiler/ProfilerMarkers.cpp
tools/profiler/ProfilerMarkers.h
tools/profiler/PseudoStack.h
tools/profiler/SaveProfileTask.cpp
tools/profiler/SaveProfileTask.h
tools/profiler/SourceEventTypeMap.h
tools/profiler/SyncProfile.cpp
tools/profiler/SyncProfile.h
tools/profiler/TableTicker.cpp
tools/profiler/TableTicker.h
tools/profiler/ThreadResponsiveness.cpp
tools/profiler/ThreadResponsiveness.h
tools/profiler/TracedTaskCommon.cpp
tools/profiler/TracedTaskCommon.h
tools/profiler/local_debug_info_symbolizer.cc
tools/profiler/local_debug_info_symbolizer.h
tools/profiler/nsIProfileSaveEvent.idl
tools/profiler/nsIProfiler.idl
tools/profiler/nsProfiler.cpp
tools/profiler/nsProfiler.h
tools/profiler/nsProfilerCIID.h
tools/profiler/nsProfilerFactory.cpp
tools/profiler/nsProfilerStartParams.cpp
tools/profiler/nsProfilerStartParams.h
tools/profiler/platform-linux-lul.cpp
tools/profiler/platform-linux-lul.h
tools/profiler/platform-linux.cc
tools/profiler/platform-macos.cc
tools/profiler/platform-win32.cc
tools/profiler/platform.cpp
tools/profiler/platform.h
tools/profiler/shared-libraries-linux.cc
tools/profiler/shared-libraries-macos.cc
tools/profiler/shared-libraries-win32.cc
tools/profiler/shared-libraries.h
tools/profiler/shim_mac_dump_syms.h
tools/profiler/shim_mac_dump_syms.mm
tools/profiler/v8-support.h
xpcom/build/XPCOMInit.cpp
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1178215 requires clobber for libvpx file moves.
+Bug 1178892 requires clobber for profiler file moves.
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -1260,17 +1260,17 @@ nsAccessibilityService::Init()
 
   for (uint32_t i = 0; i < ArrayLength(sMarkupMapList); i++)
     mMarkupMaps.Put(*sMarkupMapList[i].tag, &sMarkupMapList[i]);
 
 #ifdef A11Y_LOG
   logging::CheckEnv();
 #endif
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default)
+  if (XRE_IsParentProcess())
     gApplicationAccessible = new ApplicationAccessibleWrap();
   else
     gApplicationAccessible = new ApplicationAccessible();
 
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
 
 #ifdef MOZ_CRASHREPORTER
   CrashReporter::
@@ -1281,17 +1281,17 @@ nsAccessibilityService::Init()
 #ifdef XP_WIN
   sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >;
   sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
 #endif
 
   gIsShutdown = false;
 
   // Now its safe to start platform accessibility.
-  if (XRE_GetProcessType() == GeckoProcessType_Default)
+  if (XRE_IsParentProcess())
     PlatformInit();
 
   return true;
 }
 
 void
 nsAccessibilityService::Shutdown()
 {
@@ -1324,17 +1324,17 @@ nsAccessibilityService::Shutdown()
   // accessibility service as shutdown to prevent calls of its methods.
   // Don't null accessibility service static member at this point to be safe
   // if someone will try to operate with it.
 
   NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
 
   gIsShutdown = true;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default)
+  if (XRE_IsParentProcess())
     PlatformShutdown();
 
   gApplicationAccessible->Shutdown();
   NS_RELEASE(gApplicationAccessible);
   gApplicationAccessible = nullptr;
 
   NS_IF_RELEASE(gXPCApplicationAccessible);
   gXPCApplicationAccessible = nullptr;
--- a/accessible/base/nsAccessibilityService.h
+++ b/accessible/base/nsAccessibilityService.h
@@ -277,17 +277,17 @@ GetAccService()
  * Return true if we're in a content process and not B2G.
  */
 inline bool
 IPCAccessibilityActive()
 {
 #ifdef MOZ_B2G
   return false;
 #else
-  return XRE_GetProcessType() == GeckoProcessType_Content &&
+  return XRE_IsContentProcess() &&
     mozilla::Preferences::GetBool("accessibility.ipc_architecture.enabled", true);
 #endif
 }
 
 /**
  * Map nsIAccessibleEvents constants to strings. Used by
  * nsIAccessibleRetrieval::getStringEventType() method.
  */
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -420,17 +420,17 @@ bool
 nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode)
 {
   nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell());
 
   nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
   treeItem->GetParent(getter_AddRefs(parentTreeItem));
 
   // Tab document running in own process doesn't have parent.
-  if (XRE_GetProcessType() == GeckoProcessType_Content)
+  if (XRE_IsContentProcess())
     return !parentTreeItem;
 
   // Parent of docshell for tab document running in chrome process is root.
   nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
   treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
 
   return parentTreeItem == rootTreeItem;
 }
--- a/accessible/windows/msaa/nsWinUtils.cpp
+++ b/accessible/windows/msaa/nsWinUtils.cpp
@@ -59,17 +59,17 @@ nsWinUtils::MaybeStartWindowEmulation()
 {
   // Register window class that'll be used for document accessibles associated
   // with tabs.
   if (IPCAccessibilityActive())
     return false;
 
   if (Compatibility::IsJAWS() || Compatibility::IsWE() ||
       Compatibility::IsDolphin() ||
-      XRE_GetProcessType() == GeckoProcessType_Content) {
+      XRE_IsContentProcess()) {
     RegisterNativeWindow(kClassNameTabContent);
     sHWNDCache = new nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible>(2);
     return true;
   }
 
   return false;
 }
 
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,17 +10,17 @@
   <!--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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--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="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <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="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--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="4efd19d199ae52656604f794c5a77518400220fd">
     <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="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- 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"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--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="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--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="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <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="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "75071a1117605a7ac79c51025caf6ffcfc4dfa95", 
+        "git_revision": "dc6c18c0dea7af3c40bfff86c530fd877d899dc4", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "22c58f4fec82075c7110bbc59ca7f6aad0a232a8", 
+    "revision": "eed37c94d1a7e2581513af12d3bedaa9342dee43", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--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="4efd19d199ae52656604f794c5a77518400220fd">
     <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="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- 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"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--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="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75071a1117605a7ac79c51025caf6ffcfc4dfa95"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dc6c18c0dea7af3c40bfff86c530fd877d899dc4"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1433888926000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1435698725000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i71" id="youtube@2youtube.com">
@@ -3044,16 +3044,28 @@
       <pluginItem  blockID="p910">
       <match name="name" exp="Java(\(TM\))? Plug-in 10\.(4[5-9]|(5|6)\d|7[0-8])(\.[0-9]+)?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
                             <infoURL>https://java.com/</infoURL>
           </pluginItem>
       <pluginItem  blockID="p912">
       <match name="name" exp="Java(\(TM\))? Plug-in 11\.(\d|[1-3]\d|4[0-4])(\.[0-9]+)?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
                             <infoURL>https://java.com/</infoURL>
           </pluginItem>
+      <pluginItem  blockID="p928">
+                  <match name="filename" exp="(NPSWF32.*\.dll)|(Flash\ Player\.plugin)" />                      <versionRange  minVersion="13.0.0.269" maxVersion="13.0.0.295" severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://get.adobe.com/flashplayer/</infoURL>
+          </pluginItem>
+      <pluginItem  blockID="p930">
+                  <match name="filename" exp="(NPSWF32.*\.dll)|(Flash\ Player\.plugin)" />                      <versionRange  minVersion="16.0.0.305" maxVersion="18.0.0.193" severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://get.adobe.com/flashplayer/</infoURL>
+          </pluginItem>
+      <pluginItem  os="Linux" blockID="p932">
+                  <match name="filename" exp="libflashplayer\.so" />                      <versionRange  minVersion="11.2.202.442" maxVersion="11.2.202.467" severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://get.adobe.com/flashplayer/</infoURL>
+          </pluginItem>
     </pluginItems>
 
   <gfxItems>
     <gfxBlacklistEntry  blockID="g35">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
                       <device>0x0a6c</device>
                   </devices>
             <feature>DIRECT2D</feature>      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>      <driverVersion>8.17.12.5896</driverVersion>      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>    </gfxBlacklistEntry>
     <gfxBlacklistEntry  blockID="g36">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
--- a/browser/base/content/browser-fullScreen.js
+++ b/browser/base/content/browser-fullScreen.js
@@ -350,21 +350,20 @@ var FullScreen = {
         // session only. Add the permission (so Gecko knows to approve any further
         // fullscreen requests for this host in this fullscreen session) but add
         // a listener to revoke the permission when the chrome document exits
         // fullscreen.
         Services.perms.add(uri,
                            "fullscreen",
                            Services.perms.ALLOW_ACTION,
                            Services.perms.EXPIRE_SESSION);
-        let host = uri.host;
         var onFullscreenchange = function onFullscreenchange(event) {
           if (event.target == document && document.mozFullScreenElement == null) {
             // The chrome document has left fullscreen. Remove the temporary permission grant.
-            Services.perms.remove(host, "fullscreen");
+            Services.perms.remove(uri, "fullscreen");
             document.removeEventListener("mozfullscreenchange", onFullscreenchange);
           }
         }
         document.addEventListener("mozfullscreenchange", onFullscreenchange);
       }
     }
     if (this.warningBox)
       this.warningBox.setAttribute("fade-warning-out", "true");
--- a/browser/base/content/browser-trackingprotection.js
+++ b/browser/base/content/browser-trackingprotection.js
@@ -80,17 +80,17 @@ let TrackingProtection = {
 
     BrowserReload();
   },
 
   enableForCurrentPage() {
     // Remove the current host from the 'trackingprotection' consumer
     // of the permission manager. This effectively removes this host
     // from the tracking protection allowlist.
-    Services.perms.remove(gBrowser.selectedBrowser.currentURI.host,
+    Services.perms.remove(gBrowser.selectedBrowser.currentURI,
       "trackingprotection");
 
     // Telemetry for enable protection.
     this.eventsHistogram.add(2);
 
     BrowserReload();
   },
 };
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -857,17 +857,17 @@ function onBlockImage()
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
 
   var checkbox = document.getElementById("blockImage");
   var uri = makeURI(document.getElementById("imageurltext").value);
   if (checkbox.checked)
     permissionManager.add(uri, "image", nsIPermissionManager.DENY_ACTION);
   else
-    permissionManager.remove(uri.host, "image");
+    permissionManager.remove(uri, "image");
 }
 
 function onImageSelect()
 {
   var previewBox   = document.getElementById("mediaPreviewBox");
   var mediaSaveBox = document.getElementById("mediaSaveBox");
   var splitter     = document.getElementById("mediaSplitter");
   var tree = document.getElementById("imagetree");
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -278,17 +278,17 @@ function test_whitelisted_install() {
         is(notification.getAttribute("label"),
            "XPI Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
-          Services.perms.remove("example.com", "install");
+          Services.perms.remove(makeURI("http://example.com/"), "install");
           wait_for_notification_close(runNextTest);
           gBrowser.removeTab(gBrowser.selectedTab);
         });
       });
 
       accept_install_dialog();
     });
   });
@@ -310,17 +310,17 @@ function test_failed_download() {
   wait_for_progress_notification(function(aPanel) {
     // Wait for the failed notification
     wait_for_notification("addon-install-failed", function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.getAttribute("label"),
          "The add-on could not be downloaded because of a connection failure.",
          "Should have seen the right message");
 
-      Services.perms.remove("example.com", "install");
+      Services.perms.remove(makeURI("http://example.com/"), "install");
       wait_for_notification_close(runNextTest);
       gBrowser.removeTab(gBrowser.selectedTab);
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
@@ -337,17 +337,17 @@ function test_corrupt_file() {
     // Wait for the failed notification
     wait_for_notification("addon-install-failed", function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.getAttribute("label"),
          "The add-on downloaded from this site could not be installed " +
          "because it appears to be corrupt.",
          "Should have seen the right message");
 
-      Services.perms.remove("example.com", "install");
+      Services.perms.remove(makeURI("http://example.com/"), "install");
       wait_for_notification_close(runNextTest);
       gBrowser.removeTab(gBrowser.selectedTab);
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
@@ -364,17 +364,17 @@ function test_incompatible() {
     // Wait for the failed notification
     wait_for_notification("addon-install-failed", function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.getAttribute("label"),
          "XPI Test could not be installed because it is not compatible with " +
          gApp + " " + gVersion + ".",
          "Should have seen the right message");
 
-      Services.perms.remove("example.com", "install");
+      Services.perms.remove(makeURI("http://example.com/"), "install");
       wait_for_notification_close(runNextTest);
       gBrowser.removeTab(gBrowser.selectedTab);
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
@@ -398,17 +398,17 @@ function test_restartless() {
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 0, "Should be no pending installs");
 
           AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
             aAddon.uninstall();
 
-            Services.perms.remove("example.com", "install");
+            Services.perms.remove(makeURI("http://example.com/"), "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         });
       });
 
       accept_install_dialog();
     });
@@ -439,17 +439,17 @@ function test_multiple() {
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
           AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
             aAddon.uninstall();
 
-            Services.perms.remove("example.com", "install");
+            Services.perms.remove(makeURI("http://example.com/"), "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         });
       });
 
       accept_install_dialog();
     });
@@ -511,17 +511,17 @@ function test_sequential() {
             is(PopupNotifications.panel.childNodes.length, 1, "Should be the right number of notifications");
             is(PopupNotifications.panel.childNodes[0].id, "addon-install-confirmation-notification",
                "Should still have an install confirmation open");
 
             // Should have the next add-on's confirmation dialog
             is(container.childNodes.length, 1, "Should be one item listed");
             is(container.childNodes[0].firstChild.getAttribute("value"), "Theme Test", "Should have the right add-on");
 
-            Services.perms.remove("example.com", "install");
+            Services.perms.remove(makeURI("http://example.com"), "install");
             wait_for_notification_close(() => {
               gBrowser.removeTab(gBrowser.selectedTab);
               runNextTest();
             });
 
             cancel_install_dialog();
           });
         }, "addon-install-confirmation", false);
@@ -575,17 +575,17 @@ function test_someunverified() {
         AddonManager.getAddonsByIDs(["restartless-xpi@tests.mozilla.org",
                                      "theme-xpi@tests.mozilla.org"], function([a, t]) {
           a.uninstall();
           // Installing a new theme tries to switch to it, switch back to the
           // default theme.
           t.userDisabled = true;
           t.uninstall();
 
-          Services.perms.remove("example.com", "install");
+          Services.perms.remove(makeURI("http://example.com/"), "install");
           wait_for_notification_close(runNextTest);
           gBrowser.removeTab(gBrowser.selectedTab);
         });
       });
 
       accept_install_dialog();
     });
   });
@@ -623,17 +623,17 @@ function test_allunverified() {
       is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
       is(container.childNodes[0].childNodes.length, 1, "Shouldn't have the unverified marker");
 
       // Wait for the complete notification
       wait_for_notification("addon-install-complete", function(aPanel) {
         AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(aAddon) {
           aAddon.uninstall();
 
-          Services.perms.remove("example.com", "install");
+          Services.perms.remove(makeURI("http://example.com/"), "install");
           wait_for_notification_close(runNextTest);
           gBrowser.removeTab(gBrowser.selectedTab);
         });
       });
 
       accept_install_dialog();
     });
   });
@@ -790,17 +790,17 @@ function test_reload() {
           gBrowser.removeEventListener("load", arguments.callee, true);
 
           PopupNotifications.panel.removeEventListener("popuphiding", test_fail, false);
 
           AddonManager.getAllInstalls(function(aInstalls) {
             is(aInstalls.length, 1, "Should be one pending install");
             aInstalls[0].cancel();
 
-            Services.perms.remove("example.com", "install");
+            Services.perms.remove(makeURI("http://example.com/"), "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         }, true);
         gBrowser.loadURI(TESTROOT2 + "enabled.html");
       });
 
       accept_install_dialog();
@@ -834,17 +834,17 @@ function test_theme() {
           ok(aAddon.userDisabled, "Should be switching away from the default theme.");
           // Undo the pending theme switch
           aAddon.userDisabled = false;
 
           AddonManager.getAddonByID("theme-xpi@tests.mozilla.org", function(aAddon) {
             isnot(aAddon, null, "Test theme will have been installed");
             aAddon.uninstall();
 
-            Services.perms.remove("example.com", "install");
+            Services.perms.remove(makeURI("http://example.com/"), "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         });
       });
 
       accept_install_dialog();
     });
@@ -913,17 +913,17 @@ function test_renotify_installed() {
                 info("Timeouts after this probably mean bug 589954 regressed");
 
                 // Wait for the complete notification
                 wait_for_notification("addon-install-restart", function(aPanel) {
                   AddonManager.getAllInstalls(function(aInstalls) {
                   is(aInstalls.length, 1, "Should be one pending installs");
                     aInstalls[0].cancel();
 
-                    Services.perms.remove("example.com", "install");
+                    Services.perms.remove(makeURI("http://example.com/"), "install");
                     wait_for_notification_close(runNextTest);
                     gBrowser.removeTab(gBrowser.selectedTab);
                   });
                 });
 
                 accept_install_dialog();
               });
             });
@@ -981,17 +981,17 @@ function test_cancel() {
         install.removeListener(this);
 
         executeSoon(function() {
           ok(!PopupNotifications.isPanelOpen, "Notification should be closed");
 
           AddonManager.getAllInstalls(function(aInstalls) {
             is(aInstalls.length, 0, "Should be no pending install");
 
-            Services.perms.remove("example.com", "install");
+            Services.perms.remove(makeURI("http://example.com/"), "install");
             gBrowser.removeTab(gBrowser.selectedTab);
             runNextTest();
           });
         });
       }
     });
 
     // Cancel the download
--- a/browser/base/content/test/general/browser_bug592338.js
+++ b/browser/base/content/test/general/browser_bug592338.js
@@ -32,17 +32,17 @@ function test_install_http() {
     executeSoon(function() {
       var link = gBrowser.contentDocument.getElementById("theme-install");
       EventUtils.synthesizeMouse(link, 2, 2, {}, gBrowser.contentWindow);
 
       is(LightweightThemeManager.currentTheme, null, "Should not have installed the test theme");
 
       gBrowser.removeTab(gBrowser.selectedTab);
 
-      pm.remove("example.org", "install");
+      pm.remove(makeURI("http://example.org/"), "install");
 
       runNextTest();
     });
   }, false);
 },
 
 function test_install_lwtheme() {
   is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected");
@@ -61,17 +61,17 @@ function test_install_lwtheme() {
       var link = gBrowser.contentDocument.getElementById("theme-install");
       EventUtils.synthesizeMouse(link, 2, 2, {}, gBrowser.contentWindow);
 
       is(LightweightThemeManager.currentTheme.id, "test", "Should have installed the test theme");
 
       LightweightThemeManager.currentTheme = null;
       gBrowser.removeTab(gBrowser.selectedTab);
 
-      Services.perms.remove("example.com", "install");
+      Services.perms.remove(makeURI("http://example.com/"), "install");
 
       runNextTest();
     });
   }, false);
 },
 
 function test_lwtheme_switch_theme() {
   is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected");
@@ -101,17 +101,17 @@ function test_lwtheme_switch_theme() {
           is(notification.button.label, "Restart Now", "Should have seen the right button");
 
           ok(aAddon.userDisabled, "Should be waiting to disable the test theme");
           aAddon.userDisabled = false;
           Services.prefs.setBoolPref("extensions.dss.enabled", true);
 
           gBrowser.removeTab(gBrowser.selectedTab);
 
-          Services.perms.remove("example.com", "install");
+          Services.perms.remove(makeURI("http://example.com"), "install");
 
           runNextTest();
         });
         EventUtils.synthesizeMouse(link, 2, 2, {}, gBrowser.contentWindow);
       });
     }, false);
   });
 }
--- a/browser/base/content/test/general/browser_devices_get_user_media.js
+++ b/browser/base/content/test/general/browser_devices_get_user_media.js
@@ -562,17 +562,17 @@ let gTests = [
         let uri = content.document.documentURIObject;
         let devicePerms = Perms.testExactPermission(uri, aDevice);
         if (aExpected === undefined)
           is(devicePerms, Perms.UNKNOWN_ACTION, "no " + aDevice + " persistent permissions");
         else {
           is(devicePerms, aExpected ? Perms.ALLOW_ACTION : Perms.DENY_ACTION,
              aDevice + " persistently " + (aExpected ? "allowed" : "denied"));
         }
-        Perms.remove(uri.host, aDevice);
+        Perms.remove(uri, aDevice);
       }
       checkDevicePermissions("microphone", aExpectedAudioPerm);
       checkDevicePermissions("camera", aExpectedVideoPerm);
 
       if (expectedMessage == "ok")
         yield closeStream();
     }
 
@@ -668,18 +668,18 @@ let gTests = [
 
           yield closeStream();
         }
         else {
           expectObserverCalled("recording-window-ended");
         }
       }
 
-      Perms.remove(uri.host, "camera");
-      Perms.remove(uri.host, "microphone");
+      Perms.remove(uri, "camera");
+      Perms.remove(uri, "microphone");
     }
 
     // Set both permissions identically
     info("allow audio+video, request audio+video, expect ok (audio+video)");
     yield usePerm(true, true, true, true, true);
     info("deny audio+video, request audio+video, expect denied");
     yield usePerm(false, false, true, true, false);
 
@@ -789,18 +789,18 @@ let gTests = [
       if (aRequestVideo)
         is(videoPerm, Perms.UNKNOWN_ACTION, "camera permissions removed");
       else
         is(videoPerm, Perms.ALLOW_ACTION, "camera permissions untouched");
 
       // Cleanup.
       yield closeStream(true);
 
-      Perms.remove(uri.host, "camera");
-      Perms.remove(uri.host, "microphone");
+      Perms.remove(uri, "camera");
+      Perms.remove(uri, "microphone");
     }
 
     info("request audio+video, stop sharing resets both");
     yield stopAndCheckPerm(true, true);
     info("request audio, stop sharing resets audio only");
     yield stopAndCheckPerm(true, false);
     info("request video, stop sharing resets video only");
     yield stopAndCheckPerm(false, true);
@@ -883,18 +883,18 @@ let gTests = [
     for (let node of notification.childNodes) {
       if (node.localName == "menuitem")
         labels.push(node.getAttribute("label"));
     }
     is(labels.indexOf(alwaysLabel), -1, "The 'Always Allow' item isn't shown");
 
     // Cleanup.
     yield closeStream(true);
-    Perms.remove(uri.host, "camera");
-    Perms.remove(uri.host, "microphone");
+    Perms.remove(uri, "camera");
+    Perms.remove(uri, "microphone");
   }
 }
 
 ];
 
 function test() {
   waitForExplicitFinish();
 
--- a/browser/base/content/test/general/browser_notification_tab_switching.js
+++ b/browser/base/content/test/general/browser_notification_tab_switching.js
@@ -9,17 +9,17 @@ let notification;
 let notificationURL = "http://example.org/browser/browser/base/content/test/general/file_dom_notifications.html";
 let newWindowOpenedFromTab;
 
 function test () {
   waitForExplicitFinish();
 
   let pm = Services.perms;
   registerCleanupFunction(function() {
-    pm.remove(notificationURL, "desktop-notification");
+    pm.remove(makeURI(notificationURL), "desktop-notification");
     gBrowser.removeTab(tab);
     window.restore();
   });
 
   pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
 
   tab = gBrowser.addTab(notificationURL);
   tab.linkedBrowser.addEventListener("load", onLoad, true);
--- a/browser/base/content/test/general/browser_remoteTroubleshoot.js
+++ b/browser/base/content/test/general/browser_remoteTroubleshoot.js
@@ -39,17 +39,17 @@ add_task(function*() {
   // Should have no data.
   Assert.ok(got.message === undefined, "should have failed to get any data");
 
   // Add a permission manager entry for our URI.
   Services.perms.add(TEST_URI_GOOD,
                      "remote-troubleshooting",
                      Services.perms.ALLOW_ACTION);
   registerCleanupFunction(() => {
-    Services.perms.remove(TEST_URI_GOOD.spec, "remote-troubleshooting");
+    Services.perms.remove(TEST_URI_GOOD, "remote-troubleshooting");
   });
 
   // Try again - now we are expecting a response with the actual data.
   got = yield promiseNewChannelResponse(TEST_URI_GOOD);
 
   // Check some keys we expect to always get.
   Assert.ok(got.message.extensions, "should have extensions");
   Assert.ok(got.message.graphics, "should have graphics");
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -172,17 +172,17 @@ function clearAllPluginPermissions() {
   clearAllPermissionsByPrefix("plugin");
 }
 
 function clearAllPermissionsByPrefix(aPrefix) {
   let perms = Services.perms.enumerator;
   while (perms.hasMoreElements()) {
     let perm = perms.getNext();
     if (perm.type.startsWith(aPrefix)) {
-      Services.perms.remove(perm.host, perm.type);
+      Services.perms.removePermission(perm);
     }
   }
 }
 
 function pushPrefs(...aPrefs) {
   let deferred = Promise.defer();
   SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve);
   return deferred.promise;
--- a/browser/base/content/test/plugins/browser_pageInfo_plugins.js
+++ b/browser/base/content/test/plugins/browser_pageInfo_plugins.js
@@ -33,18 +33,18 @@ function doOnOpenPageInfo(continuation) 
 }
 
 function pageInfoObserve(win, topic, data) {
   Services.obs.removeObserver(pageInfoObserve, "page-info-dialog-loaded");
   executeSoon(gNextTest);
 }
 
 function finishTest() {
-  gPermissionManager.remove("127.0.0.1:8888", gTestPermissionString);
-  gPermissionManager.remove("127.0.0.1:8888", gSecondTestPermissionString);
+  gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gTestPermissionString);
+  gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gSecondTestPermissionString);
   Services.prefs.clearUserPref("plugins.click_to_play");
   gBrowser.removeCurrentTab();
 
   gPageInfo = null;
   gNextTest = null;
   gTestBrowser = null;
   gPluginHost = null;
   gPermissionManager = null;
@@ -54,18 +54,18 @@ function finishTest() {
 
 function test() {
   waitForExplicitFinish();
   Services.prefs.setBoolPref("plugins.click_to_play", true);
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
-  gPermissionManager.remove("127.0.0.1:8888", gTestPermissionString);
-  gPermissionManager.remove("127.0.0.1:8888", gSecondTestPermissionString);
+  gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gTestPermissionString);
+  gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gSecondTestPermissionString);
   doOnPageLoad(gHttpTestRoot + "plugin_two_types.html", testPart1a);
 }
 
 // The first test plugin is CtP and the second test plugin is enabled.
 function testPart1a() {
   let test = gTestBrowser.contentDocument.getElementById("test");
   let objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(!objLoadingContent.activated, "part 1a: Test plugin should not be activated");
@@ -136,18 +136,18 @@ function testPart3() {
   let secondtest = gTestBrowser.contentDocument.getElementById("secondtestA").
     QueryInterface(Ci.nsIObjectLoadingContent);
 
   ok(!secondtest.activated, "part 3: Second Test plugin should not be activated");
   is(secondtest.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED,
      "part 3: Second test plugin should be marked as PLUGIN_DISABLED");
 
   // reset permissions
-  gPermissionManager.remove("127.0.0.1:8888", gTestPermissionString);
-  gPermissionManager.remove("127.0.0.1:8888", gSecondTestPermissionString);
+  gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gTestPermissionString);
+  gPermissionManager.remove(makeURI("http://127.0.0.1:8888/"), gSecondTestPermissionString);
   // check that changing the permissions affects the radio state in the
   // open Page Info window
   let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup");
   let testRadioDefault = gPageInfo.document.getElementById(gTestPermissionString + "#0");
   is(testRadioGroup.selectedItem, testRadioDefault, "part 3: Test radio group should be set to 'Default'");
   let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup");
   let secondtestRadioDefault = gPageInfo.document.getElementById(gSecondTestPermissionString + "#0");
   is(secondtestRadioGroup.selectedItem, secondtestRadioDefault, "part 3: Second Test radio group should be set to 'Default'");
--- a/browser/base/content/test/plugins/head.js
+++ b/browser/base/content/test/plugins/head.js
@@ -234,17 +234,17 @@ function promiseReloadPlugin(aId, aBrows
 // after a test is done using the plugin doorhanger, we should just clear
 // any permissions that may have crept in
 function clearAllPluginPermissions() {
   let perms = Services.perms.enumerator;
   while (perms.hasMoreElements()) {
     let perm = perms.getNext();
     if (perm.type.startsWith('plugin')) {
       info("removing permission:" + perm.host + " " + perm.type + "\n");
-      Services.perms.remove(perm.host, perm.type);
+      Services.perms.removePermission(perm);
     }
   }
 }
 
 function updateBlocklist(aCallback) {
   let blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
                           .getService(Ci.nsITimerCallback);
   let observer = function() {
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -2430,17 +2430,17 @@ file, You can obtain one at http://mozil
           BrowserReload();
         ]]></body>
       </method>
       <method name="enableTrackingContentProtection">
         <body><![CDATA[
           // Remove the current host from the 'trackingprotection' consumer
           // of the permission manager. This effectively removes this host
           // from the tracking protection allowlist.
-          Services.perms.remove(gBrowser.selectedBrowser.currentURI.host,
+          Services.perms.remove(gBrowser.selectedBrowser.currentURI,
             "trackingprotection");
           BrowserReload();
         ]]></body>
       </method>
     </implementation>
   </binding>
 
   <binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
--- a/browser/components/preferences/aboutPermissions.js
+++ b/browser/components/preferences/aboutPermissions.js
@@ -174,17 +174,17 @@ Site.prototype = {
   /**
    * Clears a user-set permission value for the site given a permission type.
    *
    * @param aType
    *        The permission type string stored in permission manager.
    *        e.g. "cookie", "geo", "indexedDB", "popup", "image"
    */
   clearPermission: function Site_clearPermission(aType) {
-    Services.perms.remove(this.host, aType);
+    Services.perms.remove(this.httpURI, aType);
   },
 
   /**
    * Gets cookies stored for the site. This does not return cookies stored
    * for the base domain, only the exact hostname stored for the site.
    *
    * @return An array of the cookies set for the site.
    */
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -453,30 +453,30 @@ var gAdvancedPane = {
                    windowTitle      : bundlePreferences.getString("offlinepermissionstitle"),
                    introText        : bundlePreferences.getString("offlinepermissionstext") };
     document.documentElement.openWindow("Browser:Permissions",
                                         "chrome://browser/content/preferences/permissions.xul",
                                         "resizable", params);
   },
 
   // XXX: duplicated in browser.js
-  _getOfflineAppUsage: function (host, groups)
+  _getOfflineAppUsage: function (perm, groups)
   {
     var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
                        getService(Components.interfaces.nsIApplicationCacheService);
     if (!groups)
       groups = cacheService.getGroups();
 
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
               getService(Components.interfaces.nsIIOService);
 
     var usage = 0;
     for (var i = 0; i < groups.length; i++) {
       var uri = ios.newURI(groups[i], null, null);
-      if (uri.asciiHost == host) {
+      if (uri.asciiHost == perm.host) {
         var cache = cacheService.getActiveCache(groups[i]);
         usage += cache.usage;
       }
     }
 
     return usage;
   },
 
@@ -505,17 +505,17 @@ var gAdvancedPane = {
       if (perm.type == "offline-app" &&
           perm.capability != Components.interfaces.nsIPermissionManager.DEFAULT_ACTION &&
           perm.capability != Components.interfaces.nsIPermissionManager.DENY_ACTION) {
         var row = document.createElement("listitem");
         row.id = "";
         row.className = "offlineapp";
         row.setAttribute("host", perm.host);
         var converted = DownloadUtils.
-                        convertByteUnits(this._getOfflineAppUsage(perm.host, groups));
+                        convertByteUnits(this._getOfflineAppUsage(perm, groups));
         row.setAttribute("usage",
                          bundle.getFormattedString("offlineAppUsage",
                                                    converted));
         list.appendChild(row);
       }
     }
   },
 
@@ -552,30 +552,35 @@ var gAdvancedPane = {
 
     // clear offline cache entries
     var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
                        getService(Components.interfaces.nsIApplicationCacheService);
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
               getService(Components.interfaces.nsIIOService);
     var groups = cacheService.getGroups();
     for (var i = 0; i < groups.length; i++) {
-        var uri = ios.newURI(groups[i], null, null);
+        let uri = ios.newURI(groups[i], null, null);
         if (uri.asciiHost == host) {
             var cache = cacheService.getActiveCache(groups[i]);
             cache.discard();
         }
     }
 
     // remove the permission
     var pm = Components.classes["@mozilla.org/permissionmanager;1"]
                        .getService(Components.interfaces.nsIPermissionManager);
-    pm.remove(host, "offline-app",
-              Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
-    pm.remove(host, "offline-app",
-              Components.interfaces.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
+    let uri;
+    try {
+      // file:// URIs are stored with their scheme. We try to parse them first, as
+      // URIs like http://file:///foo/bar/baz.html will parse as HTTP URIs.
+      uri = ios.newURI(host, null, null);
+    } catch (e) {
+      uri = ios.newURI("http://" + host, null, null);
+    }
+    pm.remove(uri, "offline-app");
 
     list.removeChild(item);
     gAdvancedPane.offlineAppSelected();
     this.updateActualAppCacheSize();
   },
 
   // UPDATE TAB
 
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -487,27 +487,27 @@ var gAdvancedPane = {
                    introText        : bundlePreferences.getString("offlinepermissionstext") };
     openDialog("chrome://browser/content/preferences/permissions.xul",
                "Browser:Permissions",
                "modal=yes",
                params);
   },
 
   // XXX: duplicated in browser.js
-  _getOfflineAppUsage: function (host, groups)
+  _getOfflineAppUsage: function (perm, groups)
   {
     var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
                        getService(Components.interfaces.nsIApplicationCacheService);
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
               getService(Components.interfaces.nsIIOService);
 
     var usage = 0;
     for (var i = 0; i < groups.length; i++) {
       var uri = ios.newURI(groups[i], null, null);
-      if (uri.asciiHost == host) {
+      if (uri.asciiHost == perm.host) {
         var cache = cacheService.getActiveCache(groups[i]);
         usage += cache.usage;
       }
     }
 
     return usage;
   },
 
@@ -541,17 +541,17 @@ var gAdvancedPane = {
       if (perm.type == "offline-app" &&
           perm.capability != Components.interfaces.nsIPermissionManager.DEFAULT_ACTION &&
           perm.capability != Components.interfaces.nsIPermissionManager.DENY_ACTION) {
         var row = document.createElement("listitem");
         row.id = "";
         row.className = "offlineapp";
         row.setAttribute("host", perm.host);
         var converted = DownloadUtils.
-                        convertByteUnits(this._getOfflineAppUsage(perm.host, groups));
+                        convertByteUnits(this._getOfflineAppUsage(perm, groups));
         row.setAttribute("usage",
                          bundle.getFormattedString("offlineAppUsage",
                                                    converted));
         list.appendChild(row);
       }
     }
   },
 
@@ -589,31 +589,36 @@ var gAdvancedPane = {
     // clear offline cache entries
     try {
       var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
                          getService(Components.interfaces.nsIApplicationCacheService);
       var ios = Components.classes["@mozilla.org/network/io-service;1"].
                 getService(Components.interfaces.nsIIOService);
       var groups = cacheService.getGroups();
       for (var i = 0; i < groups.length; i++) {
-          var uri = ios.newURI(groups[i], null, null);
+          let uri = ios.newURI(groups[i], null, null);
           if (uri.asciiHost == host) {
               var cache = cacheService.getActiveCache(groups[i]);
               cache.discard();
           }
       }
     } catch (e) {}
 
     // remove the permission
     var pm = Components.classes["@mozilla.org/permissionmanager;1"]
                        .getService(Components.interfaces.nsIPermissionManager);
-    pm.remove(host, "offline-app",
-              Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
-    pm.remove(host, "offline-app",
-              Components.interfaces.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
+    let uri;
+    try {
+      // file:// URIs are stored with their scheme. We try to parse them first, as
+      // URIs like http://file:///foo/bar/baz.html will parse as HTTP URIs.
+      uri = ios.newURI(host, null, null);
+    } catch (e) {
+      uri = ios.newURI("http://" + host, null, null);
+    }
+    pm.remove(uri, "offline-app");
 
     list.removeChild(item);
     gAdvancedPane.offlineAppSelected();
     this.updateActualAppCacheSize();
   },
 
   // UPDATE TAB
 
--- a/browser/components/preferences/permissions.js
+++ b/browser/components/preferences/permissions.js
@@ -363,17 +363,18 @@ var gPermissionManager = {
     this.uninit();
 
     for (let permissionParams of this._permissionsToAdd.values()) {
       let uri = Services.io.newURI("http://" + permissionParams.host, null, null);
       Services.perms.add(uri, permissionParams.type, permissionParams.capability);
     }
 
     for (let p of this._permissionsToDelete.values()) {
-      Services.perms.remove(p.host, p.type);
+      let uri = Services.io.newURI("http://" + p.host, null, null);
+      Services.perms.remove(uri, p.type);
     }
 
     window.close();
   },
 
   _loadPermissions: function ()
   {
     this._tree = document.getElementById("permissionsTree");
--- a/browser/components/preferences/tests/browser_chunk_permissions.js
+++ b/browser/components/preferences/tests/browser_chunk_permissions.js
@@ -49,19 +49,19 @@ function setup(aCallback) {
     Services.perms.add(TEST_URI_3, "popup", TEST_PERMS["popup"]);
     aCallback();
   });
 }
 
 function cleanUp() {
   for (let type in TEST_PERMS) {
     if (type != "password") {
-      Services.perms.remove(TEST_URI_1.host, type);
-      Services.perms.remove(TEST_URI_2.host, type);
-      Services.perms.remove(TEST_URI_3.host, type);
+      Services.perms.remove(TEST_URI_1, type);
+      Services.perms.remove(TEST_URI_2, type);
+      Services.perms.remove(TEST_URI_3, type);
     }
   }
 }
 
 function runNextTest() {
   if (gTestIndex == tests.length) {
     PlacesTestUtils.clearHistory().then(finish);
     return;
--- a/browser/components/preferences/tests/browser_cookies_exceptions.js
+++ b/browser/components/preferences/tests/browser_cookies_exceptions.js
@@ -59,17 +59,18 @@ var testRunner = {
           let uri = params.ioService.newURI("http://test.com", null, null);
           params.pm.add(uri, "popup", Ci.nsIPermissionManager.DENY_ACTION);
           is(params.tree.view.rowCount, 0, "adding unrelated permission should not change display");
           params.btnApplyChanges.doCommand();
         },
         observances: [{ type: "popup", host: "test.com", data: "added",
                         capability: Ci.nsIPermissionManager.DENY_ACTION }],
         cleanUp: function(params) {
-          params.pm.remove("test.com", "popup");
+          let uri = params.ioService.newURI("http://test.com", null, null);
+          params.pm.remove(uri, "popup");
         },
       },
     ],
 
   _currentTest: -1,
 
   runTests: function() {
     this._currentTest++;
--- a/browser/components/preferences/translation.js
+++ b/browser/components/preferences/translation.js
@@ -183,29 +183,33 @@ let gTranslationExceptions = {
   },
 
   onAllLanguagesDeleted: function() {
     Services.prefs.setCharPref(kLanguagesPref, "");
   },
 
   onSiteDeleted: function() {
     let removedSites = this._siteTree.getSelectedItems();
-    for (let host of removedSites)
-      Services.perms.remove(host, kPermissionType);
+    for (let host of removedSites) {
+      let uri = Services.io.newURI("http://" + host, null, null);
+      Services.perms.remove(uri, 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 host of removedSites)
-      Services.perms.remove(host, kPermissionType);
+    for (let host of removedSites) {
+      let uri = Services.io.newURI("http://" + host, null, null);
+      Services.perms.remove(uri, kPermissionType);
+    }
 
     this.onSiteSelected();
   },
 
   onSiteKeyPress: function(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE)
       this.onSiteDeleted();
   },
--- a/browser/components/translation/test/browser_translation_exceptions.js
+++ b/browser/components/translation/test/browser_translation_exceptions.js
@@ -189,17 +189,17 @@ let gTests = [
     PopupNotifications.getNotification("translate").anchorElement.click();
     notif = getInfoBar();
     // Open the "options" drop down.
     yield openPopup(notif._getAnonElt("options"));
     ok(notif._getAnonElt("neverForSite").disabled,
        "The 'Never translate French' item is disabled");
 
     // Cleanup.
-    Services.perms.remove("example.com", "translate");
+    Services.perms.remove(makeURI("http://example.com"), "translate");
     notif.close();
   }
 },
 
 {
   desc: "language exception list",
   run: function* checkLanguageExceptions() {
     // Put 2 languages in the pref before opening the window to check
@@ -282,18 +282,18 @@ let gTests = [
     ok(!remove.disabled, "The 'Remove Site' button is enabled");
 
     // Click the 'Remove' button.
     remove.click();
     is(tree.view.rowCount, 1, "The site exceptions now contains 1 item");
     is(getDomainExceptions().length, 1, "One exception in the permissions");
 
     // Clear the permissions, and check the last item is removed from the display.
-    perms.remove("example.org", "translate");
-    perms.remove("example.com", "translate");
+    perms.remove(makeURI("http://example.org"), "translate");
+    perms.remove(makeURI("http://example.com"), "translate");
     is(tree.view.rowCount, 0, "The site exceptions list is empty");
     ok(remove.disabled, "The 'Remove Site' button is disabled");
     ok(removeAll.disabled, "The 'Remove All Site' button is disabled");
 
     // Add an item and check it appears.
     perms.add(makeURI("http://example.com"), "translate", perms.DENY_ACTION);
     is(tree.view.rowCount, 1, "The site exceptions list has 1 item");
     ok(remove.disabled, "The 'Remove Site' button is disabled");
--- a/browser/components/uitour/test/head.js
+++ b/browser/components/uitour/test/head.js
@@ -207,17 +207,17 @@ function UITourTest() {
     delete window.UITour;
     delete window.UITourMetricsProvider;
     delete window.gContentWindow;
     delete window.gContentAPI;
     if (gTestTab)
       gBrowser.removeTab(gTestTab);
     delete window.gTestTab;
     Services.prefs.clearUserPref("browser.uitour.enabled", true);
-    Services.perms.remove("example.com", "uitour");
+    Services.perms.remove(testUri, "uitour");
   });
 
   function done() {
     executeSoon(() => {
       if (gTestTab)
         gBrowser.removeTab(gTestTab);
       gTestTab = null;
 
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -88,17 +88,17 @@ this.SitePermissions = {
   },
 
   /* Removes the saved state of a particular permission for a given URI.
    */
   remove: function (aURI, aPermissionID) {
     if (!this.isSupportedURI(aURI))
       return;
 
-    Services.perms.remove(aURI.host, aPermissionID);
+    Services.perms.remove(aURI, aPermissionID);
   },
 
   /* Returns the localized label for the permission with the given ID, to be
    * used in a UI for managing permissions.
    */
   getPermissionLabel: function (aPermissionID) {
     return gStringBundle.GetStringFromName("permission." + aPermissionID + ".label");
   },
--- a/browser/modules/test/browser_SelfSupportBackend.js
+++ b/browser/modules/test/browser_SelfSupportBackend.js
@@ -107,17 +107,17 @@ add_task(function* setupEnvironment() {
   Preferences.set(PREF_UITOUR_ENABLED, true);
   Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL_HTTPS);
 
   // Whitelist the HTTPS page to use UITour.
   let pageURI = Services.io.newURI(TEST_PAGE_URL_HTTPS, null, null);
   Services.perms.add(pageURI, "uitour", Services.perms.ALLOW_ACTION);
 
   registerCleanupFunction(() => {
-    Services.perms.remove("example.com", "uitour");
+    Services.perms.remove(pageURI, "uitour");
     Preferences.set(PREF_SELFSUPPORT_ENABLED, selfSupportEnabled);
     Preferences.set(PREF_UITOUR_ENABLED, uitourEnabled);
     Preferences.set(PREF_SELFSUPPORT_URL, selfSupportURL);
   });
 });
 
 /**
  * Test that the self support page can use the UITour API and close itself.
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -744,24 +744,23 @@ function updateBrowserSpecificIndicator(
     callback: function () {},
     dismiss: true
   };
   let secondaryActions = [{
     label: stringBundle.getString("getUserMedia.stopSharing.label"),
     accessKey: stringBundle.getString("getUserMedia.stopSharing.accesskey"),
     callback: function () {
       let uri = Services.io.newURI(aState.documentURI, null, null);
-      let host = getHost(uri);
       let perms = Services.perms;
       if (aState.camera &&
           perms.testExactPermission(uri, "camera") == perms.ALLOW_ACTION)
-        perms.remove(host, "camera");
+        perms.remove(uri, "camera");
       if (aState.microphone &&
           perms.testExactPermission(uri, "microphone") == perms.ALLOW_ACTION)
-        perms.remove(host, "microphone");
+        perms.remove(uri, "microphone");
 
       let mm = notification.browser.messageManager;
       mm.sendAsyncMessage("webrtc:StopSharing", windowId);
     }
   }];
   let options = {
     hideNotNow: true,
     dismissed: true,
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -2908,16 +2908,17 @@ toolbarbutton.chevron > .toolbarbutton-m
 #TabsToolbar .toolbarbutton-1:not([disabled=true]):not([buttonover]):hover > .toolbarbutton-menubutton-dropmarker {
   background-image: linear-gradient(transparent, rgba(0,0,0,.15)) !important;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):hover:active,
 .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):hover:active,
 #TabsToolbar .toolbarbutton-1:not([type="menu-button"]):not([disabled=true]):hover:active,
 #TabsToolbar .toolbarbutton-1[type="menu"][open],
+#TabsToolbar .toolbarbutton-1[type="panel"][open],
 #TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):hover:active,
 #TabsToolbar .toolbarbutton-1[open]:not([disabled=true]):hover > .toolbarbutton-menubutton-dropmarker {
   background-image: linear-gradient(transparent, rgba(0,0,0,.3)) !important;
 }
 
 .tabs-newtab-button,
 #TabsToolbar > #new-tab-button,
 #TabsToolbar > toolbarpaletteitem > #new-tab-button {
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -637,16 +637,17 @@ toolbar[brighttext] .toolbarbutton-1 > .
   -moz-box-pack: center;
 }
 
 #nav-bar #PanelUI-menu-button {
   -moz-padding-start: 7px;
   -moz-padding-end: 5px;
 }
 
+#nav-bar .toolbarbutton-1[type=panel]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button),
 #nav-bar .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button) {
   padding-left: 5px;
   padding-right: 5px;
 }
 
 #nav-bar .toolbarbutton-1 > menupopup {
   margin-top: -3px;
 }
@@ -748,17 +749,20 @@ toolbarbutton[constrain-size="true"][cui
   width: 16px;
 }
 
 #nav-bar toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
   /* XXXgijs box models strike again: this is 16px + 2 * 7px padding + 2 * 1px border (from the rules above) */
   width: 32px;
 }
 
+#nav-bar .toolbarbutton-1[type=panel]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button) > .toolbarbutton-icon,
+#nav-bar .toolbarbutton-1[type=panel]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button) > .toolbarbutton-badge-container,
 #nav-bar .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button) > .toolbarbutton-icon,
+#nav-bar .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button):not(#PanelUI-menu-button) > .toolbarbutton-badge-container,
 #nav-bar .toolbarbutton-1[type=menu] > .toolbarbutton-text /* hack for add-ons that forcefully display the label */ {
   -moz-padding-end: 17px;
 }
 
 #nav-bar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
   -moz-margin-start: -15px;
 }
 
--- a/caps/DomainPolicy.cpp
+++ b/caps/DomainPolicy.cpp
@@ -17,17 +17,17 @@ using namespace ipc;
 using namespace dom;
 
 NS_IMPL_ISUPPORTS(DomainPolicy, nsIDomainPolicy)
 
 static nsresult
 BroadcastDomainSetChange(DomainSetType aSetType, DomainSetChangeType aChangeType,
                          nsIURI* aDomain = nullptr)
 {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
+    MOZ_ASSERT(XRE_IsParentProcess(),
                "DomainPolicy should only be exposed to the chrome process.");
 
     nsTArray<ContentParent*> parents;
     ContentParent::GetAll(parents);
     if (!parents.Length()) {
        return NS_OK;
     }
 
@@ -40,17 +40,17 @@ BroadcastDomainSetChange(DomainSetType a
     return NS_OK;
 }
 
 DomainPolicy::DomainPolicy() : mBlacklist(new DomainSet(BLACKLIST))
                              , mSuperBlacklist(new DomainSet(SUPER_BLACKLIST))
                              , mWhitelist(new DomainSet(WHITELIST))
                              , mSuperWhitelist(new DomainSet(SUPER_WHITELIST))
 {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         BroadcastDomainSetChange(NO_TYPE, ACTIVATE_POLICY);
     }
 }
 
 DomainPolicy::~DomainPolicy()
 {
     // The SSM holds a strong ref to the DomainPolicy until Deactivate() is
     // invoked, so we should never hit the destructor until that happens.
@@ -107,17 +107,17 @@ DomainPolicy::Deactivate()
     mWhitelist = nullptr;
     mSuperWhitelist = nullptr;
 
     // Inform the SSM.
     nsScriptSecurityManager* ssm = nsScriptSecurityManager::GetScriptSecurityManager();
     if (ssm) {
         ssm->DeactivateDomainPolicy();
     }
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         BroadcastDomainSetChange(NO_TYPE, DEACTIVATE_POLICY);
     }
     return NS_OK;
 }
 
 void
 DomainPolicy::CloneDomainPolicy(DomainPolicyClone* aClone)
 {
@@ -165,39 +165,39 @@ GetCanonicalClone(nsIURI* aURI)
 NS_IMPL_ISUPPORTS(DomainSet, nsIDomainSet)
 
 NS_IMETHODIMP
 DomainSet::Add(nsIURI* aDomain)
 {
     nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
     NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
     mHashTable.PutEntry(clone);
-    if (XRE_GetProcessType() == GeckoProcessType_Default)
+    if (XRE_IsParentProcess())
         return BroadcastDomainSetChange(mType, ADD_DOMAIN, aDomain);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 DomainSet::Remove(nsIURI* aDomain)
 {
     nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
     NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
     mHashTable.RemoveEntry(clone);
-    if (XRE_GetProcessType() == GeckoProcessType_Default)
+    if (XRE_IsParentProcess())
         return BroadcastDomainSetChange(mType, REMOVE_DOMAIN, aDomain);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 DomainSet::Clear()
 {
     mHashTable.Clear();
-    if (XRE_GetProcessType() == GeckoProcessType_Default)
+    if (XRE_IsParentProcess())
         return BroadcastDomainSetChange(mType, CLEAR_DOMAINS);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 DomainSet::Contains(nsIURI* aDomain, bool* aContains)
 {
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -1278,17 +1278,17 @@ nsScriptSecurityManager::~nsScriptSecuri
 {
     Preferences::RemoveObservers(this, kObservedPrefs);
     if (mDomainPolicy) {
         mDomainPolicy->Deactivate();
     }
     // ContentChild might hold a reference to the domain policy,
     // and it might release it only after the security manager is
     // gone. But we can still assert this for the main process.
-    MOZ_ASSERT_IF(XRE_GetProcessType() == GeckoProcessType_Default,
+    MOZ_ASSERT_IF(XRE_IsParentProcess(),
                   !mDomainPolicy);
 }
 
 void
 nsScriptSecurityManager::Shutdown()
 {
     if (sRuntime) {
         JS_SetSecurityCallbacks(sRuntime, nullptr);
@@ -1495,17 +1495,17 @@ nsScriptSecurityManager::GetDomainPolicy
 {
     *aRv = !!mDomainPolicy;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::ActivateDomainPolicy(nsIDomainPolicy** aRv)
 {
-    if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    if (!XRE_IsParentProcess()) {
         return NS_ERROR_SERVICE_NOT_AVAILABLE;
     }
 
     return ActivateDomainPolicyInternal(aRv);
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::ActivateDomainPolicyInternal(nsIDomainPolicy** aRv)
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -411,17 +411,17 @@ nsDefaultURIFixup::KeywordToURI(const ns
 
   // Strip leading "?" and leading/trailing spaces from aKeyword
   nsAutoCString keyword(aKeyword);
   if (StringBeginsWith(keyword, NS_LITERAL_CSTRING("?"))) {
     keyword.Cut(0, 1);
   }
   keyword.Trim(" ");
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
     if (!contentChild) {
       return NS_ERROR_NOT_AVAILABLE;
     }
 
     ipc::OptionalInputStreamParams postData;
     ipc::OptionalURIParams uri;
     nsAutoString providerName;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -819,31 +819,31 @@ ConvertLoadTypeToNavigationType(uint32_t
 
 static nsISHEntry* GetRootSHEntry(nsISHEntry* aEntry);
 
 static void
 IncreasePrivateDocShellCount()
 {
   gNumberOfPrivateDocShells++;
   if (gNumberOfPrivateDocShells > 1 ||
-      XRE_GetProcessType() != GeckoProcessType_Content) {
+      !XRE_IsContentProcess()) {
     return;
   }
 
   mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
   cc->SendPrivateDocShellsExist(true);
 }
 
 static void
 DecreasePrivateDocShellCount()
 {
   MOZ_ASSERT(gNumberOfPrivateDocShells > 0);
   gNumberOfPrivateDocShells--;
   if (!gNumberOfPrivateDocShells) {
-    if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    if (XRE_IsContentProcess()) {
       dom::ContentChild* cc = dom::ContentChild::GetSingleton();
       cc->SendPrivateDocShellsExist(false);
       return;
     }
 
     nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService();
     if (obsvc) {
       obsvc->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
@@ -5015,17 +5015,17 @@ nsDocShell::DisplayLoadError(nsresult aE
 
         // If this is an HTTP Strict Transport Security host or a pinned host
         // and the certificate is bad, don't allow overrides (RFC 6797 section
         // 12.1, HPKP draft spec section 2.6).
         uint32_t flags =
           mInPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
         bool isStsHost = false;
         bool isPinnedHost = false;
-        if (XRE_GetProcessType() == GeckoProcessType_Default) {
+        if (XRE_IsParentProcess()) {
           nsCOMPtr<nsISiteSecurityService> sss =
             do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
           NS_ENSURE_SUCCESS(rv, rv);
           rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI,
                                 flags, &isStsHost);
           NS_ENSURE_SUCCESS(rv, rv);
           rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI,
                                 flags, &isPinnedHost);
@@ -9443,17 +9443,17 @@ NS_IMPL_ISUPPORTS(nsCopyFaviconCallback,
 
 } // anonymous namespace
 
 void
 nsDocShell::CopyFavicon(nsIURI* aOldURI,
                         nsIURI* aNewURI,
                         bool aInPrivateBrowsing)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
     if (contentChild) {
       mozilla::ipc::URIParams oldURI, newURI;
       SerializeURI(aOldURI, oldURI);
       SerializeURI(aNewURI, newURI);
       contentChild->SendCopyFavicon(oldURI, newURI, aInPrivateBrowsing);
     }
     return;
@@ -13986,17 +13986,17 @@ nsDocShell::NotifyJSRunToCompletionStop(
 void
 nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
                                             const nsString& aKeyword)
 {
   if (aProvider.IsEmpty()) {
     return;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
     if (contentChild) {
       contentChild->SendNotifyKeywordSearchLoading(aProvider, aKeyword);
     }
     return;
   }
 
 #ifdef MOZ_TOOLKIT_SEARCH
--- a/dom/asmjscache/AsmJSCache.cpp
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -52,22 +52,16 @@ namespace mozilla {
 
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, PR_Close);
 
 namespace dom {
 namespace asmjscache {
 
 namespace {
 
-bool
-IsMainProcess()
-{
-  return XRE_GetProcessType() == GeckoProcessType_Default;
-}
-
 // Anything smaller should compile fast enough that caching will just add
 // overhead.
 static const size_t sMinCachedModuleLength = 10000;
 
 // The number of characters to hash into the Metadata::Entry::mFastHash.
 static const unsigned sNumFastHashChars = 4096;
 
 nsresult
@@ -499,17 +493,17 @@ public:
     mOpenMode(aOpenMode),
     mWriteParams(aWriteParams),
     mPersistence(quota::PERSISTENCE_TYPE_INVALID),
     mState(eInitial),
     mResult(JS::AsmJSCache_InternalError),
     mIsApp(false),
     mEnforcingQuota(true)
   {
-    MOZ_ASSERT(IsMainProcess());
+    MOZ_ASSERT(XRE_IsParentProcess());
   }
 
   virtual ~MainProcessRunnable()
   {
     MOZ_ASSERT(mState == eFinished);
     MOZ_ASSERT(!mDirectoryLock);
   }
 
@@ -1142,17 +1136,17 @@ public:
   // the main thread.
   SingleProcessRunnable(nsIPrincipal* aPrincipal,
                         OpenMode aOpenMode,
                         WriteParams aWriteParams,
                         ReadParams aReadParams)
   : MainProcessRunnable(aPrincipal, aOpenMode, aWriteParams),
     mReadParams(aReadParams)
   {
-    MOZ_ASSERT(IsMainProcess());
+    MOZ_ASSERT(XRE_IsParentProcess());
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_COUNT_CTOR(SingleProcessRunnable);
   }
 
 protected:
   ~SingleProcessRunnable()
   {
     MOZ_COUNT_DTOR(SingleProcessRunnable);
@@ -1224,17 +1218,17 @@ public:
                         OpenMode aOpenMode,
                         WriteParams aWriteParams)
   : MainProcessRunnable(aPrincipal, aOpenMode, aWriteParams),
     mPrincipalHolder(aPrincipal),
     mActorDestroyed(false),
     mOpened(false),
     mFinished(false)
   {
-    MOZ_ASSERT(IsMainProcess());
+    MOZ_ASSERT(XRE_IsParentProcess());
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_COUNT_CTOR(ParentProcessRunnable);
   }
 
 private:
   ~ParentProcessRunnable()
   {
     MOZ_ASSERT(!mPrincipalHolder, "Should have already been released");
@@ -1403,17 +1397,17 @@ public:
                        ReadParams aReadParams)
   : mPrincipal(aPrincipal),
     mOpenMode(aOpenMode),
     mWriteParams(aWriteParams),
     mReadParams(aReadParams),
     mActorDestroyed(false),
     mState(eInitial)
   {
-    MOZ_ASSERT(!IsMainProcess());
+    MOZ_ASSERT(!XRE_IsParentProcess());
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_COUNT_CTOR(ChildProcessRunnable);
   }
 
 protected:
   ~ChildProcessRunnable()
   {
     MOZ_ASSERT(mState == eFinished);
@@ -1599,17 +1593,17 @@ OpenFile(nsIPrincipal* aPrincipal,
   if (NS_IsMainThread()) {
     return JS::AsmJSCache_SynchronousScript;
   }
 
   // If we are in a child process, we need to synchronously call into the
   // parent process to open the file and interact with the QuotaManager. The
   // child can then map the file into its address space to perform I/O.
   nsRefPtr<File> file;
-  if (IsMainProcess()) {
+  if (XRE_IsParentProcess()) {
     file = new SingleProcessRunnable(aPrincipal, aOpenMode, aWriteParams,
                                      aReadParams);
   } else {
     file = new ChildProcessRunnable(aPrincipal, aOpenMode, aWriteParams,
                                     aReadParams);
   }
 
   JS::AsmJSCacheResult openResult = file->BlockUntilOpen(aFile);
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -65,31 +65,31 @@ static const nsAttrValue::EnumTable kMoz
 };
 
 // static
 AudioChannelService*
 AudioChannelService::GetAudioChannelService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return AudioChannelServiceChild::GetAudioChannelService();
   }
 
   return gAudioChannelService;
 
 }
 
 // static
 AudioChannelService*
 AudioChannelService::GetOrCreateAudioChannelService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return AudioChannelServiceChild::GetOrCreateAudioChannelService();
   }
 
   // If we already exist, exit early
   if (gAudioChannelService) {
     return gAudioChannelService;
   }
 
@@ -99,17 +99,17 @@ AudioChannelService::GetOrCreateAudioCha
 
   gAudioChannelService = service;
   return gAudioChannelService;
 }
 
 void
 AudioChannelService::Shutdown()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return AudioChannelServiceChild::Shutdown();
   }
 
   if (gAudioChannelService) {
     gAudioChannelService = nullptr;
   }
 }
 
@@ -117,17 +117,17 @@ NS_IMPL_ISUPPORTS(AudioChannelService, n
 
 AudioChannelService::AudioChannelService()
 : mCurrentHigherChannel(-1)
 , mCurrentVisibleHigherChannel(-1)
 , mPlayableHiddenContentChildID(CONTENT_PROCESS_ID_UNKNOWN)
 , mDisabled(false)
 , mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->AddObserver(this, "ipc:content-shutdown", false);
       obs->AddObserver(this, "xpcom-shutdown", false);
       obs->AddObserver(this, "inner-window-destroyed", false);
 #ifdef MOZ_WIDGET_GONK
       // To monitor the volume settings based on audio channel.
       obs->AddObserver(this, "mozsettings-changed", false);
@@ -175,17 +175,17 @@ AudioChannelService::RegisterType(AudioC
 {
   if (mDisabled) {
     return;
   }
 
   AudioChannelInternalType type = GetInternalType(aChannel, true);
   mChannelCounters[type].AppendElement(aChildID);
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
 
     // We must keep the childIds in order to decide which app is allowed to play
     // with then telephony channel.
     if (aChannel == AudioChannel::Telephony) {
       RegisterTelephonyChild(aChildID);
     }
 
     // Since there is another telephony registered, we can unregister old one
@@ -267,17 +267,17 @@ AudioChannelService::UnregisterType(Audi
 {
   if (mDisabled) {
     return;
   }
 
   // There are two reasons to defer the decrease of telephony channel.
   // 1. User can have time to remove device from his ear before music resuming.
   // 2. Give BT SCO to be disconnected before starting to connect A2DP.
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
 
     if (aChannel == AudioChannel::Telephony) {
       UnregisterTelephonyChild(aChildID);
     }
 
     if (aChannel == AudioChannel::Telephony &&
         (mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY_HIDDEN].Length() +
          mChannelCounters[AUDIO_CHANNEL_INT_TELEPHONY].Length()) == 1) {
@@ -301,17 +301,17 @@ AudioChannelService::UnregisterTypeInter
   // The array may contain multiple occurrence of this appId but
   // this should remove only the first one.
   AudioChannelInternalType type = GetInternalType(aChannel, aElementHidden);
   MOZ_ASSERT(mChannelCounters[type].Contains(aChildID));
   mChannelCounters[type].RemoveElement(aChildID);
 
   // In order to avoid race conditions, it's safer to notify any existing
   // agent any time a new one is registered.
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // No hidden content channel is playable if the original playable hidden
     // process does not need to play audio from background anymore.
     if (aChannel == AudioChannel::Content &&
         mPlayableHiddenContentChildID == aChildID &&
         !mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].Contains(aChildID)) {
       mPlayableHiddenContentChildID = CONTENT_PROCESS_ID_UNKNOWN;
     }
 
@@ -542,17 +542,17 @@ AudioChannelService::SetDefaultVolumeCon
                                          CONTENT_PROCESS_ID_MAIN);
 }
 
 void
 AudioChannelService::SetDefaultVolumeControlChannelInternal(int32_t aChannel,
                                                             bool aVisible,
                                                             uint64_t aChildID)
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return;
   }
 
   // If this child is in the background and mDefChannelChildID is set to
   // others then it means other child in the foreground already set it's
   // own default channel already.
   if (!aVisible && mDefChannelChildID != aChildID) {
     return;
@@ -585,17 +585,17 @@ AudioChannelService::SetDefaultVolumeCon
     obs->NotifyObservers(nullptr, "default-volume-channel-changed",
                          channelName.get());
   }
 }
 
 void
 AudioChannelService::SendAudioChannelChangedNotification(uint64_t aChildID)
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return;
   }
 
   nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
   props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), aChildID);
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
--- a/dom/base/Crypto.cpp
+++ b/dom/base/Crypto.cpp
@@ -86,17 +86,17 @@ Crypto::GetRandomValues(JSContext* aCx, 
     return;
   } else if (dataLen > 65536) {
     aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
     return;
   }
 
   uint8_t* data = aArray.Data();
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     InfallibleTArray<uint8_t> randomValues;
     // Tell the parent process to generate random values via PContent
     ContentChild* cc = ContentChild::GetSingleton();
     if (!cc->SendGetRandomValues(dataLen, &randomValues) ||
         randomValues.Length() == 0) {
       aRv.Throw(NS_ERROR_FAILURE);
       return;
     }
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1476,17 +1476,17 @@ Navigator::GetFeature(const nsAString& a
   nsRefPtr<Promise> p = Promise::Create(go, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
 #if defined(XP_LINUX)
   if (aName.EqualsLiteral("hardware.memory")) {
     // with seccomp enabled, fopen() should be in a non-sandboxed process
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       uint32_t memLevel = mozilla::hal::GetTotalSystemMemoryLevel();
       if (memLevel == 0) {
         p->MaybeReject(NS_ERROR_NOT_AVAILABLE);
         return p.forget();
       }
       p->MaybeResolve((int)memLevel);
     } else {
       mozilla::dom::ContentChild* cc =
@@ -2544,17 +2544,17 @@ Navigator::HasTVSupport(JSContext* aCx, 
   // Only support TV Manager API for certified apps for now.
   return status == nsIPrincipal::APP_STATUS_CERTIFIED;
 }
 
 /* static */
 bool
 Navigator::IsE10sEnabled(JSContext* aCx, JSObject* aGlobal)
 {
-  return XRE_GetProcessType() == GeckoProcessType_Content;
+  return XRE_IsContentProcess();
 }
 
 bool
 Navigator::MozE10sEnabled()
 {
   // This will only be called if IsE10sEnabled() is true.
   return true;
 }
--- a/dom/base/nsCCUncollectableMarker.cpp
+++ b/dom/base/nsCCUncollectableMarker.cpp
@@ -136,17 +136,17 @@ MarkChildMessageManagers(nsIMessageBroad
     }
   }
 }
 
 static void
 MarkMessageManagers()
 {
   // The global message manager only exists in the root process.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return;
   }
   nsCOMPtr<nsIMessageBroadcaster> strongGlobalMM =
     do_GetService("@mozilla.org/globalmessagemanager;1");
   if (!strongGlobalMM) {
     return;
   }
   nsIMessageBroadcaster* globalMM = strongGlobalMM;
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -331,17 +331,17 @@ nsContentPermissionUtils::CreateContentP
 
 /* static */ nsresult
 nsContentPermissionUtils::AskPermission(nsIContentPermissionRequest* aRequest, nsPIDOMWindow* aWindow)
 {
   MOZ_ASSERT(!aWindow || aWindow->IsInnerWindow());
   NS_ENSURE_STATE(aWindow && aWindow->IsCurrentInnerWindow());
 
   // for content process
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
 
     nsRefPtr<RemotePermissionRequest> req =
       new RemotePermissionRequest(aRequest, aWindow);
 
     MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread.
 
     TabChild* child = TabChild::GetFrom(aWindow->GetDocShell());
     NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -10653,17 +10653,17 @@ PLDHashOperator UnlockEnumerator(imgIReq
   aKey->UnlockImage();
   return PL_DHASH_NEXT;
 }
 
 
 nsresult
 nsDocument::SetImageLockingState(bool aLocked)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content &&
+  if (XRE_IsContentProcess() &&
       !Preferences::GetBool("image.mem.allow_locking_in_content_processes", true)) {
     return NS_OK;
   }
 
   // If there's no change, there's nothing to do.
   if (mLockingImages == aLocked)
     return NS_OK;
 
@@ -11156,18 +11156,27 @@ static void
 ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
 {
   MOZ_ASSERT(aMaybeNotARootDoc);
   nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
   NS_ASSERTION(root, "Should have root when in fullscreen!");
   if (!root) {
     return;
   }
-  NS_ASSERTION(root->IsFullScreenDoc(),
-    "Fullscreen root should be a fullscreen doc...");
+  if (!root->IsFullScreenDoc()) {
+    // If a document was detached before exiting from fullscreen, it is
+    // possible that the root had left fullscreen state. In this case,
+    // we would not get anything from the ResetFullScreen() call. Root's
+    // not being a fullscreen doc also means the widget should have
+    // exited fullscreen state. It means even if we do not return here,
+    // we would actually do nothing below except crashing ourselves via
+    // dispatching the "MozDOMFullscreen:Exited" event to an nonexistent
+    // document.
+    return;
+  }
 
   // Stores a list of documents to which we must dispatch "mozfullscreenchange".
   // We're required by the spec to dispatch the events in leaf-to-root
   // order when exiting fullscreen, but we traverse the doctree in a
   // root-to-leaf order, so we save references to the documents we must
   // dispatch to so that we dispatch in the specified order.
   nsAutoTArray<nsIDocument*, 8> changed;
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -692,17 +692,17 @@ nsFocusManager::WindowRaised(nsIDOMWindo
     if (!sTestMode) {
       baseWindow->SetVisibility(true);
     }
   }
 
   // If this is a parent or single process window, send the activate event.
   // Events for child process windows will be sent when ParentActivated
   // is called.
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     ActivateOrDeactivate(window, true);
   }
 
   // retrieve the last focused element within the window that was raised
   nsCOMPtr<nsPIDOMWindow> currentWindow;
   nsCOMPtr<nsIContent> currentFocus =
     GetFocusedDescendant(window, true, getter_AddRefs(currentWindow));
 
@@ -755,17 +755,17 @@ nsFocusManager::WindowLowered(nsIDOMWind
     return NS_OK;
 
   // clear the mouse capture as the active window has changed
   nsIPresShell::SetCapturingContent(nullptr, 0);
 
   // If this is a parent or single process window, send the deactivate event.
   // Events for child process windows will be sent when ParentActivated
   // is called.
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     ActivateOrDeactivate(window, false);
   }
 
   // keep track of the window being lowered, so that attempts to raise the
   // window can be prevented until we return. Otherwise, focus can get into
   // an unusual state.
   mWindowBeingLowered = mActiveWindow;
   mActiveWindow = nullptr;
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -1595,22 +1595,22 @@ nsFrameLoader::ShouldUseRemoteProcess()
 {
   if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
       Preferences::GetBool("dom.ipc.tabs.disabled", false)) {
     return false;
   }
 
   // Don't try to launch nested children if we don't have OMTC.
   // They won't render!
-  if (XRE_GetProcessType() == GeckoProcessType_Content &&
+  if (XRE_IsContentProcess() &&
       !CompositorChild::ChildProcessHasCompositor()) {
     return false;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content &&
+  if (XRE_IsContentProcess() &&
       !(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
         Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
     return false;
   }
 
   // If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
   // fall back to the default.
   if (OwnerIsBrowserOrAppFrame() &&
@@ -2644,17 +2644,17 @@ nsFrameLoader::AttributeChanged(nsIDocum
   }
 }
 
 void
 nsFrameLoader::ResetPermissionManagerStatus()
 {
   // The resetting of the permissions status can run only
   // in the main process.
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return;
   }
 
   // Finding the new app Id:
   // . first we check if the owner is an app frame
   // . second, we check if the owner is a browser frame
   // in both cases we populate the appId variable.
   uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -897,17 +897,17 @@ nsFrameMessageManager::Dump(const nsAStr
   fputs(NS_ConvertUTF16toUTF8(aStr).get(), stdout);
   fflush(stdout);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::PrivateNoteIntentionalCrash()
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     mozilla::NoteIntentionalCrash("tab");
     return NS_OK;
   } else {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 }
 
 NS_IMETHODIMP
@@ -1571,17 +1571,17 @@ ReportReferentCount(const char* aManager
 }
 
 NS_IMETHODIMP
 MessageManagerReporter::CollectReports(nsIMemoryReporterCallback* aCb,
                                        nsISupports* aClosure, bool aAnonymize)
 {
   nsresult rv;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsCOMPtr<nsIMessageBroadcaster> globalmm =
       do_GetService("@mozilla.org/globalmessagemanager;1");
     if (globalmm) {
       nsRefPtr<nsFrameMessageManager> mm =
         static_cast<nsFrameMessageManager*>(globalmm.get());
       MessageManagerReferentCount count;
       CountReferents(mm, &count);
       rv = ReportReferentCount("global-manager", count, aCb, aClosure);
@@ -1607,17 +1607,17 @@ MessageManagerReporter::CollectReports(n
 }
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult
 NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult)
 {
-  NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
+  NS_ENSURE_TRUE(XRE_IsParentProcess(),
                  NS_ERROR_NOT_AVAILABLE);
   nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
                                                                  nullptr,
                                                                  MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
   RegisterStrongMemoryReporter(new MessageManagerReporter());
   mm.forget(aResult);
   return NS_OK;
 }
@@ -2136,17 +2136,17 @@ nsFrameMessageManager::NewProcessMessage
 
 nsresult
 NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
 {
   NS_ASSERTION(!nsFrameMessageManager::GetChildProcessManager(),
                "Re-creating sChildProcessManager");
 
   MessageManagerCallback* cb;
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     cb = new SameChildProcessMessageManagerCallback();
   } else {
     cb = new ChildProcessMessageManagerCallback();
     RegisterStrongMemoryReporter(new MessageManagerReporter());
   }
   nsFrameMessageManager* mm = new nsFrameMessageManager(cb,
                                                         nullptr,
                                                         MM_PROCESSMANAGER | MM_OWNSCALLBACK);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8955,17 +8955,17 @@ nsGlobalWindow::ShowModalDialog(const ns
   if (mDoc) {
     mDoc->WarnOnceAbout(nsIDocument::eShowModalDialog);
   }
 
   FORWARD_TO_OUTER_OR_THROW(ShowModalDialog,
                             (aUrl, aArgument, aOptions, aError), aError,
                             nullptr);
 
-  if (!IsShowModalDialogEnabled() || XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (!IsShowModalDialogEnabled() || XRE_IsContentProcess()) {
     aError.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
   Telemetry::Accumulate(Telemetry::DOM_WINDOW_SHOWMODALDIALOG_USED, true);
 
   nsRefPtr<DialogValueHolder> argHolder =
     new DialogValueHolder(nsContentUtils::SubjectPrincipal(), aArgument);
@@ -10744,17 +10744,17 @@ nsGlobalWindow::ShowSlowScriptDialog()
     return KillSlowScript;
   }
 
   // Check if we should offer the option to debug
   JS::AutoFilename filename;
   unsigned lineno;
   bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno);
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content &&
+  if (XRE_IsContentProcess() &&
       ProcessHangMonitor::Get()) {
     ProcessHangMonitor::SlowScriptAction action;
     nsRefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
     nsCOMPtr<nsITabChild> child = do_GetInterface(GetDocShell());
     action = monitor->NotifySlowScript(child,
                                        filename.get(),
                                        lineno);
     if (action == ProcessHangMonitor::Terminate) {
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -3206,17 +3206,17 @@ nsObjectLoadingContent::ShouldPlay(Fallb
   if (!sPrefsInitialized) {
     Preferences::AddUintVarCache(&sSessionTimeoutMinutes,
                                  "plugin.sessionPermissionNow.intervalInMinutes", 60);
     Preferences::AddUintVarCache(&sPersistentTimeoutDays,
                                  "plugin.persistentPermissionAlways.intervalInDays", 90);
     sPrefsInitialized = true;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default &&
+  if (XRE_IsParentProcess() &&
       BrowserTabsRemoteAutostart()) {
     // Plugins running OOP from the chrome process along with plugins running
     // OOP from the content process will hang. Let's prevent that situation.
     aReason = eFallbackDisabled;
     return false;
   }
 
   nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -529,17 +529,17 @@ nsWindowMemoryReporter::CollectReports(n
   NS_ENSURE_SUCCESS(rv, rv);
 
   WindowPaths windowPaths;
   WindowPaths topWindowPaths;
 
   // Collect window memory usage.
   nsWindowSizes windowTotalSizes(nullptr);
   nsCOMPtr<amIAddonManager> addonManager;
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // Only try to access the service from the main process.
     addonManager = do_GetService("@mozilla.org/addons/integration;1");
   }
   for (uint32_t i = 0; i < windows.Length(); i++) {
     rv = CollectWindowReports(windows[i], addonManager,
                               &windowTotalSizes, &ghostWindows,
                               &windowPaths, &topWindowPaths, aCb,
                               aClosure, aAnonymize);
--- a/dom/base/nsXMLHttpRequest.cpp
+++ b/dom/base/nsXMLHttpRequest.cpp
@@ -2941,17 +2941,17 @@ nsXMLHttpRequest::Send(nsIVariant* aVari
       nsAutoCString scheme;
 
       rv = mChannel->GetURI(getter_AddRefs(uri));
       if (NS_SUCCEEDED(rv)) {
         uri->GetScheme(scheme);
         if (scheme.LowerCaseEqualsLiteral("app") ||
             scheme.LowerCaseEqualsLiteral("jar")) {
           mIsMappedArrayBuffer = true;
-          if (XRE_GetProcessType() != GeckoProcessType_Default) {
+          if (!XRE_IsParentProcess()) {
             nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(mChannel);
             // For memory mapping from child process, we need to get file
             // descriptor of the JAR file opened remotely on the parent proess.
             // Set this to make sure that file descriptor can be obtained by
             // child process.
             jarChannel->EnsureChildFd();
           }
         }
--- a/dom/bluetooth/BluetoothUtils.cpp
+++ b/dom/bluetooth/BluetoothUtils.cpp
@@ -328,15 +328,9 @@ DispatchStatusChangedEvent(const nsAStri
 #ifndef MOZ_B2G_BT_API_V1
   bs->DistributeSignal(aType, NS_LITERAL_STRING(KEY_ADAPTER), data);
 #else
   BluetoothSignal signal(nsString(aType), NS_LITERAL_STRING(KEY_ADAPTER), data);
   bs->DistributeSignal(signal);
 #endif
 }
 
-bool
-IsMainProcess()
-{
-  return XRE_GetProcessType() == GeckoProcessType_Default;
-}
-
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/BluetoothUtils.h
+++ b/dom/bluetooth/BluetoothUtils.h
@@ -152,19 +152,11 @@ void
 DispatchReplyError(BluetoothReplyRunnable* aRunnable,
                    const enum BluetoothStatus aStatus);
 
 void
 DispatchStatusChangedEvent(const nsAString& aType,
                            const nsAString& aDeviceAddress,
                            bool aStatus);
 
-/**
- * Check whether the caller runs at B2G process.
- *
- * @return true if the caller runs at B2G process, false otherwise.
- */
-bool
-IsMainProcess();
-
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -233,17 +233,17 @@ BluetoothHfpManager::Reset()
   mAudioState = HFP_AUDIO_STATE_DISCONNECTED;
   Cleanup();
 }
 
 bool
 BluetoothHfpManager::Init()
 {
   // The function must run at b2g process since it would access SettingsService.
-  MOZ_ASSERT(IsMainProcess());
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE(obs, false);
 
   if (NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false)) ||
       NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
--- a/dom/bluetooth/bluetooth1/BluetoothAdapter.cpp
+++ b/dom/bluetooth/bluetooth1/BluetoothAdapter.cpp
@@ -779,17 +779,17 @@ BluetoothAdapter::SendFile(const nsAStri
     new BluetoothVoidReplyRunnable(request);
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // In-process transfer
     bs->SendFile(aDeviceAddress, &aBlob, results);
   } else {
     ContentChild *cc = ContentChild::GetSingleton();
     if (!cc) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
--- a/dom/bluetooth/bluetooth1/BluetoothService.cpp
+++ b/dom/bluetooth/bluetooth1/BluetoothService.cpp
@@ -93,22 +93,16 @@ USING_BLUETOOTH_NAMESPACE
 
 namespace {
 
 StaticRefPtr<BluetoothService> sBluetoothService;
 
 bool sInShutdown = false;
 bool sToggleInProgress = false;
 
-bool
-IsMainProcess()
-{
-  return XRE_GetProcessType() == GeckoProcessType_Default;
-}
-
 void
 ShutdownTimeExceeded(nsITimer* aTimer, void* aClosure)
 {
   MOZ_ASSERT(NS_IsMainThread());
   *static_cast<bool*>(aClosure) = true;
 }
 
 void
@@ -215,17 +209,17 @@ RemoveObserversExceptBluetoothManager
   return PL_DHASH_NEXT;
 }
 
 // static
 BluetoothService*
 BluetoothService::Create()
 {
 #if defined(MOZ_B2G_BT)
-  if (!IsMainProcess()) {
+  if (!XRE_IsParentProcess()) {
     return BluetoothServiceChildProcess::Create();
   }
 
 #if defined(MOZ_B2G_BT_BLUEZ)
   return new BluetoothDBusService();
 #elif defined(MOZ_B2G_BT_BLUEDROID)
   return new BluetoothServiceBluedroid();
 #elif defined(MOZ_B2G_BT_DAEMON)
@@ -249,17 +243,17 @@ BluetoothService::Init()
 
   if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                  false))) {
     BT_WARNING("Failed to add shutdown observer!");
     return false;
   }
 
   // Only the main process should observe bluetooth settings changes.
-  if (IsMainProcess() &&
+  if (XRE_IsParentProcess() &&
       NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false))) {
     BT_WARNING("Failed to add settings change observer!");
     return false;
   }
 
   return true;
 }
 
--- a/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth/bluetooth2/BluetoothAdapter.cpp
@@ -1261,17 +1261,17 @@ BluetoothAdapter::SendFile(const nsAStri
     new BluetoothVoidReplyRunnable(request);
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // In-process transfer
     bs->SendFile(aDeviceAddress, &aBlob, results);
   } else {
     ContentChild *cc = ContentChild::GetSingleton();
     if (!cc) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
--- a/dom/bluetooth/bluetooth2/BluetoothService.cpp
+++ b/dom/bluetooth/bluetooth2/BluetoothService.cpp
@@ -188,17 +188,17 @@ BluetoothService::~BluetoothService()
   Cleanup();
 }
 
 // static
 BluetoothService*
 BluetoothService::Create()
 {
 #if defined(MOZ_B2G_BT)
-  if (!IsMainProcess()) {
+  if (!XRE_IsParentProcess()) {
     return BluetoothServiceChildProcess::Create();
   }
 
 #if defined(MOZ_B2G_BT_BLUEZ)
   return new BluetoothDBusService();
 #elif defined(MOZ_B2G_BT_BLUEDROID)
   return new BluetoothServiceBluedroid();
 #elif defined(MOZ_B2G_BT_DAEMON)
@@ -222,17 +222,17 @@ BluetoothService::Init()
 
   if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                  false))) {
     BT_WARNING("Failed to add shutdown observer!");
     return false;
   }
 
   // Only the main process should observe bluetooth settings changes.
-  if (IsMainProcess() &&
+  if (XRE_IsParentProcess() &&
       NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false))) {
     BT_WARNING("Failed to add settings change observer!");
     return false;
   }
 
   return true;
 }
 
@@ -264,17 +264,17 @@ BluetoothService::RegisterBluetoothSigna
     ol = new BluetoothSignalObserverList();
     mBluetoothSignalObserverTable.Put(aNodeName, ol);
   }
 
   ol->AddObserver(aHandler);
 
   // Distribute pending pairing requests when pairing listener has been added
   // to signal observer table.
-  if (IsMainProcess() &&
+  if (XRE_IsParentProcess() &&
       !mPendingPairReqSignals.IsEmpty() &&
       aNodeName.EqualsLiteral(KEY_PAIRING_LISTENER)) {
     for (uint32_t i = 0; i < mPendingPairReqSignals.Length(); ++i) {
       DistributeSignal(mPendingPairReqSignals[i]);
     }
     mPendingPairReqSignals.Clear();
   }
 }
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -438,17 +438,17 @@ BluetoothHfpManager::Reset()
   mReceiveVgsFlag = false;
   mController = nullptr;
 }
 
 bool
 BluetoothHfpManager::Init()
 {
   // The function must run at b2g process since it would access SettingsService.
-  MOZ_ASSERT(IsMainProcess());
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE(obs, false);
 
   if (NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false)) ||
       NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
     BT_WARNING("Failed to add observers!");
--- a/dom/cellbroadcast/CellBroadcast.cpp
+++ b/dom/cellbroadcast/CellBroadcast.cpp
@@ -147,17 +147,17 @@ CellBroadcast::NotifyMessageReceived(uin
   return DispatchTrustedEvent(event);
 }
 
 already_AddRefed<nsICellBroadcastService>
 NS_CreateCellBroadcastService()
 {
   nsCOMPtr<nsICellBroadcastService> service;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     service = new mozilla::dom::cellbroadcast::CellBroadcastIPCService();
 #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
   } else {
     service = do_GetService(GONK_CELLBROADCAST_SERVICE_CONTRACTID);
 #endif
   }
 
   return service.forget();
--- a/dom/datastore/DataStoreService.cpp
+++ b/dom/datastore/DataStoreService.cpp
@@ -46,18 +46,18 @@
 
 #include "nsContentUtils.h"
 #include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 
 #define ASSERT_PARENT_PROCESS()                                             \
-  AssertIsInMainProcess();                                                  \
-  if (NS_WARN_IF(!IsMainProcess())) {                                       \
+  MOZ_ASSERT(XRE_IsParentProcess());                                        \
+  if (NS_WARN_IF(!XRE_IsParentProcess())) {                                 \
     return NS_ERROR_FAILURE;                                                \
   }
 
 namespace mozilla {
 namespace dom {
 
 using namespace indexedDB;
 
@@ -120,30 +120,16 @@ public:
 namespace {
 
 // Singleton for DataStoreService.
 StaticRefPtr<DataStoreService> gDataStoreService;
 static uint64_t gCounterID = 0;
 
 typedef nsClassHashtable<nsUint32HashKey, DataStoreInfo> HashApp;
 
-bool
-IsMainProcess()
-{
-  static const bool isMainProcess =
-    XRE_GetProcessType() == GeckoProcessType_Default;
-  return isMainProcess;
-}
-
-void
-AssertIsInMainProcess()
-{
-  MOZ_ASSERT(IsMainProcess());
-}
-
 void
 RejectPromise(nsPIDOMWindow* aWindow, Promise* aPromise, nsresult aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(NS_FAILED(aRv));
 
   nsRefPtr<DOMError> error;
   if (aRv == NS_ERROR_DOM_SECURITY_ERR) {
@@ -156,48 +142,45 @@ RejectPromise(nsPIDOMWindow* aWindow, Pr
 
   aPromise->MaybeRejectBrokenly(error);
 }
 
 void
 DeleteDatabase(const nsAString& aName,
                const nsAString& aManifestURL)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   nsRefPtr<DataStoreDB> db = new DataStoreDB(aManifestURL, aName);
   db->Delete();
 }
 
 PLDHashOperator
 DeleteDataStoresAppEnumerator(
                              const uint32_t& aAppId,
                              nsAutoPtr<DataStoreInfo>& aInfo,
                              void* aUserData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   auto* appId = static_cast<uint32_t*>(aUserData);
   if (*appId != aAppId) {
     return PL_DHASH_NEXT;
   }
 
   DeleteDatabase(aInfo->mName, aInfo->mManifestURL);
   return PL_DHASH_REMOVE;
 }
 
 PLDHashOperator
 DeleteDataStoresEnumerator(const nsAString& aName,
                            nsAutoPtr<HashApp>& aApps,
                            void* aUserData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   aApps->Enumerate(DeleteDataStoresAppEnumerator, aUserData);
   return aApps->Count() ? PL_DHASH_NEXT : PL_DHASH_REMOVE;
 }
 
 void
 GeneratePermissionName(nsAString& aPermission,
                        const nsAString& aName,
@@ -210,18 +193,17 @@ GeneratePermissionName(nsAString& aPermi
 }
 
 nsresult
 ResetPermission(uint32_t aAppId, const nsAString& aOriginURL,
                 const nsAString& aManifestURL,
                 const nsAString& aPermission,
                 bool aReadOnly)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   nsresult rv;
   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<nsIURI> uri;
@@ -342,18 +324,17 @@ public:
   nsTArray<DataStoreInfo>& mStores;
 };
 
 PLDHashOperator
 GetDataStoreInfosEnumerator(const uint32_t& aAppId,
                             DataStoreInfo* aInfo,
                             void* aUserData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   auto* data = static_cast<GetDataStoreInfosData*>(aUserData);
   if (aAppId == data->mAppId) {
     return PL_DHASH_NEXT;
   }
 
   HashApp* apps;
   if (!data->mAccessStores.Get(data->mName, &apps)) {
@@ -379,18 +360,17 @@ GetDataStoreInfosEnumerator(const uint32
   return PL_DHASH_NEXT;
 }
 
 PLDHashOperator
 GetAppManifestURLsEnumerator(const uint32_t& aAppId,
                              DataStoreInfo* aInfo,
                              void* aUserData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   auto* manifestURLs = static_cast<nsIMutableArray*>(aUserData);
   nsCOMPtr<nsISupportsString> manifestURL(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
   if (manifestURL) {
     manifestURL->SetData(aInfo->mManifestURL);
     manifestURLs->AppendElement(manifestURL, false);
   }
 
@@ -412,18 +392,17 @@ public:
   nsresult mResult;
 };
 
 PLDHashOperator
 AddPermissionsEnumerator(const uint32_t& aAppId,
                          DataStoreInfo* aInfo,
                          void* userData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   auto* data = static_cast<AddPermissionsData*>(userData);
 
   // ReadOnly is decided by the owner first.
   bool readOnly = data->mReadOnly || aInfo->mReadOnly;
 
   data->mResult = ResetPermission(aAppId, aInfo->mOriginURL,
                                   aInfo->mManifestURL,
@@ -452,18 +431,17 @@ public:
   nsresult mResult;
 };
 
 PLDHashOperator
 AddAccessPermissionsEnumerator(const uint32_t& aAppId,
                                DataStoreInfo* aInfo,
                                void* userData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   auto* data = static_cast<AddAccessPermissionsData*>(userData);
 
   nsString permission;
   GeneratePermissionName(permission, data->mName, aInfo->mManifestURL);
 
   // ReadOnly is decided by the owner first.
   bool readOnly = aInfo->mReadOnly || data->mReadOnly;
@@ -512,25 +490,23 @@ public:
 
   RevisionAddedEnableStoreCallback(uint32_t aAppId,
                                    const nsAString& aName,
                                    const nsAString& aManifestURL)
     : mAppId(aAppId)
     , mName(aName)
     , mManifestURL(aManifestURL)
   {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
   }
 
   void
   Run(const nsAString& aRevisionId)
   {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
     nsRefPtr<DataStoreService> service = DataStoreService::Get();
     MOZ_ASSERT(service);
 
     service->EnableDataStore(mAppId, mName, mManifestURL);
   }
 
 private:
@@ -548,25 +524,23 @@ public:
   NS_DECL_ISUPPORTS
 
   FirstRevisionIdCallback(uint32_t aAppId, const nsAString& aName,
                           const nsAString& aManifestURL)
     : mAppId(aAppId)
     , mName(aName)
     , mManifestURL(aManifestURL)
   {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
   }
 
   void
   Run(DataStoreDB* aDb, RunStatus aStatus) override
   {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
     MOZ_ASSERT(aDb);
 
     if (aStatus == Error) {
       NS_WARNING("Failed to create the first revision.");
       return;
     }
 
     ErrorResult error;
@@ -637,18 +611,17 @@ public:
 
     return NS_OK;
   }
 
   // nsIDOMEventListener
   NS_IMETHOD
   HandleEvent(nsIDOMEvent* aEvent) override
   {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
     nsRefPtr<IDBRequest> request;
     request.swap(mRequest);
 
     nsRefPtr<IDBTransaction> txn;
     txn.swap(mTxn);
 
     request->RemoveEventListener(NS_LITERAL_STRING("success"), this, false);
@@ -825,17 +798,17 @@ DataStoreService::Get()
 }
 
 /* static */ void
 DataStoreService::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (gDataStoreService) {
-    if (IsMainProcess()) {
+    if (XRE_IsParentProcess()) {
       nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
       if (obs) {
         obs->RemoveObserver(gDataStoreService, "webapps-clear-data");
       }
     }
 
     gDataStoreService = nullptr;
   }
@@ -858,17 +831,17 @@ DataStoreService::DataStoreService()
 DataStoreService::~DataStoreService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 nsresult
 DataStoreService::Init()
 {
-  if (!IsMainProcess()) {
+  if (!XRE_IsParentProcess()) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (!obs) {
     return NS_ERROR_FAILURE;
   }
 
@@ -968,17 +941,17 @@ DataStoreService::GetDataStores(nsIDOMWi
 
   nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
   MOZ_ASSERT(principal);
 
   nsTArray<DataStoreInfo> stores;
 
   // If this request comes from the main process, we have access to the
   // window, so we can skip the ipc communication.
-  if (IsMainProcess()) {
+  if (XRE_IsParentProcess()) {
     uint32_t appId;
     nsresult rv = principal->GetAppId(&appId);
     if (NS_FAILED(rv)) {
       RejectPromise(window, promise, rv);
       promise.forget(aDataStores);
       return NS_OK;
     }
 
@@ -1127,18 +1100,17 @@ DataStoreService::GetDataStoresResolve(n
 // name and available for this 'aAppId'.
 nsresult
 DataStoreService::GetDataStoreInfos(const nsAString& aName,
                                     const nsAString& aOwner,
                                     uint32_t aAppId,
                                     nsIPrincipal* aPrincipal,
                                     nsTArray<DataStoreInfo>& aStores)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   nsCOMPtr<nsIAppsService> appsService =
     do_GetService("@mozilla.org/AppsService;1");
   if (NS_WARN_IF(!appsService)) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<mozIApplication> app;
@@ -1237,30 +1209,28 @@ DataStoreService::CheckPermission(nsIPri
 
   return NS_OK;
 }
 
 // This method is called when an app with DataStores is deleted.
 void
 DataStoreService::DeleteDataStores(uint32_t aAppId)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   mStores.Enumerate(DeleteDataStoresEnumerator, &aAppId);
   mAccessStores.Enumerate(DeleteDataStoresEnumerator, &aAppId);
 }
 
 NS_IMETHODIMP
 DataStoreService::Observe(nsISupports* aSubject,
                           const char* aTopic,
                           const char16_t* aData)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   if (strcmp(aTopic, "webapps-clear-data")) {
     return NS_OK;
   }
 
   nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
     do_QueryInterface(aSubject);
   MOZ_ASSERT(params);
@@ -1289,18 +1259,17 @@ DataStoreService::Observe(nsISupports* a
 
 nsresult
 DataStoreService::AddPermissions(uint32_t aAppId,
                                  const nsAString& aName,
                                  const nsAString& aOriginURL,
                                  const nsAString& aManifestURL,
                                  bool aReadOnly)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   // This is the permission name.
   nsString permission;
   GeneratePermissionName(permission, aName, aManifestURL);
 
   // When a new DataStore is installed, the permissions must be set for the
   // owner app.
   nsresult rv = ResetPermission(aAppId, aOriginURL, aManifestURL, permission,
@@ -1322,18 +1291,17 @@ DataStoreService::AddPermissions(uint32_
 }
 
 nsresult
 DataStoreService::AddAccessPermissions(uint32_t aAppId, const nsAString& aName,
                                        const nsAString& aOriginURL,
                                        const nsAString& aManifestURL,
                                        bool aReadOnly)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   // When an app wants to have access to a DataStore, the permissions must be
   // set.
   HashApp* apps = nullptr;
   if (!mStores.Get(aName, &apps)) {
     return NS_OK;
   }
 
@@ -1344,18 +1312,17 @@ DataStoreService::AddAccessPermissions(u
 
 // This method starts the operation to create the first revision for a DataStore
 // if needed.
 nsresult
 DataStoreService::CreateFirstRevisionId(uint32_t aAppId,
                                         const nsAString& aName,
                                         const nsAString& aManifestURL)
 {
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   nsRefPtr<DataStoreDB> db = new DataStoreDB(aManifestURL, aName);
 
   nsRefPtr<FirstRevisionIdCallback> callback =
     new FirstRevisionIdCallback(aAppId, aName, aManifestURL);
 
   Sequence<nsString> dbs;
   if (!dbs.AppendElement(NS_LITERAL_STRING(DATASTOREDB_REVISION), fallible)) {
@@ -1375,17 +1342,17 @@ DataStoreService::EnableDataStore(uint32
     HashApp* apps = nullptr;
     DataStoreInfo* info = nullptr;
     if (mStores.Get(aName, &apps) && apps->Get(aAppId, &info)) {
       info->Enable();
     }
   }
 
   // Notify the child processes.
-  if (IsMainProcess()) {
+  if (XRE_IsParentProcess()) {
     nsTArray<ContentParent*> children;
     ContentParent::GetAll(children);
     for (uint32_t i = 0; i < children.Length(); i++) {
       if (children[i]->NeedsDataStoreInfos()) {
         unused << children[i]->SendDataStoreNotify(aAppId, nsAutoString(aName),
                                                    nsAutoString(aManifestURL));
       }
     }
@@ -1442,18 +1409,17 @@ DataStoreService::RemoveCounter(uint32_t
 }
 
 nsresult
 DataStoreService::GetDataStoresFromIPC(const nsAString& aName,
                                        const nsAString& aOwner,
                                        nsIPrincipal* aPrincipal,
                                        nsTArray<DataStoreSetting>* aValue)
 {
-  MOZ_ASSERT(IsMainProcess());
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
 
   uint32_t appId;
   nsresult rv = aPrincipal->GetAppId(&appId);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsTArray<DataStoreInfo> stores;
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -556,17 +556,17 @@ FileUpdateDispatcher::Observe(nsISupport
     return NS_OK;
   }
 
   if (!dsf || !dsf->mFile) {
     NS_WARNING("FileUpdateDispatcher: Device storage file looks invalid!");
     return NS_OK;
   }
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     // Child process. Forward the notification to the parent.
     ContentChild::GetSingleton()
       ->SendFilePathUpdateNotify(dsf->mStorageType,
                                  dsf->mStorageName,
                                  dsf->mPath,
                                  NS_ConvertUTF16toUTF8(aData));
     return NS_OK;
   }
@@ -687,17 +687,17 @@ DeviceStorageFile::Dump(const char* labe
 {
   nsString path;
   if (mFile) {
     mFile->GetPath(path);
   } else {
     path = NS_LITERAL_STRING("(null)");
   }
   const char* ptStr;
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     ptStr = "parent";
   } else {
     ptStr = "child";
   }
 
   printf_stderr("DSF (%s) %s: mStorageType '%s' mStorageName '%s' "
                 "mRootDir '%s' mPath '%s' mFile->GetPath '%s'\n",
                 ptStr, label,
@@ -809,17 +809,17 @@ OverrideRootDir::Init()
       NS_NewLocalFile(overrideRootDir, false,
                       getter_AddRefs(sDirs->overrideRootDir));
     } else {
       sDirs->overrideRootDir = nullptr;
     }
   }
 
   if (sDirs->overrideRootDir) {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       // Only the parent process can create directories. In testing, because
       // the preference is updated after startup, its entirely possible that
       // the preference updated notification will be received by a child
       // prior to the parent.
       nsresult rv
         = sDirs->overrideRootDir->Create(nsIFile::DIRECTORY_TYPE, 0777);
       nsString path;
       sDirs->overrideRootDir->GetPath(path);
@@ -931,17 +931,17 @@ InitDirs()
 #else
   dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
                   getter_AddRefs(sDirs->apps));
   if (sDirs->apps) {
     sDirs->apps->AppendRelativeNativePath(NS_LITERAL_CSTRING("webapps"));
   }
 #endif
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     NS_GetSpecialDirectory("UAppData", getter_AddRefs(sDirs->crashes));
     if (sDirs->crashes) {
       sDirs->crashes->Append(NS_LITERAL_STRING("Crash Reports"));
     }
   } else {
     // NS_GetSpecialDirectory("UAppData") fails in content processes because
     // gAppData from toolkit/xre/nsAppRunner.cpp is not initialized.
 #ifdef MOZ_WIDGET_GONK
@@ -2053,17 +2053,17 @@ ContinueCursorEvent::GetNextFile()
   return nullptr;
 }
 
 ContinueCursorEvent::~ContinueCursorEvent() {}
 
 void
 ContinueCursorEvent::Continue()
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     DebugOnly<nsresult> rv = NS_DispatchToMainThread(this);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     return;
   }
 
   nsRefPtr<DeviceStorageFile> file = GetNextFile();
 
   if (!file) {
@@ -2239,17 +2239,17 @@ nsDOMDeviceStorageCursor::Allow(JS::Hand
   MOZ_ASSERT(aChoices.isUndefined());
 
   if (!mFile->IsSafePath()) {
     nsCOMPtr<nsIRunnable> r
       = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED);
     return NS_DispatchToMainThread(r);
   }
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     PDeviceStorageRequestChild* child
       = new DeviceStorageRequestChild(this, mFile);
     DeviceStorageEnumerationParams params(mFile->mStorageType,
                                           mFile->mStorageName,
                                           mFile->mRootDir,
                                           mSince);
     ContentChild::GetSingleton()->SendPDeviceStorageRequestConstructor(child,
                                                                        params);
@@ -3008,17 +3008,17 @@ public:
         }
 
         if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
           r = new PostErrorEvent(mRequest.forget(),
                                  POST_ERROR_EVENT_ILLEGAL_TYPE);
           return NS_DispatchToCurrentThread(r);
         }
 
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
 
           DeviceStorageCreateFdParams params;
           params.type() = mFile->mStorageType;
           params.storageName() = mFile->mStorageName;
           params.relpath() = mFile->mPath;
 
           mFile->Dump("DeviceStorageCreateFdParams");
 
@@ -3048,17 +3048,17 @@ public:
 
         if (!typeChecker->Check(mFile->mStorageType, mFile->mFile) ||
             !typeChecker->Check(mFile->mStorageType, mBlob)) {
           r = new PostErrorEvent(mRequest.forget(),
                                  POST_ERROR_EVENT_ILLEGAL_TYPE);
           return NS_DispatchToCurrentThread(r);
         }
 
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           BlobChild* actor
             = ContentChild::GetSingleton()->GetOrCreateActorForBlob(
               static_cast<Blob*>(mBlob.get()));
           if (!actor) {
             return NS_ERROR_FAILURE;
           }
 
           DeviceStorageAddParams params;
@@ -3094,17 +3094,17 @@ public:
 
         if (!typeChecker->Check(mFile->mStorageType, mFile->mFile) ||
             !typeChecker->Check(mFile->mStorageType, mBlob)) {
           r = new PostErrorEvent(mRequest.forget(),
                                  POST_ERROR_EVENT_ILLEGAL_TYPE);
           return NS_DispatchToCurrentThread(r);
         }
 
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           BlobChild* actor
             = ContentChild::GetSingleton()->GetOrCreateActorForBlob(
               static_cast<Blob*>(mBlob.get()));
           if (!actor) {
             return NS_ERROR_FAILURE;
           }
 
           DeviceStorageAppendParams params;
@@ -3140,17 +3140,17 @@ public:
         }
 
         if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
           r = new PostErrorEvent(mRequest.forget(),
                                  POST_ERROR_EVENT_ILLEGAL_TYPE);
           return NS_DispatchToCurrentThread(r);
         }
 
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageGetParams params(mFile->mStorageType,
                                         mFile->mStorageName,
                                         mFile->mRootDir,
                                         mFile->mPath);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
@@ -3174,48 +3174,48 @@ public:
         }
 
         if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
           r = new PostErrorEvent(mRequest.forget(),
                                  POST_ERROR_EVENT_ILLEGAL_TYPE);
           return NS_DispatchToCurrentThread(r);
         }
 
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageDeleteParams params(mFile->mStorageType,
                                            mFile->mStorageName,
                                            mFile->mPath);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
         r = new DeleteFileEvent(mFile, mRequest.forget());
         break;
       }
 
       case DEVICE_STORAGE_REQUEST_FREE_SPACE:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageFreeSpaceParams params(mFile->mStorageType,
                                               mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
         r = new FreeSpaceFileEvent(mFile, mRequest.forget());
         break;
       }
 
       case DEVICE_STORAGE_REQUEST_USED_SPACE:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageUsedSpaceParams params(mFile->mStorageType,
                                               mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
@@ -3226,32 +3226,32 @@ public:
         MOZ_ASSERT(usedSpaceCache);
         r = new UsedSpaceFileEvent(mFile, mRequest.forget());
         usedSpaceCache->Dispatch(r);
         return NS_OK;
       }
 
       case DEVICE_STORAGE_REQUEST_AVAILABLE:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageAvailableParams params(mFile->mStorageType,
                                               mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
         r = new PostAvailableResultEvent(mFile, mRequest);
         return NS_DispatchToCurrentThread(r);
       }
 
       case DEVICE_STORAGE_REQUEST_STATUS:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageStatusParams params(mFile->mStorageType,
                                               mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
@@ -3262,47 +3262,47 @@ public:
       case DEVICE_STORAGE_REQUEST_WATCH:
       {
         mDeviceStorage->mAllowedToWatchFile = true;
         return NS_OK;
       }
 
       case DEVICE_STORAGE_REQUEST_FORMAT:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageFormatParams params(mFile->mStorageType,
                                            mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
         r = new PostFormatResultEvent(mFile, mRequest);
         return NS_DispatchToCurrentThread(r);
       }
 
       case DEVICE_STORAGE_REQUEST_MOUNT:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageMountParams params(mFile->mStorageType,
                                            mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
         r = new PostMountResultEvent(mFile, mRequest);
         return NS_DispatchToCurrentThread(r);
       }
 
       case DEVICE_STORAGE_REQUEST_UNMOUNT:
       {
-        if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        if (!XRE_IsParentProcess()) {
           PDeviceStorageRequestChild* child
             = new DeviceStorageRequestChild(mRequest, mFile);
           DeviceStorageUnmountParams params(mFile->mStorageType,
                                            mFile->mStorageName);
           ContentChild::GetSingleton()
             ->SendPDeviceStorageRequestConstructor(child, params);
           return NS_OK;
         }
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -592,17 +592,17 @@ EventStateManager::PreHandleEvent(nsPres
   case NS_MOUSE_EXIT_WIDGET:
     // If this is a remote frame, we receive NS_MOUSE_EXIT_WIDGET from the parent
     // the mouse exits our content. Since the parent may update the cursor
     // while the mouse is outside our frame, and since PuppetWidget caches the
     // current cursor internally, re-entering our content (say from over a
     // window edge) wont update the cursor if the cached value and the current
     // cursor match. So when the mouse exits a remote frame, clear the cached
     // widget cursor so a proper update will occur when the mouse re-enters.
-    if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    if (XRE_IsContentProcess()) {
       ClearCachedWidgetCursor(mCurrentTarget);
     }
 
     // Flag helps to suppress double event sending into process of content.
     // For more information see comment above, at NS_MOUSE_ENTER_WIDGET case.
     aEvent->mFlags.mNoCrossProcessBoundaryForwarding = true;
 
     // If the event is not a top-level window exit, then it's not
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -1059,17 +1059,17 @@ IMEStateManager::SetIMEState(const IMESt
                      (formElement ?
                        NS_LITERAL_STRING("next") : EmptyString()));
     }
   }
 
   // XXX I think that we should use nsContentUtils::IsCallerChrome() instead
   //     of the process type.
   if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN &&
-      XRE_GetProcessType() != GeckoProcessType_Content) {
+      !XRE_IsContentProcess()) {
     aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME;
   }
 
   SetInputContext(aWidget, context, aAction);
 }
 
 // static
 void
--- a/dom/filehandle/FileStreamWrappers.cpp
+++ b/dom/filehandle/FileStreamWrappers.cpp
@@ -237,17 +237,17 @@ FileInputStreamWrapper::IsNonBlocking(bo
   *_retval = false;
   return NS_OK;
 }
 
 void
 FileInputStreamWrapper::Serialize(InputStreamParams& aParams,
                                   FileDescriptorArray& /* aFDs */)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIInputStream> thisStream = do_QueryObject(this);
 
   aParams = mozilla::ipc::SameProcessInputStreamParams(
     reinterpret_cast<intptr_t>(thisStream.forget().take()));
 }
 
--- a/dom/filesystem/CreateDirectoryTask.cpp
+++ b/dom/filesystem/CreateDirectoryTask.cpp
@@ -34,17 +34,17 @@ CreateDirectoryTask::CreateDirectoryTask
 }
 
 CreateDirectoryTask::CreateDirectoryTask(
   FileSystemBase* aFileSystem,
   const FileSystemCreateDirectoryParams& aParam,
   FileSystemRequestParent* aParent)
   : FileSystemTaskBase(aFileSystem, aParam, aParent)
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
   mTargetRealPath = aParam.realPath();
 }
 
 CreateDirectoryTask::~CreateDirectoryTask()
 {
@@ -79,17 +79,17 @@ CreateDirectoryTask::SetSuccessRequestRe
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   FileSystemDirectoryResponse r = aValue;
   mTargetRealPath = r.realPath();
 }
 
 nsresult
 CreateDirectoryTask::Work()
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
 
   if (mFileSystem->IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath);
--- a/dom/filesystem/CreateFileTask.cpp
+++ b/dom/filesystem/CreateFileTask.cpp
@@ -34,17 +34,17 @@ CreateFileTask::CreateFileTask(FileSyste
   : FileSystemTaskBase(aFileSystem)
   , mTargetRealPath(aPath)
   , mReplace(replace)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
   GetOutputBufferSize();
   if (aBlobData) {
-    if (FileSystemUtils::IsParentProcess()) {
+    if (XRE_IsParentProcess()) {
       aBlobData->GetInternalStream(getter_AddRefs(mBlobStream), aRv);
       NS_WARN_IF(aRv.Failed());
     } else {
       mBlobData = aBlobData;
     }
   }
   mArrayData.SwapElements(aArrayData);
   nsCOMPtr<nsIGlobalObject> globalObject =
@@ -56,17 +56,17 @@ CreateFileTask::CreateFileTask(FileSyste
 }
 
 CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,
                                const FileSystemCreateFileParams& aParam,
                                FileSystemRequestParent* aParent)
   : FileSystemTaskBase(aFileSystem, aParam, aParent)
   , mReplace(false)
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
   GetOutputBufferSize();
 
   mTargetRealPath = aParam.realPath();
 
   mReplace = aParam.replace();
@@ -163,17 +163,17 @@ CreateFileTask::Work()
     ~AutoClose()
     {
       mStream->Close();
     }
   private:
     nsCOMPtr<nsIOutputStream> mStream;
   };
 
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
 
   if (mFileSystem->IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath);
@@ -319,17 +319,17 @@ CreateFileTask::GetPermissionAccessType(
   }
 
   aAccess.AssignLiteral("create");
 }
 
 void
 CreateFileTask::GetOutputBufferSize() const
 {
-  if (sOutputBufferSize || !FileSystemUtils::IsParentProcess()) {
+  if (sOutputBufferSize || !XRE_IsParentProcess()) {
     return;
   }
   sOutputBufferSize =
     mozilla::Preferences::GetUint("dom.filesystem.outputBufferSize", 4096 * 4);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/filesystem/DeviceStorageFileSystem.cpp
+++ b/dom/filesystem/DeviceStorageFileSystem.cpp
@@ -42,17 +42,17 @@ DeviceStorageFileSystem::DeviceStorageFi
   // Get the permission name required to access the file system.
   nsresult rv =
     DeviceStorageTypeChecker::GetPermissionForType(mStorageType, mPermission);
   NS_WARN_IF(NS_FAILED(rv));
 
   // Get the local path of the file system root.
   // Since the child process is not allowed to access the file system, we only
   // do this from the parent process.
-  if (!FileSystemUtils::IsParentProcess()) {
+  if (!XRE_IsParentProcess()) {
     return;
   }
   nsCOMPtr<nsIFile> rootFile;
   DeviceStorageFile::GetRootDirectoryForType(aStorageType,
                                              aStorageName,
                                              getter_AddRefs(rootFile));
 
   NS_WARN_IF(!rootFile || NS_FAILED(rootFile->GetPath(mLocalRootPath)));
@@ -95,33 +95,33 @@ DeviceStorageFileSystem::GetWindow() con
     return nullptr;
   }
   return mDeviceStorage->GetOwner();
 }
 
 already_AddRefed<nsIFile>
 DeviceStorageFileSystem::GetLocalFile(const nsAString& aRealPath) const
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Should be on parent process!");
   nsAutoString localPath;
   FileSystemUtils::NormalizedPathToLocalPath(aRealPath, localPath);
   localPath = mLocalRootPath + localPath;
   nsCOMPtr<nsIFile> file;
   nsresult rv = NS_NewLocalFile(localPath, false, getter_AddRefs(file));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
   return file.forget();
 }
 
 bool
 DeviceStorageFileSystem::GetRealPath(BlobImpl* aFile, nsAString& aRealPath) const
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Should be on parent process!");
   MOZ_ASSERT(aFile, "aFile Should not be null.");
 
   aRealPath.Truncate();
 
   nsAutoString filePath;
   ErrorResult rv;
   aFile->GetMozFullPathInternal(filePath, rv);
@@ -136,17 +136,17 @@ const nsAString&
 DeviceStorageFileSystem::GetRootName() const
 {
   return mStorageName;
 }
 
 bool
 DeviceStorageFileSystem::IsSafeFile(nsIFile* aFile) const
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Should be on parent process!");
   MOZ_ASSERT(aFile);
 
   // Check if this file belongs to this storage.
   nsAutoString path;
   if (NS_FAILED(aFile->GetPath(path))) {
     return false;
   }
--- a/dom/filesystem/FileSystemTaskBase.cpp
+++ b/dom/filesystem/FileSystemTaskBase.cpp
@@ -30,17 +30,17 @@ FileSystemTaskBase::FileSystemTaskBase(F
 
 FileSystemTaskBase::FileSystemTaskBase(FileSystemBase* aFileSystem,
                                        const FileSystemParams& aParam,
                                        FileSystemRequestParent* aParent)
   : mErrorValue(NS_OK)
   , mFileSystem(aFileSystem)
   , mRequestParent(aParent)
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem, "aFileSystem should not be null.");
 }
 
 FileSystemTaskBase::~FileSystemTaskBase()
 {
 }
@@ -56,17 +56,17 @@ FileSystemTaskBase::Start()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
 
   if (HasError()) {
     NS_DispatchToMainThread(this);
     return;
   }
 
-  if (FileSystemUtils::IsParentProcess()) {
+  if (XRE_IsParentProcess()) {
     // Run in parent process.
     // Start worker thread.
     nsCOMPtr<nsIEventTarget> target
       = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
     NS_ASSERTION(target, "Must have stream transport service.");
     target->Dispatch(this, NS_DISPATCH_NORMAL);
     return;
   }
@@ -116,30 +116,30 @@ FileSystemTaskBase::HandleResult()
   } else {
     HandlerCallback();
   }
 }
 
 FileSystemResponseValue
 FileSystemTaskBase::GetRequestResult() const
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   if (HasError()) {
     return FileSystemErrorResponse(mErrorValue);
   } else {
     return GetSuccessRequestResult();
   }
 }
 
 void
 FileSystemTaskBase::SetRequestResult(const FileSystemResponseValue& aValue)
 {
-  MOZ_ASSERT(!FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(!XRE_IsParentProcess(),
              "Only call from child process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   if (aValue.type() == FileSystemResponseValue::TFileSystemErrorResponse) {
     FileSystemErrorResponse r = aValue;
     mErrorValue = r.error();
   } else {
     SetSuccessRequestResult(aValue);
   }
@@ -151,17 +151,17 @@ FileSystemTaskBase::Recv__delete__(const
   SetRequestResult(aValue);
   HandlerCallback();
   return true;
 }
 
 BlobParent*
 FileSystemTaskBase::GetBlobParent(BlobImpl* aFile) const
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFile);
 
   // Load the lazy dom file data from the parent before sending to the child.
   nsString mimeType;
   aFile->GetType(mimeType);
 
--- a/dom/filesystem/FileSystemUtils.cpp
+++ b/dom/filesystem/FileSystemUtils.cpp
@@ -60,17 +60,10 @@ FileSystemUtils::IsDescendantPath(const 
   if (aDescendantPath.Length() < prefix.Length() ||
       !StringBeginsWith(aDescendantPath, prefix)) {
     return false;
   }
 
   return true;
 }
 
-// static
-bool
-FileSystemUtils::IsParentProcess()
-{
-  return XRE_GetProcessType() == GeckoProcessType_Default;
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/filesystem/FileSystemUtils.h
+++ b/dom/filesystem/FileSystemUtils.h
@@ -36,18 +36,15 @@ public:
 
   /*
    * Return true if aDescendantPath is a descendant of aPath. Both aPath and
    * aDescendantPath are absolute DOM path.
    */
   static bool
   IsDescendantPath(const nsAString& aPath, const nsAString& aDescendantPath);
 
-  static bool
-  IsParentProcess();
-
   static const char16_t kSeparatorChar = char16_t('/');
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_FileSystemUtils_h
--- a/dom/filesystem/GetDirectoryListingTask.cpp
+++ b/dom/filesystem/GetDirectoryListingTask.cpp
@@ -37,17 +37,17 @@ GetDirectoryListingTask::GetDirectoryLis
   mPromise = Promise::Create(globalObject, aRv);
 }
 
 GetDirectoryListingTask::GetDirectoryListingTask(FileSystemBase* aFileSystem,
                                                  const FileSystemGetDirectoryListingParams& aParam,
                                                  FileSystemRequestParent* aParent)
   : FileSystemTaskBase(aFileSystem, aParam, aParent)
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
   mTargetRealPath = aParam.realPath();
 }
 
 GetDirectoryListingTask::~GetDirectoryListingTask()
 {
@@ -100,17 +100,17 @@ GetDirectoryListingTask::SetSuccessReque
   for (unsigned i = 0; i < blobs.Length(); i++) {
     mTargetBlobImpls.AppendElement(static_cast<BlobChild*>(blobs[i])->GetBlobImpl());
   }
 }
 
 nsresult
 GetDirectoryListingTask::Work()
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
 
   if (mFileSystem->IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   // Whether we want to get the root directory.
@@ -217,17 +217,17 @@ GetDirectoryListingTask::HandlerCallback
   for (unsigned i = 0; i < count; i++) {
     if (mTargetBlobImpls[i]->IsDirectory()) {
       nsAutoString name;
       mTargetBlobImpls[i]->GetName(name);
       nsAutoString path(mTargetRealPath);
       path.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR);
       path.Append(name);
 #ifdef DEBUG
-      if (FileSystemUtils::IsParentProcess()) {
+      if (XRE_IsParentProcess()) {
         nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(path);
         bool exist;
         file->Exists(&exist);
         MOZ_ASSERT(exist);
       }
 #endif
       listing[i].SetAsDirectory() = new Directory(mFileSystem, path);
     } else {
--- a/dom/filesystem/GetFileOrDirectoryTask.cpp
+++ b/dom/filesystem/GetFileOrDirectoryTask.cpp
@@ -42,17 +42,17 @@ GetFileOrDirectoryTask::GetFileOrDirecto
 
 GetFileOrDirectoryTask::GetFileOrDirectoryTask(
   FileSystemBase* aFileSystem,
   const FileSystemGetFileOrDirectoryParams& aParam,
   FileSystemRequestParent* aParent)
   : FileSystemTaskBase(aFileSystem, aParam, aParent)
   , mIsDirectory(false)
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
   mTargetRealPath = aParam.realPath();
 }
 
 GetFileOrDirectoryTask::~GetFileOrDirectoryTask()
 {
@@ -114,17 +114,17 @@ GetFileOrDirectoryTask::SetSuccessReques
       break;
     }
   }
 }
 
 nsresult
 GetFileOrDirectoryTask::Work()
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
 
   if (mFileSystem->IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   // Whether we want to get the root directory.
--- a/dom/filesystem/RemoveTask.cpp
+++ b/dom/filesystem/RemoveTask.cpp
@@ -44,17 +44,17 @@ RemoveTask::RemoveTask(FileSystemBase* a
 
 RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
                        const FileSystemRemoveParams& aParam,
                        FileSystemRequestParent* aParent)
   : FileSystemTaskBase(aFileSystem, aParam, aParent)
   , mRecursive(false)
   , mReturnValue(false)
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   MOZ_ASSERT(aFileSystem);
 
   mDirRealPath = aParam.directory();
 
   mRecursive = aParam.recursive();
 
@@ -118,17 +118,17 @@ RemoveTask::SetSuccessRequestResult(cons
   MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   FileSystemBooleanResponse r = aValue;
   mReturnValue = r.success();
 }
 
 nsresult
 RemoveTask::Work()
 {
-  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Only call from parent process!");
   MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
 
   if (mFileSystem->IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   // Get the DOM path if a File is passed as the target.
--- a/dom/fmradio/FMRadioService.cpp
+++ b/dom/fmradio/FMRadioService.cpp
@@ -37,17 +37,17 @@ using namespace mozilla::hal;
 using mozilla::Preferences;
 
 BEGIN_FMRADIO_NAMESPACE
 
 // static
 IFMRadioService*
 IFMRadioService::Singleton()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return FMRadioChild::Singleton();
   } else {
     return FMRadioService::Singleton();
   }
 }
 
 StaticRefPtr<FMRadioService> FMRadioService::sFMRadioService;
 
@@ -1238,17 +1238,17 @@ FMRadioService::UpdateFrequency()
     mRadiotextSet = false;
   }
 }
 
 // static
 FMRadioService*
 FMRadioService::Singleton()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!sFMRadioService) {
     sFMRadioService = new FMRadioService();
     ClearOnShutdown(&sFMRadioService);
   }
 
   return sFMRadioService;
--- a/dom/fmradio/ipc/FMRadioChild.cpp
+++ b/dom/fmradio/ipc/FMRadioChild.cpp
@@ -333,17 +333,17 @@ FMRadioChild::EnableAudio(bool aAudioEna
 {
   SendEnableAudio(aAudioEnabled);
 }
 
 // static
 FMRadioChild*
 FMRadioChild::Singleton()
 {
-  MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
+  MOZ_ASSERT(!XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!sFMRadioChild) {
     sFMRadioChild = new FMRadioChild();
   }
 
   return sFMRadioChild;
 }
--- a/dom/gamepad/GamepadFunctions.cpp
+++ b/dom/gamepad/GamepadFunctions.cpp
@@ -19,17 +19,17 @@ namespace {
 uint32_t gGamepadIndex = 0;
 }
 
 template<class T>
 void
 NotifyGamepadChange(const T& aInfo)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   GamepadChangeEvent e(aInfo);
   nsTArray<ContentParent*> t;
   ContentParent::GetAll(t);
   for(uint32_t i = 0; i < t.Length(); ++i) {
     unused << t[i]->SendGamepadUpdate(e);
   }
   // If we have a GamepadService in the main process, send directly to it.
   if (GamepadService::IsServiceRunning()) {
@@ -39,69 +39,69 @@ NotifyGamepadChange(const T& aInfo)
 }
 
 uint32_t
 AddGamepad(const char* aID,
            GamepadMappingType aMapping,
            uint32_t aNumButtons, uint32_t aNumAxes)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   int index = gGamepadIndex;
   gGamepadIndex++;
   GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
                  (uint32_t)aMapping, aNumButtons, aNumAxes);
   gGamepadIndex++;
   NotifyGamepadChange<GamepadAdded>(a);
   return index;
 }
 
 void
 RemoveGamepad(uint32_t aIndex)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   GamepadRemoved a(aIndex);
   NotifyGamepadChange<GamepadRemoved>(a);
 }
 
 void
 NewButtonEvent(uint32_t aIndex, uint32_t aButton,
                bool aPressed, double aValue)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   GamepadButtonInformation a(aIndex, aButton, aPressed, aValue);
   NotifyGamepadChange<GamepadButtonInformation>(a);
 }
 
 void
 NewButtonEvent(uint32_t aIndex, uint32_t aButton,
                bool aPressed)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   // When only a digital button is available the value will be synthesized.
   NewButtonEvent(aIndex, aButton, aPressed, aPressed ? 1.0L : 0.0L);
 }
 
 void
 NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
                  double aValue)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   GamepadAxisInformation a(aIndex, aAxis, aValue);
   NotifyGamepadChange<GamepadAxisInformation>(a);
 }
 
 void
 ResetGamepadIndexes()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   gGamepadIndex = 0;
 }
 
 } // namespace GamepadFunctions
 } // namespace dom
 } // namespace mozilla
--- a/dom/gamepad/GamepadMonitoring.cpp
+++ b/dom/gamepad/GamepadMonitoring.cpp
@@ -12,17 +12,17 @@ namespace mozilla {
 namespace dom {
 
 using namespace GamepadFunctions;
 
 void
 MaybeStopGamepadMonitoring()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   nsTArray<ContentParent*> t;
   ContentParent::GetAll(t);
   for(uint32_t i = 0; i < t.Length(); ++i) {
     if (t[i]->HasGamepadListener()) {
       return;
     }
   }
   StopGamepadMonitoring();
--- a/dom/gamepad/GamepadService.cpp
+++ b/dom/gamepad/GamepadService.cpp
@@ -80,17 +80,17 @@ GamepadService::Observe(nsISupports* aSu
 void
 GamepadService::BeginShutdown()
 {
   mShuttingDown = true;
   if (mTimer) {
     mTimer->Cancel();
   }
   if (mStarted) {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       MaybeStopGamepadMonitoring();
     } else {
       ContentChild::GetSingleton()->SendGamepadListenerRemoved();
     }
     mStarted = false;
   }
   // Don't let windows call back to unregister during shutdown
   for (uint32_t i = 0; i < mListeners.Length(); i++) {
@@ -110,17 +110,17 @@ GamepadService::AddListener(nsGlobalWind
     return;
   }
 
   if (mListeners.IndexOf(aWindow) != NoIndex) {
     return; // already exists
   }
 
   if (!mStarted && mEnabled) {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       StartGamepadMonitoring();
     } else {
       ContentChild::GetSingleton()->SendGamepadListenerAdded();
     }
     mStarted = true;
   }
   mListeners.AppendElement(aWindow);
 }
@@ -495,17 +495,17 @@ GamepadService::TimeoutHandler(nsITimer*
     return;
   }
 
   if (self->mShuttingDown) {
     return;
   }
 
   if (self->mListeners.Length() == 0) {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       MaybeStopGamepadMonitoring();
     } else {
       ContentChild::GetSingleton()->SendGamepadListenerRemoved();
     }
 
     self->mStarted = false;
       self->mGamepads.Clear();
     }
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -559,17 +559,17 @@ SynthesizeLocation(DOMTimeStamp aTimesta
   return pos.forget();
 }
 
 
 already_AddRefed<nsIDOMGeoPosition>
 nsGeolocationRequest::AdjustedLocation(nsIDOMGeoPosition *aPosition)
 {
   nsCOMPtr<nsIDOMGeoPosition> pos = aPosition;
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     GPSLOG("child process just copying position");
     return pos.forget();
   }
 
   // get the settings cache
   nsRefPtr<nsGeolocationSettings> gs = nsGeolocationSettings::GetGeolocationSettings();
   if (!gs) {
     return pos.forget();
@@ -753,17 +753,17 @@ nsresult nsGeolocationService::Init()
 {
   Preferences::AddIntVarCache(&sProviderTimeout, "geo.timeout", sProviderTimeout);
   Preferences::AddBoolVarCache(&sGeoEnabled, "geo.enabled", sGeoEnabled);
 
   if (!sGeoEnabled) {
     return NS_ERROR_FAILURE;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     sGeoInitPending = false;
     return NS_OK;
   }
 
   // check if the geolocation service is enable from settings
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
 
@@ -1008,17 +1008,17 @@ nsGeolocationService::StartDevice(nsIPri
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // we do not want to keep the geolocation devices online
   // indefinitely.  Close them down after a reasonable period of
   // inactivivity
   SetDisconnectTimer();
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     ContentChild* cpc = ContentChild::GetSingleton();
     cpc->SendAddGeolocationListener(IPC::Principal(aPrincipal),
                                     HighAccuracyRequested());
     return NS_OK;
   }
 
   // Start them up!
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
@@ -1071,17 +1071,17 @@ nsGeolocationService::HighAccuracyReques
   return false;
 }
 
 void
 nsGeolocationService::UpdateAccuracy(bool aForceHigh)
 {
   bool highRequired = aForceHigh || HighAccuracyRequested();
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     ContentChild* cpc = ContentChild::GetSingleton();
     if (cpc->IsAlive()) {
       cpc->SendSetGeolocationHigherAccuracy(highRequired);
     }
     return;
   }
 
   if (!mHigherAccuracy && highRequired) {
@@ -1098,17 +1098,17 @@ nsGeolocationService::UpdateAccuracy(boo
 void
 nsGeolocationService::StopDevice()
 {
   if(mDisconnectTimer) {
     mDisconnectTimer->Cancel();
     mDisconnectTimer = nullptr;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     ContentChild* cpc = ContentChild::GetSingleton();
     cpc->SendRemoveGeolocationListener();
     return; // bail early
   }
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     return;
--- a/dom/geolocation/nsGeolocationSettings.cpp
+++ b/dom/geolocation/nsGeolocationSettings.cpp
@@ -44,17 +44,17 @@ using namespace mozilla::dom;
 NS_IMPL_ISUPPORTS(nsGeolocationSettings, nsIObserver)
 
 StaticRefPtr<nsGeolocationSettings> nsGeolocationSettings::sSettings;
 
 already_AddRefed<nsGeolocationSettings>
 nsGeolocationSettings::GetGeolocationSettings()
 {
   // this singleton is only needed in the parent process...
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return nullptr;
   }
 
   nsRefPtr<nsGeolocationSettings> result;
   if (nsGeolocationSettings::sSettings) {
     result = nsGeolocationSettings::sSettings;
     return result.forget();
   }
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -741,17 +741,17 @@ UploadLastDir::FetchDirectoryAndDisplayP
   nsIURI* docURI = aDoc->GetDocumentURI();
   NS_PRECONDITION(docURI, "docURI is null");
 
   nsCOMPtr<nsILoadContext> loadContext = aDoc->GetLoadContext();
   nsCOMPtr<nsIContentPrefCallback2> prefCallback = 
     new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback);
 
 #ifdef MOZ_B2G
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     prefCallback->HandleCompletion(nsIContentPrefCallback2::COMPLETE_ERROR);
     return NS_OK;
   }
 #endif
 
   // Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder
   nsCOMPtr<nsIContentPrefService2> contentPrefService =
     do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
@@ -772,17 +772,17 @@ nsresult
 UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir)
 {
   NS_PRECONDITION(aDoc, "aDoc is null");
   if (!aDir) {
     return NS_OK;
   }
 
 #ifdef MOZ_B2G
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return NS_OK;
   }
 #endif
 
   nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
   NS_PRECONDITION(docURI, "docURI is null");
 
   // Attempt to get the CPS, if it's not present we'll just return
@@ -2100,17 +2100,17 @@ HTMLInputElement::MozSetFileArray(const 
     files.AppendElement(file);
   }
   SetFiles(files, true);
 }
 
 void
 HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
   nsTArray<nsRefPtr<File>> files;
   for (uint32_t i = 0; i < aFileNames.Length(); ++i) {
     nsCOMPtr<nsIFile> file;
 
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -591,17 +591,17 @@ nsGenericHTMLFrameElement::GetAppManifes
 
   // At the moment, you can't be an app without being a browser.
   if (!nsIMozBrowserFrame::GetReallyIsBrowserOrApp()) {
     return NS_OK;
   }
 
   // Only allow content process to embed an app when nested content
   // process is enabled.
-  if (XRE_GetProcessType() != GeckoProcessType_Default &&
+  if (!XRE_IsParentProcess() &&
       !(GetBoolAttr(nsGkAtoms::Remote) && NestedEnabled())){
     NS_WARNING("Can't embed-apps. Embed-apps is restricted to in-proc apps "
                "or content processes with nested pref enabled, see bug 1097479");
     return NS_OK;
   }
 
   nsAutoString appManifestURL;
   nsAutoString widgetManifestURL;
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -463,16 +463,18 @@ skip-if = (toolkit == 'gonk' && debug) |
 [test_formData.html]
 [test_formSubmission.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) b2g-debug(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) b2g-desktop(NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
 [test_formSubmission2.html]
 skip-if = toolkit == 'android'
 [test_formelements.html]
 [test_fullscreen-api.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #TIMED_OUT # b2g(time out, some kind of focus issue) b2g-debug(time out, some kind of focus issue) b2g-desktop(time out, some kind of focus issue)
+[test_fullscreen-api-race.html]
+skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || toolkit == 'cocoa' || e10s # just copy the conditions from the test above
 [test_hidden.html]
 [test_html_attributes_reflection.html]
 [test_htmlcollection.html]
 [test_iframe_sandbox_general.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_iframe_sandbox_inheritance.html]
 [test_iframe_sandbox_modal.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #modal tests fail on android # b2g(modal tests fail on B2G) b2g-debug(modal tests fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
new file mode 100644
--- /dev/null
+++ b/dom/html/test/test_fullscreen-api-race.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test for race conditions of Fullscreen API</title>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+
+function Deferred() {
+  this.promise = new Promise(resolve => {
+    this.resolve = resolve;
+  });
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function () {
+  SpecialPowers.pushPrefEnv({
+    "set": [["full-screen-api.allow-trusted-requests-only", false]]
+  }, next);
+});
+
+const OPEN_WINDOW_FUNCS = [
+  function openNewTab() {
+    return window.open("about:blank");
+  },
+  function openNewWindow() {
+    return window.open("about:blank", "", "width=300,height=200");
+  }
+];
+
+const ACTION_FUNCS = [
+  function navigate(win) {
+    info("About to navigate to another page");
+    var deferred = new Deferred();
+    win.location = "data:text/html,<html>";
+    setTimeout(() => {
+      SimpleTest.waitForFocus(() => {
+        ok(!win.fullScreen, "The window should no longer be in fullscreen");
+        win.close();
+        deferred.resolve();
+      }, win);
+    }, 0);
+    return deferred.promise;
+  },
+  function closeWindow(win) {
+    info("About to close the window");
+    win.close();
+    return Promise.resolve();
+  },
+  function exitFullscreen(win) {
+    info("About to cancel fullscreen");
+    var deferred = new Deferred();
+    function listener() {
+      win.removeEventListener("mozfullscreenchange", listener);
+      ok(!win.document.mozFullScreen, "Should exit fullscreen");
+      ok(!win.fullScreen, "The window should no longer be in fullscreen");
+      win.close();
+      deferred.resolve();
+    }
+    win.addEventListener("mozfullscreenchange", listener);
+    win.document.mozCancelFullScreen();
+    return deferred.promise;
+  },
+  function exitAndClose(win) {
+    info("About to cancel fullscreen and close the window");
+    win.document.mozCancelFullScreen();
+    win.close();
+    return Promise.resolve();
+  }
+];
+
+function* testGenerator() {
+  for (var openWinFunc of OPEN_WINDOW_FUNCS) {
+    for (var actionFunc of ACTION_FUNCS) {
+      info(`Testing ${openWinFunc.name}, ${actionFunc.name}`);
+      yield { openWinFunc: openWinFunc, actionFunc: actionFunc };
+    }
+  }
+}
+
+var tests = testGenerator();
+
+function next() {
+  var test = tests.next().value;
+  if (!test) {
+    SimpleTest.finish();
+    return;
+  }
+  var win = test.openWinFunc();
+  new Promise(resolve => {
+    SimpleTest.waitForFocus(resolve, win, true);
+  }).then(() => {
+    return new Promise(resolve => {
+      function listener() {
+        win.removeEventListener("mozfullscreenchange", listener);
+        ok(win.document.mozFullScreen, "Should have entered fullscreen");
+        ok(win.fullScreen, "The window should be in fullscreen");
+        test.actionFunc(win).then(resolve);
+      }
+      win.addEventListener("mozfullscreenchange", listener);
+      win.document.documentElement.mozRequestFullScreen();
+    });
+  }).then(() => {
+    ok(win.closed, "The window should have been closed");
+    SimpleTest.waitForFocus(next);
+  });
+}
+
+</script>
+</body>
+</html>
--- a/dom/icc/IccManager.cpp
+++ b/dom/icc/IccManager.cpp
@@ -138,17 +138,17 @@ IccManager::GetIccById(const nsAString& 
   return nullptr;
 }
 
 already_AddRefed<nsIIccService>
 NS_CreateIccService()
 {
   nsCOMPtr<nsIIccService> service;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     service = new mozilla::dom::icc::IccIPCService();
 #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
   } else {
     service = do_GetService(GONK_ICC_SERVICE_CONTRACTID);
 #endif
   }
 
   return service.forget();
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -813,17 +813,17 @@ class WorkerPermissionRequest final : pu
 
 public:
   WorkerPermissionRequest(Element* aElement,
                           nsIPrincipal* aPrincipal,
                           WorkerPermissionChallenge* aChallenge)
     : PermissionRequestBase(aElement, aPrincipal)
     , mChallenge(aChallenge)
   {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+    MOZ_ASSERT(XRE_IsParentProcess());
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aChallenge);
   }
 
 private:
   ~WorkerPermissionRequest()
   {
     MOZ_ASSERT(NS_IsMainThread());
@@ -839,17 +839,17 @@ class WorkerPermissionRequestChildProces
 {
   nsRefPtr<WorkerPermissionChallenge> mChallenge;
 
 public:
   explicit WorkerPermissionRequestChildProcessActor(
                                           WorkerPermissionChallenge* aChallenge)
     : mChallenge(aChallenge)
   {
-    MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
+    MOZ_ASSERT(!XRE_IsParentProcess());
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aChallenge);
   }
 
 protected:
   ~WorkerPermissionRequestChildProcessActor()
   {}
 
@@ -945,17 +945,17 @@ private:
 
     nsresult rv;
     nsCOMPtr<nsIPrincipal> principal =
       mozilla::ipc::PrincipalInfoToPrincipal(mPrincipalInfo, &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return true;
     }
 
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       nsCOMPtr<Element> ownerElement =
         do_QueryInterface(window->GetChromeEventHandler());
       if (NS_WARN_IF(!ownerElement)) {
         return true;
       }
 
       nsRefPtr<WorkerPermissionRequest> helper =
         new WorkerPermissionRequest(ownerElement, principal, this);
@@ -1394,17 +1394,17 @@ BackgroundFactoryRequestChild::RecvPermi
 
   nsresult rv;
   nsCOMPtr<nsIPrincipal> principal =
     mozilla::ipc::PrincipalInfoToPrincipal(aPrincipalInfo, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return false;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsCOMPtr<nsPIDOMWindow> window = mFactory->GetParentObject();
     MOZ_ASSERT(window);
 
     nsCOMPtr<Element> ownerElement =
       do_QueryInterface(window->GetChromeEventHandler());
     if (NS_WARN_IF(!ownerElement)) {
       return false;
     }
--- a/dom/indexedDB/FileSnapshot.cpp
+++ b/dom/indexedDB/FileSnapshot.cpp
@@ -78,17 +78,17 @@ BlobImplSnapshot::~BlobImplSnapshot()
 }
 
 #ifdef DEBUG
 
 // static
 void
 BlobImplSnapshot::AssertSanity()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 #endif // DEBUG
 
 NS_IMPL_ISUPPORTS_INHERITED(BlobImplSnapshot, BlobImpl, PIBlobImplSnapshot)
 
 void
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -297,17 +297,17 @@ IndexedDatabaseManager::GetOrCreate()
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (IsClosed()) {
     NS_ERROR("Calling GetOrCreate() after shutdown!");
     return nullptr;
   }
 
   if (!gDBManager) {
-    sIsMainProcess = XRE_GetProcessType() == GeckoProcessType_Default;
+    sIsMainProcess = XRE_IsParentProcess();
 
     if (!sLoggingModule) {
       sLoggingModule = PR_NewLogModule("IndexedDB");
     }
 
     if (sIsMainProcess && Preferences::GetBool("disk_space_watcher.enabled", false)) {
       // See if we're starting up in low disk space conditions.
       nsCOMPtr<nsIDiskSpaceWatcher> watcher =
@@ -634,17 +634,17 @@ IndexedDatabaseManager::IsClosed()
 
 #ifdef DEBUG
 // static
 bool
 IndexedDatabaseManager::IsMainProcess()
 {
   NS_ASSERTION(gDBManager,
                "IsMainProcess() called before indexedDB has been initialized!");
-  NS_ASSERTION((XRE_GetProcessType() == GeckoProcessType_Default) ==
+  NS_ASSERTION((XRE_IsParentProcess()) ==
                sIsMainProcess, "XRE_GetProcessType changed its tune!");
   return sIsMainProcess;
 }
 
 //static
 bool
 IndexedDatabaseManager::InLowDiskSpaceMode()
 {
--- a/dom/indexedDB/PermissionRequestBase.cpp
+++ b/dom/indexedDB/PermissionRequestBase.cpp
@@ -38,17 +38,17 @@ const char kPermissionResponseTopic[] = 
 #undef TOPIC_PREFIX
 #undef IDB_PREFIX
 
 const uint32_t kPermissionDefault = nsIPermissionManager::UNKNOWN_ACTION;
 
 void
 AssertSanity()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 } // anonymous namespace
 
 PermissionRequestBase::PermissionRequestBase(Element* aOwnerElement,
                                              nsIPrincipal* aPrincipal)
   : mOwnerElement(aOwnerElement)
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -3289,17 +3289,17 @@ BlobChild::AssertIsOnOwningThread() cons
 }
 
 #endif // DEBUG
 
 // static
 void
 BlobChild::Startup(const FriendKey& /* aKey */)
 {
-  MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
+  MOZ_ASSERT(!XRE_IsParentProcess());
 
   CommonStartup();
 }
 
 // static
 BlobChild*
 BlobChild::GetOrCreate(nsIContentChild* aManager, BlobImpl* aBlobImpl)
 {
@@ -3817,17 +3817,17 @@ BlobParent::AssertIsOnOwningThread() con
 }
 
 #endif // DEBUG
 
 // static
 void
 BlobParent::Startup(const FriendKey& /* aKey */)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   CommonStartup();
 
   ClearOnShutdown(&sIDTable);
 
   sIDTableMutex = new Mutex("BlobParent::sIDTableMutex");
   ClearOnShutdown(&sIDTableMutex);
 }
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2825,17 +2825,17 @@ static const uint64_t kWindowIDProcessBi
 static const uint64_t kWindowIDWindowBits = kWindowIDTotalBits - kWindowIDProcessBits;
 
 // Try to return a window ID that is unique across processes and that will never
 // be recycled.
 uint64_t
 NextWindowID()
 {
   uint64_t processID = 0;
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     ContentChild* cc = ContentChild::GetSingleton();
     processID = cc->GetID();
   }
 
   MOZ_RELEASE_ASSERT(processID < (uint64_t(1) << kWindowIDProcessBits));
   uint64_t processBits = processID & ((uint64_t(1) << kWindowIDProcessBits) - 1);
 
   // Make sure no actual window ends up with mWindowID == 0.
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -773,17 +773,17 @@ ContentParent::GetNewOrPreallocatedAppPr
 /*static*/ void
 ContentParent::StartUp()
 {
     // We could launch sub processes from content process
     // FIXME Bug 1023701 - Stop using ContentParent static methods in
     // child process
     sCanLaunchSubprocesses = true;
 
-    if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    if (!XRE_IsParentProcess()) {
         return;
     }
 
 #if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
     // Require sandboxing on B2G >= KitKat.  This condition must stay
     // in sync with ContentChild::RecvSetProcessSandbox.
     if (!SandboxInfo::Get().CanSandboxContent()) {
         // MOZ_CRASH strings are only for debug builds; make sure the
@@ -1147,17 +1147,17 @@ ContentParent::CreateBrowserOrApp(const 
     }
 
     if (TabParent* parent = TabParent::GetNextTabParent()) {
         parent->SetOwnerElement(aFrameElement);
         return parent;
     }
 
     ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
-    bool isInContentProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
+    bool isInContentProcess = !XRE_IsParentProcess();
     TabId tabId;
 
     nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
     TabId openerTabId;
     if (docShell) {
         openerTabId = TabParent::GetTabIdFrom(docShell);
     }
 
@@ -1806,17 +1806,17 @@ ContentParent::OnChannelError()
     // Handle app or Nuwa process exit before normal channel error handling.
     PreallocatedProcessManager::MaybeForgetSpare(this);
 #endif
     PContentParent::OnChannelError();
 }
 
 void
 ContentParent::OnBeginSyncTransaction() {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
         JSContext *cx = nsContentUtils::GetCurrentJSContext();
         if (!sDisableUnsafeCPOWWarnings) {
             if (console && cx) {
                 nsAutoString filename;
                 uint32_t lineno = 0;
                 nsJSUtils::GetCallingLocation(cx, filename, &lineno);
                 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
@@ -4890,34 +4890,34 @@ ContentParent::NotifyUpdatedDictionaries
 }
 
 /*static*/ TabId
 ContentParent::AllocateTabId(const TabId& aOpenerTabId,
                              const IPCTabContext& aContext,
                              const ContentParentId& aCpId)
 {
     TabId tabId;
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
         tabId = cpm->AllocateTabId(aOpenerTabId, aContext, aCpId);
     }
     else {
         ContentChild::GetSingleton()->SendAllocateTabId(aOpenerTabId,
                                                         aContext,
                                                         aCpId,
                                                         &tabId);
     }
     return tabId;
 }
 
 /*static*/ void
 ContentParent::DeallocateTabId(const TabId& aTabId,
                                const ContentParentId& aCpId)
 {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         ContentProcessManager::GetSingleton()->DeallocateTabId(aCpId,
                                                                aTabId);
     }
     else {
         ContentChild::GetSingleton()->SendDeallocateTabId(aTabId);
     }
 }
 
@@ -5106,25 +5106,25 @@ ContentParent::DeallocPContentPermission
     nsContentPermissionUtils::NotifyRemoveContentPermissionRequestParent(actor);
     delete actor;
     return true;
 }
 
 bool
 ContentParent::RecvGetBrowserConfiguration(const nsCString& aURI, BrowserConfiguration* aConfig)
 {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+    MOZ_ASSERT(XRE_IsParentProcess());
 
     return GetBrowserConfiguration(aURI, *aConfig);;
 }
 
 /*static*/ bool
 ContentParent::GetBrowserConfiguration(const nsCString& aURI, BrowserConfiguration& aConfig)
 {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
         MOZ_ASSERT(swr);
 
         swr->GetRegistrations(aConfig.serviceWorkerRegistrations());
         return true;
     }
 
     return ContentChild::GetSingleton()->SendGetBrowserConfiguration(aURI, &aConfig);
--- a/dom/ipc/ContentProcessManager.cpp
+++ b/dom/ipc/ContentProcessManager.cpp
@@ -27,17 +27,17 @@ static uint64_t gTabId = 0;
 
 /* static */
 StaticAutoPtr<ContentProcessManager>
 ContentProcessManager::sSingleton;
 
 /* static */ ContentProcessManager*
 ContentProcessManager::GetSingleton()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if (!sSingleton) {
     sSingleton = new ContentProcessManager();
     ClearOnShutdown(&sSingleton);
   }
   return sSingleton;
 }
 
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -882,17 +882,17 @@ ProcessHangMonitor* ProcessHangMonitor::
 
 ProcessHangMonitor::ProcessHangMonitor()
  : mCPOWTimeout(false)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   MOZ_COUNT_CTOR(ProcessHangMonitor);
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     obs->AddObserver(this, "xpcom-shutdown", false);
   }
 
   mThread = new base::Thread("ProcessHangMonitor");
   if (!mThread->Start()) {
     delete mThread;
     mThread = nullptr;
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -379,17 +379,17 @@ ProcessPriorityManagerImpl::PrefsEnabled
 /* static */ void
 ProcessPriorityManagerImpl::StaticInit()
 {
   if (sInitialized) {
     return;
   }
 
   // The process priority manager is main-process only.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     sInitialized = true;
     return;
   }
 
   // If IPC tabs aren't enabled at startup, don't bother with any of this.
   if (!PrefsEnabled()) {
     LOG("InitProcessPriorityManager bailing due to prefs.");
 
@@ -422,17 +422,17 @@ ProcessPriorityManagerImpl::GetSingleton
   return sSingleton;
 }
 
 ProcessPriorityManagerImpl::ProcessPriorityManagerImpl()
     : mHighPriority(false)
     , mBackgroundLRUPool(PROCESS_PRIORITY_BACKGROUND)
     , mBackgroundPerceivableLRUPool(PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   RegisterWakeLockObserver(this);
 }
 
 ProcessPriorityManagerImpl::~ProcessPriorityManagerImpl()
 {
   UnregisterWakeLockObserver(this);
 }
 
@@ -655,17 +655,17 @@ ParticularProcessPriorityManager::Partic
   , mChildID(aContentParent->ChildID())
   , mPriority(PROCESS_PRIORITY_UNKNOWN)
   , mLRU(0)
   , mHoldsCPUWakeLock(false)
   , mHoldsHighPriorityWakeLock(false)
   , mIsActivityOpener(false)
   , mFrozen(aFrozen)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   LOGP("Creating ParticularProcessPriorityManager.");
 }
 
 void
 ParticularProcessPriorityManager::Init()
 {
   RegisterWakeLockObserver(this);
 
@@ -821,17 +821,17 @@ void
 ParticularProcessPriorityManager::OnRemoteBrowserFrameShown(nsISupports* aSubject)
 {
   nsCOMPtr<nsIFrameLoader> fl = do_QueryInterface(aSubject);
   NS_ENSURE_TRUE_VOID(fl);
 
   TabParent* tp = TabParent::GetFrom(fl);
   NS_ENSURE_TRUE_VOID(tp);
 
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   if (tp->Manager() != mContentParent) {
     return;
   }
 
   // Ignore notifications that aren't from a BrowserOrApp
   bool isBrowserOrApp;
   fl->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
   if (isBrowserOrApp) {
@@ -845,17 +845,17 @@ ParticularProcessPriorityManager::OnRemo
 }
 
 void
 ParticularProcessPriorityManager::OnTabParentDestroyed(nsISupports* aSubject)
 {
   nsCOMPtr<nsITabParent> tp = do_QueryInterface(aSubject);
   NS_ENSURE_TRUE_VOID(tp);
 
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   if (TabParent::GetFrom(tp)->Manager() != mContentParent) {
     return;
   }
 
   ResetPriority();
 }
 
 void
@@ -868,17 +868,17 @@ ParticularProcessPriorityManager::OnFram
     return; // Ignore visibility changes when the screen is off
   }
 
   TabParent* tp = TabParent::GetFrom(fl);
   if (!tp) {
     return;
   }
 
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   if (tp->Manager() != mContentParent) {
     return;
   }
 
   // Most of the time when something changes in a process we call
   // ResetPriority(), giving a grace period before downgrading its priority.
   // But notice that here don't give a grace period: We call ResetPriorityNow()
   // instead.
@@ -1208,29 +1208,29 @@ ProcessPriorityManagerChild::Singleton()
   return sSingleton;
 }
 
 NS_IMPL_ISUPPORTS(ProcessPriorityManagerChild,
                   nsIObserver)
 
 ProcessPriorityManagerChild::ProcessPriorityManagerChild()
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     mCachedPriority = PROCESS_PRIORITY_MASTER;
   } else {
     mCachedPriority = PROCESS_PRIORITY_UNKNOWN;
   }
 }
 
 void
 ProcessPriorityManagerChild::Init()
 {
   // The process priority should only be changed in child processes; don't even
   // bother listening for changes if we're in the main process.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     NS_ENSURE_TRUE_VOID(os);
     os->AddObserver(this, "ipc:process-priority-changed", /* weak = */ false);
   }
 }
 
 NS_IMETHODIMP
 ProcessPriorityManagerChild::Observe(
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -442,17 +442,17 @@ TabParent::Destroy()
   unused << SendDestroy();
 
   if (RenderFrameParent* frame = GetRenderFrame()) {
     RemoveTabParentFromTable(frame->GetLayersId());
     frame->Destroy();
   }
   mIsDestroyed = true;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     Manager()->AsContentParent()->NotifyTabDestroying(this);
   }
 
   // Let all PluginWidgets know we are tearing down. Prevents
   // these objects from sending async events after the child side
   // is shut down.
   const nsTArray<PPluginWidgetParent*>& kids = ManagedPPluginWidgetParent();
   for (uint32_t idx = 0; idx < kids.Length(); ++idx) {
@@ -460,17 +460,17 @@ TabParent::Destroy()
   }
 
   mMarkedDestroying = true;
 }
 
 bool
 TabParent::Recv__delete__()
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     Manager()->AsContentParent()->NotifyTabDestroyed(this, mMarkedDestroying);
     ContentParent::DeallocateTabId(mTabId,
                                    Manager()->AsContentParent()->ChildID());
   }
   else {
     ContentParent::DeallocateTabId(mTabId, ContentParentId(0));
   }
 
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1473,17 +1473,17 @@ MediaManager::NotifyRecordingStatusChang
   props->SetPropertyAsAString(NS_LITERAL_STRING("requestURL"), requestURL);
 
   obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
                        "recording-device-events",
                        aMsg.get());
 
   // Forward recording events to parent process.
   // The events are gathered in chrome process and used for recording indicator
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     unused <<
       dom::ContentChild::GetSingleton()->SendRecordingDeviceEvents(aMsg,
                                                                    requestURL,
                                                                    aIsAudio,
                                                                    aIsVideo);
   }
 
   return NS_OK;
--- a/dom/media/eme/CDMProxy.cpp
+++ b/dom/media/eme/CDMProxy.cpp
@@ -631,25 +631,26 @@ CDMProxy::KeySystem() const
   return mKeySystem;
 }
 
 CDMCaps&
 CDMProxy::Capabilites() {
   return mCapabilites;
 }
 
-void
-CDMProxy::Decrypt(MediaRawData* aSample,
-                  DecryptionClient* aClient,
-                  MediaTaskQueue* aTaskQueue)
+nsRefPtr<CDMProxy::DecryptPromise>
+CDMProxy::Decrypt(MediaRawData* aSample)
 {
-  nsRefPtr<DecryptJob> job(new DecryptJob(aSample, aClient, aTaskQueue));
+  nsRefPtr<DecryptJob> job(new DecryptJob(aSample));
+  nsRefPtr<DecryptPromise> promise(job->Ensure());
+
   nsCOMPtr<nsIRunnable> task(
     NS_NewRunnableMethodWithArg<nsRefPtr<DecryptJob>>(this, &CDMProxy::gmp_Decrypt, job));
   mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
+  return promise;
 }
 
 void
 CDMProxy::gmp_Decrypt(nsRefPtr<DecryptJob> aJob)
 {
   MOZ_ASSERT(IsOnGMPThread());
 
   if (!mCDM) {
@@ -698,41 +699,31 @@ CDMProxy::DecryptJob::PostResult(GMPErr 
 }
 
 void
 CDMProxy::DecryptJob::PostResult(GMPErr aResult, const nsTArray<uint8_t>& aDecryptedData)
 {
   if (aDecryptedData.Length() != mSample->mSize) {
     NS_WARNING("CDM returned incorrect number of decrypted bytes");
   }
-  mResult = aResult;
   if (GMP_SUCCEEDED(aResult)) {
     nsAutoPtr<MediaRawDataWriter> writer(mSample->CreateWriter());
     PodCopy(writer->mData,
             aDecryptedData.Elements(),
             std::min<size_t>(aDecryptedData.Length(), mSample->mSize));
   } else if (aResult == GMPNoKeyErr) {
     NS_WARNING("CDM returned GMPNoKeyErr");
     // We still have the encrypted sample, so we can re-enqueue it to be
     // decrypted again once the key is usable again.
   } else {
     nsAutoCString str("CDM returned decode failure GMPErr=");
     str.AppendInt(aResult);
     NS_WARNING(str.get());
-    mSample = nullptr;
   }
-  mTaskQueue->Dispatch(RefPtr<nsIRunnable>(this).forget());
-}
-
-nsresult
-CDMProxy::DecryptJob::Run()
-{
-  MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-  mClient->Decrypted(mResult, mSample);
-  return NS_OK;
+  mPromise.Resolve(DecryptResult(aResult, mSample), __func__);
 }
 
 void
 CDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
                                 nsTArray<nsCString>& aSessionIds)
 {
   CDMCaps::AutoLock caps(Capabilites());
   caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
--- a/dom/media/eme/CDMProxy.h
+++ b/dom/media/eme/CDMProxy.h
@@ -9,43 +9,48 @@
 
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "mozilla/dom/MediaKeys.h"
 #include "mozilla/Monitor.h"
 #include "nsIThread.h"
 #include "GMPDecryptorProxy.h"
 #include "mozilla/CDMCaps.h"
+#include "MediaPromise.h"
 
 namespace mozilla {
 class MediaRawData;
 class CDMCallbackProxy;
 
 namespace dom {
 class MediaKeySession;
 }
 
-class DecryptionClient {
-public:
-  virtual ~DecryptionClient() {}
-  virtual void Decrypted(GMPErr aResult,
-                         MediaRawData* aSample) = 0;
+struct DecryptResult {
+  DecryptResult(GMPErr aStatus, MediaRawData* aSample)
+    : mStatus(aStatus)
+    , mSample(aSample)
+  {}
+  GMPErr mStatus;
+  nsRefPtr<MediaRawData> mSample;
 };
 
 // Proxies calls GMP/CDM, and proxies calls back.
 // Note: Promises are passed in via a PromiseId, so that the ID can be
 // passed via IPC to the CDM, which can then signal when to reject or
 // resolve the promise using its PromiseId.
 class CDMProxy {
   typedef dom::PromiseId PromiseId;
   typedef dom::SessionType SessionType;
 public:
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMProxy)
 
+  typedef MediaPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise;
+
   // Main thread only.
   CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem);
 
   // Main thread only.
   // Loads the CDM corresponding to mKeySystem.
   // Calls MediaKeys::OnCDMCreated() when the CDM is created.
   void Init(PromiseId aPromiseId,
             const nsAString& aOrigin,
@@ -135,20 +140,17 @@ public:
                       uint32_t aSystemCode,
                       const nsAString& aMsg);
 
   // Main thread only.
   void OnRejectPromise(uint32_t aPromiseId,
                        nsresult aDOMException,
                        const nsCString& aMsg);
 
-  // Threadsafe.
-  void Decrypt(MediaRawData* aSample,
-               DecryptionClient* aSink,
-               MediaTaskQueue* aTaskQueue);
+  nsRefPtr<DecryptPromise> Decrypt(MediaRawData* aSample);
 
   // Reject promise with DOMException corresponding to aExceptionCode.
   // Can be called from any thread.
   void RejectPromise(PromiseId aId, nsresult aExceptionCode,
                      const nsCString& aReason);
 
   // Resolves promise with "undefined".
   // Can be called from any thread.
@@ -231,42 +233,38 @@ private:
   void gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData);
 
   // GMP thread only.
   void gmp_CloseSession(nsAutoPtr<SessionOpData> aData);
 
   // GMP thread only.
   void gmp_RemoveSession(nsAutoPtr<SessionOpData> aData);
 
-  class DecryptJob : public nsRunnable {
+  class DecryptJob {
   public:
-    explicit DecryptJob(MediaRawData* aSample,
-                        DecryptionClient* aClient,
-                        MediaTaskQueue* aTaskQueue)
+    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecryptJob)
+
+    explicit DecryptJob(MediaRawData* aSample)
       : mId(0)
       , mSample(aSample)
-      , mClient(aClient)
-      , mResult(GMPGenericErr)
-      , mTaskQueue(aTaskQueue)
     {
-      MOZ_ASSERT(mClient);
-      MOZ_ASSERT(mSample);
     }
 
-    NS_METHOD Run() override;
     void PostResult(GMPErr aResult, const nsTArray<uint8_t>& aDecryptedData);
     void PostResult(GMPErr aResult);
 
+    nsRefPtr<DecryptPromise> Ensure() {
+      return mPromise.Ensure(__func__);
+    }
+
     uint32_t mId;
     nsRefPtr<MediaRawData> mSample;
   private:
     ~DecryptJob() {}
-    nsAutoPtr<DecryptionClient> mClient;
-    GMPErr mResult;
-    nsRefPtr<MediaTaskQueue> mTaskQueue;
+    MediaPromiseHolder<DecryptPromise> mPromise;
   };
   // GMP thread only.
   void gmp_Decrypt(nsRefPtr<DecryptJob> aJob);
 
   class RejectPromiseTask : public nsRunnable {
   public:
     RejectPromiseTask(CDMProxy* aProxy,
                       PromiseId aId,
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -181,17 +181,17 @@ EnsureMinCDMVersion(mozIGeckoMediaPlugin
     if (!AdobePluginDLLExists(versionStr)) {
       aOutMessage = NS_LITERAL_CSTRING("Adobe DLL was expected to be on disk but was not");
       somethingMissing = true;
     }
     if (!AdobePluginVoucherExists(versionStr)) {
       aOutMessage = NS_LITERAL_CSTRING("Adobe plugin voucher was expected to be on disk but was not");
       somethingMissing = true;
     }
-    if (somethingMissing) {    
+    if (somethingMissing) {
       NS_WARNING("Adobe EME plugin or voucher disappeared from disk!");
       // Reset the prefs that Firefox's GMP downloader sets, so that
       // Firefox will try to download the plugin next time the updater runs.
       Preferences::ClearUser("media.gmp-eme-adobe.lastUpdate");
       Preferences::ClearUser("media.gmp-eme-adobe.version");
       return MediaKeySystemStatus::Cdm_not_installed;
     }
   }
--- a/dom/media/gmp/GMPService.cpp
+++ b/dom/media/gmp/GMPService.cpp
@@ -104,17 +104,17 @@ private:
   }
 
   static already_AddRefed<GeckoMediaPluginService>
   GetOrCreateOnMainThread()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (!sSingletonService) {
-      if (XRE_GetProcessType() == GeckoProcessType_Default) {
+      if (XRE_IsParentProcess()) {
         nsRefPtr<GeckoMediaPluginServiceParent> service =
           new GeckoMediaPluginServiceParent();
         service->Init();
         sSingletonService = service;
       } else {
         nsRefPtr<GeckoMediaPluginServiceChild> service =
           new GeckoMediaPluginServiceChild();
         service->Init();
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -28,17 +28,17 @@ namespace mozilla {
 #endif
 #define __CLASS__ "GMPService"
 
 namespace gmp {
 
 already_AddRefed<GeckoMediaPluginServiceChild>
 GeckoMediaPluginServiceChild::GetSingleton()
 {
-  MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
+  MOZ_ASSERT(!XRE_IsParentProcess());
   nsRefPtr<GeckoMediaPluginService> service(
     GeckoMediaPluginService::GetGeckoMediaPluginService());
 #ifdef DEBUG
   if (service) {
     nsCOMPtr<mozIGeckoMediaPluginChromeService> chromeService;
     CallQueryInterface(service.get(), getter_AddRefs(chromeService));
     MOZ_ASSERT(!chromeService);
   }
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -55,17 +55,17 @@ namespace mozilla {
 
 namespace gmp {
 
 static const uint32_t NodeIdSaltLength = 32;
 
 already_AddRefed<GeckoMediaPluginServiceParent>
 GeckoMediaPluginServiceParent::GetSingleton()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   nsRefPtr<GeckoMediaPluginService> service(
     GeckoMediaPluginServiceParent::GetGeckoMediaPluginService());
 #ifdef DEBUG
   if (service) {
     nsCOMPtr<mozIGeckoMediaPluginChromeService> chromeService;
     CallQueryInterface(service.get(), getter_AddRefs(chromeService));
     MOZ_ASSERT(chromeService);
   }
@@ -139,17 +139,17 @@ GeckoMediaPluginServiceParent::Init()
 
 
 nsresult
 GeckoMediaPluginServiceParent::InitStorage()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // GMP storage should be used in the chrome process only.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return NS_OK;
   }
 
   // Directory service is main thread only, so cache the profile dir here
   // so that we can use it off main thread.
 #ifdef MOZ_WIDGET_GONK
   nsresult rv = NS_NewLocalFile(NS_LITERAL_STRING("/data/b2g/mozilla"), false, getter_AddRefs(mStorageBaseDir));
 #else
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -8,19 +8,31 @@
 #include "EMEAudioDecoder.h"
 #include "EMEVideoDecoder.h"
 #include "MediaDataDecoderProxy.h"
 #include "mozIGeckoMediaPluginService.h"
 #include "mozilla/CDMProxy.h"
 #include "mozilla/unused.h"
 #include "nsServiceManagerUtils.h"
 #include "MediaInfo.h"
+#include "nsClassHashtable.h"
 
 namespace mozilla {
 
+typedef MediaPromiseRequestHolder<CDMProxy::DecryptPromise> DecryptPromiseRequestHolder;
+
+static PLDHashOperator
+DropDecryptPromises(MediaRawData* aKey,
+                    nsAutoPtr<DecryptPromiseRequestHolder>& aData,
+                    void* aUserArg)
+{
+  aData->DisconnectIfExists();
+  return PL_DHASH_REMOVE;
+}
+
 class EMEDecryptor : public MediaDataDecoder {
 
 public:
 
   EMEDecryptor(MediaDataDecoder* aDecoder,
                MediaDataDecoderCallback* aCallback,
                CDMProxy* aProxy,
                MediaTaskQueue* aDecodeTaskQueue)
@@ -33,79 +45,84 @@ public:
   {
   }
 
   virtual nsresult Init() override {
     MOZ_ASSERT(!mIsShutdown);
     return mDecoder->Init();
   }
 
-  class DeliverDecrypted : public DecryptionClient {
-  public:
-    explicit DeliverDecrypted(EMEDecryptor* aDecryptor)
-      : mDecryptor(aDecryptor)
-    { }
-    virtual void Decrypted(GMPErr aResult, MediaRawData* aSample) override {
-      mDecryptor->Decrypted(aResult, aSample);
-      mDecryptor = nullptr;
-    }
-  private:
-    nsRefPtr<EMEDecryptor> mDecryptor;
-  };
-
   virtual nsresult Input(MediaRawData* aSample) override {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     MOZ_ASSERT(!mIsShutdown);
     if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
       return NS_OK;
     }
 
     nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
     mProxy->GetSessionIdsForKeyId(aSample->mCrypto.mKeyId,
                                   writer->mCrypto.mSessionIds);
 
-    mProxy->Decrypt(aSample, new DeliverDecrypted(this), mTaskQueue);
+    mDecrypts.Put(aSample, new DecryptPromiseRequestHolder());
+    mDecrypts.Get(aSample)->Begin(mProxy->Decrypt(aSample)->Then(
+      mTaskQueue, __func__, this,
+      &EMEDecryptor::Decrypted,
+      &EMEDecryptor::Decrypted));
     return NS_OK;
   }
 
-  void Decrypted(GMPErr aResult, MediaRawData* aSample) {
+  void Decrypted(const DecryptResult& aDecrypted) {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+    MOZ_ASSERT(aDecrypted.mSample);
+
+    nsAutoPtr<DecryptPromiseRequestHolder> holder;
+    mDecrypts.RemoveAndForget(aDecrypted.mSample, holder);
+    if (holder) {
+      holder->Complete();
+    } else {
+      // Decryption is not in the list of decrypt operations waiting
+      // for a result. It must have been flushed or drained. Ignore result.
+      return;
+    }
+
     if (mIsShutdown) {
       NS_WARNING("EME decrypted sample arrived after shutdown");
       return;
     }
-    if (aResult == GMPNoKeyErr) {
+
+    if (aDecrypted.mStatus == GMPNoKeyErr) {
       // Key became unusable after we sent the sample to CDM to decrypt.
       // Call Input() again, so that the sample is enqueued for decryption
       // if the key becomes usable again.
-      Input(aSample);
-    } else if (GMP_FAILED(aResult)) {
+      Input(aDecrypted.mSample);
+    } else if (GMP_FAILED(aDecrypted.mStatus)) {
       if (mCallback) {
         mCallback->Error();
       }
-      MOZ_ASSERT(!aSample);
     } else {
       MOZ_ASSERT(!mIsShutdown);
-      nsresult rv = mDecoder->Input(aSample);
+      nsresult rv = mDecoder->Input(aDecrypted.mSample);
       unused << NS_WARN_IF(NS_FAILED(rv));
     }
   }
 
   virtual nsresult Flush() override {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     MOZ_ASSERT(!mIsShutdown);
+    mDecrypts.Enumerate(&DropDecryptPromises, nullptr);
     nsresult rv = mDecoder->Flush();
     unused << NS_WARN_IF(NS_FAILED(rv));
     mSamplesWaitingForKey->Flush();
     return rv;
   }
 
   virtual nsresult Drain() override {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     MOZ_ASSERT(!mIsShutdown);
+    mDecrypts.Enumerate(&DropDecryptPromises, nullptr);
     nsresult rv = mDecoder->Drain();
     unused << NS_WARN_IF(NS_FAILED(rv));
     return rv;
   }
 
   virtual nsresult Shutdown() override {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     MOZ_ASSERT(!mIsShutdown);
@@ -121,16 +138,17 @@ public:
   }
 
 private:
 
   nsRefPtr<MediaDataDecoder> mDecoder;
   MediaDataDecoderCallback* mCallback;
   nsRefPtr<MediaTaskQueue> mTaskQueue;
   nsRefPtr<CDMProxy> mProxy;
+  nsClassHashtable<nsRefPtrHashKey<MediaRawData>, DecryptPromiseRequestHolder> mDecrypts;
   nsRefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
   bool mIsShutdown;
 };
 
 class EMEMediaDataDecoderProxy : public MediaDataDecoderProxy {
 public:
   EMEMediaDataDecoderProxy(nsIThread* aProxyThread, MediaDataDecoderCallback* aCallback, CDMProxy* aProxy, FlushableMediaTaskQueue* aTaskQueue)
    : MediaDataDecoderProxy(aProxyThread, aCallback)
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp
+++ b/dom/media/webspeech/synth/nsSpeechTask.cpp
@@ -141,17 +141,17 @@ nsSpeechTask::SetChosenVoiceURI(const ns
 {
   mChosenVoiceURI = aUri;
 }
 
 NS_IMETHODIMP
 nsSpeechTask::Setup(nsISpeechTaskCallback* aCallback,
                     uint32_t aChannels, uint32_t aRate, uint8_t argc)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   LOG(LogLevel::Debug, ("nsSpeechTask::Setup"));
 
   mCallback = aCallback;
 
   if (mIndirectAudio) {
     if (argc > 0) {
       NS_WARNING("Audio info arguments in Setup() are ignored for indirect audio services.");
@@ -192,17 +192,17 @@ makeSamples(int16_t* aData, uint32_t aDa
 
   return samples;
 }
 
 NS_IMETHODIMP
 nsSpeechTask::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                         JSContext* aCx)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if(NS_WARN_IF(!(mStream))) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if(NS_WARN_IF(mStream->IsDestroyed())) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if(NS_WARN_IF(!(mChannels))) {
@@ -242,17 +242,17 @@ nsSpeechTask::SendAudio(JS::Handle<JS::V
   SendAudioImpl(samples, dataLen);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSpeechTask::SendAudioNative(int16_t* aData, uint32_t aDataLen)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if(NS_WARN_IF(!(mStream))) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if(NS_WARN_IF(mStream->IsDestroyed())) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if(NS_WARN_IF(!(mChannels))) {
@@ -503,49 +503,49 @@ nsSpeechTask::DispatchMarkImpl(const nsA
                                            aCharIndex, aElapsedTime,
                                            aName);
   return NS_OK;
 }
 
 void
 nsSpeechTask::Pause()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if (mCallback) {
     DebugOnly<nsresult> rv = mCallback->OnPause();
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onPause() callback");
   }
 
   if (mStream) {
     mStream->ChangeExplicitBlockerCount(1);
     DispatchPauseImpl(GetCurrentTime(), GetCurrentCharOffset());
   }
 }
 
 void
 nsSpeechTask::Resume()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if (mCallback) {
     DebugOnly<nsresult> rv = mCallback->OnResume();
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onResume() callback");
   }
 
   if (mStream) {
     mStream->ChangeExplicitBlockerCount(-1);
     DispatchResumeImpl(GetCurrentTime(), GetCurrentCharOffset());
   }
 }
 
 void
 nsSpeechTask::Cancel()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   LOG(LogLevel::Debug, ("nsSpeechTask::Cancel"));
 
   if (mCallback) {
     DebugOnly<nsresult> rv = mCallback->OnCancel();
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onCancel() callback");
   }
 
--- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
+++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
@@ -95,17 +95,17 @@ public:
 
 static StaticRefPtr<nsSynthVoiceRegistry> gSynthVoiceRegistry;
 
 NS_IMPL_ISUPPORTS(nsSynthVoiceRegistry, nsISynthVoiceRegistry)
 
 nsSynthVoiceRegistry::nsSynthVoiceRegistry()
   : mSpeechSynthChild(nullptr)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
 
     mSpeechSynthChild = new SpeechSynthesisChild();
     ContentChild::GetSingleton()->SendPSpeechSynthesisConstructor(mSpeechSynthChild);
 
     InfallibleTArray<RemoteVoice> voices;
     InfallibleTArray<nsString> defaults;
 
     mSpeechSynthChild->SendReadVoiceList(&voices, &defaults);
@@ -160,17 +160,17 @@ nsSynthVoiceRegistry::GetInstanceForServ
 
   return registry.forget();
 }
 
 void
 nsSynthVoiceRegistry::Shutdown()
 {
   LOG(LogLevel::Debug, ("[%s] nsSynthVoiceRegistry::Shutdown()",
-                     (XRE_GetProcessType() == GeckoProcessType_Content) ? "Content" : "Default"));
+                     (XRE_IsContentProcess()) ? "Content" : "Default"));
   gSynthVoiceRegistry = nullptr;
 }
 
 void
 nsSynthVoiceRegistry::SendVoices(InfallibleTArray<RemoteVoice>* aVoices,
                                  InfallibleTArray<nsString>* aDefaults)
 {
   for (uint32_t i=0; i < mVoices.Length(); ++i) {
@@ -231,32 +231,32 @@ nsSynthVoiceRegistry::AddVoice(nsISpeech
                                bool aLocalService)
 {
   LOG(LogLevel::Debug,
       ("nsSynthVoiceRegistry::AddVoice uri='%s' name='%s' lang='%s' local=%s",
        NS_ConvertUTF16toUTF8(aUri).get(), NS_ConvertUTF16toUTF8(aName).get(),
        NS_ConvertUTF16toUTF8(aLang).get(),
        aLocalService ? "true" : "false"));
 
-  if(NS_WARN_IF(XRE_GetProcessType() == GeckoProcessType_Content)) {
+  if(NS_WARN_IF(XRE_IsContentProcess())) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   return AddVoiceImpl(aService, aUri, aName, aLang,
                       aLocalService);
 }
 
 NS_IMETHODIMP
 nsSynthVoiceRegistry::RemoveVoice(nsISpeechService* aService,
                                   const nsAString& aUri)
 {
   LOG(LogLevel::Debug,
       ("nsSynthVoiceRegistry::RemoveVoice uri='%s' (%s)",
        NS_ConvertUTF16toUTF8(aUri).get(),
-       (XRE_GetProcessType() == GeckoProcessType_Content) ? "child" : "parent"));
+       (XRE_IsContentProcess()) ? "child" : "parent"));
 
   bool found = false;
   VoiceData* retval = mUriVoiceMap.GetWeak(aUri, &found);
 
   if(NS_WARN_IF(!(found))) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if(NS_WARN_IF(!(aService == retval->mService))) {
@@ -291,17 +291,17 @@ nsSynthVoiceRegistry::SetDefaultVoice(co
   LOG(LogLevel::Debug, ("nsSynthVoiceRegistry::SetDefaultVoice %s %s",
                      NS_ConvertUTF16toUTF8(aUri).get(),
                      aIsDefault ? "true" : "false"));
 
   if (aIsDefault) {
     mDefaultVoices.AppendElement(retval);
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsTArray<SpeechSynthesisParent*> ssplist;
     GetAllSpeechSynthActors(ssplist);
 
     for (uint32_t i = 0; i < ssplist.Length(); ++i) {
       unused << ssplist[i]->SendSetDefaultVoice(nsString(aUri), aIsDefault);
     }
   }
 
@@ -539,17 +539,17 @@ nsSynthVoiceRegistry::SpeakUtterance(Spe
   nsString lang = nsString(aUtterance.mLang.IsEmpty() ? aDocLang : aUtterance.mLang);
   nsAutoString uri;
 
   if (aUtterance.mVoice) {
     aUtterance.mVoice->GetVoiceURI(uri);
   }
 
   nsRefPtr<nsSpeechTask> task;
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     task = new SpeechTaskChild(&aUtterance);
     SpeechSynthesisRequestChild* actor =
       new SpeechSynthesisRequestChild(static_cast<SpeechTaskChild*>(task.get()));
     mSpeechSynthChild->SendPSpeechSynthesisRequestConstructor(actor,
                                                               aUtterance.mText,
                                                               lang,
                                                               uri,
                                                               aUtterance.Volume(),
--- a/dom/media/webspeech/synth/pico/nsPicoService.cpp
+++ b/dom/media/webspeech/synth/pico/nsPicoService.cpp
@@ -724,17 +724,17 @@ nsPicoService::CurrentVoice()
 }
 
 // static methods
 
 nsPicoService*
 nsPicoService::GetInstance()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     MOZ_ASSERT(false, "nsPicoService can only be started on main gecko process");
     return nullptr;
   }
 
   if (!sSingleton) {
     sSingleton = new nsPicoService();
   }
 
--- a/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
+++ b/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
@@ -323,17 +323,17 @@ nsFakeSynthServices::Observe(nsISupports
 }
 
 // static methods
 
 nsFakeSynthServices*
 nsFakeSynthServices::GetInstance()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     MOZ_ASSERT(false, "nsFakeSynthServices can only be started on main gecko process");
     return nullptr;
   }
 
   if (!sSingleton) {
     sSingleton = new nsFakeSynthServices();
   }
 
--- a/dom/mobileconnection/MobileConnectionArray.cpp
+++ b/dom/mobileconnection/MobileConnectionArray.cpp
@@ -96,17 +96,17 @@ MobileConnectionArray::IndexedGetter(uin
   return mMobileConnections[aIndex];
 }
 
 already_AddRefed<nsIMobileConnectionService>
 NS_CreateMobileConnectionService()
 {
   nsCOMPtr<nsIMobileConnectionService> service;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     service = new mozilla::dom::mobileconnection::MobileConnectionIPCService();
   } else {
 #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
     service = do_GetService(GONK_MOBILECONNECTION_SERVICE_CONTRACTID);
 #endif
   }
 
   return service.forget();
--- a/dom/mobilemessage/MobileMessageManager.cpp
+++ b/dom/mobilemessage/MobileMessageManager.cpp
@@ -840,34 +840,34 @@ MobileMessageManager::SetSmscAddress(con
 } // namespace dom
 } // namespace mozilla
 
 already_AddRefed<nsISmsService>
 NS_CreateSmsService()
 {
   nsCOMPtr<nsISmsService> smsService;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     smsService = SmsIPCService::GetSingleton();
   } else {
 #ifdef MOZ_WIDGET_ANDROID
     smsService = new SmsService();
 #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
     smsService = do_GetService(GONK_SMSSERVICE_CONTRACTID);
 #endif
   }
 
   return smsService.forget();
 }
 
 already_AddRefed<nsIMobileMessageDatabaseService>
 NS_CreateMobileMessageDatabaseService()
 {
   nsCOMPtr<nsIMobileMessageDatabaseService> mobileMessageDBService;
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     mobileMessageDBService = SmsIPCService::GetSingleton();
   } else {
 #ifdef MOZ_WIDGET_ANDROID
     mobileMessageDBService = new MobileMessageDatabaseService();
 #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
     mobileMessageDBService =
       do_CreateInstance(GONK_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
 #endif
@@ -876,17 +876,17 @@ NS_CreateMobileMessageDatabaseService()
   return mobileMessageDBService.forget();
 }
 
 already_AddRefed<nsIMmsService>
 NS_CreateMmsService()
 {
   nsCOMPtr<nsIMmsService> mmsService;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     mmsService = SmsIPCService::GetSingleton();
   } else {
 #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
     mmsService = do_CreateInstance("@mozilla.org/mms/gonkmmsservice;1");
 #endif
   }
 
   return mmsService.forget();
--- a/dom/network/UDPSocket.cpp
+++ b/dom/network/UDPSocket.cpp
@@ -553,17 +553,17 @@ UDPSocket::Init(const nsString& aLocalAd
       }
 
       uint16_t localPort = 0;
       if (!mSocket->mLocalPort.IsNull()) {
         localPort = mSocket->mLocalPort.Value();
       }
 
       nsresult rv;
-      if (XRE_GetProcessType() != GeckoProcessType_Default) {
+      if (!XRE_IsParentProcess()) {
         rv = mSocket->InitRemote(mSocket->mLocalAddress, localPort);
       } else {
         rv = mSocket->InitLocal(mSocket->mLocalAddress, localPort);
       }
 
       if (NS_WARN_IF(NS_FAILED(rv))) {
         mSocket->CloseWithReason(NS_ERROR_DOM_NETWORK_ERR);
       }
--- a/dom/nfc/gonk/NfcService.cpp
+++ b/dom/nfc/gonk/NfcService.cpp
@@ -307,17 +307,17 @@ NfcService::NfcService()
 NfcService::~NfcService()
 {
   MOZ_ASSERT(!gNfcService);
 }
 
 already_AddRefed<NfcService>
 NfcService::FactoryCreate()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return nullptr;
   }
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gNfcService) {
     gNfcService = new NfcService();
     ClearOnShutdown(&gNfcService);
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -244,17 +244,17 @@ nsNPAPIPlugin::PluginCrashed(const nsASt
 {
   nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
   host->PluginCrashed(this, pluginDumpID, browserDumpID);
 }
 
 bool
 nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return true;
   }
 
 #if (MOZ_WIDGET_GTK == 3)
   // We force OOP on Linux/GTK3 because some plugins use GTK2 and both GTK
   // libraries can't be loaded in the same process.
   return true;
 #else
@@ -399,17 +399,17 @@ nsNPAPIPlugin::RunPluginOOP(const nsPlug
 
 inline PluginLibrary*
 GetNewPluginLibrary(nsPluginTag *aPluginTag)
 {
   if (!aPluginTag) {
     return nullptr;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return PluginModuleContentParent::LoadModule(aPluginTag->mId);
   }
 
   if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
     return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
   }
   return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
 }
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -248,17 +248,17 @@ static bool UnloadPluginsASAP()
 nsPluginHost::nsPluginHost()
   // No need to initialize members to nullptr, false etc because this class
   // has a zeroing operator new.
 {
   // Bump the pluginchanged epoch on startup. This insures content gets a
   // good plugin list the first time it requests it. Normally we'd just
   // init this to 1, but due to the unique nature of our ctor we need to do
   // this manually.
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     IncrementChromeEpoch();
   }
 
   // check to see if pref is set at startup to let plugins take over in
   // full page mode for certain image mime types that we handle internally
   mOverrideInternalTypes =
     Preferences::GetBool("plugin.override_internal_types", false);
 
@@ -1266,17 +1266,17 @@ nsresult nsPluginHost::EnsurePluginLoade
     aPluginTag->mPlugin = plugin;
   }
   return NS_OK;
 }
 
 nsresult
 nsPluginHost::GetPluginForContentProcess(uint32_t aPluginId, nsNPAPIPlugin** aPlugin)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   // If plugins haven't been scanned yet, do so now
   LoadPlugins();
 
   nsPluginTag* pluginTag = PluginWithId(aPluginId);
   if (pluginTag) {
     // When setting up a bridge, double check with chrome to see if this plugin
     // is blocked hard. Note this does not protect against vulnerable plugins
@@ -1331,17 +1331,17 @@ public:
 
 protected:
   uint32_t mPluginId;
 };
 
 void
 nsPluginHost::NotifyContentModuleDestroyed(uint32_t aPluginId)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   // This is called in response to a message from the plugin. Don't unload the
   // plugin until the message handler is off the stack.
   nsRefPtr<nsPluginUnloadRunnable> runnable =
     new nsPluginUnloadRunnable(aPluginId);
   NS_DispatchToMainThread(runnable);
 }
 
@@ -1837,17 +1837,17 @@ nsPluginHost::AddPluginTag(nsPluginTag* 
 }
 
 typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
 
 nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
                                             bool aCreatePluginList,
                                             bool *aPluginsChanged)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   NS_ENSURE_ARG_POINTER(aPluginsChanged);
   nsresult rv;
 
   *aPluginsChanged = false;
 
 #ifdef PLUGIN_LOGGING
   nsAutoCString dirPath;
@@ -2044,17 +2044,17 @@ nsresult nsPluginHost::ScanPluginsDirect
 
   return NS_OK;
 }
 
 nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
                                                 bool aCreatePluginList,
                                                 bool *aPluginsChanged)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
     bool hasMore;
     while (NS_SUCCEEDED(dirEnum->HasMoreElements(&hasMore)) && hasMore) {
       nsCOMPtr<nsISupports> supports;
       nsresult rv = dirEnum->GetNext(getter_AddRefs(supports));
       if (NS_FAILED(rv))
         continue;
       nsCOMPtr<nsIFile> nextDir(do_QueryInterface(supports, &rv));
@@ -2073,38 +2073,38 @@ nsresult nsPluginHost::ScanPluginsDirect
         break;
     }
     return NS_OK;
 }
 
 void
 nsPluginHost::IncrementChromeEpoch()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   mPluginEpoch++;
 }
 
 uint32_t
 nsPluginHost::ChromeEpoch()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   return mPluginEpoch;
 }
 
 uint32_t
 nsPluginHost::ChromeEpochForContent()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
+  MOZ_ASSERT(XRE_IsContentProcess());
   return mPluginEpoch;
 }
 
 void
 nsPluginHost::SetChromeEpochForContent(uint32_t aEpoch)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
+  MOZ_ASSERT(XRE_IsContentProcess());
   mPluginEpoch = aEpoch;
 }
 
 #ifdef XP_WIN
 static void
 WatchRegKey(uint32_t aRoot, nsCOMPtr<nsIWindowsRegKey>& aKey)
 {
   if (aKey) {
@@ -2124,17 +2124,17 @@ WatchRegKey(uint32_t aRoot, nsCOMPtr<nsI
   }
   aKey->StartWatching(true);
 }
 #endif
 
 nsresult nsPluginHost::LoadPlugins()
 {
 #ifdef ANDROID
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return NS_OK;
   }
 #endif
   // do not do anything if it is already done
   // use ReloadPlugins() to enforce loading
   if (mPluginsLoaded)
     return NS_OK;
 
@@ -2148,33 +2148,33 @@ nsresult nsPluginHost::LoadPlugins()
 
   bool pluginschanged;
   nsresult rv = FindPlugins(true, &pluginschanged);
   if (NS_FAILED(rv))
     return rv;
 
   // only if plugins have changed will we notify plugin-change observers
   if (pluginschanged) {
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       IncrementChromeEpoch();
     }
 
     nsCOMPtr<nsIObserverService> obsService =
       mozilla::services::GetObserverService();
     if (obsService)
       obsService->NotifyObservers(nullptr, "plugins-list-updated", nullptr);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
+  MOZ_ASSERT(XRE_IsContentProcess());
 
   dom::ContentChild* cp = dom::ContentChild::GetSingleton();
   nsTArray<PluginTag> plugins;
   uint32_t parentEpoch;
   if (!cp->SendFindPlugins(ChromeEpochForContent(), &plugins, &parentEpoch)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
@@ -2220,17 +2220,17 @@ nsPluginHost::FindPluginsInContent(bool 
 nsresult nsPluginHost::FindPlugins(bool aCreatePluginList, bool * aPluginsChanged)
 {
   Telemetry::AutoTimer<Telemetry::FIND_PLUGINS> telemetry;
 
   NS_ENSURE_ARG_POINTER(aPluginsChanged);
 
   *aPluginsChanged = false;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     return FindPluginsInContent(aCreatePluginList, aPluginsChanged);
   }
 
   nsresult rv;
 
   // Read cached plugins info. If the profile isn't yet available then don't
   // scan for plugins
   if (ReadPluginInfo() == NS_ERROR_NOT_AVAILABLE)
@@ -2387,29 +2387,29 @@ nsresult nsPluginHost::FindPlugins(bool 
   return NS_OK;
 }
 
 bool
 mozilla::plugins::FindPluginsForContent(uint32_t aPluginEpoch,
                                         nsTArray<PluginTag>* aPlugins,
                                         uint32_t* aNewPluginEpoch)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
   host->FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
   return true;
 }
 
 void
 nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
                                     nsTArray<PluginTag>* aPlugins,
                                     uint32_t* aNewPluginEpoch)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   // Load plugins so that the epoch is correct.
   LoadPlugins();
 
   *aNewPluginEpoch = ChromeEpoch();
   if (aPluginEpoch == ChromeEpoch()) {
     return;
   }
@@ -2439,17 +2439,17 @@ nsPluginHost::FindPluginsForContent(uint
                                       tag->mLastModifiedTime,
                                       tag->IsFromExtension()));
   }
 }
 
 void
 nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   ReadPluginInfo();
   WritePluginInfo();
   NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
   NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
 
   if (!aPluginTag) {
     return;
@@ -2525,17 +2525,17 @@ nsPluginHost::RegisterWithCategoryManage
                                   true);
     }
   }
 }
 
 nsresult
 nsPluginHost::WritePluginInfo()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
   if (NS_FAILED(rv))
     return rv;
 
   directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
                         getter_AddRefs(mPluginRegFile));
@@ -2670,17 +2670,17 @@ nsPluginHost::WritePluginInfo()
   NS_ENSURE_SUCCESS(rv, rv);
   rv = pluginReg->MoveToNative(parent, kPluginRegistryFilename);
   return rv;
 }
 
 nsresult
 nsPluginHost::ReadPluginInfo()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   const long PLUGIN_REG_MIMETYPES_ARRAY_SIZE = 12;
   const long PLUGIN_REG_MAX_MIMETYPES = 1000;
 
   // we need to import the legacy flags from the plugin registry once
   const bool pluginStateImported =
     Preferences::GetDefaultBool("plugin.importedState", false);
 
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -647,17 +647,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   // Given that this HWND may not be that of the document's window, there is a slight risk
   // of confusing a plugin that is using this HWND for illicit purposes, but since the documentation
   // does not suggest this HWND IS that of the document window, rather that of the window
   // the plugin is drawn in, this seems like a safe fix.
 
   // we only attempt to get the nearest window if this really is a "windowless" plugin so as not
   // to change any behaviour for the much more common windowed plugins,
   // though why this method would even be being called for a windowed plugin escapes me.
-  if (XRE_GetProcessType() != GeckoProcessType_Content &&
+  if (!XRE_IsContentProcess() &&
       mPluginWindow && mPluginWindow->type == NPWindowTypeDrawable) {
     // it turns out that flash also uses this window for determining focus, and is currently
     // unable to show a caret correctly if we return the enclosing window. Therefore for
     // now we only return the enclosing window when there is an actual offset which
     // would otherwise cause coordinates to be offset incorrectly. (i.e.
     // if the enclosing window if offset from the document window)
     //
     // fixing both the caret and ability to interact issues for a windowless control in a non document aligned windw
@@ -2835,17 +2835,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
     nsCOMPtr<nsIWidget> parentWidget;
     nsIDocument *doc = nullptr;
     nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
     if (content) {
       doc = content->OwnerDoc();
       parentWidget = nsContentUtils::WidgetForDocument(doc);
 #ifndef XP_MACOSX
       // If we're running in the content process, we need a remote widget created in chrome.
-      if (XRE_GetProcessType() == GeckoProcessType_Content) {
+      if (XRE_IsContentProcess()) {
         nsCOMPtr<nsIDOMWindow> window = doc->GetWindow();
         if (window) {
           nsCOMPtr<nsIDOMWindow> topWindow;
           window->GetTop(getter_AddRefs(topWindow));
           if (topWindow) {
             dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
             if (tc) {
               // This returns a PluginWidgetProxy which remotes a number of calls.
@@ -2957,17 +2957,17 @@ void nsPluginInstanceOwner::FixUpPluginW
   // fix up the clipping region
   mPluginWindow->clipRect.top  = 0;
   mPluginWindow->clipRect.left = 0;
 
   if (inPaintState == ePluginPaintDisable) {
     mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
     mPluginWindow->clipRect.right  = mPluginWindow->clipRect.left;
   }
-  else if (XRE_GetProcessType() != GeckoProcessType_Default)
+  else if (!XRE_IsParentProcess())
   {
     // For e10s we only support async windowless plugin. This means that
     // we're always going to allocate a full window for the plugin to draw
     // for even if the plugin is mostly outside of the scroll port. Thus
     // we never trim the window to the bounds of the widget.
     mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top + mPluginWindow->height;
     mPluginWindow->clipRect.right  = mPluginWindow->clipRect.left + mPluginWindow->width;
   }
@@ -3151,17 +3151,17 @@ nsPluginInstanceOwner::UpdateDocumentAct
   }
 #endif // #ifdef MOZ_WIDGET_ANDROID
 
   // We don't have a connection to PluginWidgetParent in the chrome
   // process when dealing with tab visibility changes, so this needs
   // to be forwarded over after the active state is updated. If we
   // don't hide plugin widgets in hidden tabs, the native child window
   // in chrome will remain visible after a tab switch.
-  if (mWidget && XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (mWidget && XRE_IsContentProcess()) {
     mWidget->Show(aIsActive);
     mWidget->Enable(aIsActive);
   }
 #endif // #ifndef XP_MACOSX
 }
 
 NS_IMETHODIMP
 nsPluginInstanceOwner::CallSetWindow()
--- a/dom/plugins/base/nsPluginNativeWindowGtk.cpp
+++ b/dom/plugins/base/nsPluginNativeWindowGtk.cpp
@@ -67,17 +67,17 @@ nsresult PLUG_DeletePluginNativeWindow(n
   delete p;
   return NS_OK;
 }
 
 nsresult nsPluginNativeWindowGtk::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance> &aPluginInstance)
 {
   if (aPluginInstance) {
     if (type == NPWindowTypeWindow &&
-        XRE_GetProcessType() == GeckoProcessType_Content) {
+        XRE_IsContentProcess()) {
       // In this case, most of the initialization code here has already happened
       // in the chrome process. The window we have in content is the XID of the
       // socket widget we need to hand to plugins.
       SetWindow((XID)window);
 	  } else if (type == NPWindowTypeWindow) {
       if (!mSocketWidget) {
         nsresult rv;
 
--- a/dom/plugins/base/nsPluginNativeWindowWin.cpp
+++ b/dom/plugins/base/nsPluginNativeWindowWin.cpp
@@ -612,17 +612,17 @@ nsresult nsPluginNativeWindowWin::CallSe
     if (NS_SUCCEEDED(aPluginInstance->GetMIMEType(&mimetype)) && mimetype) {
       mPluginType = nsPluginHost::GetSpecialType(nsDependentCString(mimetype));
     }
   }
 
   // With e10s we execute in the content process and as such we don't
   // have access to native widgets. CallSetWindow and skip native widget
   // subclassing.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     nsPluginNativeWindow::CallSetWindow(aPluginInstance);
     return NS_OK;
   }
 
   if (window) {
     // grab the widget procedure before the plug-in does a subclass in
     // setwindow. We'll use this in PluginWndProc for forwarding focus
     // events to the widget.
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -646,17 +646,17 @@ nsPluginTag::GetBlocklistState(uint32_t 
   *aResult = nsIBlocklistService::STATE_NOT_BLOCKED;
   return NS_OK;
 #else
   if (mCachedBlocklistStateValid) {
     *aResult = mCachedBlocklistState;
     return NS_OK;
   }
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     *aResult = nsIBlocklistService::STATE_BLOCKED;
     dom::ContentChild* cp = dom::ContentChild::GetSingleton();
     if (!cp->SendGetBlocklistState(mId, aResult)) {
       return NS_OK;
     }
   } else {
     nsCOMPtr<nsIBlocklistService> blocklist =
       do_GetService("@mozilla.org/extensions/blocklist;1");
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1851,17 +1851,17 @@ PluginInstanceParent::PluginWindowHookPr
 
 void
 PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
 {
     if ((aWnd && mPluginHWND == aWnd) || (!aWnd && mPluginHWND)) {
         return;
     }
 
-    if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    if (XRE_IsContentProcess()) {
         if (!aWnd) {
             NS_WARNING("PluginInstanceParent::SubclassPluginWindow unexpected null window");
             return;
         }
         mPluginHWND = aWnd; // now a remote window, we can't subclass this
         mPluginWndProc = nullptr;
         // Note sPluginInstanceList wil delete 'this' if we do not remove
         // it on shutdown.
@@ -1881,17 +1881,17 @@ PluginInstanceParent::SubclassPluginWind
         "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
     NS_ASSERTION(bRes,
         "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
 }
 
 void
 PluginInstanceParent::UnsubclassPluginWindow()
 {
-    if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    if (XRE_IsContentProcess()) {
         if (mPluginHWND) {
             // Remove 'this' from the plugin list safely
             nsAutoPtr<PluginInstanceParent> tmp;
             MOZ_ASSERT(sPluginInstanceList);
             sPluginInstanceList->RemoveAndForget((void*)mPluginHWND, tmp);
             tmp.forget();
             if (!sPluginInstanceList->Count()) {
                 delete sPluginInstanceList;
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -347,17 +347,17 @@ PRCList PluginModuleMapping::sModuleList
 
 bool PluginModuleMapping::sIsLoadModuleOnStack = false;
 
 } // anonymous namespace
 
 void
 mozilla::plugins::TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDumpId)
 {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+    MOZ_ASSERT(XRE_IsParentProcess());
 
     nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
     nsPluginTag* pluginTag = host->PluginWithId(aPluginId);
     if (!pluginTag || !pluginTag->mPlugin) {
         return;
     }
     nsRefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
     PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
@@ -365,17 +365,17 @@ mozilla::plugins::TerminatePlugin(uint32
 }
 
 /* static */ PluginLibrary*
 PluginModuleContentParent::LoadModule(uint32_t aPluginId)
 {
     PluginModuleMapping::NotifyLoadingModule loadingModule;
     nsAutoPtr<PluginModuleMapping> mapping(new PluginModuleMapping(aPluginId));
 
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
+    MOZ_ASSERT(XRE_IsContentProcess());
 
     /*
      * We send a LoadPlugin message to the chrome process using an intr
      * message. Before it sends its response, it sends a message to create
      * PluginModuleParent instance. That message is handled by
      * PluginModuleContentParent::Initialize, which saves the instance in
      * its module mapping. We fetch it from there after LoadPlugin finishes.
      */
--- a/dom/promise/PromiseDebugging.cpp
+++ b/dom/promise/PromiseDebugging.cpp
@@ -91,17 +91,17 @@ PromiseDebugging::sIDPrefix;
 
 /* static */ void
 PromiseDebugging::Init()
 {
   FlushRejections::Init();
 
   // Generate a prefix for identifiers: "PromiseDebugging.$processid."
   sIDPrefix = NS_LITERAL_STRING("PromiseDebugging.");
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     sIDPrefix.AppendInt(ContentChild::GetSingleton()->GetID());
     sIDPrefix.Append('.');
   } else {
     sIDPrefix.AppendLiteral("0.");
   }
 }
 
 /* static */ void
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -1070,22 +1070,16 @@ public:
             const nsACString& aOrigin)
   {
     PersistenceTypeToText(aPersistenceType, *this);
     Append(':');
     Append(aOrigin);
   }
 };
 
-bool
-IsMainProcess()
-{
-  return XRE_GetProcessType() == GeckoProcessType_Default;
-}
-
 void
 SanitizeOriginString(nsCString& aOrigin)
 {
   // We want profiles to be platform-independent so we always need to replace
   // the same characters on every platform. Windows has the most extensive set
   // of illegal characters so we use its FILE_ILLEGAL_CHARACTERS and
   // FILE_PATH_SEPARATOR.
   static const char kReplaceChars[] = CONTROL_CHARACTERS "/:*?\"<>|\\";
@@ -2388,17 +2382,17 @@ QuotaManager::CollectOriginsForEviction(
 
   return 0;
 }
 
 nsresult
 QuotaManager::Init()
 {
   nsresult rv;
-  if (IsMainProcess()) {
+  if (XRE_IsParentProcess()) {
     nsCOMPtr<nsIFile> baseDir;
     rv = NS_GetSpecialDirectory(NS_APP_INDEXEDDB_PARENT_DIR,
                                 getter_AddRefs(baseDir));
     if (NS_FAILED(rv)) {
       rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                   getter_AddRefs(baseDir));
     }
     NS_ENSURE_SUCCESS(rv, rv);
@@ -3734,17 +3728,17 @@ QuotaManager::GetUsageForURI(nsIURI* aUR
                              nsIQuotaRequest** _retval)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   NS_ENSURE_ARG_POINTER(aURI);
   NS_ENSURE_ARG_POINTER(aCallback);
 
   // This only works from the main process.
-  NS_ENSURE_TRUE(IsMainProcess(), NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
 
   if (!aOptionalArgCount) {
     aAppId = nsIScriptSecurityManager::NO_APP_ID;
   }
 
   // Figure out which origin we're dealing with.
   nsCString group;
   nsCString origin;
@@ -3794,17 +3788,17 @@ QuotaManager::ClearStoragesForURI(nsIURI
   Nullable<PersistenceType> persistenceType;
   nsresult rv =
     NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return NS_ERROR_INVALID_ARG;
   }
 
   // This only works from the main process.
-  NS_ENSURE_TRUE(IsMainProcess(), NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
 
   if (!aOptionalArgCount) {
     aAppId = nsIScriptSecurityManager::NO_APP_ID;
   }
 
   // Figure out which origin we're dealing with.
   nsCString origin;
   rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, nullptr, &origin,
@@ -3848,17 +3842,17 @@ QuotaManager::Observe(nsISupports* aSubj
 
   if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_OBSERVER_ID)) {
     // Setting this flag prevents the service from being recreated and prevents
     // further storagess from being created.
     if (gShutdown.exchange(true)) {
       NS_ERROR("Shutdown more than once?!");
     }
 
-    if (IsMainProcess()) {
+    if (XRE_IsParentProcess()) {
       // Kick off the shutdown timer.
       if (NS_FAILED(mShutdownTimer->Init(this, DEFAULT_SHUTDOWN_TIMER_MS,
                                          nsITimer::TYPE_ONE_SHOT))) {
         NS_WARNING("Failed to initialize shutdown timer!");
       }
 
       // Each client will spin the event loop while we wait on all the threads
       // to close. Our timer may fire during that loop.
@@ -3891,17 +3885,17 @@ QuotaManager::Observe(nsISupports* aSubj
         lock->Invalidate();
       }
     }
 
     return NS_OK;
   }
 
   if (!strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC)) {
-    NS_ASSERTION(IsMainProcess(), "Should only happen in the main process!");
+    NS_ASSERTION(XRE_IsParentProcess(), "Should only happen in the main process!");
 
     NS_WARNING("Some storage operations are taking longer than expected "
                "during shutdown and will be aborted!");
 
     // Abort all operations.
     for (nsRefPtr<Client>& client : mClients) {
       client->AbortOperations(NullCString());
     }
@@ -3993,17 +3987,17 @@ QuotaManager::LockedRemoveQuotaForOrigin
 
 nsresult
 QuotaManager::ClearStoragesForApp(uint32_t aAppId, bool aBrowserOnly)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aAppId != kUnknownAppId, "Bad appId!");
 
   // This only works from the main process.
-  NS_ENSURE_TRUE(IsMainProcess(), NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
 
   nsAutoCString pattern;
   GetOriginPatternStringMaybeIgnoreBrowser(aAppId, aBrowserOnly, pattern);
 
   nsRefPtr<OriginClearOp> op =
     new OriginClearOp(Nullable<PersistenceType>(),
                       OriginScope::FromPattern(pattern));
 
--- a/dom/speakermanager/SpeakerManagerService.cpp
+++ b/dom/speakermanager/SpeakerManagerService.cpp
@@ -25,17 +25,17 @@ using namespace mozilla::dom;
 StaticRefPtr<SpeakerManagerService> gSpeakerManagerService;
 
 // static
 SpeakerManagerService*
 SpeakerManagerService::GetOrCreateSpeakerManagerService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return SpeakerManagerServiceChild::GetOrCreateSpeakerManagerService();
   }
 
   // If we already exist, exit early
   if (gSpeakerManagerService) {
     return gSpeakerManagerService;
   }
 
@@ -47,27 +47,27 @@ SpeakerManagerService::GetOrCreateSpeake
   return gSpeakerManagerService;
 }
 
 SpeakerManagerService*
 SpeakerManagerService::GetSpeakerManagerService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return SpeakerManagerServiceChild::GetSpeakerManagerService();
   }
 
   return gSpeakerManagerService;
 }
 
 void
 SpeakerManagerService::Shutdown()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return SpeakerManagerServiceChild::Shutdown();
   }
 
   if (gSpeakerManagerService) {
     gSpeakerManagerService = nullptr;
   }
 }
 
@@ -183,17 +183,17 @@ SpeakerManagerService::Observe(nsISuppor
   return NS_OK;
 }
 
 SpeakerManagerService::SpeakerManagerService()
   : mOrgSpeakerStatus(false),
     mVisible(false)
 {
   MOZ_COUNT_CTOR(SpeakerManagerService);
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->AddObserver(this, "ipc:content-shutdown", false);
     }
   }
   AudioChannelService* audioChannelService =
     AudioChannelService::GetOrCreateAudioChannelService();
   if (audioChannelService) {
--- a/dom/storage/DOMStorageCache.cpp
+++ b/dom/storage/DOMStorageCache.cpp
@@ -756,17 +756,17 @@ DOMStorageCache::StartDatabase()
 {
   if (sDatabase || sDatabaseDown) {
     // When sDatabaseDown is at true, sDatabase is null.
     // Checking sDatabaseDown flag here prevents reinitialization of
     // the database after shutdown.
     return sDatabase;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsAutoPtr<DOMStorageDBThread> db(new DOMStorageDBThread());
 
     nsresult rv = db->Init();
     if (NS_FAILED(rv)) {
       return nullptr;
     }
 
     sDatabase = db.forget();
@@ -801,17 +801,17 @@ DOMStorageCache::StopDatabase()
 {
   if (!sDatabase) {
     return NS_OK;
   }
 
   sDatabaseDown = true;
 
   nsresult rv = sDatabase->Shutdown();
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     delete sDatabase;
   } else {
     DOMStorageDBChild* child = static_cast<DOMStorageDBChild*>(sDatabase);
     NS_RELEASE(child);
   }
 
   sDatabase = nullptr;
   return rv;
--- a/dom/storage/DOMStorageManager.cpp
+++ b/dom/storage/DOMStorageManager.cpp
@@ -587,17 +587,17 @@ DOMStorageManager::Observe(const char* a
 
     // This immediately completely reloads all caches from the database.
     ClearCacheEnumeratorData data(DOMStorageCache::kTestReload);
     mCaches.EnumerateEntries(ClearCacheEnumerator, &data);
     return NS_OK;
   }
 
   if (!strcmp(aTopic, "test-flushed")) {
-    if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    if (!XRE_IsParentProcess()) {
       nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
       if (obs) {
         obs->NotifyObservers(nullptr, "domstorage-test-flushed", nullptr);
       }
     }
 
     return NS_OK;
   }
@@ -610,17 +610,17 @@ DOMStorageManager::Observe(const char* a
 // DOMLocalStorageManager
 
 DOMLocalStorageManager::DOMLocalStorageManager()
   : DOMStorageManager(LocalStorage)
 {
   NS_ASSERTION(!sSelf, "Somebody is trying to do_CreateInstance(\"@mozilla/dom/localStorage-manager;1\"");
   sSelf = this;
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     // Do this only on the child process.  The thread IPC bridge
     // is also used to communicate chrome observer notifications.
     // Note: must be called after we set sSelf
     DOMStorageCache::StartDatabase();
   }
 }
 
 DOMLocalStorageManager::~DOMLocalStorageManager()
@@ -643,17 +643,17 @@ DOMLocalStorageManager::Ensure()
   return sSelf;
 }
 
 // DOMSessionStorageManager
 
 DOMSessionStorageManager::DOMSessionStorageManager()
   : DOMStorageManager(SessionStorage)
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     // Do this only on the child process.  The thread IPC bridge
     // is also used to communicate chrome observer notifications.
     DOMStorageCache::StartDatabase();
   }
 }
 
 } // ::dom
 } // ::mozilla
--- a/dom/storage/DOMStorageObserver.cpp
+++ b/dom/storage/DOMStorageObserver.cpp
@@ -70,17 +70,17 @@ DOMStorageObserver::Init()
   obs->AddObserver(sSelf, "xpcom-shutdown", true);
 
   // Observe low device storage notifications.
   obs->AddObserver(sSelf, "disk-space-watcher", true);
 
 #ifdef DOM_STORAGE_TESTS
   // Testing
   obs->AddObserver(sSelf, "domstorage-test-flush-force", true);
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // Only to forward to child process.
     obs->AddObserver(sSelf, "domstorage-test-flushed", true);
   }
 
   obs->AddObserver(sSelf, "domstorage-test-reload", true);
 #endif
 
   return NS_OK;
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -550,17 +550,17 @@ AudioManager::~AudioManager() {
 }
 
 static StaticRefPtr<AudioManager> sAudioManager;
 
 already_AddRefed<AudioManager>
 AudioManager::GetInstance()
 {
   // Avoid createing AudioManager from content process.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     MOZ_CRASH("Non-chrome processes should not get here.");
   }
 
   // Avoid createing multiple AudioManager instance inside main process.
   if (!sAudioManager) {
     sAudioManager = new AudioManager();
     ClearOnShutdown(&sAudioManager);
   }
--- a/dom/system/gonk/AutoMounter.cpp
+++ b/dom/system/gonk/AutoMounter.cpp
@@ -1293,57 +1293,57 @@ ShutdownAutoMounterIOThread()
 
   sAutoMounter = nullptr;
   ShutdownVolumeManager();
 }
 
 static void
 SetAutoMounterModeIOThread(const int32_t& aMode)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   MOZ_ASSERT(sAutoMounter);
 
   sAutoMounter->SetMode(aMode);
 }
 
 static void
 SetAutoMounterSharingModeIOThread(const nsCString& aVolumeName, const bool& aAllowSharing)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   MOZ_ASSERT(sAutoMounter);
 
   sAutoMounter->SetSharingMode(aVolumeName, aAllowSharing);
 }
 
 static void
 AutoMounterFormatVolumeIOThread(const nsCString& aVolumeName)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   MOZ_ASSERT(sAutoMounter);
 
   sAutoMounter->FormatVolume(aVolumeName);
 }
 
 static void
 AutoMounterMountVolumeIOThread(const nsCString& aVolumeName)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   MOZ_ASSERT(sAutoMounter);
 
   sAutoMounter->MountVolume(aVolumeName);
 }
 
 static void
 AutoMounterUnmountVolumeIOThread(const nsCString& aVolumeName)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   MOZ_ASSERT(sAutoMounter);
 
   sAutoMounter->UnmountVolume(aVolumeName);
 }
 
 static void
 UsbCableEventIOThread()
--- a/dom/system/gonk/NetworkWorker.cpp
+++ b/dom/system/gonk/NetworkWorker.cpp
@@ -129,17 +129,17 @@ NetworkWorker::~NetworkWorker()
 {
   MOZ_ASSERT(!gNetworkWorker);
   MOZ_ASSERT(!mListener);
 }
 
 already_AddRefed<NetworkWorker>
 NetworkWorker::FactoryCreate()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return nullptr;
   }
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gNetworkWorker) {
     gNetworkWorker = new NetworkWorker();
     ClearOnShutdown(&gNetworkWorker);
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -67,17 +67,17 @@ SystemWorkerManager::~SystemWorkerManage
   NS_ASSERTION(!gInstance || gInstance == this,
                "There should only be one instance!");
   gInstance = nullptr;
 }
 
 nsresult
 SystemWorkerManager::Init()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread");
   NS_ASSERTION(!mShutdown, "Already shutdown!");
 
   mozilla::AutoSafeJSContext cx;
 
--- a/dom/system/gonk/Volume.cpp
+++ b/dom/system/gonk/Volume.cpp
@@ -228,17 +228,17 @@ Volume::SetConfig(const nsCString& aConf
     return;
   }
   ERR("Volume %s: invalid config '%s'", NameStr(), aConfigName.get());
 }
 
 void
 Volume::SetMediaPresent(bool aMediaPresent)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   // mMediaPresent is slightly redunant to the state, however
   // when media is removed (while Idle), we get the following:
   //    631 Volume sdcard /mnt/sdcard disk removed (179:0)
   //    605 Volume sdcard /mnt/sdcard state changed from 1 (Idle-Unmounted) to 0 (No-Media)
   //
   // And on media insertion, we get:
@@ -303,17 +303,17 @@ Volume::SetUnmountRequested(bool aUnmoun
 
   LOG("SetUnmountRequested for volume %s to %d CanBeMounted = %d",
       NameStr(), (int)mUnmountRequested, (int)CanBeMounted());
 }
 
 void
 Volume::SetState(Volume::STATE aNewState)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   if (aNewState == mState) {
     return;
   }
   if (aNewState == nsIVolume::STATE_MOUNTED) {
     mMountGeneration = ++sMountGeneration;
     LOG("Volume %s (%u): changing state from %s to %s @ '%s' (%d observers) "
         "mountGeneration = %d, locked = %d",
@@ -375,85 +375,85 @@ Volume::SetState(Volume::STATE aNewState
   }
   mState = aNewState;
   sEventObserverList.Broadcast(this);
 }
 
 void
 Volume::SetMountPoint(const nsCSubstring& aMountPoint)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   if (mMountPoint.Equals(aMountPoint)) {
     return;
   }
   mMountPoint = aMountPoint;
   DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
 }
 
 void
 Volume::StartMount(VolumeResponseCallback* aCallback)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   StartCommand(new VolumeActionCommand(this, "mount", "", aCallback));
 }
 
 void
 Volume::StartUnmount(VolumeResponseCallback* aCallback)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   StartCommand(new VolumeActionCommand(this, "unmount", "force", aCallback));
 }
 
 void
 Volume::StartFormat(VolumeResponseCallback* aCallback)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   StartCommand(new VolumeActionCommand(this, "format", "", aCallback));
 }
 
 void
 Volume::StartShare(VolumeResponseCallback* aCallback)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   StartCommand(new VolumeActionCommand(this, "share", "ums", aCallback));
 }
 
 void
 Volume::StartUnshare(VolumeResponseCallback* aCallback)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   StartCommand(new VolumeActionCommand(this, "unshare", "ums", aCallback));
 }
 
 void
 Volume::StartCommand(VolumeCommand* aCommand)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   VolumeManager::PostCommand(aCommand);
 }
 
 //static
 void
 Volume::RegisterVolumeObserver(Volume::EventObserver* aObserver, const char* aName)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   sEventObserverList.AddObserver(aObserver);
 
   DBG("Added Volume Observer '%s' @%p, length = %u",
       aName, aObserver, sEventObserverList.Length());
 
   // Send an initial event to the observer (for each volume)
@@ -463,49 +463,49 @@ Volume::RegisterVolumeObserver(Volume::E
     aObserver->Notify(vol);
   }
 }
 
 //static
 void
 Volume::UnregisterVolumeObserver(Volume::EventObserver* aObserver, const char* aName)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   sEventObserverList.RemoveObserver(aObserver);
 
   DBG("Removed Volume Observer '%s' @%p, length = %u",
       aName, aObserver, sEventObserverList.Length());
 }
 
 //static
 void
 Volume::UpdateMountLock(const nsACString& aVolumeName,
                         const int32_t& aMountGeneration,
                         const bool& aMountLocked)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
   if (!vol || (vol->mMountGeneration != aMountGeneration)) {
     return;
   }
   if (vol->mMountLocked != aMountLocked) {
     vol->mMountLocked = aMountLocked;
     DBG("Volume::UpdateMountLock for '%s' to %d\n", vol->NameStr(), (int)aMountLocked);
     sEventObserverList.Broadcast(vol);
   }
 }
 
 void
 Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
 
   // The volume name will have already been parsed, and the tokenizer will point
   // to the token after the volume name
   switch (aResponseCode) {
     case ::ResponseCode::VolumeListResult: {
       // Each line will look something like:
       //
--- a/dom/system/gonk/nsVolume.cpp
+++ b/dom/system/gonk/nsVolume.cpp
@@ -241,77 +241,77 @@ NS_IMETHODIMP nsVolume::GetIsRemovable(b
 NS_IMETHODIMP nsVolume::GetIsHotSwappable(bool *aIsHotSwappable)
 {
   *aIsHotSwappable = mIsHotSwappable;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsVolume::Format()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   XRE_GetIOMessageLoop()->PostTask(
       FROM_HERE,
       NewRunnableFunction(FormatVolumeIOThread, NameStr()));
 
   return NS_OK;
 }
 
 /* static */
 void nsVolume::FormatVolumeIOThread(const nsCString& aVolume)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
     return;
   }
 
   AutoMounterFormatVolume(aVolume);
 }
 
 NS_IMETHODIMP nsVolume::Mount()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   XRE_GetIOMessageLoop()->PostTask(
       FROM_HERE,
       NewRunnableFunction(MountVolumeIOThread, NameStr()));
 
   return NS_OK;
 }
 
 /* static */
 void nsVolume::MountVolumeIOThread(const nsCString& aVolume)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
     return;
   }
 
   AutoMounterMountVolume(aVolume);
 }
 
 NS_IMETHODIMP nsVolume::Unmount()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   XRE_GetIOMessageLoop()->PostTask(
       FROM_HERE,
       NewRunnableFunction(UnmountVolumeIOThread, NameStr()));
 
   return NS_OK;
 }
 
 /* static */
 void nsVolume::UnmountVolumeIOThread(const nsCString& aVolume)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
     return;
   }
 
   AutoMounterUnmountVolume(aVolume);
 }
@@ -359,17 +359,17 @@ void nsVolume::Set(nsIVolume* aVolume)
   }
   if (mMountGeneration == volMountGeneration) {
     // No change in mount generation, nothing else to do
     return;
   }
 
   mMountGeneration = volMountGeneration;
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     // Child processes just track the state, not maintain it.
     aVolume->GetIsMountLocked(&mMountLocked);
     return;
   }
 
   // Notify the Volume on IOThread whether the volume is locked or not.
   nsCOMPtr<nsIPowerManagerService> pmService =
     do_GetService(POWERMANAGERSERVICE_CONTRACTID);
@@ -381,28 +381,28 @@ void nsVolume::Set(nsIVolume* aVolume)
   nsString mountLockState;
   pmService->GetWakeLockState(mountLockName, mountLockState);
   UpdateMountLock(mountLockState);
 }
 
 void
 nsVolume::UpdateMountLock(const nsAString& aMountLockState)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   // There are 3 states, unlocked, locked-background, and locked-foreground
   // I figured it was easier to use negtive logic and compare for unlocked.
   UpdateMountLock(!aMountLockState.EqualsLiteral("unlocked"));
 }
 
 void
 nsVolume::UpdateMountLock(bool aMountLocked)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aMountLocked == mMountLocked) {
     return;
   }
   // The locked/unlocked state changed. Tell IOThread about it.
   mMountLocked = aMountLocked;
   LogState();
@@ -442,17 +442,17 @@ nsVolume::SetIsHotSwappable(bool aIsHotS
   }
 }
 
 void
 nsVolume::SetState(int32_t aState)
 {
   static int32_t sMountGeneration = 0;
 
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(IsFake());
 
   if (aState == mState) {
     return;
   }
 
   if (aState == nsIVolume::STATE_MOUNTED) {
--- a/dom/system/gonk/nsVolumeService.cpp
+++ b/dom/system/gonk/nsVolumeService.cpp
@@ -63,17 +63,17 @@ nsVolumeService::GetSingleton()
 
 // static
 void
 nsVolumeService::Shutdown()
 {
   if (!sSingleton) {
     return;
   }
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     sSingleton = nullptr;
     return;
   }
 
   nsCOMPtr<nsIPowerManagerService> pmService =
     do_GetService(POWERMANAGERSERVICE_CONTRACTID);
   if (pmService) {
     pmService->RemoveWakeLockListener(sSingleton.get());
@@ -87,17 +87,17 @@ nsVolumeService::Shutdown()
 }
 
 nsVolumeService::nsVolumeService()
   : mArrayMonitor("nsVolumeServiceArray"),
     mGotVolumesFromParent(false)
 {
   sSingleton = this;
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     // VolumeServiceIOThread and the WakeLock listener should only run in the
     // parent, so we return early.
     return;
   }
 
   // Startup the IOThread side of things. The actual volume changes
   // are captured by the IOThread and forwarded to main thread.
   XRE_GetIOMessageLoop()->PostTask(
@@ -266,17 +266,17 @@ nsVolumeService::GetVolumeNames(nsIArray
 
   volNames.forget(aVolNames);
   return NS_OK;
 }
 
 void
 nsVolumeService::GetVolumesForIPC(nsTArray<VolumeInfo>* aResult)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   MonitorAutoLock autoLock(mArrayMonitor);
 
   nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
   nsVolume::Array::index_type volIndex;
   for (volIndex = 0; volIndex < numVolumes; volIndex++) {
     nsRefPtr<nsVolume> vol = mVolumeArray[volIndex];
@@ -294,17 +294,17 @@ nsVolumeService::GetVolumesForIPC(nsTArr
     volInfo->isRemovable()      = vol->mIsRemovable;
     volInfo->isHotSwappable()   = vol->mIsHotSwappable;
   }
 }
 
 void
 nsVolumeService::RecvVolumesFromParent(const nsTArray<VolumeInfo>& aVolumes)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // We are the parent. Therefore our volumes are already correct.
     return;
   }
   if (mGotVolumesFromParent) {
     // We've already done this, no need to do it again.
     return;
   }
 
@@ -335,17 +335,17 @@ nsVolumeService::CreateMountLock(const n
   mountLock.forget(aResult);
   return NS_OK;
 }
 
 void
 nsVolumeService::CheckMountLock(const nsAString& aMountLockName,
                                 const nsAString& aMountLockState)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   nsRefPtr<nsVolume> vol = FindVolumeByMountLockName(aMountLockName);
   if (vol) {
     vol->UpdateMountLock(aMountLockState);
   }
 }
 
@@ -433,17 +433,17 @@ nsVolumeService::UpdateVolume(nsIVolume*
   }
   NS_ConvertUTF8toUTF16 stateStr(vol->StateStr());
   obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
 }
 
 NS_IMETHODIMP
 nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsRefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_INIT,
                                           -1    /* mountGeneration */,
                                           true  /* isMediaPresent */,
                                           false /* isSharing */,
                                           false /* isFormatting */,
                                           true  /* isFake */,
                                           false /* isUnmounting */,
                                           false /* isRemovable */,
@@ -456,17 +456,17 @@ nsVolumeService::CreateFakeVolume(const 
 
   ContentChild::GetSingleton()->SendCreateFakeVolume(nsString(name), nsString(path));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsRefPtr<nsVolume> vol;
     {
       MonitorAutoLock autoLock(mArrayMonitor);
       vol = FindVolumeByName(name);
     }
     if (!vol || !vol->IsFake()) {
       return NS_ERROR_NOT_AVAILABLE;
     }
@@ -484,17 +484,17 @@ nsVolumeService::SetFakeVolumeState(cons
 
   ContentChild::GetSingleton()->SendSetFakeVolumeState(nsString(name), state);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsVolumeService::RemoveFakeVolume(const nsAString& name)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     SetFakeVolumeState(name, nsIVolume::STATE_NOMEDIA);
     RemoveVolumeByName(name);
     return NS_OK;
   }
 
   ContentChild::GetSingleton()->SendRemoveFakeVolume(nsString(name));
   return NS_OK;
 }
@@ -507,17 +507,17 @@ nsVolumeService::RemoveVolumeByName(cons
     MonitorAutoLock autoLock(mArrayMonitor);
     vol = FindVolumeByName(aName);
   }
   if (!vol) {
     return;
   }
   mVolumeArray.RemoveElement(vol);
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsCOMPtr<nsIObserverService> obs = GetObserverService();
     if (!obs) {
       return;
     }
     obs->NotifyObservers(nullptr, NS_VOLUME_REMOVED, nsString(aName).get());
   }
 }
 
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -715,17 +715,17 @@ Telephony::DispatchCallEvent(const nsASt
   return DispatchTrustedEvent(event);
 }
 
 already_AddRefed<nsITelephonyService>
 NS_CreateTelephonyService()
 {
   nsCOMPtr<nsITelephonyService> service;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     service = new mozilla::dom::telephony::TelephonyIPCService();
   } else {
 #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
     service = do_CreateInstance(GONK_TELEPHONY_SERVICE_CONTRACTID);
 #endif
   }
 
   return service.forget();
--- a/dom/voicemail/Voicemail.cpp
+++ b/dom/voicemail/Voicemail.cpp
@@ -245,17 +245,17 @@ Voicemail::NotifyStatusChanged(nsIVoicem
   return DispatchTrustedEvent(event);
 }
 
 already_AddRefed<nsIVoicemailService>
 NS_CreateVoicemailService()
 {
   nsCOMPtr<nsIVoicemailService> service;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     service = new mozilla::dom::voicemail::VoicemailIPCService();
   } else {
 #if defined(MOZ_B2G_RIL)
 #if defined(MOZ_WIDGET_GONK)
     service = do_GetService(GONK_VOICEMAIL_SERVICE_CONTRACTID);
 #endif // MOZ_WIDGET_GONK
 #endif // MOZ_B2G_RIL
   }
--- a/dom/webidl/RTCConfiguration.webidl
+++ b/dom/webidl/RTCConfiguration.webidl
@@ -9,12 +9,19 @@
 
 dictionary RTCIceServer {
     (DOMString or sequence<DOMString>) urls;
     DOMString  url; //deprecated
     DOMString? credential = null;
     DOMString? username = null;
 };
 
+enum RTCBundlePolicy {
+    "balanced",
+    "max-compat",
+    "max-bundle"
+};
+
 dictionary RTCConfiguration {
     sequence<RTCIceServer> iceServers;
+    RTCBundlePolicy bundlePolicy = "balanced";
     DOMString? peerIdentity = null;
 };
--- a/dom/wifi/WifiCertService.cpp
+++ b/dom/wifi/WifiCertService.cpp
@@ -438,17 +438,17 @@ WifiCertService::WifiCertService()
 WifiCertService::~WifiCertService()
 {
   MOZ_ASSERT(!gWifiCertService);
 }
 
 already_AddRefed<WifiCertService>
 WifiCertService::FactoryCreate()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return nullptr;
   }
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gWifiCertService) {
     gWifiCertService = new WifiCertService();
     ClearOnShutdown(&gWifiCertService);
--- a/dom/wifi/WifiProxyService.cpp
+++ b/dom/wifi/WifiProxyService.cpp
@@ -145,17 +145,17 @@ WifiProxyService::WifiProxyService()
 WifiProxyService::~WifiProxyService()
 {
   MOZ_ASSERT(!gWifiProxyService);
 }
 
 already_AddRefed<WifiProxyService>
 WifiProxyService::FactoryCreate()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return nullptr;
   }
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gWifiProxyService) {
     gWifiProxyService = new WifiProxyService();
     ClearOnShutdown(&gWifiProxyService);
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -398,17 +398,17 @@ ServiceWorkerManager::Init()
 {
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     DebugOnly<nsresult> rv;
     rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false /* ownsWeak */);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
     MOZ_ASSERT(swr);
 
     nsTArray<ServiceWorkerRegistrationData> data;
     swr->GetRegistrations(data);
     LoadRegistrations(data);
 
     if (obs) {
@@ -4542,17 +4542,17 @@ ServiceWorkerManager::RemoveAll()
   AssertIsOnMainThread();
   mRegistrationInfos.EnumerateRead(UnregisterIfMatchesHostPerPrincipal, nullptr);
 }
 
 void
 ServiceWorkerManager::PropagateRemoveAll()
 {
   AssertIsOnMainThread();
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if (!mActor) {
     nsRefPtr<nsIRunnable> runnable = new PropagateRemoveAllRunnable();
     AppendPendingOperation(runnable);
     return;
   }
 
   mActor->SendPropagateRemoveAll();
@@ -4599,31 +4599,31 @@ ServiceWorkerManager::UpdateAllRegistrat
 }
 
 NS_IMETHODIMP
 ServiceWorkerManager::Observe(nsISupports* aSubject,
                               const char* aTopic,
                               const char16_t* aData)
 {
   if (strcmp(aTopic, PURGE_SESSION_HISTORY) == 0) {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+    MOZ_ASSERT(XRE_IsParentProcess());
     RemoveAll();
     PropagateRemoveAll();
     return NS_OK;
   }
 
   if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+    MOZ_ASSERT(XRE_IsParentProcess());
     nsAutoString domain(aData);
     RemoveAndPropagate(NS_ConvertUTF16toUTF8(domain));
     return NS_OK;
   }
 
   if (strcmp(aTopic, WEBAPPS_CLEAR_DATA) == 0) {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+    MOZ_ASSERT(XRE_IsParentProcess());
     nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
       do_QueryInterface(aSubject);
     if (NS_WARN_IF(!params)) {
       return NS_OK;
     }
 
     uint32_t appId;
     nsresult rv = params->GetAppId(&appId);
@@ -4653,17 +4653,17 @@ ServiceWorkerManager::Observe(nsISupport
 
   if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
     mShuttingDown = true;
 
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
 
-      if (XRE_GetProcessType() == GeckoProcessType_Default) {
+      if (XRE_IsParentProcess()) {
         obs->RemoveObserver(this, PURGE_SESSION_HISTORY);
         obs->RemoveObserver(this, PURGE_DOMAIN_DATA);
         obs->RemoveObserver(this, WEBAPPS_CLEAR_DATA);
       }
     }
 
     if (mActor) {
       mActor->ManagerShuttingDown();
--- a/dom/workers/ServiceWorkerPeriodicUpdater.cpp
+++ b/dom/workers/ServiceWorkerPeriodicUpdater.cpp
@@ -23,17 +23,17 @@ NS_IMPL_ISUPPORTS(ServiceWorkerPeriodicU
 StaticRefPtr<ServiceWorkerPeriodicUpdater>
 ServiceWorkerPeriodicUpdater::sInstance;
 bool
 ServiceWorkerPeriodicUpdater::sPeriodicUpdatesEnabled = true;
 
 already_AddRefed<ServiceWorkerPeriodicUpdater>
 ServiceWorkerPeriodicUpdater::GetSingleton()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   if (!sInstance) {
     sInstance = new ServiceWorkerPeriodicUpdater();
     ClearOnShutdown(&sInstance);
   }
   nsRefPtr<ServiceWorkerPeriodicUpdater> copy(sInstance.get());
   return copy.forget();
 }
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -43,17 +43,17 @@ StaticRefPtr<ServiceWorkerRegistrar> gSe
 NS_IMPL_ISUPPORTS(ServiceWorkerRegistrar,
                   nsIObserver)
 
 void
 ServiceWorkerRegistrar::Initialize()
 {
   MOZ_ASSERT(!gServiceWorkerRegistrar);
 
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return;
   }
 
   gServiceWorkerRegistrar = new ServiceWorkerRegistrar();
   ClearOnShutdown(&gServiceWorkerRegistrar);
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
@@ -65,17 +65,17 @@ ServiceWorkerRegistrar::Initialize()
                           false);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 }
 
 /* static */ already_AddRefed<ServiceWorkerRegistrar>
 ServiceWorkerRegistrar::Get()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   MOZ_ASSERT(gServiceWorkerRegistrar);
   nsRefPtr<ServiceWorkerRegistrar> service = gServiceWorkerRegistrar.get();
   return service.forget();
 }
 
 ServiceWorkerRegistrar::ServiceWorkerRegistrar()
   : mMonitor("ServiceWorkerRegistrar.mMonitor")
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2700,17 +2700,17 @@ private:
     nsCOMPtr<nsIURI> scriptURI;
     if (NS_FAILED(NS_NewURI(getter_AddRefs(scriptURI),
                             mWorkerPrivate->ScriptURL()))) {
       return;
     }
 
     mAlreadyMappedToAddon = true;
 
-    if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    if (!XRE_IsParentProcess()) {
       // Only try to access the service from the main process.
       return;
     }
 
     nsAutoCString addonId;
     bool ok;
     nsCOMPtr<amIAddonManager> addonManager =
       do_GetService("@mozilla.org/addons/integration;1");
--- a/embedding/browser/nsWebBrowser.cpp
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -1233,17 +1233,17 @@ nsWebBrowser::Create()
   // event.
 
   if (!mInitInfo->sessionHistory) {
     mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory);
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // Hook up global history. Do not fail if we can't - just warn.
     rv = EnableGlobalHistory(mShouldEnableHistory);
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed");
   }
 
   NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE);
 
   // Hook into the OnSecurityChange() notification for lock/unlock icon
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -475,17 +475,17 @@ nsWindowWatcher::OpenWindowInternal(nsID
 
   nsCOMPtr<nsPIDOMWindow> parent = do_QueryInterface(aParent);
   if (parent && parent->IsInnerWindow()) {
     NS_ENSURE_STATE(parent->IsCurrentInnerWindow());
     aParent = parent->GetOuterWindow();
   }
 
   MOZ_ASSERT_IF(openedFromRemoteTab,
-                XRE_GetProcessType() == GeckoProcessType_Default);
+                XRE_IsParentProcess());
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = 0;
 
   if (!nsContentUtils::IsSafeToRunScript()) {
     nsContentUtils::WarnScriptWasIgnored(nullptr);
     return NS_ERROR_FAILURE;
   }
 
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -43,17 +43,17 @@ static nsPermissionManager *gPermissionM
 
 using mozilla::dom::ContentParent;
 using mozilla::dom::ContentChild;
 using mozilla::unused; // ha!
 
 static bool
 IsChildProcess()
 {
-  return XRE_GetProcessType() == GeckoProcessType_Content;
+  return XRE_IsContentProcess();
 }
 
 /**
  * @returns The child process object, or if we are not in the child
  *          process, nullptr.
  */
 static ContentChild*
 ChildProcess()
@@ -1047,21 +1047,23 @@ nsPermissionManager::AddInternal(nsIPrin
     }
     break;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPermissionManager::Remove(const nsACString &aHost,
-                            const char       *aType)
+nsPermissionManager::Remove(nsIURI*     aURI,
+                            const char* aType)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
+
   nsCOMPtr<nsIPrincipal> principal;
-  nsresult rv = GetPrincipal(aHost, getter_AddRefs(principal));
+  nsresult rv = GetPrincipal(aURI, getter_AddRefs(principal));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return RemoveFromPrincipal(principal, aType);
 }
 
 NS_IMETHODIMP
 nsPermissionManager::RemoveFromPrincipal(nsIPrincipal* aPrincipal,
                                          const char* aType)
@@ -1088,16 +1090,36 @@ nsPermissionManager::RemoveFromPrincipal
                      nsIPermissionManager::EXPIRE_NEVER,
                      0,
                      0,
                      eNotify,
                      eWriteToDB);
 }
 
 NS_IMETHODIMP
+nsPermissionManager::RemovePermission(nsIPermission* aPerm)
+{
+  nsAutoCString host;
+  nsresult rv = aPerm->GetHost(host);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIPrincipal> principal;
+  rv = GetPrincipal(host, getter_AddRefs(principal));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoCString type;
+  rv = aPerm->GetType(type);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Permissions are uniquely identified by their principal and type.
+  // We remove the permission using these two pieces of data.
+  return RemoveFromPrincipal(principal, type.get());
+}
+
+NS_IMETHODIMP
 nsPermissionManager::RemoveAll()
 {
   ENSURE_NOT_CHILD_PROCESS;
   return RemoveAllInternal(true);
 }
 
 NS_IMETHODIMP
 nsPermissionManager::RemoveAllSince(int64_t aSince)
--- a/extensions/cookie/test/unit/test_permmanager_mailto.js
+++ b/extensions/cookie/test/unit/test_permmanager_mailto.js
@@ -11,24 +11,24 @@ function run_test() {
   let uri = Services.io.newURI("mailto:" + kTestAddr + "?subject=test", null,
                                null);
 
   // add a permission entry for that URI
   Services.perms.add(uri, kType, kCapability);
   do_check_true(permission_exists(kTestAddr, kType, kCapability));
 
   // remove the permission, and make sure it was removed
-  Services.perms.remove(kTestAddr, kType);
+  Services.perms.remove(uri, kType);
   do_check_false(permission_exists(kTestAddr, kType, kCapability));
 
   uri = Services.io.newURI("mailto:" + kTestAddr, null, null);
   Services.perms.add(uri, kType, kCapability);
   do_check_true(permission_exists(kTestAddr, kType, kCapability));
 
-  Services.perms.remove(kTestAddr, kType);
+  Services.perms.remove(uri, kType);
   do_check_false(permission_exists(kTestAddr, kType, kCapability));
 }
 
 function permission_exists(aHost, aType, aCapability) {
   let e = Services.perms.enumerator;
   while (e.hasMoreElements()) {
     let perm = e.getNext().QueryInterface(Ci.nsIPermission);
     if (perm.host == aHost &&
new file mode 100644
--- /dev/null
+++ b/extensions/cookie/test/unit/test_permmanager_removepermission.js
@@ -0,0 +1,67 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+  // initialize the permission manager service
+  let pm = Cc["@mozilla.org/permissionmanager;1"].
+        getService(Ci.nsIPermissionManager);
+
+  do_check_eq(perm_count(), 0);
+
+  // add some permissions
+  let uri = NetUtil.newURI("http://amazon.com:8080/foobarbaz", null, null);
+  let uri2 = NetUtil.newURI("http://google.com:2048/quxx", null, null);
+
+  pm.add(uri, "apple", 0);
+  pm.add(uri, "apple", 3);
+  pm.add(uri, "pear", 3);
+  pm.add(uri, "pear", 1);
+  pm.add(uri, "cucumber", 1);
+  pm.add(uri, "cucumber", 1);
+  pm.add(uri, "cucumber", 1);
+
+  pm.add(uri2, "apple", 2);
+  pm.add(uri2, "pear", 0);
+  pm.add(uri2, "pear", 2);
+
+  // Make sure that removePermission doesn't remove more than one permission each time
+  do_check_eq(perm_count(), 5);
+
+  remove_one_by_type("apple");
+  do_check_eq(perm_count(), 4);
+
+  remove_one_by_type("apple");
+  do_check_eq(perm_count(), 3);
+
+  remove_one_by_type("pear");
+  do_check_eq(perm_count(), 2);
+
+  remove_one_by_type("cucumber");
+  do_check_eq(perm_count(), 1);
+
+  remove_one_by_type("pear");
+  do_check_eq(perm_count(), 0);
+
+
+  function perm_count() {
+    let enumerator = pm.enumerator;
+    let count = 0;
+    while (enumerator.hasMoreElements()) {
+      count++;
+      enumerator.getNext();
+    }
+
+    return count;
+  }
+
+  function remove_one_by_type(type) {
+    let enumerator = pm.enumerator;
+    while (enumerator.hasMoreElements()) {
+      let it = enumerator.getNext().QueryInterface(Ci.nsIPermission);
+      if (it.type == type) {
+        pm.removePermission(it);
+        break;
+      }
+    }
+  }
+}
--- a/extensions/cookie/test/unit/xpcshell.ini
+++ b/extensions/cookie/test/unit/xpcshell.ini
@@ -29,8 +29,9 @@ support-files =
 skip-if = debug == true
 [test_permmanager_idn.js]
 [test_permmanager_subdomains.js]
 [test_permmanager_local_files.js]
 [test_permmanager_mailto.js]
 [test_permmanager_cleardata.js]
 [test_schema_2_migration.js]
 [test_schema_3_migration.js]
+[test_permmanager_removepermission.js]
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -44,27 +44,27 @@ mozSpellChecker::~mozSpellChecker()
   if (mPersonalDictionary) {
     //    mPersonalDictionary->Save();
     mPersonalDictionary->EndSession();
   }
   mSpellCheckingEngine = nullptr;
   mPersonalDictionary = nullptr;
 
   if (mEngine) {
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content);
+    MOZ_ASSERT(XRE_IsContentProcess());
     mEngine->Send__delete__(mEngine);
     MOZ_ASSERT(!mEngine);
   }
 }
 
 nsresult
 mozSpellChecker::Init()
 {
   mSpellCheckingEngine = nullptr;
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     mozilla::dom::ContentChild* contentChild = mozilla::dom::ContentChild::GetSingleton();
     MOZ_ASSERT(contentChild);
     mEngine = new RemoteSpellcheckEngineChild(this);
     contentChild->SendPRemoteSpellcheckEngineConstructor(mEngine);
   } else {
     mPersonalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
   }
 
@@ -125,17 +125,17 @@ mozSpellChecker::NextMisspelledWord(nsAS
 }
 
 NS_IMETHODIMP 
 mozSpellChecker::CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray<nsString> *aSuggestions)
 {
   nsresult result;
   bool correct;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     nsString wordwrapped = nsString(aWord);
     bool rv;
     if (aSuggestions) {
       rv = mEngine->SendCheckAndSuggest(wordwrapped, aIsMisspelled, aSuggestions);
     } else {
       rv = mEngine->SendCheck(wordwrapped, aIsMisspelled);
     }
     return rv ? NS_OK : NS_ERROR_NOT_AVAILABLE;
@@ -304,17 +304,17 @@ mozSpellChecker::GetPersonalDictionary(n
     aWordList->AppendElement(word);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::GetDictionaryList(nsTArray<nsString> *aDictionaryList)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     ContentChild *child = ContentChild::GetSingleton();
     child->GetAvailableDictionaries(*aDictionaryList);
     return NS_OK;
   }
 
   nsresult rv;
 
   // For catching duplicates
@@ -352,17 +352,17 @@ mozSpellChecker::GetDictionaryList(nsTAr
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::GetCurrentDictionary(nsAString &aDictionary)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     aDictionary = mCurrentDictionary;
     return NS_OK;
   }
 
   if (!mSpellCheckingEngine) {
     aDictionary.Truncate();
     return NS_OK;
   }
@@ -371,17 +371,17 @@ mozSpellChecker::GetCurrentDictionary(ns
   mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
   aDictionary = dictname;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::SetCurrentDictionary(const nsAString &aDictionary)
 {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     nsString wrappedDict = nsString(aDictionary);
     bool isSuccess;
     mEngine->SendSetDictionary(wrappedDict, &isSuccess);
     if (!isSuccess) {
       mCurrentDictionary.Truncate();
       return NS_ERROR_NOT_AVAILABLE;
     }
 
@@ -531,17 +531,17 @@ mozSpellChecker::GetCurrentBlockIndex(ns
   *outBlockIndex = blockIndex;
 
   return result;
 }
 
 nsresult
 mozSpellChecker::GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aSpellCheckingEngines)
 {
-  MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Content);
+  MOZ_ASSERT(!XRE_IsContentProcess());
 
   nsresult rv;
   bool hasMoreEngines;
 
   nsCOMPtr<nsICategoryManager> catMgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
   if (!catMgr)
     return NS_ERROR_NULL_POINTER;
 
new file mode 100644
--- /dev/null
+++ b/gfx/doc/LayersHistory.md
@@ -0,0 +1,50 @@
+This is an overview of the major events in the history of our Layers infrastructure.
+
+- iPhone released in July 2007 (Built on a toolkit called LayerKit)
+
+- Core Animation (October 2007) LayerKit was publicly renamed to OS X 10.5
+
+- Webkit CSS 3d transforms (July 2009)
+
+- Original layers API (March 2010) Introduced the idea of a layer manager that
+  would composite. One of the first use cases for this was hardware accelerated
+  YUV conversion for video.
+
+- Retained layers (July 7 2010 - Bug 564991)
+This was an important concept that introduced the idea of persisting the layer
+content across paints in gecko controlled buffers instead of just by the OS. This introduced
+the concept of buffer rotation to deal with scrolling instead of using the
+native scrolling APIs like ScrollWindowEx
+
+- Layers IPC (July 2010 - Bug 570294)
+This introduced shadow layers and edit lists and was originally done for e10s v1
+
+- 3d transforms (September 2011 - Bug 505115)
+
+- OMTC (December 2012 - Bug 711168)
+This was prototyped on OS X but shipped first for Fennec
+
+- Tiling v1 (April 2012 - Bug 739679)
+Originally done for Fennec.
+This was done to avoid situations where we had to do a bunch of work for
+scrolling a small amount. i.e. buffer rotation.  It allowed us to have a
+variety of interesting features like progressive painting and lower resolution
+painting.
+
+- C++ Async pan zoom controller (July 2012 - Bug 750974)
+The existing APZ code was in Java for Fennec so this was reimplemented.
+
+- Compositor API (April 2013 - Bug 825928)
+Layers refactoring created a compositor API that abstracted away the differences between the
+D3D vs OpenGL. The main piece of API is DrawQuad.
+
+- Tiling v2 (Mar 7 2014 - Bug 963073)
+Tiling for B2G. This work is mainly porting tiled layers to new textures,
+implementing double-buffered tiles and implementing a texture client pool, to
+be used by tiled content clients.
+
+ A large motivation for the pool was the very slow performance of allocating tiles because
+of the sync messages to the compositor.
+
+ The slow performance of allocating was directly addressed by bug 959089 which allowed us
+to allocate gralloc buffers without sync messages to the compositor thread.
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -35,17 +35,16 @@ GLScreenBuffer::Create(GLContext* gl,
 {
     UniquePtr<GLScreenBuffer> ret;
     if (caps.antialias &&
         !gl->IsSupported(GLFeature::framebuffer_multisample))
     {
         return Move(ret);
     }
 
-
     layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
     if (!caps.premultAlpha) {
         flags |= layers::TextureFlags::NON_PREMULTIPLIED;
     }
 
     UniquePtr<SurfaceFactory> factory = MakeUnique<SurfaceFactory_Basic>(gl, caps, flags);
 
     ret.reset( new GLScreenBuffer(gl, caps, Move(factory)) );
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -600,16 +600,17 @@ APZCTreeManager::ReceiveInputEvent(Input
         // scrolling, which changes the async transform. However, the event we
         // want to pass to gecko should be the pre-scroll event coordinates,
         // transformed into the gecko space. (pre-scroll because the mouse
         // cursor is stationary during wheel scrolling, unlike touchmove
         // events). Since we just flushed the pending repaints the transform to
         // gecko space should only consist of overscroll-cancelling transforms.
         Matrix4x4 transformToGecko = GetScreenToApzcTransform(apzc)
                                    * GetApzcToGeckoTransform(apzc);
+        MOZ_ASSERT(transformToGecko.Is2D());
         ScreenPoint untransformedOrigin = TransformTo<ScreenPixel>(
           transformToGecko, wheelInput.mOrigin);
 
         result = mInputQueue->ReceiveInputEvent(
           apzc,
           /* aTargetConfirmed = */ hitResult == HitLayer,
           wheelInput, aOutInputBlockId);
 
@@ -629,16 +630,17 @@ APZCTreeManager::ReceiveInputEvent(Input
             apzc,
             /* aTargetConfirmed = */ hitResult == HitLayer,
             panInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 transformToGecko = GetScreenToApzcTransform(apzc)
                                    * GetApzcToGeckoTransform(apzc);
+        MOZ_ASSERT(transformToGecko.Is2D());
         panInput.mPanStartPoint = TransformTo<ScreenPixel>(
             transformToGecko, panInput.mPanStartPoint);
         panInput.mPanDisplacement = TransformVector<ScreenPixel>(
             transformToGecko, panInput.mPanDisplacement, panInput.mPanStartPoint);
       }
       break;
     } case PINCHGESTURE_INPUT: {  // note: no one currently sends these
       PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
@@ -651,16 +653,17 @@ APZCTreeManager::ReceiveInputEvent(Input
             apzc,
             /* aTargetConfirmed = */ hitResult == HitLayer,
             pinchInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 outTransform = GetScreenToApzcTransform(apzc)
                                * GetApzcToGeckoTransform(apzc);
+        MOZ_ASSERT(outTransform.Is2D());
         pinchInput.mFocusPoint = TransformTo<ScreenPixel>(
             outTransform, pinchInput.mFocusPoint);
       }
       break;
     } case TAPGESTURE_INPUT: {  // note: no one currently sends these
       TapGestureInput& tapInput = aEvent.AsTapGestureInput();
       nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
                                                             &hitResult);
@@ -671,16 +674,17 @@ APZCTreeManager::ReceiveInputEvent(Input
             apzc,
             /* aTargetConfirmed = */ hitResult == HitLayer,
             tapInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         Matrix4x4 outTransform = GetScreenToApzcTransform(apzc)
                                * GetApzcToGeckoTransform(apzc);
+        MOZ_ASSERT(outTransform.Is2D());
         tapInput.mPoint = TransformTo<ScreenPixel>(outTransform, tapInput.mPoint);
       }
       break;
     }
   }
   return result;
 }
 
@@ -780,16 +784,18 @@ APZCTreeManager::ProcessTouchInput(Multi
         aInput, aOutInputBlockId);
 
     // For computing the event to pass back to Gecko, use up-to-date transforms
     // (i.e. not anything cached in an input block).
     // This ensures that transformToApzc and transformToGecko are in sync.
     Matrix4x4 transformToApzc = GetScreenToApzcTransform(mApzcForInputBlock);
     Matrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
     Matrix4x4 outTransform = transformToApzc * transformToGecko;
+    MOZ_ASSERT(outTransform.Is2D());
+    
     for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
       SingleTouchData& touchData = aInput.mTouches[i];
       touchData.mScreenPoint = TransformTo<ScreenPixel>(
           outTransform, touchData.mScreenPoint);
     }
   }
 
   if (aInput.mType == MultiTouchInput::MULTITOUCH_END) {
@@ -820,16 +826,17 @@ APZCTreeManager::TransformCoordinateToGe
                                             LayoutDeviceIntPoint* aOutTransformedPoint)
 {
   MOZ_ASSERT(aOutTransformedPoint);
   nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aPoint, nullptr);
   if (apzc && aOutTransformedPoint) {
     Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
     Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
     Matrix4x4 outTransform = transformToApzc * transformToGecko;
+    MOZ_ASSERT(outTransform.Is2D());
     *aOutTransformedPoint = TransformTo<LayoutDevicePixel>(outTransform, aPoint);
   }
 }
 
 void
 APZCTreeManager::UpdateWheelTransaction(WidgetInputEvent& aEvent)
 {
   WheelBlockState* txn = mInputQueue->GetCurrentWheelTransaction();
@@ -887,16 +894,17 @@ APZCTreeManager::ProcessEvent(WidgetInpu
   nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y),
                                                         &hitResult);
   if (apzc) {
     MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion);
     apzc->GetGuid(aOutTargetGuid);
     Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
     Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
     Matrix4x4 outTransform = transformToApzc * transformToGecko;
+    MOZ_ASSERT(outTransform.Is2D());
     aEvent.refPoint = TransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint);
   }
   return result;
 }
 
 nsEventStatus
 APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
                                    ScrollableLayerGuid* aOutTargetGuid,
@@ -1183,32 +1191,41 @@ APZCTreeManager::GetRootNode() const
  * Transform a displacement from the ParentLayer coordinates of a source APZC
  * to the ParentLayer coordinates of a target APZC.
  * @param aTreeManager the tree manager for the APZC tree containing |aSource|
  *                     and |aTarget|
  * @param aSource the source APZC
  * @param aTarget the target APZC
  * @param aStartPoint the start point of the displacement
  * @param aEndPoint the end point of the displacement
+ * @return true on success, false if aStartPoint or aEndPoint cannot be transformed into target's coordinate space
  */
-static void
+static bool
 TransformDisplacement(APZCTreeManager* aTreeManager,
                       AsyncPanZoomController* aSource,
                       AsyncPanZoomController* aTarget,
                       ParentLayerPoint& aStartPoint,
                       ParentLayerPoint& aEndPoint) {
   // Convert start and end points to Screen coordinates.
   Matrix4x4 untransformToApzc = aTreeManager->GetScreenToApzcTransform(aSource).Inverse();
   ScreenPoint screenStart = TransformTo<ScreenPixel>(untransformToApzc, aStartPoint);
   ScreenPoint screenEnd = TransformTo<ScreenPixel>(untransformToApzc, aEndPoint);
 
+
   // Convert start and end points to aTarget's ParentLayer coordinates.
   Matrix4x4 transformToApzc = aTreeManager->GetScreenToApzcTransform(aTarget);
-  aStartPoint = TransformTo<ParentLayerPixel>(transformToApzc, screenStart);
-  aEndPoint = TransformTo<ParentLayerPixel>(transformToApzc, screenEnd);
+  Maybe<ParentLayerPoint> startPoint = UntransformTo<ParentLayerPixel>(transformToApzc, screenStart);
+  Maybe<ParentLayerPoint> endPoint = UntransformTo<ParentLayerPixel>(transformToApzc, screenEnd);
+  if (!startPoint || !endPoint) {
+    return false;
+  }
+  aEndPoint = *endPoint;
+  aStartPoint = *startPoint;
+
+  return true;
 }
 
 bool
 APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev,
                                 ParentLayerPoint aStartPoint,
                                 ParentLayerPoint aEndPoint,
                                 OverscrollHandoffState& aOverscrollHandoffState)
 {
@@ -1229,17 +1246,19 @@ APZCTreeManager::DispatchScroll(AsyncPan
   }
 
   // Convert the start and end points from |aPrev|'s coordinate space to
   // |next|'s coordinate space. Since |aPrev| may be the same as |next|
   // (if |aPrev| is the APZC that is initiating the scroll and there is no
   // scroll grabbing to grab the scroll from it), don't bother doing the
   // transformations in that case.
   if (next != aPrev) {
-    TransformDisplacement(this, aPrev, next, aStartPoint, aEndPoint);
+    if (!TransformDisplacement(this, aPrev, next, aStartPoint, aEndPoint)) {
+      return false;
+    }
   }
 
   // Scroll |next|. If this causes overscroll, it will call DispatchScroll()
   // again with an incremented index.
   return next->AttemptScroll(aStartPoint, aEndPoint, aOverscrollHandoffState);
 }
 
 bool
@@ -1282,21 +1301,23 @@ APZCTreeManager::DispatchFling(AsyncPanZ
     if (current == nullptr || current->IsDestroyed()) {
       return false;
     }
 
     endPoint = startPoint + transformedVelocity;
 
     // Only transform when current apcz can be transformed with previous
     if (startIndex > 0) {
-      TransformDisplacement(this,
+      if (!TransformDisplacement(this,
                             aOverscrollHandoffChain->GetApzcAtIndex(startIndex - 1),
                             current,
                             startPoint,
-                            endPoint);
+                            endPoint)) {
+          return false;
+      }
     }
 
     transformedVelocity = endPoint - startPoint;
 
     if (current->AttemptFling(transformedVelocity,
                               aOverscrollHandoffChain,
                               aHandoff)) {
       return true;
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -946,17 +946,19 @@ nsEventStatus AsyncPanZoomController::Ha
                                                        const Matrix4x4& aTransformToApzc) {
   APZThreadUtils::AssertOnControllerThread();
 
   nsEventStatus rv = nsEventStatus_eIgnore;
 
   switch (aEvent.mInputType) {
   case MULTITOUCH_INPUT: {
     MultiTouchInput multiTouchInput = aEvent.AsMultiTouchInput();
-    multiTouchInput.TransformToLocal(aTransformToApzc);
+    if (!multiTouchInput.TransformToLocal(aTransformToApzc)) { 
+      return rv;
+    }
 
     nsRefPtr<GestureEventListener> listener = GetGestureEventListener();
     if (listener) {
       rv = listener->HandleInputEvent(multiTouchInput);
       if (rv == nsEventStatus_eConsumeNoDefault) {
         return rv;
       }
     }
@@ -967,48 +969,56 @@ nsEventStatus AsyncPanZoomController::Ha
       case MultiTouchInput::MULTITOUCH_END: rv = OnTouchEnd(multiTouchInput); break;
       case MultiTouchInput::MULTITOUCH_CANCEL: rv = OnTouchCancel(multiTouchInput); break;
       default: NS_WARNING("Unhandled multitouch"); break;
     }
     break;
   }
   case PANGESTURE_INPUT: {
     PanGestureInput panGestureInput = aEvent.AsPanGestureInput();
-    panGestureInput.TransformToLocal(aTransformToApzc);
+    if (!panGestureInput.TransformToLocal(aTransformToApzc)) {
+      return rv;
+    }
 
     switch (panGestureInput.mType) {
       case PanGestureInput::PANGESTURE_MAYSTART: rv = OnPanMayBegin(panGestureInput); break;
       case PanGestureInput::PANGESTURE_CANCELLED: rv = OnPanCancelled(panGestureInput); break;
       case PanGestureInput::PANGESTURE_START: rv = OnPanBegin(panGestureInput); break;
       case PanGestureInput::PANGESTURE_PAN: rv = OnPan(panGestureInput, ScrollSource::Touch, true); break;
       case PanGestureInput::PANGESTURE_END: rv = OnPanEnd(panGestureInput); break;
       case PanGestureInput::PANGESTURE_MOMENTUMSTART: rv = OnPanMomentumStart(panGestureInput); break;
       case PanGestureInput::PANGESTURE_MOMENTUMPAN: rv = OnPan(panGestureInput, ScrollSource::Touch, false); break;
       case PanGestureInput::PANGESTURE_MOMENTUMEND: rv = OnPanMomentumEnd(panGestureInput); break;
       default: NS_WARNING("Unhandled pan gesture"); break;
     }
     break;
   }
   case SCROLLWHEEL_INPUT: {
     ScrollWheelInput scrollInput = aEvent.AsScrollWheelInput();
-    scrollInput.TransformToLocal(aTransformToApzc);
+    if (!scrollInput.TransformToLocal(aTransformToApzc)) { 
+      return rv;
+    }
 
     rv = OnScrollWheel(scrollInput);
     break;
   }
   case PINCHGESTURE_INPUT: {
     PinchGestureInput pinchInput = aEvent.AsPinchGestureInput();
-    pinchInput.TransformToLocal(aTransformToApzc);
+    if (!pinchInput.TransformToLocal(aTransformToApzc)) { 
+      return rv;
+    }
 
     rv = HandleGestureEvent(pinchInput);
     break;
   }
   case TAPGESTURE_INPUT: {
     TapGestureInput tapInput = aEvent.AsTapGestureInput();
-    tapInput.TransformToLocal(aTransformToApzc);
+    if (!tapInput.TransformToLocal(aTransformToApzc)) { 
+      return rv;
+    }
 
     rv = HandleGestureEvent(tapInput);
     break;
   }
   default: NS_WARNING("Unhandled input event type"); break;
   }
 
   return rv;
@@ -1254,20 +1264,16 @@ nsEventStatus AsyncPanZoomController::On
   APZC_LOG("%p got a scale-begin in state %d\n", this, mState);
 
   // Note that there may not be a touch block at this point, if we received the
   // PinchGestureEvent directly from widget code without any touch events.
   if (HasReadyTouchBlock() && !CurrentTouchBlock()->TouchActionAllowsPinchZoom()) {
     return nsEventStatus_eIgnore;
   }
 
-  if (!mZoomConstraints.mAllowZoom) {
-    return nsEventStatus_eConsumeNoDefault;
-  }
-
   SetState(PINCHING);
   mX.SetVelocity(0);
   mY.SetVelocity(0);
   mLastZoomFocus = aEvent.mLocalFocusPoint - mFrameMetrics.GetCompositionBounds().TopLeft();
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
@@ -1325,16 +1331,20 @@ nsEventStatus AsyncPanZoomController::On
                                  mFrameMetrics.GetCompositionBounds().height / mFrameMetrics.GetScrollableRect().height);
     if (realMaxZoom < realMinZoom) {
       realMaxZoom = realMinZoom;
     }
 
     bool doScale = (spanRatio > 1.0 && userZoom < realMaxZoom) ||
                    (spanRatio < 1.0 && userZoom > realMinZoom);
 
+    if (!mZoomConstraints.mAllowZoom) {
+      doScale = false;
+    }
+
     if (doScale) {
       spanRatio = clamped(spanRatio,
                           realMinZoom.scale / userZoom.scale,
                           realMaxZoom.scale / userZoom.scale);
 
       // Note that the spanRatio here should never put us into OVERSCROLL_BOTH because
       // up above we clamped it.
       neededDisplacement.x = -mX.ScaleWillOverscrollAmount(spanRatio, cssFocusPoint.x);
@@ -1391,22 +1401,24 @@ nsEventStatus AsyncPanZoomController::On
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 bool
 AsyncPanZoomController::ConvertToGecko(const ScreenIntPoint& aPoint, CSSPoint* aOut)
 {
   if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
-    Matrix4x4 transformToApzc = treeManagerLocal->GetScreenToApzcTransform(this);
-    Matrix4x4 transformToGecko = treeManagerLocal->GetApzcToGeckoTransform(this);
+    Matrix4x4 transformScreenToGecko = treeManagerLocal->GetScreenToApzcTransform(this) 
+                                     * treeManagerLocal->GetApzcToGeckoTransform(this);
+    
     // NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name
     // for this coordinate space and it maps the closest to LayoutDevicePoint.
+    MOZ_ASSERT(transformScreenToGecko.Is2D());
     LayoutDevicePoint layoutPoint = TransformTo<LayoutDevicePixel>(
-        transformToApzc * transformToGecko, aPoint);
+        transformScreenToGecko, aPoint);
 
     { // scoped lock to access mFrameMetrics
       ReentrantMonitorAutoEnter lock(mMonitor);
       *aOut = layoutPoint / mFrameMetrics.GetDevPixelsPerCSSPixel();
     }
     return true;
   }
   return false;
@@ -1832,32 +1844,36 @@ Matrix4x4 AsyncPanZoomController::GetTra
   return Matrix4x4();
 }
 
 ScreenPoint AsyncPanZoomController::ToScreenCoordinates(const ParentLayerPoint& aVector,
                                                         const ParentLayerPoint& aAnchor) const {
   return TransformVector<ScreenPixel>(GetTransformToThis().Inverse(), aVector, aAnchor);
 }
 
+// TODO: figure out a good way to check the w-coordinate is positive and return the result
 ParentLayerPoint AsyncPanZoomController::ToParentLayerCoordinates(const ScreenPoint& aVector,
                                                                   const ScreenPoint& aAnchor) const {
   return TransformVector<ParentLayerPixel>(GetTransformToThis(), aVector, aAnchor);
 }
 
 bool AsyncPanZoomController::Contains(const ScreenIntPoint& aPoint) const
 {
   Matrix4x4 transformToThis = GetTransformToThis();
-  ParentLayerIntPoint point = TransformTo<ParentLayerPixel>(transformToThis, aPoint);
+  Maybe<ParentLayerIntPoint> point = UntransformTo<ParentLayerPixel>(transformToThis, aPoint);
+  if (!point) {
+    return false;
+  }
 
   ParentLayerIntRect cb;
   {
     ReentrantMonitorAutoEnter lock(mMonitor);
     GetFrameMetrics().GetCompositionBounds().ToIntRect(&cb);
   }
-  return cb.Contains(point);
+  return cb.Contains(*point);
 }
 
 ScreenCoord AsyncPanZoomController::PanDistance() const {
   ParentLayerPoint panVector;
   ParentLayerPoint panStart;
   {
     ReentrantMonitorAutoEnter lock(mMonitor);
     panVector = ParentLayerPoint(mX.PanDistance(), mY.PanDistance());
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -202,20 +202,17 @@ HitTestingTreeNode::IsOutsideClip(const 
 Maybe<LayerPoint>
 HitTestingTreeNode::Untransform(const ParentLayerPoint& aPoint) const
 {
   // convert into Layer coordinate space
   gfx::Matrix4x4 localTransform = mTransform;
   if (mApzc) {
     localTransform = localTransform * mApzc->GetCurrentAsyncTransformWithOverscroll();
   }
-  gfx::Point4D point = localTransform.Inverse().ProjectPoint(aPoint.ToUnknownPoint());
-  return point.HasPositiveWCoord()
-        ? Some(ViewAs<LayerPixel>(point.As2DPoint()))
-        : Nothing();
+  return UntransformTo<LayerPixel>(localTransform.Inverse(), aPoint);
 }
 
 HitTestResult
 HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const
 {
   // This should only ever get called if the point is inside the clip region
   // for this node.
   MOZ_ASSERT(!IsOutsideClip(aPoint));
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -83,18 +83,17 @@ ClientCanvasLayer::Initialize(const Data
     switch (forwarder->GetCompositorBackendType()) {
       case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
 #if defined(XP_MACOSX)
         factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags);
 #elif defined(MOZ_WIDGET_GONK)
         factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags);
 #else
         if (mGLContext->GetContextType() == GLContextType::EGL) {
-          bool isCrossProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
-          if (!isCrossProcess) {
+          if (XRE_IsParentProcess()) {
             factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder,
                                                       mFlags);
           }
         }
 #endif
         break;
       }
       case mozilla::layers::LayersBackend::LAYERS_D3D11: {
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -216,17 +216,17 @@ ClientLayerManager::BeginTransactionWith
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
   if (mWidget && mWidget->GetOwningTabChild()) {
     mCompositorMightResample = AsyncPanZoomEnabled();
   }
 #endif
 
   // If we have a non-default target, we need to let our shadow manager draw
   // to it. This will happen at the end of the transaction.
-  if (aTarget && XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (aTarget && XRE_IsParentProcess()) {
     mShadowTarget = aTarget;
   } else {
     NS_ASSERTION(!aTarget,
                  "Content-process ClientLayerManager::BeginTransactionWithTarget not supported");
   }
 
   // If this is a new paint, increment the paint sequence number.
   if (!mIsRepeatTransaction && gfxPrefs::APZTestLoggingEnabled()) {
@@ -365,17 +365,17 @@ ClientLayerManager::GetRemoteRenderer()
   }
 
   return mWidget->GetRemoteRenderer();
 }
 
 CompositorChild*
 ClientLayerManager::GetCompositorChild()
 {
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     return CompositorChild::Get();
   }
   return GetRemoteRenderer();
 }
 
 void
 ClientLayerManager::Composite()
 {
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -157,17 +157,17 @@ CompositorChild::OpenSameProcess(Composi
                   ipc::ChildSide);
   return mCanSend;
 }
 
 /*static*/ CompositorChild*
 CompositorChild::Get()
 {
   // This is only expected to be used in child processes.
-  MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
+  MOZ_ASSERT(!XRE_IsParentProcess());
   return sCompositor;
 }
 
 PLayerTransactionChild*
 CompositorChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
                                              const uint64_t& aId,
                                              TextureFactoryIdentifier*,
                                              bool*)
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -143,17 +143,17 @@ ParamTraits<MagicGrallocBufferHandle>::R
     // But in shared cross-thread, dup fd is not necessary because we get
     // a pointer to the GraphicBuffer directly from SharedBufferManagerParent
     // and don't create a new GraphicBuffer around the fd.
     fds[n] = fd.fd;
   }
 
   aResult->mRef.mOwner = owner;
   aResult->mRef.mKey = index;
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     // If we are in chrome process, we can just get GraphicBuffer directly from
     // SharedBufferManagerParent.
     aResult->mGraphicBuffer = SharedBufferManagerParent::GetGraphicBuffer(aResult->mRef);
   } else {
     // Deserialize GraphicBuffer
 #if ANDROID_VERSION >= 19
     sp<GraphicBuffer> buffer(new GraphicBuffer());
     const void* datap = (const void*)data;
@@ -210,17 +210,17 @@ LayerManagerComposite::PlatformSyncBefor
 //-----------------------------------------------------------------------------
 // Both processes
 
 /*static*/ sp<GraphicBuffer>
 GetGraphicBufferFrom(MaybeMagicGrallocBufferHandle aHandle)
 {
   if (aHandle.type() != MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle) {
     if (aHandle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
-      if (XRE_GetProcessType() == GeckoProcessType_Default) {
+      if (XRE_IsParentProcess()) {
         return SharedBufferManagerParent::GetGraphicBuffer(aHandle.get_GrallocBufferRef());
       }
       return SharedBufferManagerChild::GetSingleton()->GetGraphicBuffer(aHandle.get_GrallocBufferRef().mKey);
     }
   } else {
     MagicGrallocBufferHandle realHandle = aHandle.get_MagicGrallocBufferHandle();
     return realHandle.mGraphicBuffer;
   }
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -24,17 +24,17 @@ EGLImageTextureClient::EGLImageTextureCl
                                              TextureFlags aFlags,
                                              EGLImageImage* aImage,
                                              gfx::IntSize aSize)
   : TextureClient(aAllocator, aFlags)
   , mImage(aImage)
   , mSize(aSize)
   , mIsLocked(false)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Can't pass an `EGLImage` between processes.");
 
   AddFlags(TextureFlags::DEALLOCATE_CLIENT);
 
   if (aImage->GetData()->mOriginPos == gl::OriginPos::BottomLeft) {
     AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
   }
 }
@@ -80,17 +80,17 @@ SurfaceTextureClient::SurfaceTextureClie
                                            AndroidSurfaceTexture* aSurfTex,
                                            gfx::IntSize aSize,
                                            gl::OriginPos aOriginPos)
   : TextureClient(aAllocator, aFlags)
   , mSurfTex(aSurfTex)
   , mSize(aSize)
   , mIsLocked(false)
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
+  MOZ_ASSERT(XRE_IsParentProcess(),
              "Can't pass pointers between processes.");
 
   // Our data is always owned externally.
   AddFlags(TextureFlags::DEALLOCATE_CLIENT);
 
   if (aOriginPos == gl::OriginPos::BottomLeft) {
     AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
   }
--- a/gfx/qcms/moz.build
+++ b/gfx/qcms/moz.build
@@ -12,17 +12,17 @@ EXPORTS += [
 SOURCES += [
     'chain.c',
     'iccread.c',
     'matrix.c',
     'transform.c',
     'transform_util.c',
 ]
 
-FINAL_LIBRARY = 'gkmedias'
+FINAL_LIBRARY = 'xul'
 
 if CONFIG['GNU_CC']:
     CFLAGS += ['-Wno-missing-field-initializers']
 
 use_sse1 = False
 use_sse2 = False
 use_altivec = False
 if '86' in CONFIG['OS_TEST']:
--- a/gfx/qcms/transform_util.c
+++ b/gfx/qcms/transform_util.c
@@ -258,57 +258,65 @@ uint16_fract_t lut_inverse_interp16(uint
             return 0;
 
         NumPoles = 0;
         while (LutTable[length-1- NumPoles] == 0xFFFF && NumPoles < length-1)
                         NumPoles++;
 
         // Does the curve belong to this case?
         if (NumZeroes > 1 || NumPoles > 1)
-        {               
+        {
                 int a, b;
 
-                // Identify if value fall downto 0 or FFFF zone             
+                // Identify if value fall downto 0 or FFFF zone
                 if (Value == 0) return 0;
-               // if (Value == 0xFFFF) return 0xFFFF;
+                // if (Value == 0xFFFF) return 0xFFFF;
 
                 // else restrict to valid zone
 
-                a = ((NumZeroes-1) * 0xFFFF) / (length-1);               
-                b = ((length-1 - NumPoles) * 0xFFFF) / (length-1);
-                                                                
-                l = a - 1;
-                r = b + 1;
+                if (NumZeroes > 1) {
+                        a = ((NumZeroes-1) * 0xFFFF) / (length-1);
+                        l = a - 1;
+                }
+                if (NumPoles > 1) {
+                        b = ((length-1 - NumPoles) * 0xFFFF) / (length-1);
+                        r = b + 1;
+                }
+        }
+
+        if (r <= l) {
+                // If this happens LutTable is not invertible
+                return 0;
         }
 
 
         // Seems not a degenerated case... apply binary search
-
         while (r > l) {
 
                 x = (l + r) / 2;
 
 		res = (int) lut_interp_linear16((uint16_fract_t) (x-1), LutTable, length);
 
                 if (res == Value) {
 
-                    // Found exact match. 
-                    
+                    // Found exact match.
+
                     return (uint16_fract_t) (x - 1);
                 }
 
                 if (res > Value) r = x - 1;
                 else l = x + 1;
         }
 
         // Not found, should we interpolate?
 
-                
         // Get surrounding nodes
-        
+
+        assert(x >= 1);
+
         val2 = (length-1) * ((double) (x - 1) / 65535.0);
 
         cell0 = (int) floor(val2);
         cell1 = (int) ceil(val2);
            
         if (cell0 == cell1) return (uint16_fract_t) x;
 
         y0 = LutTable[cell0] ;
--- a/gfx/qcms/transform_util.h
+++ b/gfx/qcms/transform_util.h
@@ -84,10 +84,20 @@ static inline float u8Fixed8Number_to_fl
 float *build_input_gamma_table(struct curveType *TRC);
 struct matrix build_colorant_matrix(qcms_profile *p);
 void build_output_lut(struct curveType *trc,
                       uint16_t **output_gamma_lut, size_t *output_gamma_lut_length);
 
 struct matrix matrix_invert(struct matrix mat);
 qcms_bool compute_precache(struct curveType *trc, uint8_t *output);
 
+// Tested by GTest
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int length);
+
+#ifdef  __cplusplus
+}
+#endif
 
 #endif
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -638,29 +638,29 @@ ApzcPanNoFling(const nsRefPtr<TestAsyncP
                uint64_t* aOutInputBlockId = nullptr)
 {
   Pan(aApzc, aMcc, aTouchStartY, aTouchEndY, false, nullptr, nullptr, aOutInputBlockId);
   aApzc->CancelAnimation();
 }
 
 template<class InputReceiver> static void
 PinchWithPinchInput(const nsRefPtr<InputReceiver>& aTarget,
-                    int aFocusX, int aFocusY, float aScale,
+                    int aFocusX, int aFocusY, int aSecondFocusX, int aSecondFocusY, float aScale,
                     nsEventStatus (*aOutEventStatuses)[3] = nullptr)
 {
   nsEventStatus actualStatus = aTarget->ReceiveInputEvent(
       CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
                               aFocusX, aFocusY, 10.0, 10.0),
       nullptr);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[0] = actualStatus;
   }
   actualStatus = aTarget->ReceiveInputEvent(
       CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
-                              aFocusX, aFocusY, 10.0 * aScale, 10.0),
+                              aSecondFocusX, aSecondFocusY, 10.0 * aScale, 10.0),
       nullptr);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[1] = actualStatus;
   }
   actualStatus = aTarget->ReceiveInputEvent(
       CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_END,
                               // note: negative values here tell APZC
                               //       not to turn the pinch into a pan
@@ -672,17 +672,17 @@ PinchWithPinchInput(const nsRefPtr<Input
 }
 
 template<class InputReceiver> static void
 PinchWithPinchInputAndCheckStatus(const nsRefPtr<InputReceiver>& aTarget,
                                   int aFocusX, int aFocusY, float aScale,
                                   bool aShouldTriggerPinch)
 {
   nsEventStatus statuses[3];  // scalebegin, scale, scaleend
-  PinchWithPinchInput(aTarget, aFocusX, aFocusY, aScale, &statuses);
+  PinchWithPinchInput(aTarget, aFocusX, aFocusY, aFocusX, aFocusY, aScale, &statuses);
 
   nsEventStatus expectedStatus = aShouldTriggerPinch
       ? nsEventStatus_eConsumeNoDefault
       : nsEventStatus_eIgnore;
   EXPECT_EQ(expectedStatus, statuses[0]);
   EXPECT_EQ(expectedStatus, statuses[1]);
 }
 
@@ -1046,16 +1046,34 @@ TEST_F(APZCBasicTester, ComplexTransform
   childApzc->SetFrameMetrics(childMetrics);
   childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
   EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
   EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
 
   childApzc->Destroy();
 }
 
+TEST_F(APZCPinchTester, Panning_TwoFinger_ZoomDisabled) {
+  // set up APZ
+  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
+  MakeApzcUnzoomable();
+
+  nsEventStatus statuses[3];  // scalebegin, scale, scaleend
+  PinchWithPinchInput(apzc, 250, 350, 200, 300, 10, &statuses);
+
+  FrameMetrics fm = apzc->GetFrameMetrics();
+
+  // It starts from (300, 300), then moves the focus point from (250, 350) to
+  // (200, 300) pans by (50, 50) screen pixels, but there is a 2x zoom, which
+  // causes the scroll offset to change by half of that (25, 25) pixels.
+  EXPECT_EQ(325, fm.GetScrollOffset().x);
+  EXPECT_EQ(325, fm.GetScrollOffset().y);
+  EXPECT_EQ(2.0, fm.GetZoom().ToScaleFactor().scale);
+}
+
 class APZCPanningTester : public APZCBasicTester {
 protected:
   void DoPanTest(bool aShouldTriggerScroll, bool aShouldBeConsumed, uint32_t aBehavior)
   {
     if (aShouldTriggerScroll) {
       EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtLeast(1));
       EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
     } else {
new file mode 100644
--- /dev/null
+++ b/gfx/tests/gtest/TestQcms.cpp
@@ -0,0 +1,168 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "mozilla/ArrayUtils.h"
+#include "qcms.h"
+#include "transform_util.h"
+
+const size_t allGBSize = 1 * 256 * 256 * 4;
+static unsigned char* createAllGB() {
+  unsigned char* buff = (unsigned char*)malloc(allGBSize);
+  int pos = 0;
+  for (int r = 0; r < 1; r++) { // Skip all R values for speed
+    for (int g = 0; g < 256; g++) {
+      for (int b = 0; b < 256; b++) {
+        buff[pos * 4 + 0] = r;
+        buff[pos * 4 + 1] = g;
+        buff[pos * 4 + 2] = b;
+        buff[pos * 4 + 3] = 0x80;
+        pos++;
+      }
+    }
+  }
+
+  return buff;
+}
+
+TEST(GfxQcms, Identity) {
+  // XXX: This means that we can't have qcms v2 unit test
+  //      without changing the qcms API.
+  qcms_enable_iccv4();
+
+  qcms_profile* input_profile = qcms_profile_sRGB();
+  qcms_profile* output_profile = qcms_profile_sRGB();
+
+  EXPECT_FALSE(qcms_profile_is_bogus(input_profile));
+  EXPECT_FALSE(qcms_profile_is_bogus(output_profile));
+
+  const qcms_intent intent = QCMS_INTENT_DEFAULT;
+  qcms_data_type input_type = QCMS_DATA_RGBA_8;
+  qcms_data_type output_type = QCMS_DATA_RGBA_8;
+
+  qcms_transform* transform = qcms_transform_create(input_profile, input_type,
+                                                    output_profile, output_type,
+                                                    intent);
+
+  unsigned char *data_in = createAllGB();;
+  unsigned char *data_out = (unsigned char*)malloc(allGBSize);
+  qcms_transform_data(transform, data_in, data_out, allGBSize / 4);
+
+  qcms_profile_release(input_profile);
+  qcms_profile_release(output_profile);
+  qcms_transform_release(transform);
+
+  free(data_in);
+  free(data_out);
+}
+
+TEST(GfxQcms, LutInverseCrash) {
+  uint16_t lutTable1[] = {
+    0x0000, 0x0000, 0x0000, 0x8000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+  };
+  uint16_t lutTable2[] = {
+    0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+  };
+
+  // Crash/Assert test
+  lut_inverse_interp16((uint16_t)5, lutTable1, (int)mozilla::ArrayLength(lutTable1));
+  lut_inverse_interp16((uint16_t)5, lutTable2, (int)mozilla::ArrayLength(lutTable2));
+}
+
+TEST(GfxQcms, LutInverse) {
+  // mimic sRGB_v4_ICC mBA Output
+  //
+  //       XXXX
+  //      X
+  //     X
+  // XXXX
+  uint16_t value;
+  uint16_t lutTable[256];
+
+  for (int i = 0; i < 20; i++) {
+    lutTable[i] = 0;
+  }
+
+  for (int i = 20; i < 200; i++) {
+    lutTable[i] = (i - 20) * 0xFFFF / (200 - 20);
+  }
+
+  for (int i = 200; i < (int)mozilla::ArrayLength(lutTable); i++) {
+    lutTable[i] = 0xFFFF;
+  }
+
+  for (uint16_t i = 0; i < 65535; i++) {
+    lut_inverse_interp16(i, lutTable, (int)mozilla::ArrayLength(lutTable));
+  }
+
+  // Lookup the interesting points
+
+  value = lut_inverse_interp16(0, lutTable, (int)mozilla::ArrayLength(lutTable));
+  EXPECT_LE(value, 20 * 256);
+
+  value = lut_inverse_interp16(1, lutTable, (int)mozilla::ArrayLength(lutTable));
+  EXPECT_GT(value, 20 * 256);
+
+  value = lut_inverse_interp16(65535, lutTable, (int)mozilla::ArrayLength(lutTable));
+  EXPECT_LT(value, 201 * 256);
+}
+
+TEST(GfxQcms, LutInverseNonMonotonic) {
+  // Make sure we behave sanely for non monotic functions
+  //   X  X  X
+  //  X  X  X
+  // X  X  X
+  uint16_t lutTable[256];
+
+  for (int i = 0; i < 100; i++) {
+    lutTable[i] = (i - 0) * 0xFFFF / (100 - 0);
+  }
+
+  for (int i = 100; i < 200; i++) {
+    lutTable[i] = (i - 100) * 0xFFFF / (200 - 100);
+  }
+
+  for (int i = 200; i < 256; i++) {
+    lutTable[i] = (i - 200) * 0xFFFF / (256 - 200);
+  }
+
+  for (uint16_t i = 0; i < 65535; i++) {
+    lut_inverse_interp16(i, lutTable, (int)mozilla::ArrayLength(lutTable));
+  }
+
+  // Make sure we don't crash, hang or let sanitizers do their magic
+}
--- a/gfx/tests/gtest/moz.build
+++ b/gfx/tests/gtest/moz.build
@@ -11,16 +11,17 @@ UNIFIED_SOURCES += [
     'TestAsyncPanZoomController.cpp',
     'TestBufferRotation.cpp',
     'TestColorNames.cpp',
     'TestCompositor.cpp',
     'TestGfxPrefs.cpp',
     'TestGfxWidgets.cpp',
     'TestLayers.cpp',
     'TestMoz2D.cpp',
+    'TestQcms.cpp',
     'TestRect.cpp',
     'TestRegion.cpp',
     'TestSkipChars.cpp',
     # Hangs on linux in ApplyGdkScreenFontOptions
     #'gfxFontSelectionTest.cpp',
     'TestTextures.cpp',
     # Test works but it doesn't assert anything
     #'gfxTextRunPerfTest.cpp',
@@ -38,15 +39,16 @@ UNIFIED_SOURCES += [ '/gfx/2d/unittest/%
 ]]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/gfx/2d',
     '/gfx/2d/unittest',
     '/gfx/layers',
+    '/gfx/qcms',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
 
 FAIL_ON_WARNINGS = True
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -387,17 +387,17 @@ gfxAndroidPlatform::RequiresLinearZoom()
     // browser process, not other apps.
     return true;
 #endif
 
 #ifdef MOZ_WIDGET_GONK
     // On B2G, we need linear zoom for the browser, but otherwise prefer
     // the improved glyph spacing that results from respecting the device
     // pixel resolution for glyph layout (see bug 816614).
-    return XRE_GetProcessType() == GeckoProcessType_Content &&
+    return XRE_IsContentProcess() &&
            ContentChild::GetSingleton()->IsForBrowser();
 #endif
 
     NS_NOTREACHED("oops, what platform is this?");
     return gfxPlatform::RequiresLinearZoom();
 }
 
 int
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -630,17 +630,17 @@ public:
         mOps = (PLDHashTableOps) {
             StringHash,
             HashMatchEntry,
             MoveEntry,
             PL_DHashClearEntryStub,
             nullptr
         };
 
-        MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
+        MOZ_ASSERT(XRE_IsParentProcess(),
                    "StartupCacheFontNameCache should only be used in chrome "
                    "process");
         mCache = mozilla::scache::StartupCache::GetSingleton();
 
         Init();
     }
 
     ~FontNameCache()
@@ -1143,17 +1143,17 @@ gfxFT2FontList::FindFonts()
     if (fc)
         fc->AgeAllGenerations();
     mPrefFonts.Clear();
     mCodepointsWithNoFonts.reset();
 
     mCodepointsWithNoFonts.SetRange(0,0x1f);     // C0 controls
     mCodepointsWithNoFonts.SetRange(0x7f,0x9f);  // C1 controls
 
-    if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    if (!XRE_IsParentProcess()) {
         // Content process: ask the Chrome process to give us the list
         InfallibleTArray<FontListEntry> fonts;
         mozilla::dom::ContentChild::GetSingleton()->SendReadFontList(&fonts);
         for (uint32_t i = 0, n = fonts.Length(); i < n; ++i) {
             // We don't need to identify "standard" font files here,
             // as the faces are already sorted.
             AppendFaceFromFontListEntry(fonts[i], kUnknown);
         }
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -709,17 +709,17 @@ gfxPlatform::InitLayersIPC()
 {
     if (sLayersIPCIsUp) {
       return;
     }
     sLayersIPCIsUp = true;
 
     AsyncTransactionTrackersHolder::Initialize();
 
-    if (XRE_GetProcessType() == GeckoProcessType_Default)
+    if (XRE_IsParentProcess())
     {
         mozilla::layers::CompositorParent::StartUp();
 #ifndef MOZ_WIDGET_GONK
         if (gfxPrefs::AsyncVideoEnabled()) {
             mozilla::layers::ImageBridgeChild::StartUp();
         }
 #else
         mozilla::layers::ImageBridgeChild::StartUp();
@@ -731,17 +731,17 @@ gfxPlatform::InitLayersIPC()
 /* static */ void
 gfxPlatform::ShutdownLayersIPC()
 {
     if (!sLayersIPCIsUp) {
       return;
     }
     sLayersIPCIsUp = false;
 
-    if (XRE_GetProcessType() == GeckoProcessType_Default)
+    if (XRE_IsParentProcess())
     {
         // This must happen after the shutdown of media and widgets, which
         // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
         layers::ImageBridgeChild::ShutDown();
 #ifdef MOZ_WIDGET_GONK
         layers::SharedBufferManagerChild::ShutDown();
 #endif
 
@@ -1065,17 +1065,17 @@ gfxPlatform::SetTileSize(int aWidth, int
   mTileHeight = aHeight;
 }
 
 void
 gfxPlatform::ComputeTileSize()
 {
   // The tile size should be picked in the parent processes
   // and sent to the child processes over IPDL GetTileSize.
-  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+  if (!XRE_IsParentProcess()) {
     NS_RUNTIMEABORT("wrong process.");
   }
 
   int32_t w = gfxPrefs::LayersTileWidth();
   int32_t h = gfxPrefs::LayersTileHeight();
 
   // TODO We may want to take the screen size into consideration here.
   if (gfxPrefs::LayersTilesAdjust()) {
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -646,17 +646,17 @@ gfxWindowsPlatform::CreateDevice(nsRefPt
   // If we fail here, the DirectX version or video card probably
   // changed.  We previously could use 10.1 but now we can't
   // anymore.  Revert back to doing a 10.0 check first before
   // the 10.1 check.
   if (device) {
     mD2DDevice = cairo_d2d_create_device_from_d3d10device(device);
 
     // Setup a pref for future launch optimizaitons when in main process.
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
       Preferences::SetInt(kFeatureLevelPref, featureLevelIndex);
     }
   }
 
   return device ? S_OK : hr;
 }
 #endif
 
--- a/image/decoders/icon/android/nsIconChannel.cpp
+++ b/image/decoders/icon/android/nsIconChannel.cpp
@@ -75,17 +75,17 @@ moz_icon_to_channel(nsIURI* aURI, const 
   uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size);
   NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
   uint8_t* out = buf;
 
   *(out++) = width;
   *(out++) = height;
 
   nsresult rv;
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+  if (XRE_IsParentProcess()) {
     rv = GetIconForExtension(aFileExt, aIconSize, out);
   } else {
     rv = CallRemoteGetIconForExtension(aFileExt, aIconSize, out);
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Encode the RGBA data
   const uint8_t* in = out;
--- a/ipc/glue/BackgroundImpl.cpp
+++ b/ipc/glue/BackgroundImpl.cpp
@@ -46,17 +46,17 @@
 #ifdef RELEASE_BUILD
 #define THREADSAFETY_ASSERT MOZ_ASSERT
 #else
 #define THREADSAFETY_ASSERT MOZ_RELEASE_ASSERT
 #endif
 
 #define CRASH_IN_CHILD_PROCESS(_msg)                                           \
   do {                                                                         \
-    if (IsMainProcess()) {                                                     \
+    if (XRE_IsParentProcess()) {                                                     \
       MOZ_ASSERT(false, _msg);                                                 \
     } else {                                                                   \
       MOZ_CRASH(_msg);                                                         \
     }                                                                          \
   }                                                                            \
   while (0)
 
 using namespace mozilla;
@@ -64,42 +64,27 @@ using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace {
 
 // -----------------------------------------------------------------------------
 // Utility Functions
 // -----------------------------------------------------------------------------
 
-bool
-IsMainProcess()
-{
-  static const bool isMainProcess =
-    XRE_GetProcessType() == GeckoProcessType_Default;
-  return isMainProcess;
-}
-
-#ifdef DEBUG
-bool
-IsChildProcess()
-{
-  return !IsMainProcess();
-}
-#endif
 
 void
 AssertIsInMainProcess()
 {
-  MOZ_ASSERT(IsMainProcess());
+  MOZ_ASSERT(XRE_IsParentProcess());
 }
 
 void
 AssertIsInChildProcess()
 {
-  MOZ_ASSERT(IsChildProcess());
+  MOZ_ASSERT(!XRE_IsParentProcess());
 }
 
 void
 AssertIsOnMainThread()
 {
   THREADSAFETY_ASSERT(NS_IsMainThread());
 }
 
@@ -2052,17 +2037,17 @@ ChildImpl::OpenProtocolOnMainThread(nsIE
   AssertIsOnMainThread();
   MOZ_ASSERT(aEventTarget);
 
   if (sShutdownHasStarted) {
     MOZ_CRASH("Called BackgroundChild::GetOrCreateForCurrentThread after "
               "shutdown has started!");
   }
 
-  if (IsMainProcess()) {
+  if (XRE_IsParentProcess()) {
     nsRefPtr<ParentImpl::CreateCallback> parentCallback =
       new ParentCreateCallback(aEventTarget);
 
     if (!ParentImpl::CreateActorForSameProcess(parentCallback)) {
       NS_WARNING("BackgroundParent::CreateActor() failed!");
       DispatchFailureCallback(aEventTarget);
       return false;
     }
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -43,17 +43,17 @@ using mozilla::dom::MessagePortParent;
 using mozilla::dom::PMessagePortParent;
 using mozilla::dom::UDPSocketParent;
 
 namespace {
 
 void
 AssertIsInMainProcess()
 {
-  MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
+  MOZ_ASSERT(XRE_IsParentProcess());
 }
 
 void
 AssertIsOnMainThread()
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
--- a/ipc/glue/InputStreamUtils.cpp
+++ b/ipc/glue/InputStreamUtils.cpp
@@ -101,17 +101,17 @@ DeserializeInputStream(const InputStream
 
     case InputStreamParams::TMultiplexInputStreamParams:
       serializable = do_CreateInstance(kMultiplexInputStreamCID);
       break;
 
     // When the input stream already exists in this process, all we need to do
     // is retrieve the original instead of sending any data over the wire.
     case InputStreamParams::TRemoteInputStreamParams: {
-      if (NS_WARN_IF(XRE_GetProcessType() != GeckoProcessType_Default)) {
+      if (NS_WARN_IF(!XRE_IsParentProcess())) {
         return nullptr;
       }
 
       const nsID& id = aParams.get_RemoteInputStreamParams().id();
 
       nsRefPtr<BlobImpl> blobImpl = BlobParent::GetBlobImplForID(id);
 
       MOZ_ASSERT(blobImpl, "Invalid blob contents");
--- a/ipc/glue/ScopedXREEmbed.cpp
+++ b/ipc/glue/ScopedXREEmbed.cpp
@@ -62,17 +62,17 @@ ScopedXREEmbed::Start()
   rv = localFile->GetParent(getter_AddRefs(parent));
   if (NS_FAILED(rv))
     return;
 
   localFile = do_QueryInterface(parent);
   NS_ENSURE_TRUE_VOID(localFile);
 
 #ifdef OS_MACOSX
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+  if (XRE_IsContentProcess()) {
     // We're an XPCOM-using subprocess.  Walk out of
     // [subprocess].app/Contents/MacOS to the real GRE dir.
     rv = localFile->GetParent(getter_AddRefs(parent));
     if (NS_FAILED(rv))
       return;
 
     localFile = do_QueryInterface(parent);
     NS_ENSURE_TRUE_VOID(localFile);
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -72,17 +72,19 @@ JSCompartment::JSCompartment(Zone* zone,
     watchpointMap(nullptr),
     scriptCountsMap(nullptr),
     debugScriptMap(nullptr),
     debugScopes(nullptr),
     enumerators(nullptr),
     compartmentStats(nullptr),
     scheduledForDestruction(false),
     maybeAlive(true),
-    jitCompartment_(nullptr)
+    jitCompartment_(nullptr),
+    normalArgumentsTemplate_(nullptr),
+    strictArgumentsTemplate_(nullptr)
 {
     PodArrayZero(sawDeprecatedLanguageExtension);
     runtime_->numCompartments++;
     MOZ_ASSERT_IF(options.mergeable(), options.invisibleToDebugger());
 }
 
 JSCompartment::~JSCompartment()
 {
@@ -650,17 +652,28 @@ JSCompartment::sweepCrossCompartmentWrap
         } else if (key.wrapped != e.front().key().wrapped ||
                    key.debugger != e.front().key().debugger)
         {
             e.rekeyFront(key);
         }
     }
 }
 
-void JSCompartment::fixupAfterMovingGC()
+void
+JSCompartment::sweepTemplateObjects()
+{
+    if (normalArgumentsTemplate_ && IsAboutToBeFinalized(&normalArgumentsTemplate_))
+        normalArgumentsTemplate_.set(nullptr);
+
+    if (strictArgumentsTemplate_ && IsAboutToBeFinalized(&strictArgumentsTemplate_))
+        strictArgumentsTemplate_.set(nullptr);
+}
+
+void
+JSCompartment::fixupAfterMovingGC()
 {
     fixupGlobal();
     fixupInitialShapeTable();
     objectGroups.fixupTablesAfterMovingGC();
 }
 
 void
 JSCompartment::fixupGlobal()
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -421,16 +421,17 @@ struct JSCompartment
     void sweepSavedStacks();
     void sweepGlobalObject(js::FreeOp* fop);
     void sweepSelfHostingScriptSource();
     void sweepJitCompartment(js::FreeOp* fop);
     void sweepRegExps();
     void sweepDebugScopes();
     void sweepWeakMaps();
     void sweepNativeIterators();
+    void sweepTemplateObjects();
 
     void purge();
     void clearTables();
 
     void fixupInitialShapeTable();
     void fixupAfterMovingGC();
     void fixupGlobal();
 
@@ -573,16 +574,19 @@ struct JSCompartment
     // These flags help us to discover if a compartment that shouldn't be alive
     // manages to outlive a GC.
     bool scheduledForDestruction;
     bool maybeAlive;
 
   private:
     js::jit::JitCompartment* jitCompartment_;
 
+    js::ReadBarriered<js::ArgumentsObject*> normalArgumentsTemplate_;
+    js::ReadBarriered<js::ArgumentsObject*> strictArgumentsTemplate_;
+
   public:
     bool ensureJitCompartmentExists(JSContext* cx);
     js::jit::JitCompartment* jitCompartment() {
         return jitCompartment_;
     }
 
     enum DeprecatedLanguageExtension {
         DeprecatedForEach = 0,              // JS 1.6+
@@ -592,16 +596,18 @@ struct JSCompartment
         DeprecatedLetBlock = 4,             // Added in JS 1.7
         // NO LONGER USING 5
         DeprecatedNoSuchMethod = 6,         // JS 1.7+
         DeprecatedFlagsArgument = 7,        // JS 1.3 or older
         RegExpSourceProperty = 8,           // ES5
         DeprecatedLanguageExtensionCount
     };
 
+    js::ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, bool strict);
+
   private:
     // Used for collecting telemetry on SpiderMonkey's deprecated language extensions.
     bool sawDeprecatedLanguageExtension[DeprecatedLanguageExtensionCount];
 
     void reportTelemetry();
 
   public:
     void addTelemetry(const char* filename, DeprecatedLanguageExtension e);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2252,16 +2252,17 @@ GCRuntime::sweepZoneAfterCompacting(Zone
         c->sweepRegExps();
         c->sweepSavedStacks();
         c->sweepGlobalObject(fop);
         c->sweepSelfHostingScriptSource();
         c->sweepDebugScopes();
         c->sweepJitCompartment(fop);
         c->sweepWeakMaps();
         c->sweepNativeIterators();
+        c->sweepTemplateObjects();
     }
 }
 
 template <typename T>
 static void
 UpdateCellPointersTyped(MovingTracer* trc, ArenaHeader* arena, JS::TraceKind traceKind)
 {
     for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
@@ -4922,16 +4923,17 @@ GCRuntime::beginSweepingZoneGroup()
         {
             gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_MISC);
 
             for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
                 c->sweepGlobalObject(&fop);
                 c->sweepDebugScopes();
                 c->sweepJitCompartment(&fop);
                 c->sweepWeakMaps();
+                c->sweepTemplateObjects();
             }
 
             // Bug 1071218: the following two methods have not yet been
             // refactored to work on a single zone-group at once.
 
             // Collect watch points associated with unreachable objects.
             WatchpointMap::sweepAll(rt);
 
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -152,64 +152,98 @@ struct CopyScriptFrameIterArgs
      * invalid.
      */
     void maybeForwardToCallObject(ArgumentsObject* obj, ArgumentsData* data) {
         if (!iter_.isIon())
             ArgumentsObject::MaybeForwardToCallObject(iter_.abstractFramePtr(), obj, data);
     }
 };
 
-template <typename CopyArgs>
-/* static */ ArgumentsObject*
-ArgumentsObject::create(JSContext* cx, HandleScript script, HandleFunction callee,
-                        unsigned numActuals, CopyArgs& copy)
+ArgumentsObject*
+ArgumentsObject::createTemplateObject(JSContext* cx, bool strict)
 {
-    RootedObject proto(cx, callee->global().getOrCreateObjectPrototype(cx));
+    const Class* clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
+
+    RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
     if (!proto)
         return nullptr;
 
-    bool strict = callee->strict();
-    const Class* clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
-
     RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, TaggedProto(proto.get())));
     if (!group)
         return nullptr;
 
     RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(proto),
                                                       FINALIZE_KIND, BaseShape::INDEXED));
     if (!shape)
         return nullptr;
 
+    JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, group);
+    if (!base)
+        return nullptr;
+
+    ArgumentsObject* obj = &base->as<js::ArgumentsObject>();
+    obj->initFixedSlot(ArgumentsObject::DATA_SLOT, PrivateValue(nullptr));
+    return obj;
+}
+
+ArgumentsObject*
+JSCompartment::getOrCreateArgumentsTemplateObject(JSContext* cx, bool strict)
+{
+    ReadBarriered<ArgumentsObject*>& obj =
+        strict ? strictArgumentsTemplate_ : normalArgumentsTemplate_;
+
+    ArgumentsObject* templateObj = obj;
+    if (templateObj)
+        return templateObj;
+
+    templateObj = ArgumentsObject::createTemplateObject(cx, strict);
+    if (!templateObj)
+        return nullptr;
+
+    obj.set(templateObj);
+    return templateObj;
+}
+
+template <typename CopyArgs>
+/* static */ ArgumentsObject*
+ArgumentsObject::create(JSContext* cx, HandleFunction callee, unsigned numActuals, CopyArgs& copy)
+{
+    bool strict = callee->strict();
+    ArgumentsObject* templateObj = cx->compartment()->getOrCreateArgumentsTemplateObject(cx, strict);
+    if (!templateObj)
+        return nullptr;
+
+    RootedShape shape(cx, templateObj->lastProperty());
+    RootedObjectGroup group(cx, templateObj->group());
+
     unsigned numFormals = callee->nargs();
     unsigned numDeletedWords = NumWordsForBitArrayOfLength(numActuals);
     unsigned numArgs = Max(numActuals, numFormals);
     unsigned numBytes = offsetof(ArgumentsData, args) +
                         numDeletedWords * sizeof(size_t) +
                         numArgs * sizeof(Value);
 
     Rooted<ArgumentsObject*> obj(cx);
-    JSObject* base = JSObject::create(cx, FINALIZE_KIND,
-                                      GetInitialHeap(GenericObject, clasp),
-                                      shape, group);
+    JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, group);
     if (!base)
         return nullptr;
     obj = &base->as<ArgumentsObject>();
 
     ArgumentsData* data =
         reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes));
     if (!data) {
         // Make the object safe for GC.
         obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr));
         return nullptr;
     }
 
     data->numArgs = numArgs;
     data->dataBytes = numBytes;
     data->callee.init(ObjectValue(*callee.get()));
-    data->script = script;
+    data->script = callee->nonLazyScript();
 
     // Zero the argument Values. This sets each value to DoubleValue(0), which
     // is safe for GC tracing.
     memset(data->args, 0, numArgs * sizeof(Value));
     MOZ_ASSERT(DoubleValue(0).asRawBits() == 0x0);
     MOZ_ASSERT_IF(numArgs > 0, data->args[0].asRawBits() == 0x0);
 
     obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
@@ -228,55 +262,51 @@ ArgumentsObject::create(JSContext* cx, H
     MOZ_ASSERT(!obj->hasOverriddenLength());
     return obj;
 }
 
 ArgumentsObject*
 ArgumentsObject::createExpected(JSContext* cx, AbstractFramePtr frame)
 {
     MOZ_ASSERT(frame.script()->needsArgsObj());
-    RootedScript script(cx, frame.script());
     RootedFunction callee(cx, frame.callee());
     CopyFrameArgs copy(frame);
-    ArgumentsObject* argsobj = create(cx, script, callee, frame.numActualArgs(), copy);
+    ArgumentsObject* argsobj = create(cx, callee, frame.numActualArgs(), copy);
     if (!argsobj)
         return nullptr;
 
     frame.initArgsObj(*argsobj);
     return argsobj;
 }
 
 ArgumentsObject*
 ArgumentsObject::createUnexpected(JSContext* cx, ScriptFrameIter& iter)
 {
-    RootedScript script(cx, iter.script());
     RootedFunction callee(cx, iter.callee(cx));
     CopyScriptFrameIterArgs copy(iter);
-    return create(cx, script, callee, iter.numActualArgs(), copy);
+    return create(cx, callee, iter.numActualArgs(), copy);
 }
 
 ArgumentsObject*
 ArgumentsObject::createUnexpected(JSContext* cx, AbstractFramePtr frame)
 {
-    RootedScript script(cx, frame.script());
     RootedFunction callee(cx, frame.callee());
     CopyFrameArgs copy(frame);
-    return create(cx, script, callee, frame.numActualArgs(), copy);
+    return create(cx, callee, frame.numActualArgs(), copy);
 }
 
 ArgumentsObject*
 ArgumentsObject::createForIon(JSContext* cx, jit::JitFrameLayout* frame, HandleObject scopeChain)
 {
     jit::CalleeToken token = frame->calleeToken();
     MOZ_ASSERT(jit::CalleeTokenIsFunction(token));
-    RootedScript script(cx, jit::ScriptFromCalleeToken(token));
     RootedFunction callee(cx, jit::CalleeTokenToFunction(token));
     RootedObject callObj(cx, scopeChain->is<CallObject>() ? scopeChain.get() : nullptr);
     CopyJitFrameArgs copy(frame, callObj);
-    return create(cx, script, callee, frame->numActualArgs(), copy);
+    return create(cx, callee, frame->numActualArgs(), copy);
 }
 
 static bool
 args_delProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result)
 {
     ArgumentsObject& argsobj = obj->as<ArgumentsObject>();
     if (JSID_IS_INT(id)) {
         unsigned arg = unsigned(JSID_TO_INT(id));
@@ -539,20 +569,21 @@ ArgumentsObject::finalize(FreeOp* fop, J
     MOZ_ASSERT(!IsInsideNursery(obj));
     fop->free_(reinterpret_cast<void*>(obj->as<ArgumentsObject>().data()));
 }
 
 void
 ArgumentsObject::trace(JSTracer* trc, JSObject* obj)
 {
     ArgumentsObject& argsobj = obj->as<ArgumentsObject>();
-    ArgumentsData* data = argsobj.data();
-    TraceEdge(trc, &data->callee, js_callee_str);
-    TraceRange(trc, data->numArgs, data->begin(), js_arguments_str);
-    TraceManuallyBarrieredEdge(trc, &data->script, "script");
+    if (ArgumentsData* data = argsobj.data()) { // Template objects have no ArgumentsData.
+        TraceEdge(trc, &data->callee, js_callee_str);
+        TraceRange(trc, data->numArgs, data->begin(), js_arguments_str);
+        TraceManuallyBarrieredEdge(trc, &data->script, "script");
+    }
 }
 
 /* static */ size_t
 ArgumentsObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src)
 {
     ArgumentsObject* ndst = &dst->as<ArgumentsObject>();
     ArgumentsObject* nsrc = &src->as<ArgumentsObject>();
     MOZ_ASSERT(ndst->data() == nsrc->data());
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -124,18 +124,18 @@ class ArgumentsObject : public NativeObj
     static const uint32_t MAYBE_CALL_SLOT = 2;
 
   public:
     static const uint32_t LENGTH_OVERRIDDEN_BIT = 0x1;
     static const uint32_t PACKED_BITS_COUNT = 1;
 
   protected:
     template <typename CopyArgs>
-    static ArgumentsObject* create(JSContext* cx, HandleScript script, HandleFunction callee,
-                                   unsigned numActuals, CopyArgs& copy);
+    static ArgumentsObject* create(JSContext* cx, HandleFunction callee, unsigned numActuals,
+                                   CopyArgs& copy);
 
     ArgumentsData* data() const {
         return reinterpret_cast<ArgumentsData*>(getFixedSlot(DATA_SLOT).toPrivate());
     }
 
   public:
     static const uint32_t RESERVED_SLOTS = 3;
     static const gc::AllocKind FINALIZE_KIND = gc::AllocKind::OBJECT4_BACKGROUND;
@@ -149,16 +149,18 @@ class ArgumentsObject : public NativeObj
      * This allows function-local analysis to determine that formals are
      * not aliased and generally simplifies arguments objects.
      */
     static ArgumentsObject* createUnexpected(JSContext* cx, ScriptFrameIter& iter);
     static ArgumentsObject* createUnexpected(JSContext* cx, AbstractFramePtr frame);
     static ArgumentsObject* createForIon(JSContext* cx, jit::JitFrameLayout* frame,
                                          HandleObject scopeChain);
 
+    static ArgumentsObject* createTemplateObject(JSContext* cx, bool strict);
+
     /*
      * Return the initial length of the arguments.  This may differ from the
      * current value of arguments.length!
      */
     uint32_t initialLength() const {
         uint32_t argc = uint32_t(getFixedSlot(INITIAL_LENGTH_SLOT).toInt32()) >> PACKED_BITS_COUNT;
         MOZ_ASSERT(argc <= ARGS_LENGTH_MAX);
         return argc;
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -578,18 +578,19 @@ mozJSComponentLoader::PrepareObjectForLo
     nsCOMPtr<nsIFile> testFile;
     if (NS_SUCCEEDED(rv)) {
         fileURL->GetFile(getter_AddRefs(testFile));
     }
 
     if (testFile) {
         *aRealFile = true;
 
-        if (XRE_GetProcessType() == GeckoProcessType_Default) {
+        if (XRE_IsParentProcess()) {
             RootedObject locationObj(aCx);
+
             rv = xpc->WrapNative(aCx, obj, aComponentFile,
                                  NS_GET_IID(nsIFile),
                                  locationObj.address());
             NS_ENSURE_SUCCESS(rv, nullptr);
             NS_ENSURE_TRUE(locationObj, nullptr);
 
             if (!JS_DefineProperty(aCx, obj, "__LOCATION__", locationObj, 0))
                 return nullptr;
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1349,17 +1349,17 @@ XPCJSRuntime::InterruptCallback(JSContex
         return true;
     }
 
     // Sometimes we get called back during XPConnect initialization, before Gecko
     // has finished bootstrapping. Avoid crashing in nsContentUtils below.
     if (!nsContentUtils::IsInitialized())
         return true;
 
-    bool contentProcess = XRE_GetProcessType() == GeckoProcessType_Content;
+    bool contentProcess = XRE_IsContentProcess();
 
     // This is at least the second interrupt callback we've received since
     // returning to the event loop. See how long it's been, and what the limit
     // is.
     TimeDuration duration = TimeStamp::NowLoRes() - self->mSlowScriptCheckpoint;
     bool chrome = nsContentUtils::IsCallerChrome();
     const char* prefName = contentProcess ? PREF_MAX_SCRIPT_RUN_TIME_CHILD
                                  : chrome ? PREF_MAX_SCRIPT_RUN_TIME_CHROME
@@ -2576,17 +2576,17 @@ nsresult
 ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats& rtStats,
                                  const nsACString& rtPath,
                                  nsIMemoryReporterCallback* cb,
                                  nsISupports* closure,
                                  bool anonymize,
                                  size_t* rtTotalOut)
 {
     nsCOMPtr<amIAddonManager> am;
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         // Only try to access the service from the main process.
         am = do_GetService("@mozilla.org/addons/integration;1");
     }
     return ReportJSRuntimeExplicitTreeStats(rtStats, rtPath, am.get(),
                                             cb, closure, anonymize, rtTotalOut);
 }
 
 
@@ -2832,17 +2832,17 @@ JSReporter::CollectReports(WindowPaths* 
 
     // In the first step we get all the stats and stash them in a local
     // data structure.  In the second step we pass all the stashed stats to
     // the callback.  Separating these steps is important because the
     // callback may be a JS function, and executing JS while getting these
     // stats seems like a bad idea.
 
     nsCOMPtr<amIAddonManager> addonManager;
-    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (XRE_IsParentProcess()) {
         // Only try to access the service from the main process.
         addonManager = do_GetService("@mozilla.org/addons/integration;1");
     }
     bool getLocations = !!addonManager;
     XPCJSRuntimeStats rtStats(windowPaths, topWindowPaths, getLocations,
                               anonymize);
     OrphanReporter orphanReporter(XPCConvert::GetISupportsFromJSObject);
     if (!JS::CollectRuntimeStats(xpcrt->Runtime(), &rtStats, &orphanReporter,
--- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp
@@ -231,17 +231,17 @@ XPCNativeInterface::NewInstance(nsIInter
 
     bool canScript;
     if (NS_FAILED(aInfo->IsScriptable(&canScript)) || !canScript)
         return nullptr;
 
     bool mainProcessScriptableOnly;
     if (NS_FAILED(aInfo->IsMainProcessScriptableOnly(&mainProcessScriptableOnly)))
         return nullptr;
-    if (mainProcessScriptableOnly && XRE_GetProcessType() != GeckoProcessType_Default) {
+    if (mainProcessScriptableOnly && !XRE_IsParentProcess()) {
         nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
         if (console) {
             char* intfNameChars;
             aInfo->GetName(&intfNameChars);
             nsPrintfCString errorMsg("Use of %s in content process is deprecated.", intfNameChars);
 
             nsAutoString filename;
             uint32_t lineno = 0;
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -223,17 +223,17 @@ AccessCheck::checkPassToPrivilegedCode(J
     if (!js::IsWrapper(obj))
         return true;
 
     // CPOWs use COWs (in the unprivileged junk scope) for all child->parent
     // references. Without this test, the child process wouldn't be able to
     // pass any objects at all to CPOWs.
     if (mozilla::jsipc::IsWrappedCPOW(obj) &&
         js::GetObjectCompartment(wrapper) == js::GetObjectCompartment(xpc::UnprivilegedJunkScope()) &&
-        XRE_GetProcessType() == GeckoProcessType_Default)
+        XRE_IsParentProcess())
     {
         return true;
     }
 
     // COWs are fine to pass to chrome if and only if they have __exposedProps__,
     // since presumably content should never have a reason to pass an opaque
     // object back to chrome.
     if (AccessCheck::isChrome(js::UncheckedUnwrap(wrapper)) && WrapperFactory::IsCOW(obj)) {
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -422,17 +422,17 @@ WrapperFactory::Rewrap(JSContext* cx, Ha
 
     // Special handling for chrome objects being exposed to content.
     else if (originIsChrome && !targetIsChrome) {
         // If this is a chrome function being exposed to content, we need to allow
         // call (but nothing else). We allow CPOWs that purport to be function's
         // here, but only in the content process.
         if ((IdentifyStandardInstance(obj) == JSProto_Function ||
             (jsipc::IsCPOW(obj) && JS::IsCallable(obj) &&
-             XRE_GetProcessType() == GeckoProcessType_Content)))
+             XRE_IsContentProcess())))
         {
             wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>::singleton;
         }
 
         // For Vanilla JSObjects exposed from chrome to content, we use a wrapper
         // that supports __exposedProps__. We'd like to get rid of these eventually,
         // but in their current form they don't cause much trouble.
         else if (IdentifyStandardInstance(obj) == JSProto_Object) {
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -288,17 +288,19 @@ class PaintedLayerData {
 public:
   PaintedLayerData() :
     mAnimatedGeometryRoot(nullptr),
     mFixedPosFrameForLayerData(nullptr),
     mReferenceFrame(nullptr),
     mLayer(nullptr),
     mIsSolidColorInVisibleRegion(false),
     mFontSmoothingBackgroundColor(NS_RGBA(0,0,0,0)),
+    mExclusiveToOneItem(false),
     mSingleItemFixedToViewport(false),
+    mIsCaret(false),
     mNeedComponentAlpha(false),
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
     mDisableFlattening(false),
     mImage(nullptr),
     mCommonClipCount(-1),
     mNewChildLayersIndex(-1)
@@ -445,21 +447,29 @@ public:
    */
   bool mIsSolidColorInVisibleRegion;
   /**
    * The target background color for smoothing fonts that are drawn on top of
    * transparent parts of the layer.
    */
   nscolor mFontSmoothingBackgroundColor;
   /**
+   * True if only one display item can be assigned to this layer.
+   */
+  bool mExclusiveToOneItem;
+  /**
    * True if the layer contains exactly one item that returned true for
    * ShouldFixToViewport.
    */
   bool mSingleItemFixedToViewport;
   /**
+   * True if the layer contains exactly one item for the caret.
+   */
+  bool mIsCaret;
+  /**
    * True if there is any text visible in the layer that's over
    * transparent pixels in the layer.
    */
   bool mNeedComponentAlpha;
   /**
    * Set if the layer should be treated as transparent, even if its entire
    * area is covered by opaque display items. For example, this needs to
    * be set if something is going to "punch holes" in the layer by clearing
@@ -534,16 +544,17 @@ public:
 struct NewLayerEntry {
   NewLayerEntry()
     : mAnimatedGeometryRoot(nullptr)
     , mFixedPosFrameForLayerData(nullptr)
     , mLayerContentsVisibleRect(0, 0, -1, -1)
     , mHideAllLayersBelow(false)
     , mOpaqueForAnimatedGeometryRootParent(false)
     , mPropagateComponentAlphaFlattening(true)
+    , mIsCaret(false)
   {}
   // mLayer is null if the previous entry is for a PaintedLayer that hasn't
   // been optimized to some other form (yet).
   nsRefPtr<Layer> mLayer;
   const nsIFrame* mAnimatedGeometryRoot;
   const nsIFrame* mFixedPosFrameForLayerData;
   // If non-null, this FrameMetrics is set to the be the first FrameMetrics
   // on the layer.
@@ -565,16 +576,17 @@ struct NewLayerEntry {
   // When this flag is set, we can treat this opaque region as covering
   // content whose animated geometry root is the animated geometry root for
   // mAnimatedGeometryRoot->GetParent().
   bool mOpaqueForAnimatedGeometryRootParent;
 
   // If true, then the content flags for this layer should contribute
   // to our decision to flatten component alpha layers, false otherwise.
   bool mPropagateComponentAlphaFlattening;
+  bool mIsCaret;
 };
 
 class PaintedLayerDataTree;
 
 /**
  * This is tree node type for PaintedLayerDataTree.
  * Each node corresponds to a different animated geometry root, and contains
  * a stack of PaintedLayerDatas, in bottom-to-top order.
@@ -793,17 +805,17 @@ public:
   /**
    * Find a PaintedLayerData for aItem. This can either be an existing
    * PaintedLayerData from inside a node in our tree, or a new one that gets
    * created by a call out to aNewPaintedLayerCallback.
    */
   template<typename NewPaintedLayerCallbackType>
   PaintedLayerData* FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
                                         const nsIntRect& aVisibleRect,
-                                        bool aShouldFixToViewport,
+                                        bool aForceOwnLayer,
                                         NewPaintedLayerCallbackType aNewPaintedLayerCallback);
 
   /**
    * Finish everything.
    */
   void Finish();
 
   /**
@@ -2563,27 +2575,27 @@ PaintedLayerDataNode::AddChildNodeFor(co
 }
 
 template<typename NewPaintedLayerCallbackType>
 PaintedLayerData*
 PaintedLayerDataNode::FindPaintedLayerFor(const nsIntRect& aVisibleRect,
                                           NewPaintedLayerCallbackType aNewPaintedLayerCallback)
 {
   if (!mPaintedLayerDataStack.IsEmpty()) {
-    if (mPaintedLayerDataStack[0].mSingleItemFixedToViewport) {
+    if (mPaintedLayerDataStack[0].mExclusiveToOneItem) {
       MOZ_ASSERT(mPaintedLayerDataStack.Length() == 1);
       SetAllDrawingAbove();
       MOZ_ASSERT(mPaintedLayerDataStack.IsEmpty());
     } else {
       PaintedLayerData* lowestUsableLayer = nullptr;
       for (auto& data : Reversed(mPaintedLayerDataStack)) {
         if (data.VisibleAboveRegionIntersects(aVisibleRect)) {
           break;
         }
-        MOZ_ASSERT(!data.mSingleItemFixedToViewport);
+        MOZ_ASSERT(!data.mExclusiveToOneItem);
         lowestUsableLayer = &data;
         if (data.VisibleRegionIntersects(aVisibleRect)) {
           break;
         }
       }
       if (lowestUsableLayer) {
         return lowestUsableLayer;
       }
@@ -2734,26 +2746,29 @@ PaintedLayerDataTree::AddingOwnLayer(con
     node->SetAllDrawingAbove();
   }
 }
 
 template<typename NewPaintedLayerCallbackType>
 PaintedLayerData*
 PaintedLayerDataTree::FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
                                           const nsIntRect& aVisibleRect,
-                                          bool aShouldFixToViewport,
+                                          bool aForceOwnLayer,
                                           NewPaintedLayerCallbackType aNewPaintedLayerCallback)
 {
-  const nsIntRect* bounds = aShouldFixToViewport ? nullptr : &aVisibleRect;
+  const nsIntRect* bounds = aForceOwnLayer ? nullptr : &aVisibleRect;
   FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, bounds);
   PaintedLayerDataNode* node = EnsureNodeFor(aAnimatedGeometryRoot);
-  if (aShouldFixToViewport) {
+  if (aForceOwnLayer) {
     node->SetAllDrawingAbove();
   }
-  return node->FindPaintedLayerFor(aVisibleRect, aNewPaintedLayerCallback);
+  PaintedLayerData* data =
+    node->FindPaintedLayerFor(aVisibleRect, aNewPaintedLayerCallback);
+  data->mExclusiveToOneItem = aForceOwnLayer;
+  return data;
 }
 
 void
 PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimatedGeometryRoot,
                                                          const nsIntRect* aRect)
 {
   const nsIFrame* ancestorThatIsChildOfCommonAncestor = nullptr;
   PaintedLayerDataNode* ancestorNode =
@@ -3059,16 +3074,17 @@ void ContainerState::FinishPaintedLayerD
       NS_ASSERTION(newLayerEntry->mLayer == data->mLayer,
                    "Painted layer at wrong index");
       // Store optimized layer in reserved slot
       newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex + 1];
       NS_ASSERTION(!newLayerEntry->mLayer, "Slot already occupied?");
       newLayerEntry->mLayer = layer;
       newLayerEntry->mAnimatedGeometryRoot = data->mAnimatedGeometryRoot;
       newLayerEntry->mFixedPosFrameForLayerData = data->mFixedPosFrameForLayerData;
+      newLayerEntry->mIsCaret = data->mIsCaret;
 
       // Hide the PaintedLayer. We leave it in the layer tree so that we
       // can find and recycle it later.
       ParentLayerIntRect emptyRect;
       data->mLayer->SetClipRect(Some(emptyRect));
       data->mLayer->SetVisibleRegion(nsIntRegion());
       data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion().GetBounds());
       data->mLayer->SetEventRegions(EventRegions());
@@ -3422,21 +3438,23 @@ ContainerState::NewPaintedLayerData(nsDi
 {
   PaintedLayerData data;
   data.mAnimatedGeometryRoot = aAnimatedGeometryRoot;
   data.mAnimatedGeometryRootOffset = aTopLeft;
   data.mFixedPosFrameForLayerData =
     FindFixedPosFrameForLayerData(aAnimatedGeometryRoot, aShouldFixToViewport);
   data.mReferenceFrame = aItem->ReferenceFrame();
   data.mSingleItemFixedToViewport = aShouldFixToViewport;
+  data.mIsCaret = aItem->GetType() == nsDisplayItem::TYPE_CARET;
 
   data.mNewChildLayersIndex = mNewChildLayers.Length();
   NewLayerEntry* newLayerEntry = mNewChildLayers.AppendElement();
   newLayerEntry->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
   newLayerEntry->mFixedPosFrameForLayerData = data.mFixedPosFrameForLayerData;
+  newLayerEntry->mIsCaret = data.mIsCaret;
   // newLayerEntry->mOpaqueRegion is filled in later from
   // paintedLayerData->mOpaqueRegion, if necessary.
 
   // Allocate another entry for this layer's optimization to ColorLayer/ImageLayer
   mNewChildLayers.AppendElement();
 
   return data;
 }
@@ -3588,16 +3606,56 @@ ContainerState::ComputeOpaqueRect(nsDisp
       if (opaque.Contains(displayport)) {
         *aOpaqueForAnimatedGeometryRootParent = true;
       }
     }
   }
   return opaquePixels;
 }
 
+static bool
+IsCaretWithCustomClip(nsDisplayItem* aItem, nsDisplayItem::Type aItemType)
+{
+  return aItemType == nsDisplayItem::TYPE_CARET &&
+    static_cast<nsDisplayCaret*>(aItem)->NeedsCustomScrollClip();
+}
+
+static DisplayItemClip
+GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, const nsIFrame* aAnimatedGeometryRoot,
+                          const nsIFrame* aStopAtAnimatedGeometryRoot, bool aIsCaret)
+{
+  DisplayItemClip resultClip;
+  nsIFrame* fParent;
+  for (const nsIFrame* f = aAnimatedGeometryRoot;
+       f != aStopAtAnimatedGeometryRoot;
+       f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder,
+           fParent, aStopAtAnimatedGeometryRoot)) {
+    fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
+    if (!fParent) {
+      // This means aStopAtAnimatedGeometryRoot was not an ancestor
+      // of aAnimatedGeometryRoot. This is a weird case but it
+      // can happen, e.g. when a scrolled frame contains a frame with opacity
+      // which contains a frame that is not scrolled by the scrolled frame.
+      // For now, we just don't apply any specific scroll clip to this layer.
+      return DisplayItemClip();
+    }
+
+    nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
+    if (!scrollFrame) {
+      continue;
+    }
+
+    const DisplayItemClip* clip = scrollFrame->ComputeScrollClip(aIsCaret);
+    if (clip) {
+      resultClip.IntersectWith(*clip);
+    }
+  }
+  return resultClip;
+}
+
 /*
  * Iterate through the non-clip items in aList and its descendants.
  * For each item we compute the effective clip rect. Each item is assigned
  * to a layer. We invalidate the areas in PaintedLayers where an item
  * has moved from one PaintedLayer to another. Also,
  * aState->mInvalidPaintedContent is invalidated in every PaintedLayer.
  * We set the clip rect for items that generated their own layer, and
  * create a mask layer to do any rounded rect clipping.
@@ -3656,19 +3714,60 @@ ContainerState::ProcessDisplayItems(nsDi
 
     NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),
       "items in a container layer should all have the same app units per dev pixel");
 
     if (mBuilder->NeedToForceTransparentSurfaceForItem(item)) {
       aList->SetNeedsTransparentSurface();
     }
 
+    LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
+    if (layerState == LAYER_INACTIVE &&
+        nsDisplayItem::ForceActiveLayers()) {
+      layerState = LAYER_ACTIVE;
+    }
+
+    bool forceInactive;
+    const nsIFrame* animatedGeometryRoot;
+    const nsIFrame* realAnimatedGeometryRootOfItem =
+      nsLayoutUtils::GetAnimatedGeometryRootFor(item, mBuilder, mManager);
+    if (mFlattenToSingleLayer) {
+      forceInactive = true;
+      animatedGeometryRoot = lastAnimatedGeometryRoot;
+    } else {
+      forceInactive = false;
+      if (mManager->IsWidgetLayerManager()) {
+        animatedGeometryRoot = realAnimatedGeometryRootOfItem;
+      } else {
+        // For inactive layer subtrees, splitting content into PaintedLayers
+        // based on animated geometry roots is pointless. It's more efficient
+        // to build the minimum number of layers.
+        animatedGeometryRoot = mContainerAnimatedGeometryRoot;
+
+      }
+      if (animatedGeometryRoot != lastAnimatedGeometryRoot) {
+        lastAnimatedGeometryRoot = animatedGeometryRoot;
+        topLeft = animatedGeometryRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
+      }
+    }
+
+    nsDisplayItem::Type itemType = item->GetType();
+
+    if (animatedGeometryRoot != realAnimatedGeometryRootOfItem) {
+      // Pick up any scroll clips that should apply to the item and apply them.
+      DisplayItemClip clip =
+        GetScrollClipIntersection(mBuilder, realAnimatedGeometryRootOfItem,
+                                  animatedGeometryRoot,
+                                  IsCaretWithCustomClip(item, itemType));
+      clip.IntersectWith(item->GetClip());
+      item->SetClip(mBuilder, clip);
+    }
+
     bool snap;
     nsRect itemContent = item->GetBounds(mBuilder, &snap);
-    nsDisplayItem::Type itemType = item->GetType();
     if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
       nsDisplayLayerEventRegions* eventRegions =
         static_cast<nsDisplayLayerEventRegions*>(item);
       itemContent = eventRegions->GetHitRegionBounds(mBuilder, &snap);
     }
     nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap);
     bool prerenderedTransform = itemType == nsDisplayItem::TYPE_TRANSFORM &&
         static_cast<nsDisplayTransform*>(item)->ShouldPrerender(mBuilder);
@@ -3694,42 +3793,16 @@ ContainerState::ProcessDisplayItems(nsDi
     ((nsRect&)mAccumulatedChildBounds).UnionRect(mAccumulatedChildBounds, bounds);
 #endif
     // We haven't computed visibility at this point, so item->GetVisibleRect()
     // is just the dirty rect that item was initialized with. We intersect it
     // with the clipped item bounds to get a tighter visible rect.
     nsIntRect itemVisibleRect = itemDrawRect.Intersect(
       ScaleToOutsidePixels(item->GetVisibleRect(), false));
 
-    LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
-    if (layerState == LAYER_INACTIVE &&
-        nsDisplayItem::ForceActiveLayers()) {
-      layerState = LAYER_ACTIVE;
-    }
-
-    bool forceInactive;
-    const nsIFrame* animatedGeometryRoot;
-    if (mFlattenToSingleLayer) {
-      forceInactive = true;
-      animatedGeometryRoot = lastAnimatedGeometryRoot;
-    } else {
-      forceInactive = false;
-      if (mManager->IsWidgetLayerManager()) {
-        animatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(item, mBuilder, mManager);
-      } else {
-        // For inactive layer subtrees, splitting content into PaintedLayers
-        // based on animated geometry roots is pointless. It's more efficient
-        // to build the minimum number of layers.
-        animatedGeometryRoot = mContainerAnimatedGeometryRoot;
-      }
-      if (animatedGeometryRoot != lastAnimatedGeometryRoot) {
-        lastAnimatedGeometryRoot = animatedGeometryRoot;
-        topLeft = animatedGeometryRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
-      }
-    }
     bool shouldFixToViewport = !animatedGeometryRoot->GetParent() &&
       item->ShouldFixToViewport(mManager);
 
     if (maxLayers != -1 && layerCount >= maxLayers) {
       forceInactive = true;
     }
 
     // Assign the item to a layer
@@ -3874,16 +3947,17 @@ ContainerState::ProcessDisplayItems(nsDi
       newLayerEntry->mFixedPosFrameForLayerData = fixedPosFrame;
 
       // Don't attempt to flatten compnent alpha layers that are within
       // a forced active layer, or an active transform;
       if (itemType == nsDisplayItem::TYPE_TRANSFORM ||
           layerState == LAYER_ACTIVE_FORCE) {
         newLayerEntry->mPropagateComponentAlphaFlattening = false;
       }
+      newLayerEntry->mIsCaret = itemType == nsDisplayItem::TYPE_CARET;
       // nsDisplayTransform::BuildLayer must set layerContentsVisibleRect.
       // We rely on this to ensure 3D transforms compute a reasonable
       // layer visible region.
       NS_ASSERTION(itemType != nsDisplayItem::TYPE_TRANSFORM ||
                    layerContentsVisibleRect.width >= 0,
                    "Transform items must set layerContentsVisibleRect!");
       if (mLayerBuilder->IsBuildingRetainedLayers()) {
         newLayerEntry->mLayerContentsVisibleRect = layerContentsVisibleRect;
@@ -3913,19 +3987,20 @@ ContainerState::ProcessDisplayItems(nsDi
       /**
        * No need to allocate geometry for items that aren't
        * part of a PaintedLayer.
        */
       mLayerBuilder->AddLayerDisplayItem(ownLayer, item,
                                          layerState,
                                          topLeft, nullptr);
     } else {
+      bool forceOwnLayer = shouldFixToViewport || IsCaretWithCustomClip(item, itemType);
       PaintedLayerData* paintedLayerData =
         mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, itemVisibleRect,
-                                                  shouldFixToViewport, [&]() {
+                                                  forceOwnLayer, [&]() {
           return NewPaintedLayerData(item, itemVisibleRect, animatedGeometryRoot,
                                      topLeft, shouldFixToViewport);
         });
 
       if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
         nsDisplayLayerEventRegions* eventRegions =
             static_cast<nsDisplayLayerEventRegions*>(item);
         paintedLayerData->AccumulateEventRegions(eventRegions);
@@ -4429,17 +4504,17 @@ ContainerState::SetupScrollingMetadata(N
     }
 
     nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
     if (!scrollFrame) {
       continue;
     }
 
     Maybe<FrameMetricsAndClip> info =
-      scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, mParameters);
+      scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, mParameters, aEntry->mIsCaret);
     if (!info) {
       continue;
     }
 
     FrameMetrics& metrics = info->metrics;
     const DisplayItemClip* clip = info->clip;
 
     if (clip &&
--- a/layout/base/UnitTransforms.h
+++ b/layout/base/UnitTransforms.h