Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 07 May 2015 15:12:38 -0700
changeset 272625 70a21ed63d188fb70a812e3095bef2750bbdd8f9
parent 272578 5e83fa48971d24aba9a91379feaba73f940147f4 (current diff)
parent 272624 ee863cf58138c1d0c5eecd19334ecf68fa1f5ad2 (diff)
child 272644 5e02da1141d24cb2bd35e64df6bc9ee767fc9693
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c a=merge
--- a/Makefile.in
+++ b/Makefile.in
@@ -250,18 +250,19 @@ ifdef MOZ_CRASHREPORTER
 	cd $(DIST)/crashreporter-symbols && \
           zip -r9D '../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip' . -i '*.sym' -i '*.txt'  -x '*test*' -x '*Test*'
 endif # MOZ_CRASHREPORTER
 
 uploadsymbols:
 ifdef MOZ_CRASHREPORTER
 ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE
 	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.py '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
+else
+	$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
 endif
-	$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
 endif
 
 # MOZ_SOURCE_STAMP is defined in package-name.mk with a deferred assignment.
 # exporting it makes make run its $(shell) command for each invoked submake,
 # so transform it to an immediate assignment.
 MOZ_SOURCE_STAMP := $(MOZ_SOURCE_STAMP)
 export MOZ_SOURCE_STAMP
 endif
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -24,16 +24,17 @@ Cu.import('resource://gre/modules/Resour
 // Identity
 Cu.import('resource://gre/modules/SignInToWebsite.jsm');
 SignInToWebsiteController.init();
 
 Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
 Cu.import('resource://gre/modules/DownloadsAPI.jsm');
 Cu.import('resource://gre/modules/MobileIdentityManager.jsm');
 Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm');
+Cu.import('resource://gre/modules/AboutServiceWorkers.jsm');
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Screenshot",
                                   "resource://gre/modules/Screenshot.jsm");
 
 Cu.import('resource://gre/modules/Webapps.jsm');
new file mode 100644
--- /dev/null
+++ b/b2g/components/AboutServiceWorkers.jsm
@@ -0,0 +1,174 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict"
+
+this.EXPORTED_SYMBOLS = [];
+
+const { interfaces: Ci, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
+                                  "resource://gre/modules/SystemAppProxy.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
+                                  "@mozilla.org/serviceworkers/manager;1",
+                                  "nsIServiceWorkerManager");
+
+function debug(aMsg) {
+  //dump("AboutServiceWorkers - " + aMsg + "\n");
+}
+
+function serializeServiceWorkerInfo(aServiceWorkerInfo) {
+  if (!aServiceWorkerInfo) {
+    throw new Error("Invalid service worker information");
+  }
+
+  let result = {};
+
+  Object.keys(aServiceWorkerInfo).forEach(property => {
+    if (typeof aServiceWorkerInfo[property] == "function") {
+      return;
+    }
+    if (property === "principal") {
+      result.principal = {
+        origin: aServiceWorkerInfo.principal.origin,
+        appId: aServiceWorkerInfo.principal.appId,
+        isInBrowser: aServiceWorkerInfo.principal.isInBrowser
+      };
+      return;
+    }
+    result[property] = aServiceWorkerInfo[property];
+  });
+
+  return result;
+}
+
+function sendResult(aId, aResult) {
+  SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
+    id: aId,
+    result: aResult
+  });
+}
+
+function sendError(aId, aError) {
+  SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", {
+    id: aId,
+    error: aError
+  });
+}
+
+this.AboutServiceWorkers = {
+  get enabled() {
+    if (this._enabled) {
+      return this._enabled;
+    }
+    this._enabled = false;
+    try {
+      this._enabled = Services.prefs.getBoolPref("dom.serviceWorkers.enabled");
+    } catch(e) {}
+    return this._enabled;
+  },
+
+  init: function() {
+    SystemAppProxy.addEventListener("mozAboutServiceWorkersContentEvent",
+                                   AboutServiceWorkers);
+  },
+
+  handleEvent: function(aEvent) {
+    let message = aEvent.detail;
+
+    debug("Got content event " + JSON.stringify(message));
+
+    if (!message.id || !message.name) {
+      dump("Invalid event " + JSON.stringify(message) + "\n");
+      return;
+    }
+
+    switch(message.name) {
+      case "init":
+        if (!this.enabled) {
+          sendResult({
+            enabled: false,
+            registrations: []
+          });
+          return;
+        };
+
+        let data = gServiceWorkerManager.getAllRegistrations();
+        if (!data) {
+          sendError(message.id, "NoServiceWorkersRegistrations");
+          return;
+        }
+
+        let registrations = [];
+
+        for (let i = 0; i < data.length; i++) {
+          let info = data.queryElementAt(i, Ci.nsIServiceWorkerInfo);
+          if (!info) {
+            dump("AboutServiceWorkers: Invalid nsIServiceWorkerInfo " +
+                 "interface.\n");
+            continue;
+          }
+          registrations.push(serializeServiceWorkerInfo(info));
+        }
+
+        sendResult(message.id, {
+          enabled: this.enabled,
+          registrations: registrations
+        });
+        break;
+
+      case "update":
+        if (!message.scope) {
+          sendError(message.id, "MissingScope");
+          return;
+        }
+        gServiceWorkerManager.update(message.scope);
+        sendResult(message.id, true);
+        break;
+
+      case "unregister":
+        if (!message.principal ||
+            !message.principal.origin ||
+            !message.principal.appId) {
+          sendError("MissingPrincipal");
+          return;
+        }
+
+        let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
+          Services.io.newURI(message.principal.origin, null, null),
+          message.principal.appId,
+          message.principal.isInBrowser
+        );
+
+        if (!message.scope) {
+          sendError("MissingScope");
+          return;
+        }
+
+        let serviceWorkerUnregisterCallback = {
+          unregisterSucceeded: function() {
+            sendResult(message.id, true);
+          },
+
+          unregisterFailed: function() {
+            sendError(message.id, "UnregisterError");
+          },
+
+          QueryInterface: XPCOMUtils.generateQI([
+            Ci.nsIServiceWorkerUnregisterCallback
+          ])
+        };
+        gServiceWorkerManager.unregister(principal,
+                                         serviceWorkerUnregisterCallback,
+                                         message.scope);
+        break;
+    }
+  }
+};
+
+AboutServiceWorkers.init();
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -44,16 +44,17 @@ EXTRA_PP_COMPONENTS += [
 ]
 
 if CONFIG['MOZ_UPDATER']:
     EXTRA_PP_COMPONENTS += [
         'UpdatePrompt.js',
     ]
 
 EXTRA_JS_MODULES += [
+    'AboutServiceWorkers.jsm',
     'AlertsHelper.jsm',
     'Bootstraper.jsm',
     'ContentRequestHelper.jsm',
     'DebuggerActors.js',
     'ErrorPage.jsm',
     'Frames.jsm',
     'FxAccountsMgmtService.jsm',
     'LogCapture.jsm',
--- a/config/external/moz.build
+++ b/config/external/moz.build
@@ -32,16 +32,19 @@ if CONFIG['MOZ_WEBM_ENCODER']:
     external_dirs += ['media/libmkv']
 
 if CONFIG['MOZ_VPX'] and not CONFIG['MOZ_NATIVE_LIBVPX']:
     external_dirs += ['media/libvpx']
 
 if not CONFIG['MOZ_NATIVE_PNG']:
     external_dirs += ['media/libpng']
 
+if CONFIG['CPU_ARCH'] == 'arm':
+    external_dirs += ['media/openmax_dl']
+
 external_dirs += [
     'media/kiss_fft',
     'media/libcubeb',
     'media/libogg',
     'media/libopus',
     'media/libtheora',
     'media/libspeex_resampler',
     'media/libstagefright',
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -308,38 +308,38 @@ nsIContent::GetBaseURI(bool aTryUseXHRDo
     // First check for SVG specialness (why is this SVG specific?)
     if (elem->IsSVGElement()) {
       nsIContent* bindingParent = elem->GetBindingParent();
       if (bindingParent) {
         nsXBLBinding* binding = bindingParent->GetXBLBinding();
         if (binding) {
           // XXX sXBL/XBL2 issue
           // If this is an anonymous XBL element use the binding
-          // document for the base URI. 
+          // document for the base URI.
           // XXX Will fail with xml:base
           base = binding->PrototypeBinding()->DocURI();
           break;
         }
       }
     }
 
     nsIURI* explicitBaseURI = elem->GetExplicitBaseURI();
     if (explicitBaseURI) {
       base = explicitBaseURI;
       break;
     }
-    
+
     // Otherwise check for xml:base attribute
     elem->GetAttr(kNameSpaceID_XML, nsGkAtoms::base, attr);
     if (!attr.IsEmpty()) {
       baseAttrs.AppendElement(attr);
     }
     elem = elem->GetParent();
   } while(elem);
-  
+
   // Now resolve against all xml:base attrs
   for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) {
     nsCOMPtr<nsIURI> newBase;
     nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i],
                             doc->GetDocumentCharacterSet().get(), base);
     // Do a security check, almost the same as nsDocument::SetBaseURL()
     // Only need to do this on the final uri
     if (NS_SUCCEEDED(rv) && i == 0) {
@@ -450,17 +450,17 @@ nsChildContentList::IndexOf(nsIContent* 
 //----------------------------------------------------------------------
 
 nsIHTMLCollection*
 FragmentOrElement::Children()
 {
   FragmentOrElement::nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mChildrenList) {
-    slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard, 
+    slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard,
                                              nsGkAtoms::_asterisk, nsGkAtoms::_asterisk,
                                              false);
   }
 
   return slots->mChildrenList;
 }
 
 
@@ -1681,17 +1681,17 @@ FragmentOrElement::CanSkip(nsINode* aNod
     return false;
   }
 
   nsINode* root = currentDoc ? static_cast<nsINode*>(currentDoc) :
                                FindOptimizableSubtreeRoot(aNode);
   if (!root) {
     return false;
   }
- 
+
   // Subtree has been traversed already, and aNode has
   // been handled in a way that doesn't require revisiting it.
   if (root->IsPurpleRoot()) {
     return false;
   }
 
   // nodesToClear contains nodes which are either purple or
   // gray.
@@ -1735,17 +1735,17 @@ FragmentOrElement::CanSkip(nsINode* aNod
       if (ShouldClearPurple(node)) {
         // Collect interesting nodes which we can clear if we find that
         // they are kept alive in a black tree or are in a DOM-only cycle.
         nodesToClear.AppendElement(node);
       }
     }
   }
 
-  if (!currentDoc || !foundBlack) { 
+  if (!currentDoc || !foundBlack) {
     root->SetIsPurpleRoot(true);
     if (domOnlyCycle) {
       if (!gNodesToUnbind) {
         gNodesToUnbind = new nsAutoTArray<nsIContent*, 1020>();
       }
       gNodesToUnbind->AppendElement(static_cast<nsIContent*>(root));
       for (uint32_t i = 0; i < nodesToClear.Length(); ++i) {
         nsIContent* n = nodesToClear[i];
@@ -1775,17 +1775,17 @@ FragmentOrElement::CanSkip(nsINode* aNod
   }
 
   // Subtree is black, so we can remove purple nodes from
   // purple buffer and mark stuff that to be certainly alive.
   for (uint32_t i = 0; i < nodesToClear.Length(); ++i) {
     nsIContent* n = nodesToClear[i];
     MarkNodeChildren(n);
     // Can't remove currently handled purple node,
-    // unless aRemovingAllowed is true. 
+    // unless aRemovingAllowed is true.
     if ((n != aNode || aRemovingAllowed) && n->IsPurple()) {
       n->RemovePurple();
     }
   }
   return true;
 }
 
 bool
@@ -1793,17 +1793,17 @@ FragmentOrElement::CanSkipThis(nsINode* 
 {
   if (nsCCUncollectableMarker::sGeneration == 0) {
     return false;
   }
   if (aNode->IsBlack()) {
     return true;
   }
   nsIDocument* c = aNode->GetUncomposedDoc();
-  return 
+  return
     ((c && nsCCUncollectableMarker::InGeneration(c->GetMarkedCCGeneration())) ||
      aNode->InCCBlackTree()) && !NeedsScriptTraverse(aNode);
 }
 
 void
 FragmentOrElement::InitCCCallbacks()
 {
   nsCycleCollector_setForgetSkippableCallback(ClearCycleCollectorCleanupData);
@@ -2460,17 +2460,17 @@ StartElement(Element* aContent, StringBu
     // Filter out special case of <br type="_moz*"> used by the editor.
     // Bug 16988.  Yuck.
     if (localName == nsGkAtoms::br && tagNS == kNameSpaceID_XHTML &&
         attName == nsGkAtoms::type && attNs == kNameSpaceID_None &&
         StringBeginsWith(*attValue, NS_LITERAL_STRING("_moz"))) {
       delete attValue;
       continue;
     }
-    
+
     aBuilder.Append(" ");
 
     if (MOZ_LIKELY(attNs == kNameSpaceID_None) ||
         (attNs == kNameSpaceID_XMLNS &&
          attName == nsGkAtoms::xmlns)) {
       // Nothing else required
     } else if (attNs == kNameSpaceID_XML) {
       aBuilder.Append("xml:");
@@ -2520,22 +2520,22 @@ ShouldEscape(nsIContent* aParent)
 {
   if (!aParent || !aParent->IsHTMLElement()) {
     return true;
   }
 
   static const nsIAtom* nonEscapingElements[] = {
     nsGkAtoms::style, nsGkAtoms::script, nsGkAtoms::xmp,
     nsGkAtoms::iframe, nsGkAtoms::noembed, nsGkAtoms::noframes,
-    nsGkAtoms::plaintext, 
+    nsGkAtoms::plaintext,
     // Per the current spec noscript should be escaped in case
     // scripts are disabled or if document doesn't have
     // browsing context. However the latter seems to be a spec bug
     // and Gecko hasn't traditionally done the former.
-    nsGkAtoms::noscript    
+    nsGkAtoms::noscript
   };
   static mozilla::BloomFilter<12, nsIAtom> sFilter;
   static bool sInitialized = false;
   if (!sInitialized) {
     sInitialized = true;
     for (uint32_t i = 0; i < ArrayLength(nonEscapingElements); ++i) {
       sFilter.add(nonEscapingElements[i]);
     }
--- a/dom/base/ProcessGlobal.cpp
+++ b/dom/base/ProcessGlobal.cpp
@@ -45,31 +45,33 @@ ProcessGlobal::MarkForCC()
   return mMessageManager ? mMessageManager->MarkForCC() : false;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(ProcessGlobal)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ProcessGlobal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
+  tmp->TraverseHostObjectURIs(cb);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ProcessGlobal)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   for (uint32_t i = 0; i < tmp->mAnonymousGlobalScopes.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAnonymousGlobalScopes[i])
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ProcessGlobal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnonymousGlobalScopes)
+  tmp->UnlinkHostObjectURIs();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ProcessGlobal)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentProcessMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -143,65 +143,58 @@ URL::CreateObjectURL(const GlobalObject&
                           NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME), aOptions,
                           aResult, aError);
 }
 
 void
 URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
                              const nsACString& aScheme,
                              const objectURLOptions& aOptions,
-                             nsAString& aResult, ErrorResult& aError)
+                             nsAString& aResult, ErrorResult& aRv)
 {
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!global) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
   nsAutoCString url;
   nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
                                                           principal, url);
   if (NS_FAILED(rv)) {
-    aError.Throw(rv);
+    aRv.Throw(rv);
     return;
   }
 
-  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.GetAsSupports());
-  nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
-
-  if (window) {
-    NS_PRECONDITION(window->IsInnerWindow(), "Should be inner window");
-
-    if (!window->GetExtantDoc()) {
-      aError.Throw(NS_ERROR_INVALID_POINTER);
-      return;
-    }
-
-    nsIDocument* doc = window->GetExtantDoc();
-    if (doc) {
-      doc->RegisterHostObjectUri(url);
-    }
-  }
-
+  global->RegisterHostObjectURI(url);
   CopyASCIItoUTF16(url, aResult);
 }
 
 void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL)
+URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
+                     ErrorResult& aRv)
 {
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!global) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
 
   NS_LossyConvertUTF16toASCII asciiurl(aURL);
 
   nsIPrincipal* urlPrincipal =
     nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
 
   if (urlPrincipal && principal->Subsumes(urlPrincipal)) {
-    nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.GetAsSupports());
-    nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
-
-    if (window && window->GetExtantDoc()) {
-      window->GetExtantDoc()->UnregisterHostObjectUri(asciiurl);
-    }
+    nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+    global->UnregisterHostObjectURI(asciiurl);
     nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
   }
 }
 
 void
 URL::GetHref(nsAString& aHref, ErrorResult& aRv) const
 {
   aHref.Truncate();
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -71,17 +71,18 @@ public:
                               nsAString& aResult,
                               ErrorResult& aError);
   static void CreateObjectURL(const GlobalObject& aGlobal,
                               MediaSource& aSource,
                               const objectURLOptions& aOptions,
                               nsAString& aResult,
                               ErrorResult& aError);
   static void RevokeObjectURL(const GlobalObject& aGlobal,
-                              const nsAString& aURL);
+                              const nsAString& aURL,
+                              ErrorResult& aRv);
 
   void GetHref(nsAString& aHref, ErrorResult& aRv) const;
 
   void SetHref(const nsAString& aHref, ErrorResult& aRv);
 
   void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const;
 
   void GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const;
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1772,20 +1772,16 @@ nsDocument::~nsDocument()
 
   if (mBoxObjectTable) {
     mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nullptr);
     delete mBoxObjectTable;
   }
 
   mPendingTitleChangeEvent.Revoke();
 
-  for (uint32_t i = 0; i < mHostObjectURIs.Length(); ++i) {
-    nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[i]);
-  }
-
   // We don't want to leave residual locks on images. Make sure we're in an
   // unlocked state, and then clear the table.
   SetImageLockingState(false);
   mImageTracker.Clear();
 
   mPlugins.Clear();
 }
 
@@ -2042,20 +2038,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   }
 
   if (tmp->mSubDocuments && tmp->mSubDocuments->IsInitialized()) {
     PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
 
-  for (uint32_t i = 0; i < tmp->mHostObjectURIs.Length(); ++i) {
-    nsHostObjectProtocolHandler::Traverse(tmp->mHostObjectURIs[i], cb);
-  }
-
   // We own only the items in mDOMMediaQueryLists that have listeners;
   // this reference is managed by their AddListener and RemoveListener
   // methods.
   for (PRCList *l = PR_LIST_HEAD(&tmp->mDOMMediaQueryLists);
        l != &tmp->mDOMMediaQueryLists; l = PR_NEXT_LINK(l)) {
     MediaQueryList *mql = static_cast<MediaQueryList*>(l);
     if (mql->HasListeners()) {
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDOMMediaQueryLists item");
@@ -2157,20 +2149,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
 
   tmp->mPendingTitleChangeEvent.Revoke();
 
   if (tmp->mCSSLoader) {
     tmp->mCSSLoader->DropDocumentReference();
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mCSSLoader)
   }
 
-  for (uint32_t i = 0; i < tmp->mHostObjectURIs.Length(); ++i) {
-    nsHostObjectProtocolHandler::RemoveDataEntry(tmp->mHostObjectURIs[i]);
-  }
-
   // We own only the items in mDOMMediaQueryLists that have listeners;
   // this reference is managed by their AddListener and RemoveListener
   // methods.
   for (PRCList *l = PR_LIST_HEAD(&tmp->mDOMMediaQueryLists);
        l != &tmp->mDOMMediaQueryLists; ) {
     PRCList *next = PR_NEXT_LINK(l);
     MediaQueryList *mql = static_cast<MediaQueryList*>(l);
     mql->RemoveAllListeners();
@@ -10060,28 +10048,16 @@ nsDocument::GetTemplateContentsOwner()
     // by |doc|.
     doc->mTemplateContentsOwner = doc;
   }
 
   return mTemplateContentsOwner;
 }
 
 void
-nsDocument::RegisterHostObjectUri(const nsACString& aUri)
-{
-  mHostObjectURIs.AppendElement(aUri);
-}
-
-void
-nsDocument::UnregisterHostObjectUri(const nsACString& aUri)
-{
-  mHostObjectURIs.RemoveElement(aUri);
-}
-
-void
 nsDocument::SetScrollToRef(nsIURI *aDocumentURI)
 {
   if (!aDocumentURI) {
     return;
   }
 
   nsAutoCString ref;
 
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1033,18 +1033,16 @@ public:
   virtual void TryCancelFrameLoaderInitialization(nsIDocShell* aShell) override;
   virtual nsIDocument*
     RequestExternalResource(nsIURI* aURI,
                             nsINode* aRequestingNode,
                             ExternalResourceLoad** aPendingLoad) override;
   virtual void
     EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData) override;
 
-  nsTArray<nsCString> mHostObjectURIs;
-
   // Returns our (lazily-initialized) animation controller.
   // If HasAnimationController is true, this is guaranteed to return non-null.
   nsSMILAnimationController* GetAnimationController() override;
 
   virtual mozilla::PendingAnimationTracker*
   GetPendingAnimationTracker() final override
   {
     return mPendingAnimationTracker;
@@ -1123,19 +1121,16 @@ public:
 
   virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                        mozilla::CSSStyleSheet** sheet) override;
 
   virtual nsISupports* GetCurrentContentSink() override;
 
   virtual mozilla::EventStates GetDocumentState() override;
 
-  virtual void RegisterHostObjectUri(const nsACString& aUri) override;
-  virtual void UnregisterHostObjectUri(const nsACString& aUri) override;
-
   // Only BlockOnload should call this!
   void AsyncBlockOnload();
 
   virtual void SetScrollToRef(nsIURI *aDocumentURI) override;
   virtual void ScrollToRef() override;
   virtual void ResetScrolledToRefAlready() override;
   virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) override;
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1797,16 +1797,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocationbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersonalbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMozSelfSupport)
+
+  tmp->TraverseHostObjectURIs(cb);
+
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
   nsGlobalWindow::CleanupCachedXBLHandlers(tmp);
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
 
@@ -1861,16 +1864,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocationbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersonalbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mStatusbar)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMozSelfSupport)
+
+  tmp->UnlinkHostObjectURIs();
+
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 #ifdef DEBUG
 void
 nsGlobalWindow::RiskyUnlink()
 {
   NS_CYCLE_COLLECTION_INNERNAME.Unlink(this);
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2047,25 +2047,16 @@ public:
    * Returns the document state.
    * Document state bits have the form NS_DOCUMENT_STATE_* and are declared in
    * nsIDocument.h.
    */
   virtual mozilla::EventStates GetDocumentState() = 0;
 
   virtual nsISupports* GetCurrentContentSink() = 0;
 
-  /**
-   * Register/Unregister a hostobject uri as being "owned" by this document.
-   * I.e. that its lifetime is connected with this document. When the document
-   * goes away it should "kill" the uri by calling
-   * nsHostObjectProtocolHandler::RemoveDataEntry
-   */
-  virtual void RegisterHostObjectUri(const nsACString& aUri) = 0;
-  virtual void UnregisterHostObjectUri(const nsACString& aUri) = 0;
-
   virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0;
   virtual void ScrollToRef() = 0;
   virtual void ResetScrolledToRefAlready() = 0;
   virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) = 0;
 
   /**
    * This method is similar to GetElementById() from nsIDOMDocument but it
    * returns a mozilla::dom::Element instead of a nsIDOMElement.
--- a/dom/base/nsIGlobalObject.cpp
+++ b/dom/base/nsIGlobalObject.cpp
@@ -2,17 +2,110 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIGlobalObject.h"
 #include "nsContentUtils.h"
 
+nsIGlobalObject::~nsIGlobalObject()
+{
+  UnlinkHostObjectURIs();
+}
+
 nsIPrincipal*
 nsIGlobalObject::PrincipalOrNull()
 {
   JSObject *global = GetGlobalJSObject();
   if (NS_WARN_IF(!global))
     return nullptr;
 
   return nsContentUtils::ObjectPrincipal(global);
 }
+
+void
+nsIGlobalObject::RegisterHostObjectURI(const nsACString& aURI)
+{
+  MOZ_ASSERT(!mHostObjectURIs.Contains(aURI));
+  mHostObjectURIs.AppendElement(aURI);
+}
+
+void
+nsIGlobalObject::UnregisterHostObjectURI(const nsACString& aURI)
+{
+  mHostObjectURIs.RemoveElement(aURI);
+}
+
+namespace {
+
+class UnlinkHostObjectURIsRunnable final : public nsRunnable
+{
+public:
+  explicit UnlinkHostObjectURIsRunnable(nsTArray<nsCString>& aURIs)
+  {
+    mURIs.SwapElements(aURIs);
+  }
+
+  NS_IMETHOD Run() override
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    for (uint32_t index = 0; index < mURIs.Length(); ++index) {
+      nsHostObjectProtocolHandler::RemoveDataEntry(mURIs[index]);
+    }
+
+    return NS_OK;
+  }
+
+private:
+  ~UnlinkHostObjectURIsRunnable() {}
+
+  nsTArray<nsCString> mURIs;
+};
+
+} // anonymous namespace
+
+void
+nsIGlobalObject::UnlinkHostObjectURIs()
+{
+  if (mHostObjectURIs.IsEmpty()) {
+    return;
+  }
+
+  if (NS_IsMainThread()) {
+    for (uint32_t index = 0; index < mHostObjectURIs.Length(); ++index) {
+      nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[index]);
+    }
+
+    mHostObjectURIs.Clear();
+    return;
+  }
+
+  // nsHostObjectProtocolHandler is main-thread only.
+
+  nsRefPtr<UnlinkHostObjectURIsRunnable> runnable =
+    new UnlinkHostObjectURIsRunnable(mHostObjectURIs);
+  MOZ_ASSERT(mHostObjectURIs.IsEmpty());
+
+  nsresult rv = NS_DispatchToMainThread(runnable);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch a runnable to the main-thread.");
+  }
+}
+
+void
+nsIGlobalObject::TraverseHostObjectURIs(nsCycleCollectionTraversalCallback &aCb)
+{
+  if (mHostObjectURIs.IsEmpty()) {
+    return;
+  }
+
+  // Currently we only store FileImpl objects off the the main-thread and they
+  // are not CCed.
+  if (!NS_IsMainThread()) {
+    return;
+  }
+
+  for (uint32_t index = 0; index < mHostObjectURIs.Length(); ++index) {
+    nsHostObjectProtocolHandler::Traverse(mHostObjectURIs[index], aCb);
+  }
+}
--- a/dom/base/nsIGlobalObject.h
+++ b/dom/base/nsIGlobalObject.h
@@ -3,22 +3,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIGlobalObject_h__
 #define nsIGlobalObject_h__
 
 #include "nsISupports.h"
+#include "nsTArray.h"
 #include "js/TypeDecls.h"
 
 #define NS_IGLOBALOBJECT_IID \
-{ 0xe2538ded, 0x13ef, 0x4f4d, \
-{ 0x94, 0x6b, 0x65, 0xd3, 0x33, 0xb4, 0xf0, 0x3c } }
+{ 0x11afa8be, 0xd997, 0x4e07, \
+{ 0xa6, 0xa3, 0x6f, 0x87, 0x2e, 0xc3, 0xee, 0x7f } }
 
+class nsACString;
+class nsCString;
+class nsCycleCollectionTraversalCallback;
 class nsIPrincipal;
 
 class nsIGlobalObject : public nsISupports
 {
   bool mIsDying;
 
 protected:
   nsIGlobalObject()
@@ -48,16 +52,31 @@ public:
     return mIsDying;
   }
 
   virtual JSObject* GetGlobalJSObject() = 0;
 
   // This method is not meant to be overridden.
   nsIPrincipal* PrincipalOrNull();
 
+  void RegisterHostObjectURI(const nsACString& aURI);
+
+  void UnregisterHostObjectURI(const nsACString& aURI);
+
+  // Any CC class inheriting nsIGlobalObject should call these 2 methods if it
+  // exposes the URL API.
+  void UnlinkHostObjectURIs();
+  void TraverseHostObjectURIs(nsCycleCollectionTraversalCallback &aCb);
+
+protected:
+  virtual ~nsIGlobalObject();
+
+private:
+  nsTArray<nsCString> mHostObjectURIs;
+
 protected:
   void
   StartDying()
   {
     mIsDying = true;
   }
 };
 
--- a/dom/base/nsIScriptGlobalObject.h
+++ b/dom/base/nsIScriptGlobalObject.h
@@ -73,14 +73,17 @@ public:
   virtual nsresult HandleScriptError(
                      const mozilla::dom::ErrorEventInit &aErrorEventInit,
                      nsEventStatus *aEventStatus) {
     NS_ENSURE_STATE(NS_HandleScriptError(this, aErrorEventInit, aEventStatus));
     return NS_OK;
   }
 
   virtual bool IsBlackForCC(bool aTracingNeeded = true) { return false; }
+
+protected:
+  virtual ~nsIScriptGlobalObject() {}
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptGlobalObject,
                               NS_ISCRIPTGLOBALOBJECT_IID)
 
 #endif
--- a/dom/base/nsInProcessTabChildGlobal.cpp
+++ b/dom/base/nsInProcessTabChildGlobal.cpp
@@ -141,30 +141,32 @@ nsInProcessTabChildGlobal::Init()
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
 
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
                                                   DOMEventTargetHelper)
    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
+   tmp->TraverseHostObjectURIs(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
                                                DOMEventTargetHelper)
   for (uint32_t i = 0; i < tmp->mAnonymousGlobalScopes.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAnonymousGlobalScopes[i])
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
                                                 DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnonymousGlobalScopes)
+   tmp->UnlinkHostObjectURIs();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
--- a/dom/base/test/chrome.ini
+++ b/dom/base/test/chrome.ini
@@ -21,8 +21,9 @@ support-files =
 [test_copypaste.xul]
 [test_messagemanager_principal.html]
 [test_messagemanager_send_principal.html]
 skip-if = buildapp == 'mulet'
 [test_bug945152.html]
 run-if = os == 'linux'
 [test_bug1008126.html]
 run-if = os == 'linux'
+[test_sandboxed_blob_uri.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_sandboxed_blob_uri.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for Principal in MessageManager</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+</head>
+<body>
+
+  <script type="application/javascript;version=1.7">
+    "use strict";
+
+    const Cu = Components.utils;
+
+    var sb = new Cu.Sandbox('https://example.com', { wantGlobalProperties: [ 'Blob', 'URL' ] });
+    Cu.evalInSandbox('var u = URL.createObjectURL(new Blob(["text"], { type: "text/plain" }));', sb);
+    Cu.nukeSandbox(sb);
+    Cu.forceCC();
+
+    ok(true, "are we leaking blobs?");
+
+  </script>
+</body>
+</html>
--- a/dom/base/test/test_url.html
+++ b/dom/base/test/test_url.html
@@ -330,10 +330,23 @@
   <script>
     var blob = new Blob(['a']);
     var url = URL.createObjectURL(blob);
 
     var a = document.createElement('A');
     a.href = url;
     ok(a.origin, 'http://mochi.test:8888', "The 'a' element has the correct origin");
   </script>
+
+  <script>
+    var blob = new Blob(['a']);
+    var url = URL.createObjectURL(blob);
+    URL.revokeObjectURL(url);
+    URL.revokeObjectURL(url);
+    ok(true, "Calling revokeObjectURL twice should be ok");
+  </script>
+
+  <script>
+    URL.revokeObjectURL('blob:something');
+    ok(true, "This should not throw.");
+  </script>
 </body>
 </html>
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -305,16 +305,20 @@ DOMInterfaces = {
 'CSS': {
     'concrete': False,
 },
 
 'CSS2Properties': {
     'nativeType': 'nsDOMCSSDeclaration'
 },
 
+'CSSLexer': {
+    'wrapperCache': False
+},
+
 'CSSPrimitiveValue': {
     'nativeType': 'nsROCSSPrimitiveValue',
 },
 
 'CSSStyleDeclaration': {
     'nativeType': 'nsICSSDeclaration'
 },
 
--- a/dom/cache/Action.h
+++ b/dom/cache/Action.h
@@ -6,16 +6,18 @@
 
 #ifndef mozilla_dom_cache_Action_h
 #define mozilla_dom_cache_Action_h
 
 #include "mozilla/Atomics.h"
 #include "mozilla/dom/cache/Types.h"
 #include "nsISupportsImpl.h"
 
+class mozIStorageConnection;
+
 namespace mozilla {
 namespace dom {
 namespace cache {
 
 class Action
 {
 public:
   class Resolver
@@ -28,22 +30,37 @@ public:
 
     NS_IMETHOD_(MozExternalRefCountType)
     AddRef(void) = 0;
 
     NS_IMETHOD_(MozExternalRefCountType)
     Release(void) = 0;
   };
 
+  // Class containing data that can be opportunistically shared between
+  // multiple Actions running on the same thread/Context.  In theory
+  // this could be abstracted to a generic key/value map, but for now
+  // just explicitly provide accessors for the data we need.
+  class Data
+  {
+  public:
+    virtual mozIStorageConnection*
+    GetConnection() const = 0;
+
+    virtual void
+    SetConnection(mozIStorageConnection* aConn) = 0;
+  };
+
   // Execute operations on the target thread.  Once complete call
   // Resolver::Resolve().  This can be done sync or async.
   // Note: Action should hold Resolver ref until its ready to call Resolve().
   // Note: The "target" thread is determined when the Action is scheduled on
   //       Context.  The Action should not assume any particular thread is used.
-  virtual void RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo) = 0;
+  virtual void RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo,
+                           Data* aOptionalData) = 0;
 
   // Called on initiating thread when the Action is canceled.  The Action is
   // responsible for calling Resolver::Resolve() as normal; either with a
   // normal error code or NS_ERROR_ABORT.  If CancelOnInitiatingThread() is
   // called after Resolve() has already occurred, then the cancel can be
   // ignored.
   //
   // Cancellation is a best effort to stop processing as soon as possible, but
--- a/dom/cache/Context.cpp
+++ b/dom/cache/Context.cpp
@@ -9,24 +9,26 @@
 #include "mozilla/AutoRestore.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/cache/Action.h"
 #include "mozilla/dom/cache/Manager.h"
 #include "mozilla/dom/cache/ManagerId.h"
 #include "mozilla/dom/cache/OfflineStorage.h"
 #include "mozilla/dom/quota/OriginOrPatternString.h"
 #include "mozilla/dom/quota/QuotaManager.h"
+#include "mozIStorageConnection.h"
 #include "nsIFile.h"
 #include "nsIPrincipal.h"
 #include "nsIRunnable.h"
 #include "nsThreadUtils.h"
 
 namespace {
 
 using mozilla::dom::Nullable;
+using mozilla::dom::cache::Action;
 using mozilla::dom::cache::QuotaInfo;
 using mozilla::dom::quota::Client;
 using mozilla::dom::quota::OriginOrPatternString;
 using mozilla::dom::quota::QuotaManager;
 using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
 using mozilla::dom::quota::PersistenceType;
 
 // Release our lock on the QuotaManager directory asynchronously.
@@ -49,28 +51,83 @@ public:
   }
 
 private:
   ~QuotaReleaseRunnable() { }
 
   const QuotaInfo mQuotaInfo;
 };
 
+class NullAction final : public Action
+{
+public:
+  NullAction()
+  {
+  }
+
+  virtual void
+  RunOnTarget(Resolver* aResolver, const QuotaInfo&, Data*) override
+  {
+    // Resolve success immediately.  This Action does no actual work.
+    MOZ_ASSERT(aResolver);
+    aResolver->Resolve(NS_OK);
+  }
+};
+
 } // anonymous namespace
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
 using mozilla::DebugOnly;
 using mozilla::dom::quota::OriginOrPatternString;
 using mozilla::dom::quota::QuotaManager;
 using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
 using mozilla::dom::quota::PersistenceType;
 
+class Context::Data final : public Action::Data
+{
+public:
+  explicit Data(nsIThread* aTarget)
+    : mTarget(aTarget)
+  {
+    MOZ_ASSERT(mTarget);
+  }
+
+  virtual mozIStorageConnection*
+  GetConnection() const
+  {
+    MOZ_ASSERT(mTarget == NS_GetCurrentThread());
+    return mConnection;
+  }
+
+  virtual void
+  SetConnection(mozIStorageConnection* aConn) override
+  {
+    MOZ_ASSERT(mTarget == NS_GetCurrentThread());
+    MOZ_ASSERT(!mConnection);
+    mConnection = aConn;
+    MOZ_ASSERT(mConnection);
+  }
+
+private:
+  ~Data()
+  {
+    if (mConnection) {
+      NS_ProxyRelease(mTarget, mConnection);
+    }
+  }
+
+  nsCOMPtr<nsIThread> mTarget;
+  nsCOMPtr<mozIStorageConnection> mConnection;
+
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Context::Data)
+};
+
 // Executed to perform the complicated dance of steps necessary to initialize
 // the QuotaManager.  This must be performed for each origin before any disk
 // IO occurrs.
 class Context::QuotaInitRunnable final : public nsIRunnable
 {
 public:
   QuotaInitRunnable(Context* aContext,
                     Manager* aManager,
@@ -331,17 +388,17 @@ Context::QuotaInitRunnable::Run()
 
       if (!mQuotaIOThreadAction) {
         resolver->Resolve(NS_OK);
         break;
       }
 
       // Execute the provided initialization Action.  The Action must Resolve()
       // before returning.
-      mQuotaIOThreadAction->RunOnTarget(resolver, mQuotaInfo);
+      mQuotaIOThreadAction->RunOnTarget(resolver, mQuotaInfo, nullptr);
       MOZ_ASSERT(resolver->Resolved());
 
       break;
     }
     // -------------------
     case STATE_COMPLETING:
     {
       NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
@@ -386,28 +443,30 @@ Context::QuotaInitRunnable::Run()
 // Runnable wrapper around Action objects dispatched on the Context.  This
 // runnable executes the Action on the appropriate threads while the Context
 // is initialized.
 class Context::ActionRunnable final : public nsIRunnable
                                     , public Action::Resolver
                                     , public Context::Activity
 {
 public:
-  ActionRunnable(Context* aContext, nsIEventTarget* aTarget, Action* aAction,
-                 const QuotaInfo& aQuotaInfo)
+  ActionRunnable(Context* aContext, Data* aData, nsIEventTarget* aTarget,
+                 Action* aAction, const QuotaInfo& aQuotaInfo)
     : mContext(aContext)
+    , mData(aData)
     , mTarget(aTarget)
     , mAction(aAction)
     , mQuotaInfo(aQuotaInfo)
     , mInitiatingThread(NS_GetCurrentThread())
     , mState(STATE_INIT)
     , mResult(NS_OK)
     , mExecutingRunOnTarget(false)
   {
     MOZ_ASSERT(mContext);
+    // mData may be nullptr
     MOZ_ASSERT(mTarget);
     MOZ_ASSERT(mAction);
     MOZ_ASSERT(mQuotaInfo.mDir);
     MOZ_ASSERT(mInitiatingThread);
   }
 
   nsresult Dispatch()
   {
@@ -487,16 +546,17 @@ private:
     STATE_RUN_ON_TARGET,
     STATE_RUNNING,
     STATE_RESOLVING,
     STATE_COMPLETING,
     STATE_COMPLETE
   };
 
   nsRefPtr<Context> mContext;
+  nsRefPtr<Data> mData;
   nsCOMPtr<nsIEventTarget> mTarget;
   nsRefPtr<Action> mAction;
   const QuotaInfo mQuotaInfo;
   nsCOMPtr<nsIThread> mInitiatingThread;
   State mState;
   nsresult mResult;
 
   // Only accessible on target thread;
@@ -553,17 +613,19 @@ Context::ActionRunnable::Run()
       MOZ_ASSERT(!mExecutingRunOnTarget);
 
       // Note that we are calling RunOnTarget().  This lets us detect
       // if Resolve() is called synchronously.
       AutoRestore<bool> executingRunOnTarget(mExecutingRunOnTarget);
       mExecutingRunOnTarget = true;
 
       mState = STATE_RUNNING;
-      mAction->RunOnTarget(this, mQuotaInfo);
+      mAction->RunOnTarget(this, mQuotaInfo, mData);
+
+      mData = nullptr;
 
       // Resolve was called synchronously from RunOnTarget().  We can
       // immediately move to completing now since we are sure RunOnTarget()
       // completed.
       if (mState == STATE_RESOLVING) {
         // Use recursion instead of switch case fall-through...  Seems slightly
         // easier to understand.
         Run();
@@ -662,20 +724,32 @@ Context::ThreadsafeHandle::~ThreadsafeHa
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
     mOwningThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL)));
 }
 
 void
 Context::ThreadsafeHandle::AllowToCloseOnOwningThread()
 {
   MOZ_ASSERT(mOwningThread == NS_GetCurrentThread());
+
   // A Context "closes" when its ref count drops to zero.  Dropping this
   // strong ref is necessary, but not sufficient for the close to occur.
   // Any outstanding IO will continue and keep the Context alive.  Once
   // the Context is idle, it will be destroyed.
+
+  // First, tell the context to flush any target thread shared data.  This
+  // data must be released on the target thread prior to running the Context
+  // destructor.  This will schedule an Action which ensures that the
+  // ~Context() is not immediately executed when we drop the strong ref.
+  if (mStrongRef) {
+    mStrongRef->DoomTargetData();
+  }
+
+  // Now drop our strong ref and let Context finish running any outstanding
+  // Actions.
   mStrongRef = nullptr;
 }
 
 void
 Context::ThreadsafeHandle::InvalidateAndAllowToCloseOnOwningThread()
 {
   MOZ_ASSERT(mOwningThread == NS_GetCurrentThread());
   // Cancel the Context through the weak reference.  This means we can
@@ -696,61 +770,62 @@ Context::ThreadsafeHandle::ContextDestro
   MOZ_ASSERT(!mStrongRef);
   MOZ_ASSERT(mWeakRef);
   MOZ_ASSERT(mWeakRef == aContext);
   mWeakRef = nullptr;
 }
 
 // static
 already_AddRefed<Context>
-Context::Create(Manager* aManager, Action* aQuotaIOThreadAction,
-                Context* aOldContext)
+Context::Create(Manager* aManager, nsIThread* aTarget,
+                Action* aQuotaIOThreadAction, Context* aOldContext)
 {
-  nsRefPtr<Context> context = new Context(aManager);
+  nsRefPtr<Context> context = new Context(aManager, aTarget);
 
   // Do this here to avoid doing an AddRef() in the constructor
+  // TODO: pass context->mData to allow connetion sharing with init
   context->mInitRunnable = new QuotaInitRunnable(context, aManager,
                                                  aQuotaIOThreadAction);
 
   if (aOldContext) {
     aOldContext->SetNextContext(context);
   } else {
     context->Start();
   }
 
   return context.forget();
 }
 
-Context::Context(Manager* aManager)
+Context::Context(Manager* aManager, nsIThread* aTarget)
   : mManager(aManager)
+  , mTarget(aTarget)
+  , mData(new Data(aTarget))
   , mState(STATE_CONTEXT_PREINIT)
 {
   MOZ_ASSERT(mManager);
 }
 
 void
-Context::Dispatch(nsIEventTarget* aTarget, Action* aAction)
+Context::Dispatch(Action* aAction)
 {
   NS_ASSERT_OWNINGTHREAD(Context);
-  MOZ_ASSERT(aTarget);
   MOZ_ASSERT(aAction);
 
   MOZ_ASSERT(mState != STATE_CONTEXT_CANCELED);
   if (mState == STATE_CONTEXT_CANCELED) {
     return;
   } else if (mState == STATE_CONTEXT_INIT ||
              mState == STATE_CONTEXT_PREINIT) {
     PendingAction* pending = mPendingActions.AppendElement();
-    pending->mTarget = aTarget;
     pending->mAction = aAction;
     return;
   }
 
   MOZ_ASSERT(STATE_CONTEXT_READY);
-  DispatchAction(aTarget, aAction);
+  DispatchAction(aAction);
 }
 
 void
 Context::CancelAll()
 {
   NS_ASSERT_OWNINGTHREAD(Context);
 
   // In PREINIT state we have not dispatch the init runnable yet.  Just
@@ -858,22 +933,27 @@ Context::Start()
     // Shutdown must be delayed until all Contexts are destroyed.  Shutdown
     // must also prevent any new Contexts from being constructed.  Crash
     // for this invariant violation.
     MOZ_CRASH("Failed to dispatch QuotaInitRunnable.");
   }
 }
 
 void
-Context::DispatchAction(nsIEventTarget* aTarget, Action* aAction)
+Context::DispatchAction(Action* aAction, bool aDoomData)
 {
   NS_ASSERT_OWNINGTHREAD(Context);
 
   nsRefPtr<ActionRunnable> runnable =
-    new ActionRunnable(this, aTarget, aAction, mQuotaInfo);
+    new ActionRunnable(this, mData, mTarget, aAction, mQuotaInfo);
+
+  if (aDoomData) {
+    mData = nullptr;
+  }
+
   nsresult rv = runnable->Dispatch();
   if (NS_FAILED(rv)) {
     // Shutdown must be delayed until all Contexts are destroyed.  Crash
     // for this invariant violation.
     MOZ_CRASH("Failed to dispatch ActionRunnable to target thread.");
   }
   AddActivity(runnable);
 }
@@ -903,17 +983,17 @@ Context::OnQuotaInit(nsresult aRv, const
     // Context will destruct after return here and last ref is released.
     return;
   }
 
   MOZ_ASSERT(mState == STATE_CONTEXT_INIT);
   mState = STATE_CONTEXT_READY;
 
   for (uint32_t i = 0; i < mPendingActions.Length(); ++i) {
-    DispatchAction(mPendingActions[i].mTarget, mPendingActions[i].mAction);
+    DispatchAction(mPendingActions[i].mAction);
   }
   mPendingActions.Clear();
 }
 
 void
 Context::AddActivity(Activity* aActivity)
 {
   NS_ASSERT_OWNINGTHREAD(Context);
@@ -946,11 +1026,31 @@ void
 Context::SetNextContext(Context* aNextContext)
 {
   NS_ASSERT_OWNINGTHREAD(Context);
   MOZ_ASSERT(aNextContext);
   MOZ_ASSERT(!mNextContext);
   mNextContext = aNextContext;
 }
 
+void
+Context::DoomTargetData()
+{
+  NS_ASSERT_OWNINGTHREAD(Context);
+  MOZ_ASSERT(mData);
+
+  // We are about to drop our reference to the Data.  We need to ensure that
+  // the ~Context() destructor does not run until contents of Data have been
+  // released on the Target thread.
+
+  // Dispatch a no-op Action.  This will hold the Context alive through a
+  // roundtrip to the target thread and back to the owning thread.  The
+  // ref to the Data object is cleared on the owning thread after creating
+  // the ActionRunnable, but before dispatching it.
+  nsRefPtr<Action> action = new NullAction();
+  DispatchAction(action, true /* doomed data */);
+
+  MOZ_ASSERT(!mData);
+}
+
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
--- a/dom/cache/Context.h
+++ b/dom/cache/Context.h
@@ -106,23 +106,24 @@ public:
     virtual void Cancel() = 0;
     virtual bool MatchesCacheId(CacheId aCacheId) const = 0;
   };
 
   // Create a Context attached to the given Manager.  The given Action
   // will run on the QuotaManager IO thread.  Note, this Action must
   // be execute synchronously.
   static already_AddRefed<Context>
-  Create(Manager* aManager, Action* aQuotaIOThreadAction, Context* aOldContext);
+  Create(Manager* aManager, nsIThread* aTarget,
+         Action* aQuotaIOThreadAction, Context* aOldContext);
 
   // Execute given action on the target once the quota manager has been
   // initialized.
   //
   // Only callable from the thread that created the Context.
-  void Dispatch(nsIEventTarget* aTarget, Action* aAction);
+  void Dispatch(Action* aAction);
 
   // Cancel any Actions running or waiting to run.  This should allow the
   // Context to be released and Listener::RemoveContext() will be called
   // when complete.
   //
   // Only callable from the thread that created the Context.
   void CancelAll();
 
@@ -147,16 +148,17 @@ public:
 
   const QuotaInfo&
   GetQuotaInfo() const
   {
     return mQuotaInfo;
   }
 
 private:
+  class Data;
   class QuotaInitRunnable;
   class ActionRunnable;
 
   enum State
   {
     STATE_CONTEXT_PREINIT,
     STATE_CONTEXT_INIT,
     STATE_CONTEXT_READY,
@@ -164,30 +166,35 @@ private:
   };
 
   struct PendingAction
   {
     nsCOMPtr<nsIEventTarget> mTarget;
     nsRefPtr<Action> mAction;
   };
 
-  explicit Context(Manager* aManager);
+  Context(Manager* aManager, nsIThread* aTarget);
   ~Context();
   void Start();
-  void DispatchAction(nsIEventTarget* aTarget, Action* aAction);
+  void DispatchAction(Action* aAction, bool aDoomData = false);
   void OnQuotaInit(nsresult aRv, const QuotaInfo& aQuotaInfo,
                    nsMainThreadPtrHandle<OfflineStorage>& aOfflineStorage);
 
   already_AddRefed<ThreadsafeHandle>
   CreateThreadsafeHandle();
 
   void
   SetNextContext(Context* aNextContext);
 
+  void
+  DoomTargetData();
+
   nsRefPtr<Manager> mManager;
+  nsCOMPtr<nsIThread> mTarget;
+  nsRefPtr<Data> mData;
   State mState;
   QuotaInfo mQuotaInfo;
   nsRefPtr<QuotaInitRunnable> mInitRunnable;
   nsTArray<PendingAction> mPendingActions;
 
   // Weak refs since activites must remove themselves from this list before
   // being destroyed by calling RemoveActivity().
   typedef nsTObserverArray<Activity*> ActivityList;
--- a/dom/cache/DBAction.cpp
+++ b/dom/cache/DBAction.cpp
@@ -30,17 +30,18 @@ DBAction::DBAction(Mode aMode)
 {
 }
 
 DBAction::~DBAction()
 {
 }
 
 void
-DBAction::RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo)
+DBAction::RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo,
+                      Data* aOptionalData)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aResolver);
   MOZ_ASSERT(aQuotaInfo.mDir);
 
   if (IsCanceled()) {
     aResolver->Resolve(NS_ERROR_ABORT);
     return;
@@ -48,29 +49,44 @@ DBAction::RunOnTarget(Resolver* aResolve
 
   nsCOMPtr<nsIFile> dbDir;
   nsresult rv = aQuotaInfo.mDir->Clone(getter_AddRefs(dbDir));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aResolver->Resolve(rv);
     return;
   }
 
-  rv = dbDir->Append(NS_LITERAL_STRING("cache"));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aResolver->Resolve(rv);
-    return;
+  nsCOMPtr<mozIStorageConnection> conn;
+
+  // Attempt to reuse the connection opened by a previous Action.
+  if (aOptionalData) {
+    conn = aOptionalData->GetConnection();
   }
 
-  nsCOMPtr<mozIStorageConnection> conn;
-  rv = OpenConnection(aQuotaInfo, dbDir, getter_AddRefs(conn));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aResolver->Resolve(rv);
-    return;
+  // If there is no previous Action, then we must open one.
+  if (!conn) {
+    rv = dbDir->Append(NS_LITERAL_STRING("cache"));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      aResolver->Resolve(rv);
+      return;
+    }
+
+    rv = OpenConnection(aQuotaInfo, dbDir, getter_AddRefs(conn));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      aResolver->Resolve(rv);
+      return;
+    }
+    MOZ_ASSERT(conn);
+
+    // Save this connection in the shared Data object so later Actions can
+    // use it.  This avoids opening a new connection for every Action.
+    if (aOptionalData) {
+      aOptionalData->SetConnection(conn);
+    }
   }
-  MOZ_ASSERT(conn);
 
   RunWithDBOnTarget(aResolver, aQuotaInfo, dbDir, conn);
 }
 
 nsresult
 DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
                          mozIStorageConnection** aConnOut)
 {
@@ -116,17 +132,18 @@ DBAction::OpenConnection(const QuotaInfo
   if (NS_WARN_IF(!dbFileUrl)) { return NS_ERROR_UNEXPECTED; }
 
   nsAutoCString type;
   PersistenceTypeToText(PERSISTENCE_TYPE_DEFAULT, type);
 
   rv = dbFileUrl->SetQuery(
     NS_LITERAL_CSTRING("persistenceType=") + type +
     NS_LITERAL_CSTRING("&group=") + aQuotaInfo.mGroup +
-    NS_LITERAL_CSTRING("&origin=") + aQuotaInfo.mOrigin);
+    NS_LITERAL_CSTRING("&origin=") + aQuotaInfo.mOrigin +
+    NS_LITERAL_CSTRING("&cache=private"));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   nsCOMPtr<mozIStorageService> ss =
     do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
   if (NS_WARN_IF(!ss)) { return NS_ERROR_UNEXPECTED; }
 
   rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
   if (rv == NS_ERROR_FILE_CORRUPTED) {
--- a/dom/cache/DBAction.h
+++ b/dom/cache/DBAction.h
@@ -38,17 +38,18 @@ protected:
   // ref the DB connection.  The connection can only be referenced from the
   // target thread and must be released upon resolve.
   virtual void
   RunWithDBOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo,
                     nsIFile* aDBDir, mozIStorageConnection* aConn) = 0;
 
 private:
   virtual void
-  RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo) override;
+  RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo,
+              Data* aOptionalData) override;
 
   nsresult OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aQuotaDir,
                           mozIStorageConnection** aConnOut);
 
   nsresult WipeDatabase(nsIFile* aDBFile, nsIFile* aDBDir);
 
   const Mode mMode;
 };
--- a/dom/cache/Manager.cpp
+++ b/dom/cache/Manager.cpp
@@ -88,17 +88,17 @@ public:
   { }
 
   explicit DeleteOrphanedBodyAction(const nsID& aBodyId)
   {
     mDeletedBodyIdList.AppendElement(aBodyId);
   }
 
   virtual void
-  RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo) override
+  RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo, Data*) override
   {
     MOZ_ASSERT(aResolver);
     MOZ_ASSERT(aQuotaInfo.mDir);
 
     // Note that since DeleteOrphanedBodyAction isn't used while the context is
     // being initialized, we don't need to check for cancellation here.
 
     nsCOMPtr<nsIFile> dbDir;
@@ -1326,17 +1326,17 @@ public:
         // no outstanding references, delete immediately
         nsRefPtr<Context> context = mManager->mContext;
 
         // TODO: note that we need to check this cache for staleness on startup (bug 1110446)
         if (!context->IsCanceled()) {
           context->CancelForCacheId(mCacheId);
           nsRefPtr<Action> action =
             new DeleteOrphanedCacheAction(mManager, mCacheId);
-          context->Dispatch(mManager->mIOThread, action);
+          context->Dispatch(action);
         }
       }
     }
 
     aListener->OnOpComplete(Move(aRv), StorageDeleteResult(mCacheDeleted));
   }
 
 private:
@@ -1535,17 +1535,17 @@ Manager::ReleaseCacheId(CacheId aCacheId
         bool orphaned = mCacheIdRefs[i].mOrphaned;
         mCacheIdRefs.RemoveElementAt(i);
         // TODO: note that we need to check this cache for staleness on startup (bug 1110446)
         nsRefPtr<Context> context = mContext;
         if (orphaned && context && !context->IsCanceled()) {
           context->CancelForCacheId(aCacheId);
           nsRefPtr<Action> action = new DeleteOrphanedCacheAction(this,
                                                                   aCacheId);
-          context->Dispatch(mIOThread, action);
+          context->Dispatch(action);
         }
       }
       MaybeAllowContextToClose();
       return;
     }
   }
   MOZ_ASSERT_UNREACHABLE("Attempt to release CacheId that is not referenced!");
 }
@@ -1577,17 +1577,17 @@ Manager::ReleaseBodyId(const nsID& aBody
       MOZ_ASSERT(mBodyIdRefs[i].mCount < oldRef);
       if (mBodyIdRefs[i].mCount < 1) {
         bool orphaned = mBodyIdRefs[i].mOrphaned;
         mBodyIdRefs.RemoveElementAt(i);
         // TODO: note that we need to check this body for staleness on startup (bug 1110446)
         nsRefPtr<Context> context = mContext;
         if (orphaned && context && !context->IsCanceled()) {
           nsRefPtr<Action> action = new DeleteOrphanedBodyAction(aBodyId);
-          context->Dispatch(mIOThread, action);
+          context->Dispatch(action);
         }
       }
       MaybeAllowContextToClose();
       return;
     }
   }
   MOZ_ASSERT_UNREACHABLE("Attempt to release BodyId that is not referenced!");
 }
@@ -1652,17 +1652,17 @@ Manager::ExecuteCacheOp(Listener* aListe
     case CacheOpArgs::TCacheKeysArgs:
       action = new CacheKeysAction(this, listenerId, aCacheId,
                                    aOpArgs.get_CacheKeysArgs(), streamList);
       break;
     default:
       MOZ_CRASH("Unknown Cache operation!");
   }
 
-  context->Dispatch(mIOThread, action);
+  context->Dispatch(action);
 }
 
 void
 Manager::ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
                           const CacheOpArgs& aOpArgs)
 {
   NS_ASSERT_OWNINGTHREAD(Manager);
   MOZ_ASSERT(aListener);
@@ -1699,17 +1699,17 @@ Manager::ExecuteStorageOp(Listener* aLis
       break;
     case CacheOpArgs::TStorageKeysArgs:
       action = new StorageKeysAction(this, listenerId, aNamespace);
       break;
     default:
       MOZ_CRASH("Unknown CacheStorage operation!");
   }
 
-  context->Dispatch(mIOThread, action);
+  context->Dispatch(action);
 }
 
 void
 Manager::ExecutePutAll(Listener* aListener, CacheId aCacheId,
                        const nsTArray<CacheRequestResponse>& aPutList,
                        const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
                        const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList)
 {
@@ -1725,17 +1725,17 @@ Manager::ExecutePutAll(Listener* aListen
   MOZ_ASSERT(!context->IsCanceled());
 
   ListenerId listenerId = SaveListener(aListener);
 
   nsRefPtr<Action> action = new CachePutAllAction(this, listenerId, aCacheId,
                                                   aPutList, aRequestStreamList,
                                                   aResponseStreamList);
 
-  context->Dispatch(mIOThread, action);
+  context->Dispatch(action);
 }
 
 Manager::Manager(ManagerId* aManagerId, nsIThread* aIOThread)
   : mManagerId(aManagerId)
   , mIOThread(aIOThread)
   , mContext(nullptr)
   , mShuttingDown(false)
   , mState(Open)
@@ -1769,17 +1769,18 @@ Manager::Init(Manager* aOldManager)
   if (aOldManager) {
     oldContext = aOldManager->mContext;
   }
 
   // Create the context immediately.  Since there can at most be one Context
   // per Manager now, this lets us cleanly call Factory::Remove() once the
   // Context goes away.
   nsRefPtr<Action> setupAction = new SetupAction();
-  nsRefPtr<Context> ref = Context::Create(this, setupAction, oldContext);
+  nsRefPtr<Context> ref = Context::Create(this, mIOThread, setupAction,
+                                          oldContext);
   mContext = ref;
 }
 
 void
 Manager::Shutdown()
 {
   NS_ASSERT_OWNINGTHREAD(Manager);
 
@@ -1887,17 +1888,17 @@ Manager::NoteOrphanedBodyIdList(const ns
       deleteNowList.AppendElement(aDeletedBodyIdList[i]);
     }
   }
 
   // TODO: note that we need to check these bodies for staleness on startup (bug 1110446)
   nsRefPtr<Context> context = mContext;
   if (!deleteNowList.IsEmpty() && context && !context->IsCanceled()) {
     nsRefPtr<Action> action = new DeleteOrphanedBodyAction(deleteNowList);
-    context->Dispatch(mIOThread, action);
+    context->Dispatch(action);
   }
 }
 
 void
 Manager::MaybeAllowContextToClose()
 {
   NS_ASSERT_OWNINGTHREAD(Manager);
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3221,18 +3221,31 @@ void
 TabChildGlobal::Init()
 {
   NS_ASSERTION(!mMessageManager, "Re-initializing?!?");
   mMessageManager = new nsFrameMessageManager(mTabChild,
                                               nullptr,
                                               MM_CHILD);
 }
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(TabChildGlobal, DOMEventTargetHelper,
-                                   mMessageManager, mTabChild)
+NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildGlobal)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
+                                                DOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild);
+  tmp->UnlinkHostObjectURIs();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
+                                                  DOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChild)
+  tmp->TraverseHostObjectURIs(cb);
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
--- a/dom/media/Intervals.h
+++ b/dom/media/Intervals.h
@@ -190,17 +190,17 @@ public:
   typedef IntervalSet<T> SelfType;
   typedef Interval<T> ElemType;
   typedef nsAutoTArray<ElemType,4> ContainerType;
   typedef typename ContainerType::index_type IndexType;
 
   IntervalSet()
   {
   }
-  ~IntervalSet()
+  virtual ~IntervalSet()
   {
   }
 
   IntervalSet(const SelfType& aOther)
     : mIntervals(aOther.mIntervals)
   {
   }
 
--- a/dom/media/MediaRecorder.cpp
+++ b/dom/media/MediaRecorder.cpp
@@ -363,21 +363,22 @@ class MediaRecorder::Session: public nsI
   friend class EncoderErrorNotifierRunnable;
   friend class PushBlobRunnable;
   friend class ExtractRunnable;
   friend class DestroyRunnable;
   friend class TracksAvailableCallback;
 
 public:
   Session(MediaRecorder* aRecorder, int32_t aTimeSlice)
-    : mRecorder(aRecorder),
-      mTimeSlice(aTimeSlice),
-      mStopIssued(false),
-      mCanRetrieveData(false),
-      mIsRegisterProfiler(false)
+    : mRecorder(aRecorder)
+    , mTimeSlice(aTimeSlice)
+    , mStopIssued(false)
+    , mCanRetrieveData(false)
+    , mIsRegisterProfiler(false)
+    , mNeedSessionEndTask(true)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     uint32_t maxMem = Preferences::GetUint("media.recorder.max_memory",
                                            MAX_ALLOW_MEMORY_BUFFER);
     mEncodedBufferCache = new EncodedBufferCache(maxMem);
     mLastBlobTimeStamp = TimeStamp::Now();
   }
@@ -391,16 +392,21 @@ public:
   }
 
   void Stop()
   {
     LOG(PR_LOG_DEBUG, ("Session.Stop %p", this));
     MOZ_ASSERT(NS_IsMainThread());
     mStopIssued = true;
     CleanupStreams();
+    if (mNeedSessionEndTask) {
+      LOG(PR_LOG_DEBUG, ("Session.Stop mNeedSessionEndTask %p", this));
+      // End the Session directly if there is no ExtractRunnable.
+      DoSessionEndTask(NS_OK);
+    }
     nsContentUtils::UnregisterShutdownObserver(this);
   }
 
   nsresult Pause()
   {
     LOG(PR_LOG_DEBUG, ("Session.Pause"));
     MOZ_ASSERT(NS_IsMainThread());
 
@@ -573,56 +579,69 @@ private:
     return perm == nsIPermissionManager::ALLOW_ACTION;
   }
 
   void InitEncoder(uint8_t aTrackTypes)
   {
     LOG(PR_LOG_DEBUG, ("Session.InitEncoder %p", this));
     MOZ_ASSERT(NS_IsMainThread());
 
+    if (!mRecorder) {
+      LOG(PR_LOG_DEBUG, ("Session.InitEncoder failure, mRecorder is null %p", this));
+      return;
+    }
     // Allocate encoder and bind with union stream.
     // At this stage, the API doesn't allow UA to choose the output mimeType format.
 
     // Make sure the application has permission to assign AUDIO_3GPP
     if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP) && Check3gppPermission()) {
       mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP), aTrackTypes);
     } else {
       mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""), aTrackTypes);
     }
 
     if (!mEncoder) {
+      LOG(PR_LOG_DEBUG, ("Session.InitEncoder !mEncoder %p", this));
       DoSessionEndTask(NS_ERROR_ABORT);
       return;
     }
 
     // Media stream is ready but UA issues a stop method follow by start method.
     // The Session::stop would clean the mTrackUnionStream. If the AfterTracksAdded
     // comes after stop command, this function would crash.
     if (!mTrackUnionStream) {
+      LOG(PR_LOG_DEBUG, ("Session.InitEncoder !mTrackUnionStream %p", this));
       DoSessionEndTask(NS_OK);
       return;
     }
     mTrackUnionStream->AddListener(mEncoder);
     // Create a thread to read encode media data from MediaEncoder.
     if (!mReadThread) {
       nsresult rv = NS_NewNamedThread("Media_Encoder", getter_AddRefs(mReadThread));
       if (NS_FAILED(rv)) {
+        LOG(PR_LOG_DEBUG, ("Session.InitEncoder !mReadThread %p", this));
         DoSessionEndTask(rv);
         return;
       }
     }
 
-    // In case source media stream does not notify track end, recieve
+    // In case source media stream does not notify track end, receive
     // shutdown notification and stop Read Thread.
     nsContentUtils::RegisterShutdownObserver(this);
 
     nsCOMPtr<nsIRunnable> event = new ExtractRunnable(this);
     if (NS_FAILED(mReadThread->Dispatch(event, NS_DISPATCH_NORMAL))) {
       NS_WARNING("Failed to dispatch ExtractRunnable at beginning");
+      LOG(PR_LOG_DEBUG, ("Session.InitEncoder !ReadThread->Dispatch %p", this));
+      DoSessionEndTask(NS_ERROR_ABORT);
     }
+    // Set mNeedSessionEndTask to false because the
+    // ExtractRunnable/DestroyRunnable will take the response to
+    // end the session.
+    mNeedSessionEndTask = false;
   }
   // application should get blob and onstop event
   void DoSessionEndTask(nsresult rv)
   {
     MOZ_ASSERT(NS_IsMainThread());
     if (NS_FAILED(rv)) {
       nsCOMPtr<nsIRunnable> runnable =
         NS_NewRunnableMethodWithArg<nsresult>(mRecorder,
@@ -635,16 +654,17 @@ private:
       MOZ_ASSERT(false, "NS_DispatchToMainThread EncoderErrorNotifierRunnable failed");
     }
     if (NS_FAILED(NS_DispatchToMainThread(new PushBlobRunnable(this)))) {
       MOZ_ASSERT(false, "NS_DispatchToMainThread PushBlobRunnable failed");
     }
     if (NS_FAILED(NS_DispatchToMainThread(new DestroyRunnable(this)))) {
       MOZ_ASSERT(false, "NS_DispatchToMainThread DestroyRunnable failed");
     }
+    mNeedSessionEndTask = false;
   }
   void CleanupStreams()
   {
     if (mInputPort.get()) {
       mInputPort->Destroy();
       mInputPort = nullptr;
     }
 
@@ -708,16 +728,20 @@ private:
   // by calling requestData API.
   const int32_t mTimeSlice;
   // Indicate this session's stop has been called.
   bool mStopIssued;
   // Indicate session has encoded data. This can be changed in recording thread.
   bool mCanRetrieveData;
   // The register flag for "Media_Encoder" thread to profiler
   bool mIsRegisterProfiler;
+  // False if the InitEncoder called successfully, ensure the
+  // ExtractRunnable/DestroyRunnable will end the session.
+  // Main thread only.
+  bool mNeedSessionEndTask;
 };
 
 NS_IMPL_ISUPPORTS(MediaRecorder::Session, nsIObserver)
 
 MediaRecorder::~MediaRecorder()
 {
   if (mPipeStream != nullptr) {
     mInputPort->Destroy();
--- a/dom/media/fmp4/MP4Reader.cpp
+++ b/dom/media/fmp4/MP4Reader.cpp
@@ -581,20 +581,19 @@ void
 MP4Reader::ReadUpdatedMetadata(MediaInfo* aInfo)
 {
   *aInfo = mInfo;
 }
 
 bool
 MP4Reader::IsMediaSeekable()
 {
-  // We can seek if we get a duration *and* the reader reports that it's
-  // seekable.
+  // Check Demuxer to see if this content is seekable or not.
   MonitorAutoLock mon(mDemuxerMonitor);
-  return mDecoder->GetResource()->IsTransportSeekable();
+  return mDemuxer->CanSeek();
 }
 
 bool
 MP4Reader::HasAudio()
 {
   return mAudio.mActive;
 }
 
@@ -1072,17 +1071,17 @@ MP4Reader::SkipVideoDemuxToNextKeyFrame(
 }
 
 nsRefPtr<MediaDecoderReader::SeekPromise>
 MP4Reader::Seek(int64_t aTime, int64_t aEndTime)
 {
   LOG("aTime=(%lld)", aTime);
   MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
   MonitorAutoLock mon(mDemuxerMonitor);
-  if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
+  if (!mDemuxer->CanSeek()) {
     VLOG("Seek() END (Unseekable)");
     return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
   int64_t seekTime = aTime;
   mQueuedVideoSample = nullptr;
   if (mDemuxer->HasValidVideo()) {
     mVideo.mTrackDemuxer->Seek(seekTime);
--- a/dom/media/gmp/GMPStorageParent.cpp
+++ b/dom/media/gmp/GMPStorageParent.cpp
@@ -86,17 +86,17 @@ GetGMPStorageDir(nsIFile** aTempDir, con
 
   tmpFile.forget(aTempDir);
 
   return NS_OK;
 }
 
 enum OpenFileMode  { ReadWrite, Truncate };
 
-nsresult
+static nsresult
 OpenStorageFile(const nsCString& aRecordName,
                 const nsCString& aNodeId,
                 const OpenFileMode aMode,
                 PRFileDesc** aOutFD)
 {
   MOZ_ASSERT(aOutFD);
 
   nsCOMPtr<nsIFile> f;
@@ -112,21 +112,38 @@ OpenStorageFile(const nsCString& aRecord
   auto mode = PR_RDWR | PR_CREATE_FILE;
   if (aMode == Truncate) {
     mode |= PR_TRUNCATE;
   }
 
   return f->OpenNSPRFileDesc(mode, PR_IRWXU, aOutFD);
 }
 
+static nsresult
+RemoveStorageFile(const nsCString& aRecordName,
+                  const nsCString& aNodeId)
+{
+  nsCOMPtr<nsIFile> f;
+  nsresult rv = GetGMPStorageDir(getter_AddRefs(f), aNodeId);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  nsAutoString recordNameHash;
+  recordNameHash.AppendInt(HashString(aRecordName.get()));
+  f->Append(recordNameHash);
+
+  return f->Remove(/* bool recursive= */ false);
+}
+
 PLDHashOperator
 CloseFile(const nsACString& key, PRFileDesc*& entry, void* cx)
 {
   if (PR_Close(entry) != PR_SUCCESS) {
-    NS_WARNING("GMPDiskStorage Failed to clsose file.");
+    NS_WARNING("GMPDiskStorage failed to close file.");
   }
   return PL_DHASH_REMOVE;
 }
 
 class GMPDiskStorage : public GMPStorage {
 public:
   explicit GMPDiskStorage(const nsCString& aNodeId)
     : mNodeId(aNodeId)
@@ -148,16 +165,17 @@ public:
     mFiles.Put(aRecordName, fd);
     return GMPNoErr;
   }
 
   virtual bool IsOpen(const nsCString& aRecordName) override {
     return mFiles.Contains(aRecordName);
   }
 
+  static
   GMPErr ReadRecordMetadata(PRFileDesc* aFd,
                             int32_t& aOutFileLength,
                             int32_t& aOutRecordLength,
                             nsACString& aOutRecordName)
   {
     int32_t fileLength = PR_Seek(aFd, 0, PR_SEEK_END);
     PR_Seek(aFd, 0, PR_SEEK_SET);
 
@@ -252,20 +270,32 @@ public:
   virtual GMPErr Write(const nsCString& aRecordName,
                        const nsTArray<uint8_t>& aBytes) override
   {
     PRFileDesc* fd = mFiles.Get(aRecordName);
     if (!fd) {
       return GMPGenericErr;
     }
 
+    // Write operations overwrite the entire record. So close it now.
+    PR_Close(fd);
+    mFiles.Remove(aRecordName);
+
+    // Writing 0 bytes means removing (deleting) the file.
+    if (aBytes.Length() == 0) {
+      nsresult rv = RemoveStorageFile(aRecordName, mNodeId);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        // Could not delete file -> Continue with trying to erase the contents.
+      } else {
+        return GMPNoErr;
+      }
+    }
+
     // Write operations overwrite the entire record. So re-open the file
     // in truncate mode, to clear its contents.
-    PR_Close(fd);
-    mFiles.Remove(aRecordName);
     if (NS_FAILED(OpenStorageFile(aRecordName, mNodeId, Truncate, &fd))) {
       return GMPGenericErr;
     }
     mFiles.Put(aRecordName, fd);
 
     // Store the length of the record name followed by the record name
     // at the start of the file.
     int32_t bytesWritten = 0;
@@ -353,17 +383,17 @@ public:
 
   virtual void Close(const nsCString& aRecordName) override
   {
     PRFileDesc* fd = mFiles.Get(aRecordName);
     if (fd) {
       if (PR_Close(fd) == PR_SUCCESS) {
         mFiles.Remove(aRecordName);
       } else {
-        NS_WARNING("GMPDiskStorage Failed to clsose file.");
+        NS_WARNING("GMPDiskStorage failed to close file.");
       }
     }
   }
 
 private:
   nsDataHashtable<nsCStringHashKey, PRFileDesc*> mFiles;
   const nsAutoCString mNodeId;
 };
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/AlignedTArray.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef AlignedTArray_h__
+#define AlignedTArray_h__
+
+#include "mozilla/Alignment.h"
+#include "nsTArray.h"
+
+/**
+ * E: element type, must be a POD type.
+ * N: N bytes alignment for the first element, defaults to 32
+  */
+template <typename E, int N, typename Alloc>
+class AlignedTArray_Impl : public nsTArray_Impl<E, Alloc>
+{
+  static_assert((N & (N-1)) == 0, "N must be power of 2");
+  typedef nsTArray_Impl<E, Alloc>                    base_type;
+public:
+  typedef E                                          elem_type;
+  typedef typename base_type::size_type              size_type;
+  typedef typename base_type::index_type             index_type;
+
+  AlignedTArray_Impl() {}
+  explicit AlignedTArray_Impl(size_type capacity) : base_type(capacity+sExtra) {}
+  elem_type* Elements() { return getAligned(base_type::Elements()); }
+  const elem_type* Elements() const { return getAligned(base_type::Elements()); }
+  elem_type& operator[](index_type i) { return Elements()[i];}
+  const elem_type& operator[](index_type i) const { return Elements()[i]; }
+
+  typename Alloc::ResultType SetLength(size_type newLen) {
+    return base_type::SetLength(newLen + sExtra);
+  }
+  size_type Length() const {
+    return base_type::Length() <= sExtra ? 0 : base_type::Length() - sExtra;
+  }
+
+private:
+  AlignedTArray_Impl(const AlignedTArray_Impl& other) = delete;
+  void operator=(const AlignedTArray_Impl& other) = delete;
+
+  static const size_type sPadding = N <= MOZ_ALIGNOF(E) ? 0 : N - MOZ_ALIGNOF(E);
+  static const size_type sExtra = (sPadding + sizeof(E) - 1) / sizeof(E);
+
+  template <typename U>
+  static U* getAligned(U* p)
+  {
+    return reinterpret_cast<U*>(((uintptr_t)p + N - 1) & ~(N-1));
+  }
+};
+
+template <typename E, int N=32>
+class AlignedTArray : public AlignedTArray_Impl<E, N, nsTArrayInfallibleAllocator>
+{
+public:
+  typedef AlignedTArray_Impl<E, N, nsTArrayInfallibleAllocator> base_type;
+  typedef AlignedTArray<E, N>                                   self_type;
+  typedef typename base_type::size_type                         size_type;
+
+  AlignedTArray() {}
+  explicit AlignedTArray(size_type capacity) : base_type(capacity) {}
+private:
+  AlignedTArray(const AlignedTArray& other) = delete;
+  void operator=(const AlignedTArray& other) = delete;
+};
+
+template <typename E, int N=32>
+class AlignedFallibleTArray : public AlignedTArray_Impl<E, N, nsTArrayFallibleAllocator>
+{
+public:
+  typedef AlignedTArray_Impl<E, N, nsTArrayFallibleAllocator> base_type;
+  typedef AlignedFallibleTArray<E, N>                         self_type;
+  typedef typename base_type::size_type                       size_type;
+
+  AlignedFallibleTArray() {}
+  explicit AlignedFallibleTArray(size_type capacity) : base_type(capacity) {}
+private:
+  AlignedFallibleTArray(const AlignedFallibleTArray& other) = delete;
+  void operator=(const AlignedFallibleTArray& other) = delete;
+};
+
+#endif // AlignedTArray_h__
--- a/dom/media/webaudio/AnalyserNode.cpp
+++ b/dom/media/webaudio/AnalyserNode.cpp
@@ -246,27 +246,26 @@ AnalyserNode::GetByteTimeDomainData(cons
     buffer[i] = static_cast<unsigned char>(scaled);
   }
 }
 
 bool
 AnalyserNode::FFTAnalysis()
 {
   float* inputBuffer;
-  bool allocated = false;
+  AlignedFallibleTArray<float> tmpBuffer;
   if (mWriteIndex == 0) {
     inputBuffer = mBuffer.Elements();
   } else {
-    inputBuffer = static_cast<float*>(malloc(FftSize() * sizeof(float)));
-    if (!inputBuffer) {
+    if (!tmpBuffer.SetLength(FftSize())) {
       return false;
     }
+    inputBuffer = tmpBuffer.Elements();
     memcpy(inputBuffer, mBuffer.Elements() + mWriteIndex, sizeof(float) * (FftSize() - mWriteIndex));
     memcpy(inputBuffer + FftSize() - mWriteIndex, mBuffer.Elements(), sizeof(float) * mWriteIndex);
-    allocated = true;
   }
 
   ApplyBlackmanWindow(inputBuffer, FftSize());
 
   mAnalysisBlock.PerformFFT(inputBuffer);
 
   // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor).
   const double magnitudeScale = 1.0 / FftSize();
@@ -274,19 +273,16 @@ AnalyserNode::FFTAnalysis()
   for (uint32_t i = 0; i < mOutputBuffer.Length(); ++i) {
     double scalarMagnitude = NS_hypot(mAnalysisBlock.RealData(i),
                                       mAnalysisBlock.ImagData(i)) *
                              magnitudeScale;
     mOutputBuffer[i] = mSmoothingTimeConstant * mOutputBuffer[i] +
                        (1.0 - mSmoothingTimeConstant) * scalarMagnitude;
   }
 
-  if (allocated) {
-    free(inputBuffer);
-  }
   return true;
 }
 
 void
 AnalyserNode::ApplyBlackmanWindow(float* aBuffer, uint32_t aSize)
 {
   double alpha = 0.16;
   double a0 = 0.5 * (1.0 - alpha);
@@ -300,26 +296,26 @@ AnalyserNode::ApplyBlackmanWindow(float*
   }
 }
 
 bool
 AnalyserNode::AllocateBuffer()
 {
   bool result = true;
   if (mBuffer.Length() != FftSize()) {
-    result = mBuffer.SetLength(FftSize());
-    if (result) {
-      memset(mBuffer.Elements(), 0, sizeof(float) * FftSize());
-      mWriteIndex = 0;
+    if (!mBuffer.SetLength(FftSize())) {
+      return false;
+    }
+    memset(mBuffer.Elements(), 0, sizeof(float) * FftSize());
+    mWriteIndex = 0;
 
-      result = mOutputBuffer.SetLength(FrequencyBinCount());
-      if (result) {
-        memset(mOutputBuffer.Elements(), 0, sizeof(float) * FrequencyBinCount());
-      }
+    if (!mOutputBuffer.SetLength(FrequencyBinCount())) {
+      return false;
     }
+    memset(mOutputBuffer.Elements(), 0, sizeof(float) * FrequencyBinCount());
   }
   return result;
 }
 
 void
 AnalyserNode::AppendChunk(const AudioChunk& aChunk)
 {
   const uint32_t bufferSize = mBuffer.Length();
--- a/dom/media/webaudio/AnalyserNode.h
+++ b/dom/media/webaudio/AnalyserNode.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AnalyserNode_h_
 #define AnalyserNode_h_
 
 #include "AudioNode.h"
 #include "FFTBlock.h"
+#include "AlignedTArray.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 
 class AnalyserNode final : public AudioNode
 {
@@ -72,17 +73,17 @@ private:
   void ApplyBlackmanWindow(float* aBuffer, uint32_t aSize);
 
 private:
   FFTBlock mAnalysisBlock;
   double mMinDecibels;
   double mMaxDecibels;
   double mSmoothingTimeConstant;
   uint32_t mWriteIndex;
-  FallibleTArray<float> mBuffer;
-  FallibleTArray<float> mOutputBuffer;
+  AlignedFallibleTArray<float> mBuffer;
+  AlignedFallibleTArray<float> mOutputBuffer;
 };
 
 }
 }
 
 #endif
 
--- a/dom/media/webaudio/FFTBlock.cpp
+++ b/dom/media/webaudio/FFTBlock.cpp
@@ -39,36 +39,35 @@ typedef std::complex<double> Complex;
 FFTBlock* FFTBlock::CreateInterpolatedBlock(const FFTBlock& block0, const FFTBlock& block1, double interp)
 {
     FFTBlock* newBlock = new FFTBlock(block0.FFTSize());
 
     newBlock->InterpolateFrequencyComponents(block0, block1, interp);
 
     // In the time-domain, the 2nd half of the response must be zero, to avoid circular convolution aliasing...
     int fftSize = newBlock->FFTSize();
-    nsTArray<float> buffer;
-    buffer.SetLength(fftSize);
+    AlignedTArray<float> buffer(fftSize);
     newBlock->GetInverseWithoutScaling(buffer.Elements());
     AudioBufferInPlaceScale(buffer.Elements(), 1.0f / fftSize, fftSize / 2);
     PodZero(buffer.Elements() + fftSize / 2, fftSize / 2);
 
     // Put back into frequency domain.
     newBlock->PerformFFT(buffer.Elements());
 
     return newBlock;
 }
 
 void FFTBlock::InterpolateFrequencyComponents(const FFTBlock& block0, const FFTBlock& block1, double interp)
 {
     // FIXME : with some work, this method could be optimized
 
-    kiss_fft_cpx* dft = mOutputBuffer.Elements();
+    ComplexU* dft = mOutputBuffer.Elements();
 
-    const kiss_fft_cpx* dft1 = block0.mOutputBuffer.Elements();
-    const kiss_fft_cpx* dft2 = block1.mOutputBuffer.Elements();
+    const ComplexU* dft1 = block0.mOutputBuffer.Elements();
+    const ComplexU* dft2 = block1.mOutputBuffer.Elements();
 
     MOZ_ASSERT(mFFTSize == block0.FFTSize());
     MOZ_ASSERT(mFFTSize == block1.FFTSize());
     double s1base = (1.0 - interp);
     double s2base = interp;
 
     double phaseAccum = 0.0;
     double lastPhase1 = 0.0;
@@ -149,17 +148,17 @@ void FFTBlock::InterpolateFrequencyCompo
 
         dft[i].r = static_cast<float>(mag * cos(phaseAccum));
         dft[i].i = static_cast<float>(mag * sin(phaseAccum));
     }
 }
 
 double FFTBlock::ExtractAverageGroupDelay()
 {
-    kiss_fft_cpx* dft = mOutputBuffer.Elements();
+    ComplexU* dft = mOutputBuffer.Elements();
 
     double aveSum = 0.0;
     double weightSum = 0.0;
     double lastPhase = 0.0;
 
     int halfSize = FFTSize() / 2;
 
     const double kSamplePhaseDelay = (2.0 * M_PI) / double(FFTSize());
@@ -200,17 +199,17 @@ double FFTBlock::ExtractAverageGroupDela
 
     return aveSampleDelay;
 }
 
 void FFTBlock::AddConstantGroupDelay(double sampleFrameDelay)
 {
     int halfSize = FFTSize() / 2;
 
-    kiss_fft_cpx* dft = mOutputBuffer.Elements();
+    ComplexU* dft = mOutputBuffer.Elements();
 
     const double kSamplePhaseDelay = (2.0 * M_PI) / double(FFTSize());
 
     double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay;
 
     // Add constant group delay
     for (int i = 1; i < halfSize; i++) {
         Complex c(dft[i].r, dft[i].i);
--- a/dom/media/webaudio/FFTBlock.h
+++ b/dom/media/webaudio/FFTBlock.h
@@ -2,36 +2,53 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef FFTBlock_h_
 #define FFTBlock_h_
 
-#include "nsTArray.h"
+#ifdef BUILD_ARM_NEON
+#include <cmath>
+#include "mozilla/arm.h"
+#include "dl/sp/api/omxSP.h"
+#endif
+
+#include "AlignedTArray.h"
 #include "AudioNodeEngine.h"
 #include "kiss_fft/kiss_fftr.h"
 
 namespace mozilla {
 
 // This class defines an FFT block, loosely modeled after Blink's FFTFrame
 // class to make sharing code with Blink easy.
 // Currently it's implemented on top of KissFFT on all platforms.
 class FFTBlock final
 {
+  union ComplexU {
+    kiss_fft_cpx c;
+    float f[2];
+    struct {
+      float r;
+      float i;
+    };
+  };
+
 public:
   explicit FFTBlock(uint32_t aFFTSize)
-    : mFFT(nullptr)
-    , mIFFT(nullptr)
-    , mFFTSize(aFFTSize)
+    : mKissFFT(nullptr)
+    , mKissIFFT(nullptr)
+#ifdef BUILD_ARM_NEON
+    , mOmxFFT(nullptr)
+    , mOmxIFFT(nullptr)
+#endif
   {
     MOZ_COUNT_CTOR(FFTBlock);
-    mOutputBuffer.SetLength(aFFTSize / 2 + 1);
-    PodZero(mOutputBuffer.Elements(), aFFTSize / 2 + 1);
+    SetFFTSize(aFFTSize);
   }
   ~FFTBlock()
   {
     MOZ_COUNT_DTOR(FFTBlock);
     Clear();
   }
 
   // Return a new FFTBlock with frequency components interpolated between
@@ -39,70 +56,94 @@ public:
   static FFTBlock*
   CreateInterpolatedBlock(const FFTBlock& block0,
                           const FFTBlock& block1, double interp);
 
   // Transform FFTSize() points of aData and store the result internally.
   void PerformFFT(const float* aData)
   {
     EnsureFFT();
-    kiss_fftr(mFFT, aData, mOutputBuffer.Elements());
+#ifdef BUILD_ARM_NEON
+    if (mozilla::supports_neon()) {
+      omxSP_FFTFwd_RToCCS_F32_Sfs(aData, mOutputBuffer.Elements()->f, mOmxFFT);
+    } else
+#endif
+    {
+      kiss_fftr(mKissFFT, aData, &(mOutputBuffer.Elements()->c));
+    }
   }
   // Inverse-transform internal data and store the resulting FFTSize()
-  // points in aData.
+  // points in aDataOut.
   void GetInverse(float* aDataOut)
   {
     GetInverseWithoutScaling(aDataOut);
     AudioBufferInPlaceScale(aDataOut, 1.0f / mFFTSize, mFFTSize);
   }
   // Inverse-transform internal frequency data and store the resulting
   // FFTSize() points in |aDataOut|.  If frequency data has not already been
   // scaled, then the output will need scaling by 1/FFTSize().
   void GetInverseWithoutScaling(float* aDataOut)
   {
     EnsureIFFT();
-    kiss_fftri(mIFFT, mOutputBuffer.Elements(), aDataOut);
+#ifdef BUILD_ARM_NEON
+    if (mozilla::supports_neon()) {
+      omxSP_FFTInv_CCSToR_F32_Sfs(mOutputBuffer.Elements()->f, aDataOut, mOmxIFFT);
+      // There is no function that computes de inverse FFT without scaling, so
+      // we have to scale back up here. Bug 1158741.
+      AudioBufferInPlaceScale(aDataOut, mFFTSize, mFFTSize);
+    } else
+#endif
+    {
+      kiss_fftri(mKissIFFT, &(mOutputBuffer.Elements()->c), aDataOut);
+    }
   }
   // Inverse-transform the FFTSize()/2+1 points of data in each
   // of aRealDataIn and aImagDataIn and store the resulting
   // FFTSize() points in aRealDataOut.
   void PerformInverseFFT(float* aRealDataIn,
                          float *aImagDataIn,
                          float *aRealDataOut)
   {
     EnsureIFFT();
     const uint32_t inputSize = mFFTSize / 2 + 1;
-    nsTArray<kiss_fft_cpx> inputBuffer;
-    inputBuffer.SetLength(inputSize);
+    AlignedTArray<ComplexU> inputBuffer(inputSize);
     for (uint32_t i = 0; i < inputSize; ++i) {
       inputBuffer[i].r = aRealDataIn[i];
       inputBuffer[i].i = aImagDataIn[i];
     }
-    kiss_fftri(mIFFT, inputBuffer.Elements(), aRealDataOut);
-    for (uint32_t i = 0; i < mFFTSize; ++i) {
-      aRealDataOut[i] /= mFFTSize;
+#ifdef BUILD_ARM_NEON
+    if (mozilla::supports_neon()) {
+      omxSP_FFTInv_CCSToR_F32_Sfs(inputBuffer.Elements()->f,
+                                  aRealDataOut, mOmxIFFT);
+    } else
+#endif
+    {
+      kiss_fftri(mKissIFFT, &(inputBuffer.Elements()->c), aRealDataOut);
+      for (uint32_t i = 0; i < mFFTSize; ++i) {
+        aRealDataOut[i] /= mFFTSize;
+      }
     }
   }
 
   void Multiply(const FFTBlock& aFrame)
   {
-    BufferComplexMultiply(reinterpret_cast<const float*>(mOutputBuffer.Elements()),
-                          reinterpret_cast<const float*>(aFrame.mOutputBuffer.Elements()),
-                          reinterpret_cast<float*>(mOutputBuffer.Elements()),
+    BufferComplexMultiply(mOutputBuffer.Elements()->f,
+                          aFrame.mOutputBuffer.Elements()->f,
+                          mOutputBuffer.Elements()->f,
                           mFFTSize / 2 + 1);
   }
 
   // Perform a forward FFT on |aData|, assuming zeros after dataSize samples,
   // and pre-scale the generated internal frequency domain coefficients so
   // that GetInverseWithoutScaling() can be used to transform to the time
   // domain.  This is useful for convolution kernels.
   void PadAndMakeScaledDFT(const float* aData, size_t dataSize)
   {
     MOZ_ASSERT(dataSize <= FFTSize());
-    nsTArray<float> paddedData;
+    AlignedTArray<float> paddedData;
     paddedData.SetLength(FFTSize());
     AudioBufferCopyWithScale(aData, 1.0f / FFTSize(),
                              paddedData.Elements(), dataSize);
     PodZero(paddedData.Elements() + dataSize, mFFTSize - dataSize);
     PerformFFT(paddedData.Elements());
   }
 
   void SetFFTSize(uint32_t aSize)
@@ -127,54 +168,101 @@ public:
   float ImagData(uint32_t aIndex) const
   {
     return mOutputBuffer[aIndex].i;
   }
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
   {
     size_t amount = 0;
-    amount += aMallocSizeOf(mFFT);
-    amount += aMallocSizeOf(mIFFT);
+    amount += aMallocSizeOf(mKissFFT);
+    amount += aMallocSizeOf(mKissIFFT);
     amount += mOutputBuffer.SizeOfExcludingThis(aMallocSizeOf);
     return amount;
   }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
 private:
   FFTBlock(const FFTBlock& other) = delete;
   void operator=(const FFTBlock& other) = delete;
 
   void EnsureFFT()
   {
-    if (!mFFT) {
-      mFFT = kiss_fftr_alloc(mFFTSize, 0, nullptr, nullptr);
+#ifdef BUILD_ARM_NEON
+    if (mozilla::supports_neon()) {
+      if (!mOmxFFT) {
+        mOmxFFT = createOmxFFT(mFFTSize);
+      }
+    } else
+#endif
+    {
+      if (!mKissFFT) {
+        mKissFFT = kiss_fftr_alloc(mFFTSize, 0, nullptr, nullptr);
+      }
     }
   }
   void EnsureIFFT()
   {
-    if (!mIFFT) {
-      mIFFT = kiss_fftr_alloc(mFFTSize, 1, nullptr, nullptr);
+#ifdef BUILD_ARM_NEON
+    if (mozilla::supports_neon()) {
+      if (!mOmxIFFT) {
+        mOmxIFFT = createOmxFFT(mFFTSize);
+      }
+    } else
+#endif
+    {
+      if (!mKissIFFT) {
+        mKissIFFT = kiss_fftr_alloc(mFFTSize, 1, nullptr, nullptr);
+      }
     }
   }
+
+#ifdef BUILD_ARM_NEON
+  static OMXFFTSpec_R_F32* createOmxFFT(uint32_t aFFTSize)
+  {
+    MOZ_ASSERT((aFFTSize & (aFFTSize-1)) == 0);
+    OMX_INT bufSize;
+    OMX_INT order = log((double)aFFTSize)/M_LN2;
+    MOZ_ASSERT(aFFTSize>>order == 1);
+    OMXResult status = omxSP_FFTGetBufSize_R_F32(order, &bufSize);
+    if (status == OMX_Sts_NoErr) {
+      OMXFFTSpec_R_F32* context = static_cast<OMXFFTSpec_R_F32*>(malloc(bufSize));
+      if (omxSP_FFTInit_R_F32(context, order) != OMX_Sts_NoErr) {
+        return nullptr;
+      }
+      return context;
+    }
+    return nullptr;
+  }
+#endif
+
   void Clear()
   {
-    free(mFFT);
-    free(mIFFT);
-    mFFT = mIFFT = nullptr;
+#ifdef BUILD_ARM_NEON
+    free(mOmxFFT);
+    free(mOmxIFFT);
+    mOmxFFT = mOmxIFFT = nullptr;
+#endif
+    free(mKissFFT);
+    free(mKissIFFT);
+    mKissFFT = mKissIFFT = nullptr;
   }
   void AddConstantGroupDelay(double sampleFrameDelay);
   void InterpolateFrequencyComponents(const FFTBlock& block0,
                                       const FFTBlock& block1, double interp);
 
-  kiss_fftr_cfg mFFT, mIFFT;
-  nsTArray<kiss_fft_cpx> mOutputBuffer;
+  kiss_fftr_cfg mKissFFT;
+  kiss_fftr_cfg mKissIFFT;
+#ifdef BUILD_ARM_NEON
+  OMXFFTSpec_R_F32* mOmxFFT;
+  OMXFFTSpec_R_F32* mOmxIFFT;
+#endif
+  AlignedTArray<ComplexU> mOutputBuffer;
   uint32_t mFFTSize;
 };
-
 }
 
 #endif
 
--- a/dom/media/webaudio/blink/FFTConvolver.h
+++ b/dom/media/webaudio/blink/FFTConvolver.h
@@ -30,17 +30,17 @@
 #define FFTConvolver_h
 
 #include "nsTArray.h"
 #include "mozilla/FFTBlock.h"
 #include "mozilla/MemoryReporting.h"
 
 namespace WebCore {
 
-typedef nsTArray<float> AudioFloatArray;
+typedef AlignedTArray<float> AlignedAudioFloatArray;
 using mozilla::FFTBlock;
 
 class FFTConvolver {
 public:
     // fftSize must be a power of two
     explicit FFTConvolver(size_t fftSize);
 
     // |fftKernel| must be pre-scaled for FFTBlock::GetInverseWithoutScaling().
@@ -61,20 +61,20 @@ public:
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
 private:
     FFTBlock m_frame;
 
     // Buffer input until we get fftSize / 2 samples then do an FFT
     size_t m_readWriteIndex;
-    AudioFloatArray m_inputBuffer;
+    AlignedAudioFloatArray m_inputBuffer;
 
     // Stores output which we read a little at a time
-    AudioFloatArray m_outputBuffer;
+    AlignedAudioFloatArray m_outputBuffer;
 
     // Saves the 2nd half of the FFT buffer, so we can do an overlap-add with the 1st half of the next one
-    AudioFloatArray m_lastOverlapBuffer;
+    AlignedAudioFloatArray m_lastOverlapBuffer;
 };
 
 } // namespace WebCore
 
 #endif // FFTConvolver_h
--- a/dom/media/webaudio/blink/HRTFKernel.cpp
+++ b/dom/media/webaudio/blink/HRTFKernel.cpp
@@ -46,16 +46,24 @@ static float extractAverageGroupDelay(fl
 
     return frameDelay;
 }
 
 HRTFKernel::HRTFKernel(float* impulseResponse, size_t length, float sampleRate)
     : m_frameDelay(0)
     , m_sampleRate(sampleRate)
 {
+    AlignedTArray<float> buffer;
+    // copy to a 32-byte aligned buffer
+    if (((uintptr_t)impulseResponse & 31) != 0) {
+      buffer.SetLength(length);
+      mozilla::PodCopy(buffer.Elements(), impulseResponse, length);
+      impulseResponse = buffer.Elements();
+    }
+
     // Determine the leading delay (average group delay) for the response.
     m_frameDelay = extractAverageGroupDelay(impulseResponse, length);
 
     // The FFT size (with zero padding) needs to be twice the response length
     // in order to do proper convolution.
     unsigned fftSize = 2 * length;
 
     // Quick fade-out (apply window) at truncation point
@@ -74,26 +82,26 @@ HRTFKernel::HRTFKernel(float* impulseRes
 }
 
 // Interpolates two kernels with x: 0 -> 1 and returns the result.
 nsReturnRef<HRTFKernel> HRTFKernel::createInterpolatedKernel(HRTFKernel* kernel1, HRTFKernel* kernel2, float x)
 {
     MOZ_ASSERT(kernel1 && kernel2);
     if (!kernel1 || !kernel2)
         return nsReturnRef<HRTFKernel>();
- 
+
     MOZ_ASSERT(x >= 0.0 && x < 1.0);
     x = mozilla::clamped(x, 0.0f, 1.0f);
-    
+
     float sampleRate1 = kernel1->sampleRate();
     float sampleRate2 = kernel2->sampleRate();
     MOZ_ASSERT(sampleRate1 == sampleRate2);
     if (sampleRate1 != sampleRate2)
         return nsReturnRef<HRTFKernel>();
-    
+
     float frameDelay = (1 - x) * kernel1->frameDelay() + x * kernel2->frameDelay();
-    
+
     nsAutoPtr<FFTBlock> interpolatedFrame(
         FFTBlock::CreateInterpolatedBlock(*kernel1->fftFrame(), *kernel2->fftFrame(), x));
     return HRTFKernel::create(interpolatedFrame, frameDelay, sampleRate1);
 }
 
 } // namespace WebCore
--- a/dom/media/webaudio/blink/HRTFPanner.h
+++ b/dom/media/webaudio/blink/HRTFPanner.h
@@ -30,16 +30,18 @@
 #include "mozilla/MemoryReporting.h"
 
 namespace mozilla {
 struct AudioChunk;
 }
 
 namespace WebCore {
 
+typedef nsTArray<float> AudioFloatArray;
+
 class HRTFDatabaseLoader;
 
 using mozilla::AudioChunk;
 
 class HRTFPanner {
 public:
     HRTFPanner(float sampleRate, mozilla::TemporaryRef<HRTFDatabaseLoader> databaseLoader);
     ~HRTFPanner();
--- a/dom/media/webaudio/blink/PeriodicWave.cpp
+++ b/dom/media/webaudio/blink/PeriodicWave.cpp
@@ -215,17 +215,17 @@ void PeriodicWave::createBandLimitedTabl
         // Clear any DC-offset.
         realP[0] = 0;
 
         // Clear values which have no effect.
         imagP[0] = 0;
         imagP[halfSize-1] = 0;
 
         // Create the band-limited table.
-        AudioFloatArray* table = new AudioFloatArray(m_periodicWaveSize);
+        AlignedAudioFloatArray* table = new AlignedAudioFloatArray(m_periodicWaveSize);
         m_bandLimitedTables.AppendElement(table);
 
         // Apply an inverse FFT to generate the time-domain table data.
         float* data = m_bandLimitedTables[rangeIndex]->Elements();
         frame.PerformInverseFFT(realP, imagP, data);
 
         // For the first range (which has the highest power), calculate
         // its peak value then compute normalization scale.
--- a/dom/media/webaudio/blink/PeriodicWave.h
+++ b/dom/media/webaudio/blink/PeriodicWave.h
@@ -27,20 +27,22 @@
  */
 
 #ifndef PeriodicWave_h
 #define PeriodicWave_h
 
 #include "mozilla/dom/OscillatorNodeBinding.h"
 #include <nsAutoPtr.h>
 #include <nsTArray.h>
+#include "AlignedTArray.h"
 #include "mozilla/MemoryReporting.h"
 
 namespace WebCore {
 
+typedef AlignedTArray<float> AlignedAudioFloatArray;
 typedef nsTArray<float> AudioFloatArray;
 
 class PeriodicWave {
 public:
     static PeriodicWave* createSine(float sampleRate);
     static PeriodicWave* createSquare(float sampleRate);
     static PeriodicWave* createSawtooth(float sampleRate);
     static PeriodicWave* createTriangle(float sampleRate);
@@ -93,14 +95,14 @@ private:
 
     // Maximum possible number of partials (before culling).
     unsigned maxNumberOfPartials() const;
 
     unsigned numberOfPartialsForRange(unsigned rangeIndex) const;
 
     // Creates tables based on numberOfComponents Fourier coefficients.
     void createBandLimitedTables(const float* real, const float* imag, unsigned numberOfComponents);
-    nsTArray<nsAutoPtr<AudioFloatArray> > m_bandLimitedTables;
+    nsTArray<nsAutoPtr<AlignedAudioFloatArray> > m_bandLimitedTables;
 };
 
 } // namespace WebCore
 
 #endif // PeriodicWave_h
--- a/dom/media/webaudio/moz.build
+++ b/dom/media/webaudio/moz.build
@@ -16,16 +16,17 @@ MOCHITEST_MANIFESTS += [
     'test/mochitest.ini',
 ]
 
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 
 EXPORTS += [
+    'AlignedTArray.h',
     'AudioContext.h',
     'AudioEventTimeline.h',
     'AudioNodeEngine.h',
     'AudioNodeExternalInputStream.h',
     'AudioNodeStream.h',
     'AudioParamTimeline.h',
     'MediaBufferDecoder.h',
     'ThreeDPoint.h',
@@ -102,17 +103,21 @@ UNIFIED_SOURCES += [
     'ThreeDPoint.cpp',
     'WaveShaperNode.cpp',
     'WebAudioUtils.cpp',
 ]
 
 if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
     SOURCES += ['AudioNodeEngineNEON.cpp']
     SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon']
+    LOCAL_INCLUDES += [
+        '/media/openmax_dl/dl/api/'
+    ]
 
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '..'
 ]
+
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CSSLexer.webidl
@@ -0,0 +1,132 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// The possible values for CSSToken.tokenType.
+enum CSSTokenType {
+  // Whitespace.
+  "whitespace",
+  // A CSS comment.
+  "comment",
+  // An identifier.  |text| holds the identifier text.
+  "ident",
+  // A function token.  |text| holds the function name.  Note that the
+  // function token includes (i.e., consumes) the "(" -- but this is
+  // not included in |text|.
+  "function",
+  // "@word".  |text| holds "word", without the "@".
+  "at",
+  // "#word".  |text| holds "word", without the "#".
+  "id",
+  // "#word".  ID is used when "word" would have been a valid IDENT
+  // token without the "#"; otherwise, HASH is used.
+  "hash",
+  // A number.
+  "number",
+  // A dimensioned number.
+  "dimension",
+  // A percentage.
+  "percentage",
+  // A string.
+  "string",
+  // A "bad string".  This can only be returned when a string is
+  // unterminated at EOF.  (However, currently the lexer returns
+  // ordinary STRING tokens in this situation.)
+  "bad_string",
+  // A URL.  |text| holds the URL.
+  "url",
+  // A "bad URL".  This is a URL that is unterminated at EOF.  |text|
+  // holds the URL.
+  "bad_url",
+  // A "symbol" is any one-character symbol.  This corresponds to the
+  // DELIM token in the CSS specification.
+  "symbol",
+  // The "~=" token.
+  "includes",
+  // The "|=" token.
+  "dashmatch",
+  // The "^=" token.
+  "beginsmatch",
+  // The "$=" token.
+  "endsmatch",
+  // The "*=" token.
+  "containsmatch",
+  // A unicode-range token.  This is currently not fully represented
+  // by CSSToken.
+  "urange",
+  // HTML comment delimiters, either "<!--" or "-->".  Note that each
+  // is emitted as a separate token, and the intervening text is lexed
+  // as normal; whereas ordinary CSS comments are lexed as a unit.
+  "htmlcomment"
+};
+
+dictionary CSSToken {
+  // The token type.
+  CSSTokenType tokenType = "whitespace";
+
+  // Offset of the first character of the token.
+  unsigned long startOffset = 0;
+  // Offset of the character after the final character of the token.
+  // This is chosen so that the offsets can be passed to |substring|
+  // to yield the exact contents of the token.
+  unsigned long endOffset = 0;
+
+  // If the token is a number, percentage, or dimension, this holds
+  // the value.  This is not present for other token types.
+  double number;
+  // If the token is a number, percentage, or dimension, this is true
+  // iff the number had an explicit sign.  This is not present for
+  // other token types.
+  boolean hasSign;
+  // If the token is a number, percentage, or dimension, this is true
+  // iff the number was specified as an integer.  This is not present
+  // for other token types.
+  boolean isInteger;
+
+  // Text associated with the token.  This is not present for all
+  // token types.  In particular it is:
+  //
+  // Token type    Meaning
+  // ===============================
+  //    ident      The identifier.
+  //    function   The function name.  Note that the "(" is part
+  //               of the token but is not present in |text|.
+  //    at         The word.
+  //    id         The word.
+  //    hash       The word.
+  //    dimension  The dimension.
+  //    string     The string contents after escape processing.
+  //    bad_string Ditto.
+  //    url        The URL after escape processing.
+  //    bad_url    Ditto.
+  //    symbol     The symbol text.
+  DOMString text;
+};
+
+/**
+ * CSSLexer is an interface to the CSS lexer.  It tokenizes an
+ * input stream and returns CSS tokens.
+ *
+ * @see inIDOMUtils.getCSSLexer to create an instance of the lexer.
+ */
+[ChromeOnly]
+interface CSSLexer
+{
+  /**
+   * The line number of the most recently returned token.  Line
+   * numbers are 0-based.
+   */
+  readonly attribute unsigned long lineNumber;
+
+  /**
+   * The column number of the most recently returned token.  Column
+   * numbers are 0-based.
+   */
+  readonly attribute unsigned long columnNumber;
+
+  /**
+   * Return the next token, or null at EOF.
+   */
+  CSSToken? nextToken();
+};
--- a/dom/webidl/URL.webidl
+++ b/dom/webidl/URL.webidl
@@ -21,16 +21,17 @@ interface URL {
 URL implements URLUtils;
 URL implements URLUtilsSearchParams;
 
 partial interface URL {
   [Throws]
   static DOMString? createObjectURL(Blob blob, optional objectURLOptions options);
   [Throws]
   static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options);
+  [Throws]
   static void revokeObjectURL(DOMString url);
 };
 
 dictionary objectURLOptions
 {
 /* boolean autoRevoke = true; */ /* not supported yet */
 };
 
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -83,16 +83,17 @@ WEBIDL_FILES = [
     'Constraints.webidl',
     'Contacts.webidl',
     'ContainerBoxObject.webidl',
     'ConvolverNode.webidl',
     'Coordinates.webidl',
     'Crypto.webidl',
     'CSPReport.webidl',
     'CSS.webidl',
+    'CSSLexer.webidl',
     'CSSPrimitiveValue.webidl',
     'CSSRuleList.webidl',
     'CSSStyleDeclaration.webidl',
     'CSSStyleSheet.webidl',
     'CSSValue.webidl',
     'CSSValueList.webidl',
     'DataContainerEvent.webidl',
     'DataStore.webidl',
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "URL.h"
 
-#include "nsIDocument.h"
 #include "nsIIOService.h"
 #include "nsPIDOMWindow.h"
 
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/URL.h"
 #include "mozilla/dom/URLBinding.h"
 #include "mozilla/dom/URLSearchParams.h"
 #include "mozilla/dom/ipc/BlobChild.h"
@@ -72,19 +71,19 @@ class CreateURLRunnable : public WorkerM
 private:
   FileImpl* mBlobImpl;
   nsAString& mURL;
 
 public:
   CreateURLRunnable(WorkerPrivate* aWorkerPrivate, FileImpl* aBlobImpl,
                     const mozilla::dom::objectURLOptions& aOptions,
                     nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate),
-    mBlobImpl(aBlobImpl),
-    mURL(aURL)
+  : WorkerMainThreadRunnable(aWorkerPrivate)
+  , mBlobImpl(aBlobImpl)
+  , mURL(aURL)
   {
     MOZ_ASSERT(aBlobImpl);
 
     DebugOnly<bool> isMutable;
     MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
     MOZ_ASSERT(!isMutable);
   }
 
@@ -118,109 +117,100 @@ public:
         }
       }
     }
 
     DebugOnly<bool> isMutable;
     MOZ_ASSERT(NS_SUCCEEDED(mBlobImpl->GetMutable(&isMutable)));
     MOZ_ASSERT(!isMutable);
 
-    nsCOMPtr<nsIPrincipal> principal;
-    nsIDocument* doc = nullptr;
-
-    nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
-    if (window) {
-      doc = window->GetExtantDoc();
-      if (!doc) {
-        SetDOMStringToNull(mURL);
-        return false;
-      }
-
-      principal = doc->NodePrincipal();
-    } else {
-      // We use the worker Principal in case this is a SharedWorker, a
-      // ChromeWorker or a ServiceWorker.
-      principal = mWorkerPrivate->GetPrincipal();
-    }
+    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
 
     nsAutoCString url;
     nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
         NS_LITERAL_CSTRING(BLOBURI_SCHEME),
         mBlobImpl, principal, url);
 
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to add data entry for the blob!");
       SetDOMStringToNull(mURL);
       return false;
     }
 
-    if (doc) {
-      doc->RegisterHostObjectUri(url);
-    } else {
-      mWorkerPrivate->RegisterHostObjectURI(url);
+    if (!mWorkerPrivate->IsSharedWorker() &&
+        !mWorkerPrivate->IsServiceWorker()) {
+      // Walk up to top worker object.
+      WorkerPrivate* wp = mWorkerPrivate;
+      while (WorkerPrivate* parent = wp->GetParent()) {
+        wp = parent;
+      }
+
+      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
+      // We could not have a ScriptContext in JSM code. In this case, we leak.
+      if (sc) {
+        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
+        MOZ_ASSERT(global);
+
+        global->RegisterHostObjectURI(url);
+      }
     }
 
     mURL = NS_ConvertUTF8toUTF16(url);
     return true;
   }
 };
 
 // This class revokes an URL on the main thread.
 class RevokeURLRunnable : public WorkerMainThreadRunnable
 {
 private:
   const nsString mURL;
 
 public:
   RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
                     const nsAString& aURL)
-  : WorkerMainThreadRunnable(aWorkerPrivate),
-    mURL(aURL)
+  : WorkerMainThreadRunnable(aWorkerPrivate)
+  , mURL(aURL)
   {}
 
   bool
   MainThreadRun()
   {
     AssertIsOnMainThread();
 
-    nsCOMPtr<nsIPrincipal> principal;
-    nsIDocument* doc = nullptr;
-
-    nsCOMPtr<nsPIDOMWindow> window = mWorkerPrivate->GetWindow();
-    if (window) {
-      doc = window->GetExtantDoc();
-      if (!doc) {
-        return false;
-      }
-
-      principal = doc->NodePrincipal();
-    } else {
-      // We use the worker Principal in case this is a SharedWorker, a
-      // ChromeWorker or a ServiceWorker.
-      principal = mWorkerPrivate->GetPrincipal();
-    }
-
     NS_ConvertUTF16toUTF8 url(mURL);
 
     nsIPrincipal* urlPrincipal =
       nsHostObjectProtocolHandler::GetDataEntryPrincipal(url);
 
+    nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
+
     bool subsumes;
     if (urlPrincipal &&
         NS_SUCCEEDED(principal->Subsumes(urlPrincipal, &subsumes)) &&
         subsumes) {
-      if (doc) {
-        doc->UnregisterHostObjectUri(url);
-      }
-
       nsHostObjectProtocolHandler::RemoveDataEntry(url);
     }
 
-    if (!window) {
-      mWorkerPrivate->UnregisterHostObjectURI(url);
+    if (!mWorkerPrivate->IsSharedWorker() &&
+        !mWorkerPrivate->IsServiceWorker()) {
+      // Walk up to top worker object.
+      WorkerPrivate* wp = mWorkerPrivate;
+      while (WorkerPrivate* parent = wp->GetParent()) {
+        wp = parent;
+      }
+
+      nsCOMPtr<nsIScriptContext> sc = wp->GetScriptContext();
+      // We could not have a ScriptContext in JSM code. In this case, we leak.
+      if (sc) {
+        nsCOMPtr<nsIGlobalObject> global = sc->GetGlobalObject();
+        MOZ_ASSERT(global);
+
+        global->UnregisterHostObjectURI(url);
+      }
     }
 
     return true;
   }
 };
 
 // This class creates a URL object on the main thread.
 class ConstructorRunnable : public WorkerMainThreadRunnable
@@ -906,31 +896,54 @@ URL::CreateObjectURL(const GlobalObject&
   }
 
   nsRefPtr<CreateURLRunnable> runnable =
     new CreateURLRunnable(workerPrivate, blobImpl, aOptions, aResult);
 
   if (!runnable->Dispatch(cx)) {
     JS_ReportPendingException(cx);
   }
+
+  if (aRv.Failed()) {
+    return;
+  }
+
+  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
+    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
+    MOZ_ASSERT(scope);
+
+    scope->RegisterHostObjectURI(NS_ConvertUTF16toUTF8(aResult));
+  }
 }
 
 // static
 void
-URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl)
+URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
+                     ErrorResult& aRv)
 {
   JSContext* cx = aGlobal.Context();
   WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
 
   nsRefPtr<RevokeURLRunnable> runnable =
     new RevokeURLRunnable(workerPrivate, aUrl);
 
   if (!runnable->Dispatch(cx)) {
     JS_ReportPendingException(cx);
   }
+
+  if (aRv.Failed()) {
+    return;
+  }
+
+  if (workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker()) {
+    WorkerGlobalScope* scope = workerPrivate->GlobalScope();
+    MOZ_ASSERT(scope);
+
+    scope->UnregisterHostObjectURI(NS_ConvertUTF16toUTF8(aUrl));
+  }
 }
 
 void
 URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
 {
   MOZ_ASSERT(mSearchParams);
   MOZ_ASSERT(mSearchParams == aSearchParams);
 
--- a/dom/workers/URL.h
+++ b/dom/workers/URL.h
@@ -60,17 +60,18 @@ public:
               const nsAString& aBase, ErrorResult& aRv);
 
   static void
   CreateObjectURL(const GlobalObject& aGlobal,
                   File& aArg, const objectURLOptions& aOptions,
                   nsAString& aResult, ErrorResult& aRv);
 
   static void
-  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl);
+  RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl,
+                  ErrorResult& aRv);
 
   void GetHref(nsAString& aHref, ErrorResult& aRv) const;
 
   void SetHref(const nsAString& aHref, ErrorResult& aRv);
 
   void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const;
 
   void GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const;
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -865,45 +865,37 @@ const JSStructuredCloneCallbacks gMainTh
   nullptr,
   nullptr,
   nullptr
 };
 
 class MainThreadReleaseRunnable final : public nsRunnable
 {
   nsTArray<nsCOMPtr<nsISupports>> mDoomed;
-  nsTArray<nsCString> mHostObjectURIs;
   nsCOMPtr<nsILoadGroup> mLoadGroupToCancel;
 
 public:
   MainThreadReleaseRunnable(nsTArray<nsCOMPtr<nsISupports>>& aDoomed,
-                            nsTArray<nsCString>& aHostObjectURIs,
                             nsCOMPtr<nsILoadGroup>& aLoadGroupToCancel)
   {
     mDoomed.SwapElements(aDoomed);
-    mHostObjectURIs.SwapElements(aHostObjectURIs);
     mLoadGroupToCancel.swap(aLoadGroupToCancel);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_IMETHOD
   Run() override
   {
     if (mLoadGroupToCancel) {
       mLoadGroupToCancel->Cancel(NS_BINDING_ABORTED);
       mLoadGroupToCancel = nullptr;
     }
 
     mDoomed.Clear();
-
-    for (uint32_t index = 0; index < mHostObjectURIs.Length(); index++) {
-      nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[index]);
-    }
-
     return NS_OK;
   }
 
 private:
   ~MainThreadReleaseRunnable()
   { }
 };
 
@@ -937,21 +929,18 @@ private:
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
     nsCOMPtr<nsILoadGroup> loadGroupToCancel;
     mFinishedWorker->ForgetOverridenLoadGroup(loadGroupToCancel);
 
     nsTArray<nsCOMPtr<nsISupports>> doomed;
     mFinishedWorker->ForgetMainThreadObjects(doomed);
 
-    nsTArray<nsCString> hostObjectURIs;
-    mFinishedWorker->StealHostObjectURIs(hostObjectURIs);
-
     nsRefPtr<MainThreadReleaseRunnable> runnable =
-      new MainThreadReleaseRunnable(doomed, hostObjectURIs, loadGroupToCancel);
+      new MainThreadReleaseRunnable(doomed, loadGroupToCancel);
     if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
       NS_WARNING("Failed to dispatch, going to leak!");
     }
 
     RuntimeService* runtime = RuntimeService::GetService();
     NS_ASSERTION(runtime, "This should never be null!");
 
     mFinishedWorker->DisableDebugger();
@@ -995,21 +984,18 @@ private:
     runtime->UnregisterWorker(cx, mFinishedWorker);
 
     nsCOMPtr<nsILoadGroup> loadGroupToCancel;
     mFinishedWorker->ForgetOverridenLoadGroup(loadGroupToCancel);
 
     nsTArray<nsCOMPtr<nsISupports> > doomed;
     mFinishedWorker->ForgetMainThreadObjects(doomed);
 
-    nsTArray<nsCString> hostObjectURIs;
-    mFinishedWorker->StealHostObjectURIs(hostObjectURIs);
-
     nsRefPtr<MainThreadReleaseRunnable> runnable =
-      new MainThreadReleaseRunnable(doomed, hostObjectURIs, loadGroupToCancel);
+      new MainThreadReleaseRunnable(doomed, loadGroupToCancel);
     if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
       NS_WARNING("Failed to dispatch, going to leak!");
     }
 
     mFinishedWorker->ClearSelfRef();
     return NS_OK;
   }
 };
@@ -4107,39 +4093,16 @@ WorkerPrivateParent<Derived>::ParentJSCo
 
   return mLoadInfo.mScriptContext ?
          mLoadInfo.mScriptContext->GetNativeContext() :
          nsContentUtils::GetSafeJSContext();
 }
 
 template <class Derived>
 void
-WorkerPrivateParent<Derived>::RegisterHostObjectURI(const nsACString& aURI)
-{
-  AssertIsOnMainThread();
-  mHostObjectURIs.AppendElement(aURI);
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::UnregisterHostObjectURI(const nsACString& aURI)
-{
-  AssertIsOnMainThread();
-  mHostObjectURIs.RemoveElement(aURI);
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::StealHostObjectURIs(nsTArray<nsCString>& aArray)
-{
-  aArray.SwapElements(mHostObjectURIs);
-}
-
-template <class Derived>
-void
 WorkerPrivateParent<Derived>::UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup)
 {
   AssertIsOnMainThread();
 
   // The load group should have been overriden at init time.
   mLoadInfo.mInterfaceRequestor->MaybeAddTabChild(aBaseLoadGroup);
 }
 
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -167,19 +167,16 @@ private:
   // they do not need to be cycle collected.
   WorkerLoadInfo mLoadInfo;
 
   Atomic<bool> mLoadingWorkerScript;
 
   // Only used for top level workers.
   nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
 
-  // Only for ChromeWorkers without window and only touched on the main thread.
-  nsTArray<nsCString> mHostObjectURIs;
-
   // Protected by mMutex.
   JSSettings mJSSettings;
 
   // Only touched on the parent thread (currently this is always the main
   // thread as SharedWorkers are always top-level).
   nsDataHashtable<nsUint64HashKey, SharedWorker*> mSharedWorkers;
 
   uint64_t mBusyCount;
@@ -729,25 +726,16 @@ public:
 
   void
   GetAllSharedWorkers(nsTArray<nsRefPtr<SharedWorker>>& aSharedWorkers);
 
   void
   CloseSharedWorkersForWindow(nsPIDOMWindow* aWindow);
 
   void
-  RegisterHostObjectURI(const nsACString& aURI);
-
-  void
-  UnregisterHostObjectURI(const nsACString& aURI);
-
-  void
-  StealHostObjectURIs(nsTArray<nsCString>& aArray);
-
-  void
   UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup);
 
   IMPL_EVENT_HANDLER(message)
   IMPL_EVENT_HANDLER(error)
 
 #ifdef DEBUG
   void
   AssertIsOnParentThread() const;
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -68,27 +68,29 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                   DOMEventTargetHelper)
   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
+  tmp->TraverseHostObjectURIs(cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
                                                 DOMEventTargetHelper)
   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
+  tmp->UnlinkHostObjectURIs();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerGlobalScope,
                                                DOMEventTargetHelper)
   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
 
   tmp->mWorkerPrivate->TraceTimeouts(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
@@ -551,17 +553,31 @@ public:
 
 private:
   virtual ~WorkerDebuggerSandboxPrivate()
   {
     ClearWrapper();
   }
 };
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WorkerDebuggerSandboxPrivate)
+NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerDebuggerSandboxPrivate)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WorkerDebuggerSandboxPrivate)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+  tmp->UnlinkHostObjectURIs();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WorkerDebuggerSandboxPrivate)
+
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+  tmp->TraverseHostObjectURIs(cb);
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(WorkerDebuggerSandboxPrivate)
+
 NS_IMPL_CYCLE_COLLECTING_ADDREF(WorkerDebuggerSandboxPrivate)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(WorkerDebuggerSandboxPrivate)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerDebuggerSandboxPrivate)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
 NS_INTERFACE_MAP_END
 
 static bool
--- a/dom/workers/test/file_url.jsm
+++ b/dom/workers/test/file_url.jsm
@@ -1,16 +1,20 @@
 this.EXPORTED_SYMBOLS = ['checkFromJSM'];
 
+Components.utils.importGlobalProperties(['URL']);
+
 this.checkFromJSM = function checkFromJSM(ok, is, finish) {
   let worker = new ChromeWorker("jsm_url_worker.js");
   worker.onmessage = function(event) {
 
    if (event.data.type == 'finish') {
      finish();
+    } else if (event.data.type == 'url') {
+      URL.revokeObjectURL(event.data.url);
     } else if (event.data.type == 'status') {
       ok(event.data.status, event.data.msg);
     }
   }
 
   var self = this;
   worker.onerror = function(event) {
     is(event.target, worker);
--- a/dom/workers/test/test_bug883784.jsm
+++ b/dom/workers/test/test_bug883784.jsm
@@ -1,28 +1,33 @@
 this.EXPORTED_SYMBOLS = ["Test"];
 
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+Cu.importGlobalProperties(["URL"]);
+
 this.Test = {
   start: function(ok, is, finish) {
     let worker = new ChromeWorker("jsm_url_worker.js");
     worker.onmessage = function(event) {
       if (event.data.type == 'status') {
         ok(event.data.status, event.data.msg);
       } else if (event.data.type == 'url') {
         var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                   .createInstance(Components.interfaces.nsIXMLHttpRequest);
         xhr.open('GET', event.data.url, false);
         xhr.onreadystatechange = function() {
           if (xhr.readyState == 4) {
             ok(true, "Blob readable!");
+            URL.revokeObjectURL(event.data.url);
             finish();
           }
         }
         xhr.onerror = function() {
-          ok(true, "Blob unreadable, should not happen!");
+          ok(false, "Blob unreadable, should not happen!");
+          URL.revokeObjectURL(event.data.url);
           finish();
         }
         xhr.send();
       }
     };
 
     var self = this;
     worker.onerror = function(event) {
--- a/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp
@@ -47,23 +47,23 @@ WrapTexCoord(GLfloat v)
     if (v < 0.0f) {
         return 1.0f + fmodf(v, 1.0f);
     }
 
     return fmodf(v, 1.0f);
 }
 
 void
-DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
+DecomposeIntoNoRepeatTriangles(const gfx::IntRect& aTexCoordRect,
                                const nsIntSize& aTexSize,
                                RectTriangles& aRects,
                                bool aFlipY /* = false */)
 {
     // normalize this
-    nsIntRect tcr(aTexCoordRect);
+    gfx::IntRect tcr(aTexCoordRect);
     while (tcr.x >= aTexSize.width)
         tcr.x -= aTexSize.width;
     while (tcr.y >= aTexSize.height)
         tcr.y -= aTexSize.height;
 
     // Compute top left and bottom right tex coordinates
     GLfloat tl[2] =
         { GLfloat(tcr.x) / GLfloat(aTexSize.width),
--- a/gfx/gl/DecomposeIntoNoRepeatTriangles.h
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.h
@@ -61,17 +61,17 @@ private:
   *
   * The resulting triangle vertex coordinates will be in the space of
   * (0.0, 0.0) to (1.0, 1.0) -- transform the coordinates appropriately
   * if you need a different space.
   *
   * The resulting vertex coordinates should be drawn using GL_TRIANGLES,
   * and rects.numRects * 3 * 6
   */
-void DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
+void DecomposeIntoNoRepeatTriangles(const gfx::IntRect& aTexCoordRect,
                                     const nsIntSize& aTexSize,
                                     RectTriangles& aRects,
                                     bool aFlipY = false);
 
 }
 }
 
 #endif // DecomposeIntoNoRepeatTriangles_h_
--- a/gfx/gl/GLTextureImage.h
+++ b/gfx/gl/GLTextureImage.h
@@ -148,17 +148,17 @@ public:
      * allocated.  Must not be called between BeginUpdate and EndUpdate.
      * After a resize, the contents are undefined.
      *
      * If this isn't implemented by a subclass, it will just perform
      * a dummy BeginUpdate/EndUpdate pair.
      */
     virtual void Resize(const gfx::IntSize& aSize) {
         mSize = aSize;
-        nsIntRegion r(nsIntRect(0, 0, aSize.width, aSize.height));
+        nsIntRegion r(gfx::IntRect(0, 0, aSize.width, aSize.height));
         BeginUpdate(r);
         EndUpdate();
     }
 
     /**
      * Mark this texture as having valid contents. Call this after modifying
      * the texture contents externally.
      */
--- a/gfx/gl/TextureImageEGL.h
+++ b/gfx/gl/TextureImageEGL.h
@@ -60,17 +60,17 @@ public:
 
     virtual void DestroyEGLSurface(void);
 
 protected:
     typedef gfxImageFormat ImageFormat;
 
     GLContext* mGLContext;
 
-    nsIntRect mUpdateRect;
+    gfx::IntRect mUpdateRect;
     gfx::SurfaceFormat mUpdateFormat;
     RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
     EGLImage mEGLImage;
     GLuint mTexture;
     EGLSurface mSurface;
     EGLConfig mConfig;
     TextureState mTextureState;
 
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -417,17 +417,17 @@ struct RegionParamTraits
       result->Or(*result, rect);
     }
     return false;
   }
 };
 
 template<>
 struct ParamTraits<nsIntRegion>
-  : RegionParamTraits<nsIntRegion, nsIntRect, nsIntRegionRectIterator>
+  : RegionParamTraits<nsIntRegion, mozilla::gfx::IntRect, nsIntRegionRectIterator>
 {};
 
 template<>
 struct ParamTraits<nsIntSize>
 {
   typedef nsIntSize paramType;
 
   static void Write(Message* msg, const paramType& param)
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -76,17 +76,17 @@ Compositor::DrawDiagnostics(DiagnosticFl
 {
   if (!ShouldDrawDiagnostics(aFlags)) {
     return;
   }
 
   if (aVisibleRegion.GetNumRects() > 1) {
     nsIntRegionRectIterator screenIter(aVisibleRegion);
 
-    while (const nsIntRect* rect = screenIter.Next())
+    while (const gfx::IntRect* rect = screenIter.Next())
     {
       DrawDiagnostics(aFlags | DiagnosticFlags::REGION_RECT,
                       ToRect(*rect), aClipRect, aTransform, aFlashCounter);
     }
   }
 
   DrawDiagnostics(aFlags, ToRect(aVisibleRegion.GetBounds()),
                   aClipRect, aTransform, aFlashCounter);
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -219,17 +219,17 @@ public:
 
   /**
    * Set the target for rendering. Results will have been written to aTarget by
    * the time that EndFrame returns.
    *
    * If this method is not used, or we pass in nullptr, we target the compositor's
    * usual swap chain and render to the screen.
    */
-  void SetTargetContext(gfx::DrawTarget* aTarget, const nsIntRect& aRect)
+  void SetTargetContext(gfx::DrawTarget* aTarget, const gfx::IntRect& aRect)
   {
     mTarget = aTarget;
     mTargetBounds = aRect;
   }
   void ClearTargetContext()
   {
     mTarget = nullptr;
   }
@@ -495,17 +495,17 @@ protected:
   size_t mPixelsPerFrame;
   size_t mPixelsFilled;
 
   ScreenRotation mScreenRotation;
 
   virtual gfx::IntSize GetWidgetSize() const = 0;
 
   RefPtr<gfx::DrawTarget> mTarget;
-  nsIntRect mTargetBounds;
+  gfx::IntRect mTargetBounds;
 
 private:
   static LayersBackend sBackend;
 
 };
 
 // Returns the number of rects. (Up to 4)
 typedef gfx::Rect decomposedRectArrayT[4];
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -13,17 +13,17 @@
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxUtils.h"                   // for gfxUtils
 #include "gfx2DGlue.h"                  // for thebes --> moz2d transition
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Tools.h"
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING, etc
 #include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsSize.h"                     // for nsIntSize
 #include "gfxUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
--- a/gfx/layers/D3D11ShareHandleImage.h
+++ b/gfx/layers/D3D11ShareHandleImage.h
@@ -21,25 +21,25 @@ namespace layers {
 // resource is ready to use.
 class D3D11ShareHandleImage : public Image {
 public:
 
   struct Data {
     Data(ID3D11Texture2D* aTexture,
          ID3D11Device* aDevice,
          ID3D11DeviceContext* aContext,
-         const nsIntRect& aRegion)
+         const gfx::IntRect& aRegion)
       : mTexture(aTexture),
         mDevice(aDevice),
         mContext(aContext),
         mRegion(aRegion) {}
     RefPtr<ID3D11Texture2D> mTexture;
     RefPtr<ID3D11Device> mDevice;
     RefPtr<ID3D11DeviceContext> mContext;
-    nsIntRect mRegion;
+    gfx::IntRect mRegion;
   };
 
   D3D11ShareHandleImage() : Image(NULL, ImageFormat::D3D11_SHARE_HANDLE_TEXTURE), mSize(0, 0) {}
   virtual ~D3D11ShareHandleImage() {}
 
   // Copies the surface into a sharable texture's surface, and initializes
   // the image.
   HRESULT SetData(const Data& aData);
@@ -47,22 +47,22 @@ public:
   gfx::IntSize GetSize() override;
 
   virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() override;
 
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) override;
 
   ID3D11Texture2D* GetTexture() const;
 
-  virtual nsIntRect GetPictureRect() override { return mPictureRect; }
+  virtual gfx::IntRect GetPictureRect() override { return mPictureRect; }
 
 private:
 
   gfx::IntSize mSize;
-  nsIntRect mPictureRect;
+  gfx::IntRect mPictureRect;
   RefPtr<ID3D11Texture2D> mTexture;
   RefPtr<TextureClient> mTextureClient;
   HANDLE mShareHandle;
   gfx::SurfaceFormat mFormat;
 
 };
 
 } // namepace layers
--- a/gfx/layers/D3D9SurfaceImage.cpp
+++ b/gfx/layers/D3D9SurfaceImage.cpp
@@ -102,17 +102,17 @@ D3D9SurfaceImage::SetData(const Data& aD
                                          D3DDEVTYPE_HAL,
                                          desc.Format,
                                          D3DFMT_X8R8G8B8);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   // DXVA surfaces aren't created sharable, so we need to copy the surface
   // to a sharable texture to that it's accessible to the layer manager's
   // device.
-  const nsIntRect& region = aData.mRegion;
+  const gfx::IntRect& region = aData.mRegion;
   RefPtr<IDirect3DTexture9> texture;
   HANDLE shareHandle = nullptr;
   hr = device->CreateTexture(region.width,
                              region.height,
                              1,
                              D3DUSAGE_RENDERTARGET,
                              D3DFMT_X8R8G8B8,
                              D3DPOOL_DEFAULT,
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -17,20 +17,20 @@ namespace layers {
 // Image class that wraps a IDirect3DSurface9. This class copies the image
 // passed into SetData(), so that it can be accessed from other D3D devices.
 // This class also manages the synchronization of the copy, to ensure the
 // resource is ready to use.
 class D3D9SurfaceImage : public Image {
 public:
 
   struct Data {
-    Data(IDirect3DSurface9* aSurface, const nsIntRect& aRegion)
+    Data(IDirect3DSurface9* aSurface, const gfx::IntRect& aRegion)
       : mSurface(aSurface), mRegion(aRegion) {}
     RefPtr<IDirect3DSurface9> mSurface;
-    nsIntRect mRegion;
+    gfx::IntRect mRegion;
   };
 
   D3D9SurfaceImage();
   virtual ~D3D9SurfaceImage();
 
   // Copies the surface into a sharable texture's surface, and initializes
   // the image.
   HRESULT SetData(const Data& aData);
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -17,17 +17,17 @@
 #include "mozilla/gfx/Point.h"          // For IntSize
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend, etc
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoArrayPtr, etc
 #include "nsAutoRef.h"                  // for nsCountedRef
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::Release, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsTArray
 #include "mozilla/Atomics.h"
 #include "mozilla/WeakPtr.h"
 #include "nsThreadUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "nsDataHashtable.h"
 #include "mozilla/EnumeratedArray.h"
@@ -129,19 +129,19 @@ protected:
 class Image {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Image)
 
 public:
   ImageFormat GetFormat() { return mFormat; }
   void* GetImplData() { return mImplData; }
 
   virtual gfx::IntSize GetSize() = 0;
-  virtual nsIntRect GetPictureRect()
+  virtual gfx::IntRect GetPictureRect()
   {
-    return nsIntRect(0, 0, GetSize().width, GetSize().height);
+    return gfx::IntRect(0, 0, GetSize().width, GetSize().height);
   }
 
   ImageBackendData* GetBackendData(LayersBackend aBackend)
   { return mBackendData[aBackend]; }
   void SetBackendData(LayersBackend aBackend, ImageBackendData* aData)
   { mBackendData[aBackend] = aData; }
 
   int32_t GetSerial() { return mSerial; }
@@ -634,18 +634,18 @@ struct PlanarYCbCrData {
   int32_t mCbSkip;
   int32_t mCrSkip;
   // Picture region
   uint32_t mPicX;
   uint32_t mPicY;
   gfx::IntSize mPicSize;
   StereoMode mStereoMode;
 
-  nsIntRect GetPictureRect() const {
-    return nsIntRect(mPicX, mPicY,
+  gfx::IntRect GetPictureRect() const {
+    return gfx::IntRect(mPicX, mPicY,
                      mPicSize.width,
                      mPicSize.height);
   }
 
   PlanarYCbCrData()
     : mYChannel(nullptr), mYStride(0), mYSize(0, 0), mYSkip(0)
     , mCbChannel(nullptr), mCrChannel(nullptr)
     , mCbCrStride(0), mCbCrSize(0, 0) , mCbSkip(0), mCrSkip(0)
@@ -848,12 +848,12 @@ public:
   gfx::IntSize GetSize() { return mSize; }
 
 private:
   int32_t mOverlayId;
   gfx::IntSize mSize;
 };
 #endif
 
-} //namespace
-} //namespace
+} // namespace layers
+} // namespace mozilla
 
 #endif
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -695,17 +695,17 @@ Layer::CalculateScissorRect(const Render
     gfx::Matrix matrix;
     DebugOnly<bool> is2D = container->GetEffectiveTransform().Is2D(&matrix);
     // See DefaultComputeEffectiveTransforms below
     NS_ASSERTION(is2D && matrix.PreservesAxisAlignedRectangles(),
                  "Non preserves axis aligned transform with clipped child should have forced intermediate surface");
     gfx::Rect r(scissor.x, scissor.y, scissor.width, scissor.height);
     gfxRect trScissor = gfx::ThebesRect(matrix.TransformBounds(r));
     trScissor.Round();
-    nsIntRect tmp;
+    IntRect tmp;
     if (!gfxUtils::GfxRectToIntRect(trScissor, &tmp)) {
       return RenderTargetIntRect(currentClip.TopLeft(), RenderTargetIntSize(0, 0));
     }
     scissor = ViewAs<RenderTargetPixel>(tmp);
 
     // Find the nearest ancestor with an intermediate surface
     do {
       container = container->GetParent();
@@ -1654,34 +1654,34 @@ DumpTransform(layerscope::LayersPacket::
     aLayerMatrix->add_m(aMatrix._23), aLayerMatrix->add_m(aMatrix._24);
     aLayerMatrix->add_m(aMatrix._31), aLayerMatrix->add_m(aMatrix._32);
     aLayerMatrix->add_m(aMatrix._33), aLayerMatrix->add_m(aMatrix._34);
     aLayerMatrix->add_m(aMatrix._41), aLayerMatrix->add_m(aMatrix._42);
     aLayerMatrix->add_m(aMatrix._43), aLayerMatrix->add_m(aMatrix._44);
   }
 }
 
-// The static helper function sets the nsIntRect into the packet
+// The static helper function sets the IntRect into the packet
 template <typename T, typename Sub, typename Point, typename SizeT, typename MarginT>
 static void
 DumpRect(layerscope::LayersPacket::Layer::Rect* aLayerRect,
          const BaseRect<T, Sub, Point, SizeT, MarginT>& aRect)
 {
   aLayerRect->set_x(aRect.x);
   aLayerRect->set_y(aRect.y);
   aLayerRect->set_w(aRect.width);
   aLayerRect->set_h(aRect.height);
 }
 
 // The static helper function sets the nsIntRegion into the packet
 static void
 DumpRegion(layerscope::LayersPacket::Layer::Region* aLayerRegion, const nsIntRegion& aRegion)
 {
   nsIntRegionRectIterator it(aRegion);
-  while (const nsIntRect* sr = it.Next()) {
+  while (const IntRect* sr = it.Next()) {
     DumpRect(aLayerRegion->add_r(), *sr);
   }
 }
 
 void
 Layer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
 {
   // Add a new layer (UnknownLayer)
@@ -2074,31 +2074,31 @@ void
 SetAntialiasingFlags(Layer* aLayer, DrawTarget* aTarget)
 {
   bool permitSubpixelAA = !(aLayer->GetContentFlags() & Layer::CONTENT_DISABLE_SUBPIXEL_AA);
   if (aTarget->GetFormat() != SurfaceFormat::B8G8R8A8) {
     aTarget->SetPermitSubpixelAA(permitSubpixelAA);
     return;
   }
 
-  const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
+  const IntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
   gfx::Rect transformedBounds = aTarget->GetTransform().TransformBounds(gfx::Rect(Float(bounds.x), Float(bounds.y),
                                                                                   Float(bounds.width), Float(bounds.height)));
   transformedBounds.RoundOut();
   IntRect intTransformedBounds;
   transformedBounds.ToIntRect(&intTransformedBounds);
   permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
                       aTarget->GetOpaqueRect().Contains(intTransformedBounds);
   aTarget->SetPermitSubpixelAA(permitSubpixelAA);
 }
 
-nsIntRect
+IntRect
 ToOutsideIntRect(const gfxRect &aRect)
 {
   gfxRect r = aRect;
   r.RoundOut();
-  return nsIntRect(r.X(), r.Y(), r.Width(), r.Height());
+  return IntRect(r.X(), r.Y(), r.Width(), r.Height());
 }
 
 PRLogModuleInfo* LayerManager::sLog;
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -32,17 +32,17 @@
 #include "mozilla/gfx/UserData.h"       // for UserData, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsAutoPtr, nsRefPtr, etc
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsCSSProperty.h"              // for nsCSSProperty
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Layer::Release, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsSize.h"                     // for nsIntSize
 #include "nsString.h"                   // for nsCString
 #include "nsTArray.h"                   // for nsTArray
 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
 #include "nscore.h"                     // for nsACString, nsAString
 #include "prlog.h"                      // for PRLogModuleInfo
 #include "nsIWidget.h"                  // For plugin window configuration information structs
@@ -812,17 +812,17 @@ public:
   /**
    * CONSTRUCTION PHASE ONLY
    * The union of the bounds of all the display item that got flattened
    * into this layer. This is intended to be an approximation to the
    * size of the layer if the nearest scrollable ancestor had an infinitely
    * large displayport. Computing this more exactly is too expensive,
    * but this approximation is sufficient for what we need to use it for.
    */
-  virtual void SetLayerBounds(const nsIntRect& aLayerBounds)
+  virtual void SetLayerBounds(const gfx::IntRect& aLayerBounds)
   {
     if (!mLayerBounds.IsEqualEdges(aLayerBounds)) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) LayerBounds", this));
       mLayerBounds = aLayerBounds;
       Mutated();
     }
   }
 
@@ -1218,17 +1218,17 @@ public:
     }
   }
 
   // These getters can be used anytime.
   float GetOpacity() { return mOpacity; }
   gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; }
   const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; }
   uint32_t GetContentFlags() { return mContentFlags; }
-  const nsIntRect& GetLayerBounds() const { return mLayerBounds; }
+  const gfx::IntRect& GetLayerBounds() const { return mLayerBounds; }
   const nsIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
   const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
   uint32_t GetFrameMetricsCount() const { return mFrameMetrics.Length(); }
   const nsTArray<FrameMetrics>& GetAllFrameMetrics() { return mFrameMetrics; }
   bool HasScrollableFrameMetrics() const;
   bool IsScrollInfoLayer() const;
   const EventRegions& GetEventRegions() const { return mEventRegions; }
   ContainerLayer* GetParent() { return mParent; }
@@ -1548,17 +1548,17 @@ public:
   /**
    * Mark the entirety of the layer's visible region as being invalid.
    */
   void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion(); }
 
   /**
    * Adds to the current invalid rect.
    */
-  void AddInvalidRect(const nsIntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); }
+  void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); }
 
   /**
    * Clear the invalid rect, marking the layer as being identical to what is currently
    * composited.
    */
   void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
 
   // These functions allow attaching an AsyncPanZoomController to this layer,
@@ -1670,17 +1670,17 @@ protected:
 
   LayerManager* mManager;
   ContainerLayer* mParent;
   Layer* mNextSibling;
   Layer* mPrevSibling;
   void* mImplData;
   nsRefPtr<Layer> mMaskLayer;
   gfx::UserData mUserData;
-  nsIntRect mLayerBounds;
+  gfx::IntRect mLayerBounds;
   nsIntRegion mVisibleRegion;
   nsTArray<FrameMetrics> mFrameMetrics;
   EventRegions mEventRegions;
   gfx::Matrix4x4 mTransform;
   // A mutation of |mTransform| that we've queued to be applied at the
   // end of the next transaction (if nothing else overrides it in the
   // meantime).
   nsAutoPtr<gfx::Matrix4x4> mPendingTransform;
@@ -1690,17 +1690,17 @@ protected:
   AnimationArray mAnimations;
   // See mPendingTransform above.
   nsAutoPtr<AnimationArray> mPendingAnimations;
   InfallibleTArray<AnimData> mAnimationData;
   float mOpacity;
   gfx::CompositionOp mMixBlendMode;
   bool mForceIsolatedGroup;
   Maybe<ParentLayerIntRect> mClipRect;
-  nsIntRect mTileSourceRect;
+  gfx::IntRect mTileSourceRect;
   nsIntRegion mInvalidRegion;
   nsTArray<nsRefPtr<AsyncPanZoomController> > mApzcs;
   uint32_t mContentFlags;
   bool mUseTileSourceRect;
   bool mIsFixedPosition;
   LayerPoint mAnchor;
   LayerMargin mMargins;
   struct StickyPositionData {
@@ -2069,25 +2069,25 @@ public:
   {
     if (mColor != aColor) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Color", this));
       mColor = aColor;
       Mutated();
     }
   }
 
-  void SetBounds(const nsIntRect& aBounds)
+  void SetBounds(const gfx::IntRect& aBounds)
   {
     if (!mBounds.IsEqualEdges(aBounds)) {
       mBounds = aBounds;
       Mutated();
     }
   }
 
-  const nsIntRect& GetBounds()
+  const gfx::IntRect& GetBounds()
   {
     return mBounds;
   }
 
   // This getter can be used anytime.
   virtual const gfxRGBA& GetColor() { return mColor; }
 
   MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR)
@@ -2104,17 +2104,17 @@ protected:
     : Layer(aManager, aImplData),
       mColor(0.0, 0.0, 0.0, 0.0)
   {}
 
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
 
   virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
 
-  nsIntRect mBounds;
+  gfx::IntRect mBounds;
   gfxRGBA mColor;
 };
 
 /**
  * A Layer for HTML Canvas elements.  It's backed by either a
  * gfxASurface or a GLContext (for WebGL layers), and has some control
  * for intelligent updating from the source if necessary (for example,
  * if hardware compositing is not available, for reading from the GL
@@ -2271,17 +2271,17 @@ protected:
     if (mPostTransCallback) {
       mPostTransCallback(mPostTransCallbackData);
     }
   }
 
   /**
    * 0, 0, canvaswidth, canvasheight
    */
-  nsIntRect mBounds;
+  gfx::IntRect mBounds;
   PreTransactionCallback* mPreTransCallback;
   void* mPreTransCallbackData;
   DidTransactionCallback mPostTransCallback;
   void* mPostTransCallbackData;
   GraphicsFilter mFilter;
 
 private:
   /**
@@ -2399,14 +2399,14 @@ void SetAntialiasingFlags(Layer* aLayer,
 
 #ifdef MOZ_DUMP_PAINTING
 void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf);
 void WriteSnapshotToDumpFile(LayerManager* aManager, gfx::DataSourceSurface* aSurf);
 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget);
 #endif
 
 // A utility function used by different LayerManager implementations.
-nsIntRect ToOutsideIntRect(const gfxRect &aRect);
+gfx::IntRect ToOutsideIntRect(const gfxRect &aRect);
 
-}
-}
+} // namespace layers
+} // namespace mozilla
 
 #endif /* GFX_LAYERS_H */
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -6,17 +6,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "LayersLogging.h"
 #include <stdint.h>                     // for uint8_t
 #include "gfxColor.h"                   // for gfxRGBA
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4, Matrix
 #include "nsDebug.h"                    // for NS_ERROR
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsSize.h"                     // for nsIntSize
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 void
@@ -92,17 +92,17 @@ AppendToString(std::stringstream& aStrea
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
   aStream << nsPrintfCString("(x=%d, y=%d)", p.x, p.y).get();
   aStream << sfx;
 }
 
 void
-AppendToString(std::stringstream& aStream, const nsIntRect& r,
+AppendToString(std::stringstream& aStream, const IntRect& r,
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
   aStream << nsPrintfCString(
     "(x=%d, y=%d, w=%d, h=%d)",
     r.x, r.y, r.width, r.height).get();
   aStream << sfx;
 }
@@ -127,17 +127,17 @@ AppendToString(std::stringstream& aStrea
 void
 AppendToString(std::stringstream& aStream, const nsIntRegion& r,
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
 
   nsIntRegionRectIterator it(r);
   aStream << "< ";
-  while (const nsIntRect* sr = it.Next()) {
+  while (const IntRect* sr = it.Next()) {
     AppendToString(aStream, *sr);
     aStream << "; ";
   }
   aStream << ">";
 
   aStream << sfx;
 }
 
--- a/gfx/layers/ReadbackProcessor.cpp
+++ b/gfx/layers/ReadbackProcessor.cpp
@@ -58,33 +58,33 @@ FindBackgroundLayer(ReadbackLayer* aLaye
 
   for (Layer* l = aLayer->GetPrevSibling(); l; l = l->GetPrevSibling()) {
     gfx::Matrix backgroundTransform;
     if (!l->GetTransform().Is2D(&backgroundTransform) ||
         gfx::ThebesMatrix(backgroundTransform).HasNonIntegerTranslation())
       return nullptr;
 
     nsIntPoint backgroundOffset(int32_t(backgroundTransform._31), int32_t(backgroundTransform._32));
-    nsIntRect rectInBackground(transformOffset - backgroundOffset, aLayer->GetSize());
+    IntRect rectInBackground(transformOffset - backgroundOffset, aLayer->GetSize());
     const nsIntRegion& visibleRegion = l->GetEffectiveVisibleRegion();
     if (!visibleRegion.Intersects(rectInBackground))
       continue;
     // Since l is present in the background, from here on we either choose l
     // or nothing.
     if (!visibleRegion.Contains(rectInBackground))
       return nullptr;
 
     if (l->GetEffectiveOpacity() != 1.0 ||
         l->GetMaskLayer() ||
         !(l->GetContentFlags() & Layer::CONTENT_OPAQUE))
       return nullptr;
 
     // cliprects are post-transform
     const Maybe<ParentLayerIntRect>& clipRect = l->GetEffectiveClipRect();
-    if (clipRect && !clipRect->Contains(ViewAs<ParentLayerPixel>(nsIntRect(transformOffset, aLayer->GetSize()))))
+    if (clipRect && !clipRect->Contains(ViewAs<ParentLayerPixel>(IntRect(transformOffset, aLayer->GetSize()))))
       return nullptr;
 
     Layer::LayerType type = l->GetType();
     if (type != Layer::TYPE_COLOR && type != Layer::TYPE_PAINTED)
       return nullptr;
 
     *aOffset = backgroundOffset - transformOffset;
     return l;
@@ -123,17 +123,17 @@ ReadbackProcessor::BuildUpdatesForLayer(
                                        color);
         aLayer->mSink->EndUpdate(ctx, aLayer->GetRect());
       }
     }
   } else {
     NS_ASSERTION(newBackground->AsPaintedLayer(), "Must be PaintedLayer");
     PaintedLayer* paintedLayer = static_cast<PaintedLayer*>(newBackground);
     // updateRect is relative to the PaintedLayer
-    nsIntRect updateRect = aLayer->GetRect() - offset;
+    IntRect updateRect = aLayer->GetRect() - offset;
     if (paintedLayer != aLayer->mBackgroundLayer ||
         offset != aLayer->mBackgroundLayerOffset) {
       aLayer->mBackgroundLayer = paintedLayer;
       aLayer->mBackgroundLayerOffset = offset;
       aLayer->mBackgroundColor = gfxRGBA(0,0,0,0);
       paintedLayer->SetUsedForReadback(true);
     } else {
       nsIntRegion invalid;
--- a/gfx/layers/ReadbackProcessor.h
+++ b/gfx/layers/ReadbackProcessor.h
@@ -2,17 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_READBACKPROCESSOR_H
 #define GFX_READBACKPROCESSOR_H
 
 #include <stdint.h>                     // for uint64_t
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsTArray.h"                   // for nsTArray
  
 class nsIntRegion;
 
 namespace mozilla {
 namespace layers {
 
 class ContainerLayer;
@@ -41,17 +41,17 @@ public:
      */
     ReadbackLayer* mLayer;
     /**
      * The rectangle of content that it should send, in the PaintedLayer's
      * coordinate system. This rectangle is guaranteed to be in the PaintedLayer's
      * visible region. Translate it to mLayer's coordinate system
      * by adding mLayer->GetBackgroundLayerOffset().
      */
-    nsIntRect      mUpdateRect;
+    gfx::IntRect      mUpdateRect;
     /**
      * The sequence counter value to use when calling DoUpdate
      */
     uint64_t       mSequenceCounter;
   };
   /**
    * Appends any ReadbackLayers that need to be updated, and the rects that
    * need to be updated, to aUpdates. Only need to call this for PaintedLayers
--- a/gfx/layers/RenderTrace.cpp
+++ b/gfx/layers/RenderTrace.cpp
@@ -25,17 +25,17 @@ static gfx::Matrix4x4 GetRootTransform(L
 }
 
 void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform, bool aReset) {
   if (!aLayer)
     return;
 
   gfx::Matrix4x4 trans = aRootTransform * aLayer->GetTransform();
   trans.ProjectTo2D();
-  nsIntRect clipRect = aLayer->GetEffectiveVisibleRegion().GetBounds();
+  gfx::IntRect clipRect = aLayer->GetEffectiveVisibleRegion().GetBounds();
   Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
   trans.TransformBounds(rect);
 
   if (strcmp(aLayer->Name(), "ContainerLayer") != 0 &&
       strcmp(aLayer->Name(), "ContainerLayerComposite") != 0) {
     printf_stderr("%s RENDERTRACE %u rect #%02X%s %i %i %i %i\n",
       aLayer->Name(), (int)PR_IntervalNow(),
       colorId, aColor,
@@ -47,29 +47,29 @@ void RenderTraceLayers(Layer *aLayer, co
   for (Layer* child = aLayer->GetFirstChild();
         child; child = child->GetNextSibling()) {
     RenderTraceLayers(child, aColor, aRootTransform, false);
   }
 
   if (aReset) colorId = 0;
 }
 
-void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect) {
+void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const gfx::IntRect aRect) {
   gfx::Matrix4x4 trans = GetRootTransform(aLayer);
   gfx::Rect rect(aRect.x, aRect.y, aRect.width, aRect.height);
   trans.TransformBounds(rect);
 
   printf_stderr("%s RENDERTRACE %u fillrect #%s %i %i %i %i\n",
     aLayer->Name(), (int)PR_IntervalNow(),
     aColor,
     (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
 }
 void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor) {
   // Clear with an empty rect
-  RenderTraceInvalidateStart(aLayer, aColor, nsIntRect());
+  RenderTraceInvalidateStart(aLayer, aColor, gfx::IntRect());
 }
 
 void renderTraceEventStart(const char *aComment, const char *aColor) {
   printf_stderr("%s RENDERTRACE %u fillrect #%s 0 0 10 10\n",
     aComment, (int)PR_IntervalNow(), aColor);
 }
 
 void renderTraceEventEnd(const char *aComment, const char *aColor) {
--- a/gfx/layers/RenderTrace.h
+++ b/gfx/layers/RenderTrace.h
@@ -20,17 +20,17 @@
 
 namespace mozilla {
 namespace layers {
 
 class Layer;
 
 void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform = gfx::Matrix4x4(), bool aReset = true);
 
-void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect);
+void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const gfx::IntRect aRect);
 void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor);
 
 void renderTraceEventStart(const char *aComment, const char *aColor);
 void renderTraceEventEnd(const char *aComment, const char *aColor);
 void renderTraceEventEnd(const char *aColor);
 
 struct RenderTraceScope {
 public:
@@ -47,17 +47,17 @@ private:
   const char *mComment;
   const char *mColor;
 };
 
 #ifndef MOZ_RENDERTRACE
 inline void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform, bool aReset)
 {}
 
-inline void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect)
+inline void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const gfx::IntRect aRect)
 {}
 
 inline void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor)
 {}
 
 inline void renderTraceEventStart(const char *aComment, const char *aColor)
 {}
 
--- a/gfx/layers/TiledLayerBuffer.h
+++ b/gfx/layers/TiledLayerBuffer.h
@@ -12,17 +12,17 @@
 
 #include <stdint.h>                     // for uint16_t, uint32_t
 #include <sys/types.h>                  // for int32_t
 #include "gfxPlatform.h"                // for GetTileWidth/GetTileHeight
 #include "LayersLogging.h"              // for print_stderr
 #include "mozilla/gfx/Logging.h"        // for gfxCriticalError
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray
 
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
 #include <ui/Fence.h>
 #endif
 
 namespace mozilla {
@@ -269,17 +269,17 @@ TiledLayerBuffer<Derived, Tile>::GetTile
   return mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile());
 }
 
 template<typename Derived, typename Tile> void
 TiledLayerBuffer<Derived, Tile>::Dump(std::stringstream& aStream,
                                       const char* aPrefix,
                                       bool aDumpHtml)
 {
-  nsIntRect visibleRect = GetValidRegion().GetBounds();
+  gfx::IntRect visibleRect = GetValidRegion().GetBounds();
   gfx::IntSize scaledTileSize = GetScaledTileSize();
   for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) {
     int32_t tileStartX = GetTileStart(x, scaledTileSize.width);
     int32_t w = scaledTileSize.width - tileStartX;
 
     for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) {
       int32_t tileStartY = GetTileStart(y, scaledTileSize.height);
       Tile tileTexture =
@@ -304,18 +304,18 @@ TiledLayerBuffer<Derived, Tile>::Dump(st
 template<typename Derived, typename Tile> void
 TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& newValidRegion,
                                         const nsIntRegion& aPaintRegion)
 {
   gfx::IntSize scaledTileSize = GetScaledTileSize();
 
   nsTArray<Tile>  newRetainedTiles;
   nsTArray<Tile>& oldRetainedTiles = mRetainedTiles;
-  const nsIntRect oldBound = mValidRegion.GetBounds();
-  const nsIntRect newBound = newValidRegion.GetBounds();
+  const gfx::IntRect oldBound = mValidRegion.GetBounds();
+  const gfx::IntRect newBound = newValidRegion.GetBounds();
   const nsIntPoint oldBufferOrigin(RoundDownToTileEdge(oldBound.x, scaledTileSize.width),
                                    RoundDownToTileEdge(oldBound.y, scaledTileSize.height));
   const nsIntPoint newBufferOrigin(RoundDownToTileEdge(newBound.x, scaledTileSize.width),
                                    RoundDownToTileEdge(newBound.y, scaledTileSize.height));
 
   // This is the reason we break the style guide with newValidRegion instead
   // of aNewValidRegion - so that the names match better and code easier to read
   const nsIntRegion& oldValidRegion = mValidRegion;
@@ -356,17 +356,17 @@ TiledLayerBuffer<Derived, Tile>::Update(
 
     tileY = 0;
     for (int32_t y = newBound.y; y < newBound.YMost(); tileY++) {
       int height = scaledTileSize.height - GetTileStart(y, scaledTileSize.height);
       if (y + height > newBound.y + newBound.height) {
         height = newBound.y + newBound.height - y;
       }
 
-      const nsIntRect tileRect(x,y,width,height);
+      const gfx::IntRect tileRect(x,y,width,height);
       if (oldValidRegion.Intersects(tileRect) && newValidRegion.Intersects(tileRect)) {
         // This old tiles contains some valid area so move it to the new tile
         // buffer. Replace the tile in the old buffer with a placeholder
         // to leave the old buffer index unaffected.
         int tileX = floor_div(x - oldBufferOrigin.x, scaledTileSize.width);
         int tileY = floor_div(y - oldBufferOrigin.y, scaledTileSize.height);
         int index = tileX * oldRetainedHeight + tileY;
 
@@ -501,17 +501,17 @@ TiledLayerBuffer<Derived, Tile>::Update(
     tileY = 0;
     for (int y = newBound.y; y < newBound.y + newBound.height; tileY++) {
       int tileStartY = RoundDownToTileEdge(y, scaledTileSize.height);
       int height = scaledTileSize.height - GetTileStart(y, scaledTileSize.height);
       if (y + height > newBound.YMost()) {
         height = newBound.YMost() - y;
       }
 
-      const nsIntRect tileRect(x, y, width, height);
+      const gfx::IntRect tileRect(x, y, width, height);
 
       nsIntRegion tileDrawRegion;
       tileDrawRegion.And(tileRect, regionToPaint);
 
       if (tileDrawRegion.IsEmpty()) {
         // We have a tile but it doesn't hit the draw region
         // because we can reuse all of the content from the
         // previous buffer.
--- a/gfx/layers/basic/BasicColorLayer.cpp
+++ b/gfx/layers/basic/BasicColorLayer.cpp
@@ -10,17 +10,17 @@
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxRect.h"                    // for gfxRect
 #include "gfx2DGlue.h"
 #include "mozilla/mozalloc.h"           // for operator new
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "mozilla/gfx/PathHelpers.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -484,17 +484,17 @@ BasicCompositor::BeginFrame(const nsIntR
   mWidgetSize = mWidget->GetClientSize();
   IntRect intRect = gfx::IntRect(IntPoint(), mWidgetSize);
   Rect rect = Rect(0, 0, intRect.width, intRect.height);
 
   // Sometimes the invalid region is larger than we want to draw.
   nsIntRegion invalidRegionSafe;
   invalidRegionSafe.And(aInvalidRegion, intRect);
 
-  nsIntRect invalidRect = invalidRegionSafe.GetBounds();
+  IntRect invalidRect = invalidRegionSafe.GetBounds();
   mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
   mInvalidRegion = invalidRegionSafe;
 
   if (aRenderBoundsOut) {
     *aRenderBoundsOut = Rect();
   }
 
   if (mInvalidRect.width <= 0 || mInvalidRect.height <= 0) {
@@ -568,17 +568,17 @@ BasicCompositor::EndFrame()
   RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
 
   nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
 
   // The source DrawTarget is clipped to the invalidation region, so we have
   // to copy the individual rectangles in the region or else we'll draw blank
   // pixels.
   nsIntRegionRectIterator iter(mInvalidRegion);
-  for (const nsIntRect *r = iter.Next(); r; r = iter.Next()) {
+  for (const IntRect *r = iter.Next(); r; r = iter.Next()) {
     dest->CopySurface(source,
                       IntRect(r->x - mInvalidRect.x, r->y - mInvalidRect.y, r->width, r->height),
                       IntPoint(r->x - offset.x, r->y - offset.y));
   }
   if (!mTarget) {
     mWidget->EndRemoteDrawing();
   }
 
--- a/gfx/layers/basic/BasicImageLayer.cpp
+++ b/gfx/layers/basic/BasicImageLayer.cpp
@@ -9,17 +9,17 @@
 #include "Layers.h"                     // for Layer (ptr only), etc
 #include "basic/BasicImplData.h"        // for BasicImplData
 #include "basic/BasicLayers.h"          // for BasicLayerManager
 #include "mozilla/mozalloc.h"           // for operator new
 #include "nsAutoPtr.h"                  // for nsRefPtr, getter_AddRefs, etc
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for gfxPattern::Release, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "mozilla/gfx/Point.h"          // for IntSize
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -38,17 +38,17 @@
 #include "mozilla/gfx/Rect.h"           // for IntRect, Rect
 #include "mozilla/layers/LayersTypes.h"  // for BufferMode::BUFFER_NONE, etc
 #include "mozilla/mozalloc.h"           // for operator new
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION, etc
 #include "nsISupportsImpl.h"            // for gfxContext::Release, etc
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion, etc
 #include "nsTArray.h"                   // for nsAutoTArray
 #ifdef MOZ_ENABLE_SKIA
 #include "skia/SkCanvas.h"              // for SkCanvas
 #include "skia/SkBitmapDevice.h"        // for SkBitmapDevice
 #else
 #define PIXMAN_DONT_DEFINE_STDINT
 #include "pixman.h"                     // for pixman_f_transform, etc
@@ -62,17 +62,17 @@ using namespace mozilla::gfx;
 
 /**
  * Clips to the smallest device-pixel-aligned rectangle containing aRect
  * in user space.
  * Returns true if the clip is "perfect", i.e. we actually clipped exactly to
  * aRect.
  */
 static bool
-ClipToContain(gfxContext* aContext, const nsIntRect& aRect)
+ClipToContain(gfxContext* aContext, const IntRect& aRect)
 {
   gfxRect userRect(aRect.x, aRect.y, aRect.width, aRect.height);
   gfxRect deviceRect = aContext->UserToDevice(userRect);
   deviceRect.RoundOut();
 
   gfxMatrix currentMatrix = aContext->CurrentMatrix();
   aContext->SetMatrix(gfxMatrix());
   aContext->NewPath();
@@ -110,22 +110,22 @@ BasicLayerManager::PushGroupForLayer(gfx
       aContext->PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA);
     } else {
       aContext->PushGroup(gfxContentType::COLOR_ALPHA);
     }
   }
   return result.forget();
 }
 
-static nsIntRect
+static IntRect
 ToInsideIntRect(const gfxRect& aRect)
 {
   gfxRect r = aRect;
   r.RoundIn();
-  return nsIntRect(r.X(), r.Y(), r.Width(), r.Height());
+  return IntRect(r.X(), r.Y(), r.Width(), r.Height());
 }
 
 // A context helper for BasicLayerManager::PaintLayer() that holds all the
 // painting context together in a data structure so it can be easily passed
 // around. It also uses ensures that the Transform and Opaque rect are restored
 // to their former state on destruction.
 
 class PaintLayerContext {
@@ -164,17 +164,17 @@ public:
   {
     mTarget->SetMatrix(ThebesMatrix(mTransform));
   }
 
   // Set the opaque rect to match the bounds of the visible region.
   void AnnotateOpaqueRect()
   {
     const nsIntRegion& visibleRegion = mLayer->GetEffectiveVisibleRegion();
-    const nsIntRect& bounds = visibleRegion.GetBounds();
+    const IntRect& bounds = visibleRegion.GetBounds();
 
     DrawTarget *dt = mTarget->GetDrawTarget();
     const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
 
     // Try to annotate currentSurface with a region of pixels that have been
     // (or will be) painted opaque, if no such region is currently set.
     if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
         (mLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
@@ -276,18 +276,18 @@ BasicLayerManager::BeginTransactionWithT
 #endif
 
   NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
   mPhase = PHASE_CONSTRUCTION;
   mTarget = aTarget;
 }
 
 static void
-TransformIntRect(nsIntRect& aRect, const Matrix& aMatrix,
-                 nsIntRect (*aRoundMethod)(const gfxRect&))
+TransformIntRect(IntRect& aRect, const Matrix& aMatrix,
+                 IntRect (*aRoundMethod)(const gfxRect&))
 {
   Rect gr = Rect(aRect.x, aRect.y, aRect.width, aRect.height);
   gr = aMatrix.TransformBounds(gr);
   aRect = (*aRoundMethod)(ThebesRect(gr));
 }
 
 /**
  * This function assumes that GetEffectiveTransform transforms
@@ -304,34 +304,34 @@ TransformIntRect(nsIntRect& aRect, const
  * coordinate system. Layers outside this rect should be hidden.
  * @param aOpaqueRegion the opaque region covering aLayer, in the
  * root coordinate system.
  */
 enum {
     ALLOW_OPAQUE = 0x01,
 };
 static void
-MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
-                 const nsIntRect& aDirtyRect,
+MarkLayersHidden(Layer* aLayer, const IntRect& aClipRect,
+                 const IntRect& aDirtyRect,
                  nsIntRegion& aOpaqueRegion,
                  uint32_t aFlags)
 {
-  nsIntRect newClipRect(aClipRect);
+  IntRect newClipRect(aClipRect);
   uint32_t newFlags = aFlags;
 
   // Allow aLayer or aLayer's descendants to cover underlying layers
   // only if it's opaque.
   if (aLayer->GetOpacity() != 1.0f) {
     newFlags &= ~ALLOW_OPAQUE;
   }
 
   {
     const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetEffectiveClipRect();
     if (clipRect) {
-      nsIntRect cr = ParentLayerIntRect::ToUntyped(*clipRect);
+      IntRect cr = ParentLayerIntRect::ToUntyped(*clipRect);
       // clipRect is in the container's coordinate system. Get it into the
       // global coordinate system.
       if (aLayer->GetParent()) {
         Matrix tr;
         if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
           // Clip rect is applied after aLayer's transform, i.e., in the coordinate
           // system of aLayer's parent.
           TransformIntRect(cr, tr, ToInsideIntRect);
@@ -351,27 +351,27 @@ MarkLayersHidden(Layer* aLayer, const ns
   if (!aLayer->AsContainerLayer()) {
     Matrix transform;
     if (!aLayer->GetEffectiveTransform().CanDraw2D(&transform)) {
       data->SetHidden(false);
       return;
     }
 
     nsIntRegion region = aLayer->GetEffectiveVisibleRegion();
-    nsIntRect r = region.GetBounds();
+    IntRect r = region.GetBounds();
     TransformIntRect(r, transform, ToOutsideIntRect);
     r.IntersectRect(r, aDirtyRect);
     data->SetHidden(aOpaqueRegion.Contains(r));
 
     // Allow aLayer to cover underlying layers only if aLayer's
     // content is opaque
     if ((aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
         (newFlags & ALLOW_OPAQUE)) {
       nsIntRegionRectIterator it(region);
-      while (const nsIntRect* sr = it.Next()) {
+      while (const IntRect* sr = it.Next()) {
         r = *sr;
         TransformIntRect(r, transform, ToInsideIntRect);
 
         r.IntersectRect(r, newClipRect);
         aOpaqueRegion.Or(aOpaqueRegion, r);
       }
     }
   } else {
@@ -390,28 +390,28 @@ MarkLayersHidden(Layer* aLayer, const ns
 /**
  * This function assumes that GetEffectiveTransform transforms
  * all layers to the same coordinate system (the "root coordinate system").
  * MarkLayersHidden must be called before calling this.
  * @param aVisibleRect the rectangle of aLayer that is visible (i.e. not
  * clipped and in the dirty rect), in the root coordinate system.
  */
 static void
-ApplyDoubleBuffering(Layer* aLayer, const nsIntRect& aVisibleRect)
+ApplyDoubleBuffering(Layer* aLayer, const IntRect& aVisibleRect)
 {
   BasicImplData* data = ToData(aLayer);
   if (data->IsHidden())
     return;
 
-  nsIntRect newVisibleRect(aVisibleRect);
+  IntRect newVisibleRect(aVisibleRect);
 
   {
     const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetEffectiveClipRect();
     if (clipRect) {
-      nsIntRect cr = ParentLayerIntRect::ToUntyped(*clipRect);
+      IntRect cr = ParentLayerIntRect::ToUntyped(*clipRect);
       // clipRect is in the container's coordinate system. Get it into the
       // global coordinate system.
       if (aLayer->GetParent()) {
         Matrix tr;
         if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
           NS_ASSERTION(!ThebesMatrix(tr).HasNonIntegerTranslation(),
                        "Parent can only have an integer translation");
           cr += nsIntPoint(int32_t(tr._31), int32_t(tr._32));
@@ -509,17 +509,17 @@ BasicLayerManager::EndTransactionInterna
     if (mRoot->GetMaskLayer()) {
       ToData(mRoot->GetMaskLayer())->Validate(aCallback, aCallbackData, nullptr);
     }
   }
 
   if (mTarget && mRoot &&
       !(aFlags & END_NO_IMMEDIATE_REDRAW) &&
       !(aFlags & END_NO_COMPOSITE)) {
-    nsIntRect clipRect;
+    IntRect clipRect;
 
     {
       gfxContextMatrixAutoSaveRestore save(mTarget);
       mTarget->SetMatrix(gfxMatrix());
       clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
     }
 
     if (IsRetained()) {
@@ -528,17 +528,17 @@ BasicLayerManager::EndTransactionInterna
       if (mUsingDefaultTarget && mDoubleBuffering != BufferMode::BUFFER_NONE) {
         ApplyDoubleBuffering(mRoot, clipRect);
       }
     }
 
     PaintLayer(mTarget, mRoot, aCallback, aCallbackData);
     if (!mRegionToClear.IsEmpty()) {
       nsIntRegionRectIterator iter(mRegionToClear);
-      const nsIntRect *r;
+      const IntRect *r;
       while ((r = iter.Next())) {
         mTarget->GetDrawTarget()->ClearRect(Rect(r->x, r->y, r->width, r->height));
       }
     }
     if (mWidget) {
       FlashWidgetUpdateArea(mTarget);
     }
     RecordFrame();
@@ -923,17 +923,17 @@ BasicLayerManager::PaintLayer(gfxContext
                                       &needsClipToVisibleRegion);
       PaintSelfOrChildren(paintLayerContext, groupTarget);
       aTarget->PopGroupToSource();
       FlushGroup(paintLayerContext, needsClipToVisibleRegion);
     } else {
       PaintSelfOrChildren(paintLayerContext, aTarget);
     }
   } else {
-    const nsIntRect& bounds = visibleRegion.GetBounds();
+    const IntRect& bounds = visibleRegion.GetBounds();
     RefPtr<DrawTarget> untransformedDT =
       gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(bounds.width, bounds.height),
                                                                    SurfaceFormat::B8G8R8A8);
     if (!untransformedDT) {
       return;
     }
 
     nsRefPtr<gfxContext> groupTarget = new gfxContext(untransformedDT,
--- a/gfx/layers/basic/BasicPaintedLayer.cpp
+++ b/gfx/layers/basic/BasicPaintedLayer.cpp
@@ -18,32 +18,32 @@
 #include "mozilla/gfx/Matrix.h"         // for Matrix
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for gfxContext::Release, etc
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "AutoMaskData.h"
 #include "gfx2DGlue.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 static nsIntRegion
 IntersectWithClip(const nsIntRegion& aRegion, gfxContext* aContext)
 {
   gfxRect clip = aContext->GetClipExtents();
   clip.RoundOut();
-  nsIntRect r(clip.X(), clip.Y(), clip.Width(), clip.Height());
+  IntRect r(clip.X(), clip.Y(), clip.Width(), clip.Height());
   nsIntRegion result;
   result.And(aRegion, r);
   return result;
 }
 
 void
 BasicPaintedLayer::PaintThebes(gfxContext* aContext,
                               Layer* aMaskLayer,
--- a/gfx/layers/basic/X11BasicCompositor.cpp
+++ b/gfx/layers/basic/X11BasicCompositor.cpp
@@ -49,17 +49,17 @@ X11DataTextureSourceBasic::Update(gfx::D
 
   // Image contents have changed, upload to our DrawTarget
   // If aDestRegion is null, means we're updating the whole surface
   // Note : Incremental update with a source offset is only used on Mac.
   NS_ASSERTION(!aSrcOffset, "SrcOffset should not be used with linux OMTC basic");
 
   if (aDestRegion) {
     nsIntRegionRectIterator iter(*aDestRegion);
-    while (const nsIntRect* iterRect = iter.Next()) {
+    while (const IntRect* iterRect = iter.Next()) {
       IntRect srcRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height);
       IntPoint dstPoint(iterRect->x, iterRect->y);
 
       // We're uploading regions to our buffer, so let's just copy contents over
       mBufferDrawTarget->CopySurface(aSurface, srcRect, dstPoint);
     }
   } else {
     // We're uploading the whole buffer, so let's just copy the full surface
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -10,17 +10,17 @@
 #include "SharedSurfaceEGL.h"           // for SurfaceFactory_EGLImage
 #include "SharedSurfaceGL.h"            // for SurfaceFactory_GLTexture, etc
 #include "ClientLayerManager.h"         // for ClientLayerManager, etc
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "gfxPrefs.h"                   // for WebGLForceLayersReadback
 
 #ifdef XP_WIN
 #include "SharedSurfaceANGLE.h"         // for SurfaceFactory_ANGLEShareHandle
 #include "gfxWindowsPlatform.h"
 #endif
 
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -194,17 +194,17 @@ ClientLayerManager::BeginTransactionWith
   dom::ScreenOrientation orientation;
   if (dom::TabChild* window = mWidget->GetOwningTabChild()) {
     orientation = window->GetOrientation();
   } else {
     hal::ScreenConfiguration currentConfig;
     hal::GetCurrentScreenConfiguration(&currentConfig);
     orientation = currentConfig.orientation();
   }
-  nsIntRect targetBounds = mWidget->GetNaturalBounds();
+  IntRect targetBounds = mWidget->GetNaturalBounds();
   targetBounds.x = targetBounds.y = 0;
   mForwarder->BeginTransaction(targetBounds, mTargetRotation, orientation);
 
   // If we're drawing on behalf of a context with async pan/zoom
   // enabled, then the entire buffer of painted layers might be
   // composited (including resampling) asynchronously before we get
   // a chance to repaint, so we have to ensure that it's all valid
   // and not rotated.
@@ -461,20 +461,20 @@ ClientLayerManager::MakeSnapshotIfRequir
   if (!mShadowTarget) {
     return;
   }
   if (mWidget) {
     if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
       // The compositor doesn't draw to a different sized surface
       // when there's a rotation. Instead we rotate the result
       // when drawing into dt
-      nsIntRect outerBounds;
+      IntRect outerBounds;
       mWidget->GetBounds(outerBounds);
 
-      nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
+      IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
       if (mTargetRotation) {
         bounds = RotateRect(bounds, outerBounds, mTargetRotation);
       }
 
       SurfaceDescriptor inSnapshot;
       if (!bounds.IsEmpty() &&
           mForwarder->AllocSurfaceDescriptor(bounds.Size(),
                                              gfxContentType::COLOR_ALPHA,
@@ -786,10 +786,10 @@ ClientLayerManager::ProgressiveUpdateCal
 ClientLayer::~ClientLayer()
 {
   if (HasShadow()) {
     PLayerChild::Send__delete__(GetShadow());
   }
   MOZ_COUNT_DTOR(ClientLayer);
 }
 
-} // layers
-} // mozilla
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -16,17 +16,17 @@
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersTypes.h"  // for BufferMode, LayersBackend, etc
 #include "mozilla/layers/ShadowLayers.h"  // for ShadowLayerForwarder, etc
 #include "mozilla/layers/APZTestData.h" // for APZTestData
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsIObserver.h"                // for nsIObserver
 #include "nsISupportsImpl.h"            // for Layer::Release, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsAString
 #include "mozilla/layers/TransactionIdAllocator.h"
 #include "nsIWidget.h"                  // For plugin window configuration information structs
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/client/ClientPaintedLayer.cpp
+++ b/gfx/layers/client/ClientPaintedLayer.cpp
@@ -16,17 +16,17 @@
 #include "mozilla/gfx/Matrix.h"         // for Matrix
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/Preferences.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "gfx2DGlue.h"
 #include "ReadbackProcessor.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -131,17 +131,17 @@ ContentClient::PrintInfo(std::stringstre
 // this client will not have a ContentHost on the other side.
 ContentClientBasic::ContentClientBasic()
   : ContentClient(nullptr)
   , RotatedContentBuffer(ContainsVisibleBounds)
 {}
 
 void
 ContentClientBasic::CreateBuffer(ContentType aType,
-                                 const nsIntRect& aRect,
+                                 const IntRect& aRect,
                                  uint32_t aFlags,
                                  RefPtr<gfx::DrawTarget>* aBlackDT,
                                  RefPtr<gfx::DrawTarget>* aWhiteDT)
 {
   MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA));
   gfxImageFormat format =
     gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
 
@@ -166,17 +166,17 @@ ContentClientRemoteBuffer::DestroyBuffer
 
   DestroyFrontBuffer();
 }
 
 class RemoteBufferReadbackProcessor : public TextureReadbackSink
 {
 public:
   RemoteBufferReadbackProcessor(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates,
-                                const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
+                                const IntRect& aBufferRect, const nsIntPoint& aBufferRotation)
     : mReadbackUpdates(*aReadbackUpdates)
     , mBufferRect(aBufferRect)
     , mBufferRotation(aBufferRotation)
   {
     for (uint32_t i = 0; i < mReadbackUpdates.Length(); ++i) {
       mLayerRefs.push_back(mReadbackUpdates[i].mLayer);
     }
   }
@@ -216,17 +216,17 @@ public:
     }
   }
 
 private:
   nsTArray<ReadbackProcessor::Update> mReadbackUpdates;
   // This array is used to keep the layers alive until the callback.
   vector<RefPtr<Layer>> mLayerRefs;
 
-  nsIntRect mBufferRect;
+  IntRect mBufferRect;
   nsIntPoint mBufferRotation;
 };
 
 void
 ContentClientRemoteBuffer::BeginPaint()
 {
   EnsureBackBufferIfFrontBuffer();
 
@@ -271,17 +271,17 @@ ContentClientRemoteBuffer::EndPaint(nsTA
     mTextureClientOnWhite->SyncWithObject(mForwarder->GetSyncObject());
   }
 
   ContentClientRemote::EndPaint(aReadbackUpdates);
 }
 
 void
 ContentClientRemoteBuffer::BuildTextureClients(SurfaceFormat aFormat,
-                                               const nsIntRect& aRect,
+                                               const IntRect& aRect,
                                                uint32_t aFlags)
 {
   // If we hit this assertion, then it might be due to an empty transaction
   // followed by a real transaction. Our buffers should be created (but not
   // painted in the empty transaction) and then painted (but not created) in the
   // real transaction. That is kind of fragile, and this assert will catch
   // circumstances where we screw that up, e.g., by unnecessarily recreating our
   // buffers.
@@ -299,17 +299,17 @@ ContentClientRemoteBuffer::BuildTextureC
   if (aFlags & BUFFER_COMPONENT_ALPHA) {
     mTextureFlags |= TextureFlags::COMPONENT_ALPHA;
   }
 
   CreateBackBuffer(mBufferRect);
 }
 
 void
-ContentClientRemoteBuffer::CreateBackBuffer(const nsIntRect& aBufferRect)
+ContentClientRemoteBuffer::CreateBackBuffer(const IntRect& aBufferRect)
 {
   // gfx::BackendType::NONE means fallback to the content backend
   mTextureClient = CreateTextureClientForDrawing(
     mSurfaceFormat, mSize, gfx::BackendType::NONE,
     mTextureFlags,
     TextureAllocationFlags::ALLOC_CLEAR_BUFFER
   );
   if (!mTextureClient || !AddTextureClient(mTextureClient)) {
@@ -326,17 +326,17 @@ ContentClientRemoteBuffer::CreateBackBuf
       AbortTextureClientCreation();
       return;
     }
   }
 }
 
 void
 ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
-                                        const nsIntRect& aRect,
+                                        const IntRect& aRect,
                                         uint32_t aFlags,
                                         RefPtr<gfx::DrawTarget>* aBlackDT,
                                         RefPtr<gfx::DrawTarget>* aWhiteDT)
 {
   BuildTextureClients(gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aType), aRect, aFlags);
   if (!mTextureClient) {
     return;
   }
@@ -482,17 +482,17 @@ ContentClientDoubleBuffered::SwapBuffers
   RefPtr<TextureClient> oldBack = mTextureClient;
   mTextureClient = mFrontClient;
   mFrontClient = oldBack;
 
   oldBack = mTextureClientOnWhite;
   mTextureClientOnWhite = mFrontClientOnWhite;
   mFrontClientOnWhite = oldBack;
 
-  nsIntRect oldBufferRect = mBufferRect;
+  IntRect oldBufferRect = mBufferRect;
   mBufferRect = mFrontBufferRect;
   mFrontBufferRect = oldBufferRect;
 
   nsIntPoint oldBufferRotation = mBufferRotation;
   mBufferRotation = mFrontBufferRotation;
   mFrontBufferRotation = oldBufferRotation;
 
   MOZ_ASSERT(mFrontClient);
@@ -663,10 +663,10 @@ ContentClientSingleBuffered::FinalizeFra
     MOZ_ASSERT(locked);
   }
   if (mTextureClientOnWhite) {
     DebugOnly<bool> locked = mTextureClientOnWhite->Lock(OpenMode::OPEN_READ_WRITE);
     MOZ_ASSERT(locked);
   }
 }
 
-}
-}
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -19,17 +19,17 @@
 #include "mozilla/layers/CompositorTypes.h"  // for TextureInfo, etc
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "ReadbackProcessor.h"          // For ReadbackProcessor::Update
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray
 
 namespace mozilla {
 namespace gfx {
 class DrawTarget;
 }
 
@@ -156,17 +156,17 @@ public:
               gfx::CompositionOp aOp,
               gfx::SourceSurface* aMask,
               const gfx::Matrix* aMaskTransform)
   {
     RotatedContentBuffer::DrawTo(aLayer, aTarget, aOpacity, aOp,
                                  aMask, aMaskTransform);
   }
 
-  virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
+  virtual void CreateBuffer(ContentType aType, const gfx::IntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) override;
 
   virtual TextureInfo GetTextureInfo() const override
   {
     MOZ_CRASH("Should not be called on non-remote ContentClient");
   }
 };
 
@@ -242,40 +242,40 @@ public:
 
   virtual void Updated(const nsIntRegion& aRegionToDraw,
                        const nsIntRegion& aVisibleRegion,
                        bool aDidSelfCopy) override;
 
   virtual void SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) override;
 
   // Expose these protected methods from the superclass.
-  virtual const nsIntRect& BufferRect() const
+  virtual const gfx::IntRect& BufferRect() const
   {
     return RotatedContentBuffer::BufferRect();
   }
   virtual const nsIntPoint& BufferRotation() const
   {
     return RotatedContentBuffer::BufferRotation();
   }
 
-  virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
+  virtual void CreateBuffer(ContentType aType, const gfx::IntRect& aRect, uint32_t aFlags,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) override;
 
 protected:
   void DestroyBuffers();
 
   virtual nsIntRegion GetUpdatedRegion(const nsIntRegion& aRegionToDraw,
                                        const nsIntRegion& aVisibleRegion,
                                        bool aDidSelfCopy);
 
   void BuildTextureClients(gfx::SurfaceFormat aFormat,
-                           const nsIntRect& aRect,
+                           const gfx::IntRect& aRect,
                            uint32_t aFlags);
 
-  void CreateBackBuffer(const nsIntRect& aBufferRect);
+  void CreateBackBuffer(const gfx::IntRect& aBufferRect);
 
   // Ensure we have a valid back buffer if we have a valid front buffer (i.e.
   // if a backbuffer has been created.)
   virtual void EnsureBackBufferIfFrontBuffer() {}
 
   // Create the front buffer for the ContentClient/Host pair if necessary
   // and notify the compositor that we have created the buffer(s).
   virtual void DestroyFrontBuffer() {}
@@ -360,17 +360,17 @@ private:
     mTextureClientOnWhite = nullptr;
     mFrontClient = nullptr;
     mFrontClientOnWhite = nullptr;
   }
 
   RefPtr<TextureClient> mFrontClient;
   RefPtr<TextureClient> mFrontClientOnWhite;
   nsIntRegion mFrontUpdatedRegion;
-  nsIntRect mFrontBufferRect;
+  gfx::IntRect mFrontBufferRect;
   nsIntPoint mFrontBufferRotation;
 };
 
 /**
  * A single buffered ContentClient. We have a single TextureClient/Host
  * which we update and then send a message to the compositor that we are
  * done updating. It is not safe for the compositor to use the corresponding
  * TextureHost's memory directly, it must upload it to video memory of some
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -25,17 +25,17 @@
 #include "mozilla/layers/SharedRGBImage.h"
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
 #include "mozilla/layers/TextureClientOGL.h"  // for SurfaceTextureClient
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::Release, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "mozilla/gfx/2D.h"
 #ifdef MOZ_WIDGET_GONK
 #include "GrallocImages.h"
 #endif
 
 namespace mozilla {
 namespace layers {
 
@@ -274,17 +274,17 @@ ImageClientSingle::OnDetach()
 ImageClient::ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
                          CompositableType aType)
 : CompositableClient(aFwd, aFlags)
 , mType(aType)
 , mLastPaintedImageSerial(0)
 {}
 
 void
-ImageClient::UpdatePictureRect(nsIntRect aRect)
+ImageClient::UpdatePictureRect(IntRect aRect)
 {
   if (mPictureRect == aRect) {
     return;
   }
   mPictureRect = aRect;
   MOZ_ASSERT(mForwarder);
   GetForwarder()->UpdatePictureRect(this, aRect);
 }
@@ -380,10 +380,10 @@ ImageClientOverlay::CreateImage(ImageFor
       img = new OverlayImage();
       return img.forget();
     default:
       return nullptr;
   }
 }
 
 #endif
-}
-}
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/client/ImageClient.h
+++ b/gfx/layers/client/ImageClient.h
@@ -13,17 +13,17 @@
 #include "mozilla/gfx/Types.h"          // for SurfaceFormat
 #include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
 #include "mozilla/layers/CompositorTypes.h"  // for CompositableType, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 
 namespace mozilla {
 namespace layers {
 
 class CompositableForwarder;
 class AsyncTransactionTracker;
 class Image;
 class ImageContainer;
@@ -54,17 +54,17 @@ public:
    * Note that returning true does not necessarily imply success
    */
   virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) = 0;
 
   /**
    * The picture rect is the area of the texture which makes up the image. That
    * is, the area that should be composited. In texture space.
    */
-  virtual void UpdatePictureRect(nsIntRect aPictureRect);
+  virtual void UpdatePictureRect(gfx::IntRect aPictureRect);
 
   virtual already_AddRefed<Image> CreateImage(ImageFormat aFormat) = 0;
 
   /**
    * Create AsyncTransactionTracker that is used for FlushAllImagesAsync().
    */
   virtual TemporaryRef<AsyncTransactionTracker> PrepareFlushAllImages() { return nullptr; }
 
@@ -81,17 +81,17 @@ public:
                                 AsyncTransactionTracker* aAsyncTransactionTracker = nullptr);
 
 protected:
   ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
               CompositableType aType);
 
   CompositableType mType;
   int32_t mLastPaintedImageSerial;
-  nsIntRect mPictureRect;
+  gfx::IntRect mPictureRect;
 };
 
 /**
  * An image client which uses a single texture client.
  */
 class ImageClientSingle : public ImageClient
 {
 public:
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -613,17 +613,17 @@ CopyFrontToBack(TextureClient* aFront,
 }
 
 void
 TileClient::ValidateBackBufferFromFront(const nsIntRegion& aDirtyRegion,
                                         nsIntRegion& aAddPaintedRegion)
 {
   if (mBackBuffer && mFrontBuffer) {
     gfx::IntSize tileSize = mFrontBuffer->GetSize();
-    const nsIntRect tileRect = nsIntRect(0, 0, tileSize.width, tileSize.height);
+    const IntRect tileRect = IntRect(0, 0, tileSize.width, tileSize.height);
 
     if (aDirtyRegion.Contains(tileRect)) {
       // The dirty region means that we no longer need the front buffer, so
       // discard it.
       DiscardFrontBuffer();
     } else {
       // Region that needs copying.
       nsIntRegion regionToCopy = mInvalidBack;
@@ -635,17 +635,17 @@ TileClient::ValidateBackBufferFromFront(
       if (regionToCopy.IsEmpty()) {
         // Just redraw it all.
         return;
       }
 
       // Copy the bounding rect of regionToCopy. As tiles are quite small, it
       // is unlikely that we'd save much by copying each individual rect of the
       // region, but we can reevaluate this if it becomes an issue.
-      const nsIntRect rectToCopy = regionToCopy.GetBounds();
+      const IntRect rectToCopy = regionToCopy.GetBounds();
       gfx::IntRect gfxRectToCopy(rectToCopy.x, rectToCopy.y, rectToCopy.width, rectToCopy.height);
       CopyFrontToBack(mFrontBuffer, mBackBuffer, gfxRectToCopy);
 
       if (mBackBufferOnWhite) {
         MOZ_ASSERT(mFrontBufferOnWhite);
         CopyFrontToBack(mFrontBufferOnWhite, mBackBufferOnWhite, gfxRectToCopy);
       }
 
@@ -785,17 +785,17 @@ TileClient::GetBackBuffer(const nsIntReg
       mBackLock = new gfxMemorySharedReadLock();
     } else {
       mBackLock = new gfxShmSharedReadLock(mManager->AsShadowForwarder());
     }
 
     MOZ_ASSERT(mBackLock->IsValid());
 
     *aCreatedTextureClient = true;
-    mInvalidBack = nsIntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
+    mInvalidBack = IntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
   }
 
   ValidateBackBufferFromFront(aDirtyRegion, aAddPaintedRegion);
 
   *aBackBufferOnWhite = mBackBufferOnWhite;
   return mBackBuffer;
 }
 
@@ -897,17 +897,17 @@ ClientTiledLayerBuffer::PaintThebes(cons
 #endif
 
   // If this region is empty XMost() - 1 will give us a negative value.
   NS_ASSERTION(!aPaintRegion.GetBounds().IsEmpty(), "Empty paint region\n");
 
   if (!gfxPrefs::TiledDrawTargetEnabled()) {
     nsRefPtr<gfxContext> ctxt;
 
-    const nsIntRect bounds = aPaintRegion.GetBounds();
+    const IntRect bounds = aPaintRegion.GetBounds();
     {
       PROFILER_LABEL("ClientTiledLayerBuffer", "PaintThebesSingleBufferAlloc",
         js::ProfileEntry::Category::GRAPHICS);
 
       gfxImageFormat format =
         gfxPlatform::GetPlatform()->OptimalFormatForContent(
           GetContentType());
 
@@ -938,38 +938,38 @@ ClientTiledLayerBuffer::PaintThebes(cons
     PROFILER_LABEL("ClientTiledLayerBuffer", "PaintThebesSingleBufferDraw",
       js::ProfileEntry::Category::GRAPHICS);
 
     mCallback(mPaintedLayer, ctxt, aPaintRegion, DrawRegionClip::NONE, nsIntRegion(), mCallbackData);
   }
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   if (PR_IntervalNow() - start > 30) {
-    const nsIntRect bounds = aPaintRegion.GetBounds();
+    const IntRect bounds = aPaintRegion.GetBounds();
     printf_stderr("Time to draw %i: %i, %i, %i, %i\n", PR_IntervalNow() - start, bounds.x, bounds.y, bounds.width, bounds.height);
     if (aPaintRegion.IsComplex()) {
       printf_stderr("Complex region\n");
       nsIntRegionRectIterator it(aPaintRegion);
-      for (const nsIntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) {
+      for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) {
         printf_stderr(" rect %i, %i, %i, %i\n", rect->x, rect->y, rect->width, rect->height);
       }
     }
   }
   start = PR_IntervalNow();
 #endif
 
   PROFILER_LABEL("ClientTiledLayerBuffer", "PaintThebesUpdate",
     js::ProfileEntry::Category::GRAPHICS);
 
   mNewValidRegion = aNewValidRegion;
   Update(aNewValidRegion, aPaintRegion);
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   if (PR_IntervalNow() - start > 10) {
-    const nsIntRect bounds = aPaintRegion.GetBounds();
+    const IntRect bounds = aPaintRegion.GetBounds();
     printf_stderr("Time to tile %i: %i, %i, %i, %i\n", PR_IntervalNow() - start, bounds.x, bounds.y, bounds.width, bounds.height);
   }
 #endif
 
   mLastPaintContentType = GetContentType(&mLastPaintSurfaceMode);
   mCallback = nullptr;
   mCallbackData = nullptr;
   mSinglePaintDrawTarget = nullptr;
@@ -1199,26 +1199,26 @@ ClientTiledLayerBuffer::ValidateTile(Til
       return aTile;
     }
 
     mMoz2DTiles.push_back(moz2DTile);
     mTilingOrigin.x = std::min(mTilingOrigin.x, moz2DTile.mTileOrigin.x);
     mTilingOrigin.y = std::min(mTilingOrigin.y, moz2DTile.mTileOrigin.y);
 
     nsIntRegionRectIterator it(aDirtyRegion);
-    for (const nsIntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
+    for (const IntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
       gfx::Rect drawRect(dirtyRect->x - aTileOrigin.x,
                          dirtyRect->y - aTileOrigin.y,
                          dirtyRect->width,
                          dirtyRect->height);
       drawRect.Scale(mResolution);
 
       // Mark the newly updated area as invalid in the front buffer
       aTile.mInvalidFront.Or(aTile.mInvalidFront,
-        nsIntRect(NS_lroundf(drawRect.x), NS_lroundf(drawRect.y),
+        IntRect(NS_lroundf(drawRect.x), NS_lroundf(drawRect.y),
                   drawRect.width, drawRect.height));
 
       if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
         dt->FillRect(drawRect, ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
         dtOnWhite->FillRect(drawRect, ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
       } else if (content == gfxContentType::COLOR_ALPHA) {
         dt->ClearRect(drawRect);
       }
@@ -1242,17 +1242,17 @@ ClientTiledLayerBuffer::ValidateTile(Til
   RefPtr<DrawTarget> drawTarget = backBuffer->BorrowDrawTarget();
   drawTarget->SetTransform(Matrix());
 
   RefPtr<gfxContext> ctxt = new gfxContext(drawTarget);
 
   // XXX Perhaps we should just copy the bounding rectangle here?
   RefPtr<gfx::SourceSurface> source = mSinglePaintDrawTarget->Snapshot();
   nsIntRegionRectIterator it(aDirtyRegion);
-  for (const nsIntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
+  for (const IntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
     printf_stderr(" break into subdirtyRect %i, %i, %i, %i\n",
                   dirtyRect->x, dirtyRect->y, dirtyRect->width, dirtyRect->height);
 #endif
     gfx::Rect drawRect(dirtyRect->x - aTileOrigin.x,
                        dirtyRect->y - aTileOrigin.y,
                        dirtyRect->width,
                        dirtyRect->height);
@@ -1261,24 +1261,24 @@ ClientTiledLayerBuffer::ValidateTile(Til
     gfx::IntRect copyRect(NS_lroundf((dirtyRect->x - mSinglePaintBufferOffset.x) * mResolution),
                           NS_lroundf((dirtyRect->y - mSinglePaintBufferOffset.y) * mResolution),
                           drawRect.width,
                           drawRect.height);
     gfx::IntPoint copyTarget(NS_lroundf(drawRect.x), NS_lroundf(drawRect.y));
     drawTarget->CopySurface(source, copyRect, copyTarget);
 
     // Mark the newly updated area as invalid in the front buffer
-    aTile.mInvalidFront.Or(aTile.mInvalidFront, nsIntRect(copyTarget.x, copyTarget.y, copyRect.width, copyRect.height));
+    aTile.mInvalidFront.Or(aTile.mInvalidFront, IntRect(copyTarget.x, copyTarget.y, copyRect.width, copyRect.height));
   }
 
   // only worry about padding when not doing low-res
   // because it simplifies the math and the artifacts
   // won't be noticable
   if (mResolution == 1) {
-    nsIntRect unscaledTile = nsIntRect(aTileOrigin.x,
+    IntRect unscaledTile = IntRect(aTileOrigin.x,
                                        aTileOrigin.y,
                                        GetTileSize().width,
                                        GetTileSize().height);
 
     nsIntRegion tileValidRegion = GetValidRegion();
     tileValidRegion.Or(tileValidRegion, aDirtyRegion);
     // We only need to pad out if the tile has area that's not valid
     if (!tileValidRegion.Contains(unscaledTile)) {
@@ -1296,17 +1296,17 @@ ClientTiledLayerBuffer::ValidateTile(Til
   DrawDebugOverlay(drawTarget, aTileOrigin.x * mResolution,
                    aTileOrigin.y * GetPresShellResolution(), GetTileLength(), GetTileLength());
 #endif
 
   ctxt = nullptr;
   drawTarget = nullptr;
 
   nsIntRegion tileRegion =
-    nsIntRect(aTileOrigin.x, aTileOrigin.y,
+    IntRect(aTileOrigin.x, aTileOrigin.y,
               GetScaledTileSize().width, GetScaledTileSize().height);
   // Intersect this area with the portion that's invalid.
   tileRegion.SubOut(GetValidRegion());
   tileRegion.SubOut(aDirtyRegion); // Has now been validated
 
   backBuffer->Unlock();
   backBuffer->SetWaste(tileRegion.Area() * mResolution * mResolution);
 
@@ -1440,17 +1440,17 @@ ClientTiledLayerBuffer::ComputeProgressi
   // single transaction. This is to avoid rendering glitches on animated
   // page content, and when layers change size/shape.
   // On Fennec uploads are more expensive because we're not using gralloc, so
   // we use a coherent update rect that is intersected with the screen at the
   // time of issuing the draw command. This will paint faster but also potentially
   // make the progressive paint more visible to the user while scrolling.
   // On B2G uploads are cheaper and we value coherency more, especially outside
   // the browser, so we always use the entire user-visible area.
-  nsIntRect coherentUpdateRect(LayerIntRect::ToUntyped(RoundedOut(
+  IntRect coherentUpdateRect(LayerIntRect::ToUntyped(RoundedOut(
 #ifdef MOZ_WIDGET_ANDROID
     transformedCompositionBounds.Intersect(aPaintData->mCompositionBounds)
 #else
     transformedCompositionBounds
 #endif
   )));
 
   TILING_LOG("TILING %p: Progressive update final coherency rect %s\n", mPaintedLayer, Stringify(coherentUpdateRect).c_str());
@@ -1476,17 +1476,17 @@ ClientTiledLayerBuffer::ComputeProgressi
   bool paintInSingleTransaction = paintingVisible && (drawingStale || aPaintData->mFirstPaint);
 
   TILING_LOG("TILING %p: paintingVisible %d drawingStale %d firstPaint %d singleTransaction %d\n",
     mPaintedLayer, paintingVisible, drawingStale, aPaintData->mFirstPaint, paintInSingleTransaction);
 
   // The following code decides what order to draw tiles in, based on the
   // current scroll direction of the primary scrollable layer.
   NS_ASSERTION(!aRegionToPaint.IsEmpty(), "Unexpectedly empty paint region!");
-  nsIntRect paintBounds = aRegionToPaint.GetBounds();
+  IntRect paintBounds = aRegionToPaint.GetBounds();
 
   int startX, incX, startY, incY;
   gfx::IntSize scaledTileSize = GetScaledTileSize();
   if (aPaintData->mScrollOffset.x >= aPaintData->mLastScrollOffset.x) {
     startX = RoundDownToTileEdge(paintBounds.x, scaledTileSize.width);
     incX = scaledTileSize.width;
   } else {
     startX = RoundDownToTileEdge(paintBounds.XMost() - 1, scaledTileSize.width);
@@ -1497,17 +1497,17 @@ ClientTiledLayerBuffer::ComputeProgressi
     startY = RoundDownToTileEdge(paintBounds.y, scaledTileSize.height);
     incY = scaledTileSize.height;
   } else {
     startY = RoundDownToTileEdge(paintBounds.YMost() - 1, scaledTileSize.height);
     incY = -scaledTileSize.height;
   }
 
   // Find a tile to draw.
-  nsIntRect tileBounds(startX, startY, scaledTileSize.width, scaledTileSize.height);
+  IntRect tileBounds(startX, startY, scaledTileSize.width, scaledTileSize.height);
   int32_t scrollDiffX = aPaintData->mScrollOffset.x - aPaintData->mLastScrollOffset.x;
   int32_t scrollDiffY = aPaintData->mScrollOffset.y - aPaintData->mLastScrollOffset.y;
   // This loop will always terminate, as there is at least one tile area
   // along the first/last row/column intersecting with regionToPaint, or its
   // bounds would have been smaller.
   while (true) {
     aRegionToPaint.And(aInvalidRegion, tileBounds);
     if (!aRegionToPaint.IsEmpty()) {
@@ -1618,10 +1618,10 @@ TiledContentClient::PrintInfo(std::strin
 void
 TiledContentClient::Dump(std::stringstream& aStream,
                        const char* aPrefix,
                        bool aDumpHtml)
 {
   mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml);
 }
 
-}
-}
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -24,17 +24,17 @@
 #include "mozilla/layers/LayersMessages.h" // for TileDescriptor
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/layers/TextureClientPool.h"
 #include "ClientLayerManager.h"
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_DTOR
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "nsExpirationTracker.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "gfxReusableSurfaceWrapper.h"
 #include "pratom.h"                     // For PR_ATOMIC_INCREMENT/DECREMENT
 #include "gfxPrefs.h"
 
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -22,17 +22,17 @@
 #include "mozilla/layers/CompositorParent.h" // for CompositorParent, etc
 #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
 #include "nsCoord.h"                    // for NSAppUnitsToFloatPixels, etc
 #include "nsDebug.h"                    // for NS_ASSERTION, etc
 #include "nsDeviceContext.h"            // for nsDeviceContext
 #include "nsDisplayList.h"              // for nsDisplayTransform, etc
 #include "nsMathUtils.h"                // for NS_round
 #include "nsPoint.h"                    // for nsPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
 #include "UnitTransforms.h"             // for TransformTo
 #if defined(MOZ_WIDGET_ANDROID)
 # include <android/log.h>
 # include "AndroidBridge.h"
 #endif
@@ -51,17 +51,17 @@ static bool
 IsSameDimension(dom::ScreenOrientation o1, dom::ScreenOrientation o2)
 {
   bool isO1portrait = (o1 == dom::eScreenOrientation_PortraitPrimary || o1 == dom::eScreenOrientation_PortraitSecondary);
   bool isO2portrait = (o2 == dom::eScreenOrientation_PortraitPrimary || o2 == dom::eScreenOrientation_PortraitSecondary);
   return !(isO1portrait ^ isO2portrait);
 }
 
 static bool
-ContentMightReflowOnOrientationChange(const nsIntRect& rect)
+ContentMightReflowOnOrientationChange(const IntRect& rect)
 {
   return rect.width != rect.height;
 }
 
 template<Op OP>
 static void
 WalkTheTree(Layer* aLayer,
             bool& aReady,
--- a/gfx/layers/composite/CanvasLayerComposite.cpp
+++ b/gfx/layers/composite/CanvasLayerComposite.cpp
@@ -75,17 +75,17 @@ CanvasLayerComposite::GetRenderState()
 {
   if (mDestroyed || !mImageHost || !mImageHost->IsAttached()) {
     return LayerRenderState();
   }
   return mImageHost->GetRenderState();
 }
 
 void
-CanvasLayerComposite::RenderLayer(const nsIntRect& aClipRect)
+CanvasLayerComposite::RenderLayer(const IntRect& aClipRect)
 {
   if (!mImageHost || !mImageHost->IsAttached()) {
     return;
   }
 
   mCompositor->MakeCurrent();
 
 #ifdef MOZ_DUMP_PAINTING
--- a/gfx/layers/composite/CanvasLayerComposite.h
+++ b/gfx/layers/composite/CanvasLayerComposite.h
@@ -7,17 +7,17 @@
 #define GFX_CanvasLayerComposite_H
 
 #include "Layers.h"                     // for CanvasLayer, etc
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/layers/LayerManagerComposite.h"  // for LayerComposite, etc
 #include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nscore.h"                     // for nsACString
 
 namespace mozilla {
 namespace layers {
 
 class CompositableHost;
 // Canvas layers use ImageHosts (but CanvasClients) because compositing a
 // canvas is identical to compositing an image.
@@ -46,27 +46,27 @@ public:
   virtual void Disconnect() override
   {
     Destroy();
   }
 
   virtual void SetLayerManager(LayerManagerComposite* aManager) override;
 
   virtual Layer* GetLayer() override;
-  virtual void RenderLayer(const nsIntRect& aClipRect) override;
+  virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
 
   virtual void CleanupResources() override;
 
   virtual void GenEffectChain(EffectChain& aEffect) override;
 
   CompositableHost* GetCompositableHost() override;
 
   virtual LayerComposite* AsLayerComposite() override { return this; }
 
-  void SetBounds(nsIntRect aBounds) { mBounds = aBounds; }
+  void SetBounds(gfx::IntRect aBounds) { mBounds = aBounds; }
 
   virtual const char* Name() const override { return "CanvasLayerComposite"; }
 
 protected:
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
 
 private:
   gfx::Filter GetEffectFilter();
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -88,33 +88,33 @@ ContentHostTexture::Composite(EffectChai
 
   nsIntRegion region(*renderRegion);
   nsIntPoint origin = GetOriginOffset();
   // translate into TexImage space, buffer origin might not be at texture (0,0)
   region.MoveBy(-origin);
 
   // Figure out the intersecting draw region
   gfx::IntSize texSize = mTextureSource->GetSize();
-  nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
+  IntRect textureRect = IntRect(0, 0, texSize.width, texSize.height);
   textureRect.MoveBy(region.GetBounds().TopLeft());
   nsIntRegion subregion;
   subregion.And(region, textureRect);
   if (subregion.IsEmpty()) {
     // Region is empty, nothing to draw
     return;
   }
 
   nsIntRegion screenRects;
   nsIntRegion regionRects;
 
   // Collect texture/screen coordinates for drawing
   nsIntRegionRectIterator iter(subregion);
-  while (const nsIntRect* iterRect = iter.Next()) {
-    nsIntRect regionRect = *iterRect;
-    nsIntRect screenRect = regionRect;
+  while (const IntRect* iterRect = iter.Next()) {
+    IntRect regionRect = *iterRect;
+    IntRect screenRect = regionRect;
     screenRect.MoveBy(origin);
 
     screenRects.Or(screenRects, screenRect);
     regionRects.Or(regionRects, regionRect);
   }
 
   BigImageIterator* bigImgIter = mTextureSource->AsBigImageIterator();
   BigImageIterator* iterOnWhite = nullptr;
@@ -133,39 +133,39 @@ ContentHostTexture::Composite(EffectChai
 
   bool usingTiles = (bigImgIter && bigImgIter->GetTileCount() > 1);
   do {
     if (iterOnWhite) {
       MOZ_ASSERT(iterOnWhite->GetTileRect() == bigImgIter->GetTileRect(),
                  "component alpha textures should be the same size.");
     }
 
-    nsIntRect texRect = bigImgIter ? bigImgIter->GetTileRect()
-                                 : nsIntRect(0, 0,
+    IntRect texRect = bigImgIter ? bigImgIter->GetTileRect()
+                                 : IntRect(0, 0,
                                              texSize.width,
                                              texSize.height);
 
     // Draw texture. If we're using tiles, we do repeating manually, as texture
     // repeat would cause each individual tile to repeat instead of the
     // compound texture as a whole. This involves drawing at most 4 sections,
     // 2 for each axis that has texture repeat.
     for (int y = 0; y < (usingTiles ? 2 : 1); y++) {
       for (int x = 0; x < (usingTiles ? 2 : 1); x++) {
-        nsIntRect currentTileRect(texRect);
+        IntRect currentTileRect(texRect);
         currentTileRect.MoveBy(x * texSize.width, y * texSize.height);
 
         nsIntRegionRectIterator screenIter(screenRects);
         nsIntRegionRectIterator regionIter(regionRects);
 
-        const nsIntRect* screenRect;
-        const nsIntRect* regionRect;
+        const IntRect* screenRect;
+        const IntRect* regionRect;
         while ((screenRect = screenIter.Next()) &&
                (regionRect = regionIter.Next())) {
-          nsIntRect tileScreenRect(*screenRect);
-          nsIntRect tileRegionRect(*regionRect);
+          IntRect tileScreenRect(*screenRect);
+          IntRect tileRegionRect(*regionRect);
 
           // When we're using tiles, find the intersection between the tile
           // rect and this region rect. Tiling is then handled by the
           // outer for-loops and modifying the tile rect.
           if (usingTiles) {
             tileScreenRect.MoveBy(-origin);
             tileScreenRect = tileScreenRect.Intersect(currentTileRect);
             tileScreenRect.MoveBy(origin);
@@ -281,17 +281,17 @@ ContentHostTexture::Dump(std::stringstre
 #endif
 }
 
 static inline void
 AddWrappedRegion(const nsIntRegion& aInput, nsIntRegion& aOutput,
                  const nsIntSize& aSize, const nsIntPoint& aShift)
 {
   nsIntRegion tempRegion;
-  tempRegion.And(nsIntRect(aShift, aSize), aInput);
+  tempRegion.And(IntRect(aShift, aSize), aInput);
   tempRegion.MoveBy(-aShift);
   aOutput.Or(aOutput, tempRegion);
 }
 
 bool
 ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
                                         const nsIntRegion& aUpdated,
                                         const nsIntRegion& aOldValidRegionBack,
@@ -330,17 +330,17 @@ ContentHostSingleBuffered::UpdateThebes(
   finalRegion.And(IntRect(IntPoint(), bufferSize), destRegion);
 
   // For each of the overlap areas (right, bottom-right, bottom), select those
   // pixels and wrap them around to the opposite edge of the buffer rect.
   AddWrappedRegion(destRegion, finalRegion, bufferSize, nsIntPoint(aData.rect().width, 0));
   AddWrappedRegion(destRegion, finalRegion, bufferSize, nsIntPoint(aData.rect().width, aData.rect().height));
   AddWrappedRegion(destRegion, finalRegion, bufferSize, nsIntPoint(0, aData.rect().height));
 
-  MOZ_ASSERT(nsIntRect(0, 0, aData.rect().width, aData.rect().height).Contains(finalRegion.GetBounds()));
+  MOZ_ASSERT(IntRect(0, 0, aData.rect().width, aData.rect().height).Contains(finalRegion.GetBounds()));
 
   mTextureHost->Updated(&finalRegion);
   if (mTextureHostOnWhite) {
     mTextureHostOnWhite->Updated(&finalRegion);
   }
   mInitialised = true;
 
   mBufferRect = aData.rect();
@@ -452,10 +452,10 @@ ContentHostTexture::GetAsSurface()
   if (!mTextureHost) {
     return nullptr;
   }
 
   return mTextureHost->GetAsSurface();
 }
 
 
-} // namespace
-} // namespace
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -23,17 +23,17 @@
 #include "mozilla/layers/LayersTypes.h"  // for etc
 #include "mozilla/layers/TextureHost.h"  // for TextureHost
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "mozilla/UniquePtr.h"          // for UniquePtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsACString
 
 namespace mozilla {
 namespace gfx {
 class Matrix4x4;
 }
@@ -97,17 +97,17 @@ public:
 
 protected:
   virtual nsIntPoint GetOriginOffset()
   {
     return mBufferRect.TopLeft() - mBufferRotation;
   }
 
 
-  nsIntRect mBufferRect;
+  gfx::IntRect mBufferRect;
   nsIntPoint mBufferRotation;
   bool mInitialised;
 };
 
 /**
  * Shared ContentHostBase implementation for content hosts that
  * use up to two TextureHosts.
  */
--- a/gfx/layers/composite/FPSCounter.cpp
+++ b/gfx/layers/composite/FPSCounter.cpp
@@ -10,17 +10,17 @@
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect
 #include "mozilla/gfx/Types.h"          // for Color, SurfaceFormat
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/Effects.h"     // for Effect, EffectChain, etc
 #include "mozilla/TimeStamp.h"          // for TimeStamp, TimeDuration
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsIFile.h"                    // for nsIFile
 #include "nsDirectoryServiceDefs.h"     // for NS_OS_TMP_DIR
 #include "prprf.h"                      // for PR_snprintf
 #include "FPSCounter.h"
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -136,17 +136,17 @@ ImageHost::Composite(EffectChain& aEffec
     // the corresponding source tiles from all planes, with appropriate
     // per-plane per-tile texture coords.
     // DrawQuad currently assumes that all planes use the same texture coords.
     MOZ_ASSERT(it->GetTileCount() == 1 || !mTextureSource->GetNextSibling(),
                "Can't handle multi-plane BigImages");
 
     it->BeginBigImageIteration();
     do {
-      nsIntRect tileRect = it->GetTileRect();
+      IntRect tileRect = it->GetTileRect();
       gfx::Rect rect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
       if (mHasPictureRect) {
         rect = rect.Intersect(pictureRect);
         effect->mTextureCoords = Rect(Float(rect.x - tileRect.x)/ tileRect.width,
                                       Float(rect.y - tileRect.y) / tileRect.height,
                                       Float(rect.width) / tileRect.width,
                                       Float(rect.height) / tileRect.height);
       } else {
@@ -373,10 +373,10 @@ ImageHostOverlay::PrintInfo(std::strings
   if (mOverlay.handle().type() == OverlayHandle::Tint32_t) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
     aStream << nsPrintfCString("Overlay: %d", mOverlay.handle().get_int32_t()).get();
   }
 }
 
 #endif
-}
-}
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/composite/ImageHost.h
+++ b/gfx/layers/composite/ImageHost.h
@@ -14,17 +14,17 @@
 #include "mozilla/gfx/Rect.h"           // for Rect
 #include "mozilla/gfx/Types.h"          // for Filter
 #include "mozilla/layers/CompositorTypes.h"  // for TextureInfo, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
 #include "mozilla/layers/TextureHost.h"  // for TextureHost, etc
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nscore.h"                     // for nsACString
 
 class nsIntRegion;
 
 namespace mozilla {
 namespace gfx {
 class Matrix4x4;
 }
@@ -54,17 +54,17 @@ public:
   virtual void UseTextureHost(TextureHost* aTexture) override;
 
   virtual void RemoveTextureHost(TextureHost* aTexture) override;
 
   virtual TextureHost* GetAsTextureHost() override;
 
   virtual void SetCompositor(Compositor* aCompositor) override;
 
-  virtual void SetPictureRect(const nsIntRect& aPictureRect) override
+  virtual void SetPictureRect(const gfx::IntRect& aPictureRect) override
   {
     mPictureRect = aPictureRect;
     mHasPictureRect = true;
   }
 
   gfx::IntSize GetImageSize() const override;
 
   virtual LayerRenderState GetRenderState() override;
@@ -82,17 +82,17 @@ public:
   virtual void Unlock() override;
 
   virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) override;
 
 protected:
 
   CompositableTextureHostRef mFrontBuffer;
   CompositableTextureSourceRef mTextureSource;
-  nsIntRect mPictureRect;
+  gfx::IntRect mPictureRect;
   bool mHasPictureRect;
   bool mLocked;
 };
 
 #ifdef MOZ_WIDGET_GONK
 
 /**
  * ImageHostOverlay works with ImageClientOverlay
@@ -107,24 +107,24 @@ public:
   virtual void Composite(EffectChain& aEffectChain,
                          float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Filter& aFilter,
                          const gfx::Rect& aClipRect,
                          const nsIntRegion* aVisibleRegion = nullptr) override;
   virtual LayerRenderState GetRenderState() override;
   virtual void UseOverlaySource(OverlaySource aOverlay) override;
-  virtual void SetPictureRect(const nsIntRect& aPictureRect) override
+  virtual void SetPictureRect(const gfx::IntRect& aPictureRect) override
   {
     mPictureRect = aPictureRect;
     mHasPictureRect = true;
   }
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
 protected:
-  nsIntRect mPictureRect;
+  gfx::IntRect mPictureRect;
   bool mHasPictureRect;
   OverlaySource mOverlay;
 };
 
 #endif
 
 }
 }
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -46,17 +46,17 @@
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAppRunner.h"
 #include "nsRefPtr.h"                   // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_WARNING, NS_RUNTIMEABORT, etc
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
 #include "nsIWidget.h"                  // for nsIWidget
 #include "nsPoint.h"                    // for nsIntPoint
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion, etc
 #ifdef MOZ_WIDGET_ANDROID
 #include <android/log.h>
 #include "AndroidBridge.h"
 #include "opengl/CompositorOGL.h"
 #include "GLContextEGL.h"
 #include "GLContextProvider.h"
 #include "ScopedGLHelpers.h"
@@ -143,17 +143,17 @@ LayerManagerComposite::Destroy()
       RootLayer()->Destroy();
     }
     mRoot = nullptr;
     mDestroyed = true;
   }
 }
 
 void
-LayerManagerComposite::UpdateRenderBounds(const nsIntRect& aRect)
+LayerManagerComposite::UpdateRenderBounds(const IntRect& aRect)
 {
   mRenderBounds = aRect;
 }
 
 bool
 LayerManagerComposite::AreComponentAlphaLayersEnabled()
 {
   return Compositor::GetBackend() != LayersBackend::LAYERS_BASIC &&
@@ -170,17 +170,17 @@ LayerManagerComposite::BeginTransaction(
   }
   
   mIsCompositorReady = true;
 
   mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot());
 }
 
 void
-LayerManagerComposite::BeginTransactionWithDrawTarget(DrawTarget* aTarget, const nsIntRect& aRect)
+LayerManagerComposite::BeginTransactionWithDrawTarget(DrawTarget* aTarget, const IntRect& aRect)
 {
   mInTransaction = true;
   
   if (!mCompositor->Ready()) {
     return;
   }
 
 #ifdef MOZ_LAYERS_HAVE_LOG
@@ -548,17 +548,17 @@ LayerManagerComposite::PushGroupForLayer
       mTwoPassTmpTarget->GetOrigin() != previousTarget->GetOrigin()) {
     mTwoPassTmpTarget = mCompositor->CreateRenderTarget(rect, INIT_MODE_NONE);
   }
   mCompositor->SetRenderTarget(mTwoPassTmpTarget);
   return previousTarget;
 }
 void
 LayerManagerComposite::PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
-                                               nsIntRect aClipRect,
+                                               IntRect aClipRect,
                                                bool aGrayscaleEffect,
                                                bool aInvertEffect,
                                                float aContrastEffect)
 {
   MOZ_ASSERT(mTwoPassTmpTarget);
 
   // This is currently true, so just making sure that any new use of this
   // method is flagged for investigation
@@ -719,17 +719,17 @@ LayerManagerComposite::Render()
   }
 
   if (actualBounds.IsEmpty()) {
     mCompositor->GetWidget()->PostRender(this);
     return;
   }
 
   // Allow widget to render a custom background.
-  mCompositor->GetWidget()->DrawWindowUnderlay(this, nsIntRect(actualBounds.x,
+  mCompositor->GetWidget()->DrawWindowUnderlay(this, IntRect(actualBounds.x,
                                                                actualBounds.y,
                                                                actualBounds.width,
                                                                actualBounds.height));
 
   RefPtr<CompositingRenderTarget> previousTarget;
   if (haveLayerEffects) {
     previousTarget = PushGroupForLayerEffects();
   } else {
@@ -737,30 +737,30 @@ LayerManagerComposite::Render()
   }
 
   // Render our layers.
   RootLayer()->Prepare(ViewAs<RenderTargetPixel>(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot));
   RootLayer()->RenderLayer(ParentLayerIntRect::ToUntyped(clipRect));
 
   if (!mRegionToClear.IsEmpty()) {
     nsIntRegionRectIterator iter(mRegionToClear);
-    const nsIntRect *r;
+    const IntRect *r;
     while ((r = iter.Next())) {
       mCompositor->ClearRect(Rect(r->x, r->y, r->width, r->height));
     }
   }
 
   if (mTwoPassTmpTarget) {
     MOZ_ASSERT(haveLayerEffects);
     PopGroupForLayerEffects(previousTarget, ParentLayerIntRect::ToUntyped(clipRect),
                             grayscaleVal, invertVal, contrastVal);
   }
 
   // Allow widget to render a custom foreground.
-  mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x,
+  mCompositor->GetWidget()->DrawWindowOverlay(this, IntRect(actualBounds.x,
                                                               actualBounds.y,
                                                               actualBounds.width,
                                                               actualBounds.height));
 
   // Debugging
   RenderDebugOverlay(actualBounds);
 
   {
@@ -935,17 +935,17 @@ LayerManagerComposite::RenderToPresentat
 
   // The Java side of Fennec sets a scissor rect that accounts for
   // chrome such as the URL bar. Override that so that the entire frame buffer
   // is cleared.
   ScopedScissorRect screen(egl, 0, 0, actualWidth, actualHeight);
   egl->fClearColor(0.0, 0.0, 0.0, 0.0);
   egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
 
-  const nsIntRect clipRect = nsIntRect(0, 0, (int)(scale * pageWidth), actualHeight);
+  const IntRect clipRect = IntRect(0, 0, (int)(scale * pageWidth), actualHeight);
   RootLayer()->Prepare(RenderTargetPixel::FromUntyped(clipRect));
   RootLayer()->RenderLayer(clipRect);
 
   mCompositor->EndFrame();
   mCompositor->SetDispAcquireFence(mRoot);
 }
 #endif
 
@@ -956,19 +956,19 @@ SubtractTransformedRegion(nsIntRegion& a
 {
   if (aRegionToSubtract.IsEmpty()) {
     return;
   }
 
   // For each rect in the region, find out its bounds in screen space and
   // subtract it from the screen region.
   nsIntRegionRectIterator it(aRegionToSubtract);
-  while (const nsIntRect* rect = it.Next()) {
+  while (const IntRect* rect = it.Next()) {
     Rect incompleteRect = aTransform.TransformBounds(ToRect(*rect));
-    aRegion.Sub(aRegion, nsIntRect(incompleteRect.x,
+    aRegion.Sub(aRegion, IntRect(incompleteRect.x,
                                    incompleteRect.y,
                                    incompleteRect.width,
                                    incompleteRect.height));
   }
 }
 
 /* static */ void
 LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
@@ -1034,23 +1034,23 @@ LayerManagerComposite::ComputeRenderInte
     }
   }
 }
 
 #ifdef MOZ_WIDGET_ANDROID
 static float
 GetDisplayportCoverage(const CSSRect& aDisplayPort,
                        const Matrix4x4& aTransformToScreen,
-                       const nsIntRect& aScreenRect)
+                       const IntRect& aScreenRect)
 {
   Rect transformedDisplayport =
     aTransformToScreen.TransformBounds(aDisplayPort.ToUnknownRect());
 
   transformedDisplayport.RoundOut();
-  nsIntRect displayport = nsIntRect(transformedDisplayport.x,
+  IntRect displayport = IntRect(transformedDisplayport.x,
                                     transformedDisplayport.y,
                                     transformedDisplayport.width,
                                     transformedDisplayport.height);
   if (!displayport.Contains(aScreenRect)) {
     nsIntRegion coveredRegion;
     coveredRegion.And(aScreenRect, displayport);
     return coveredRegion.Area() / (float)(aScreenRect.width * aScreenRect.height);
   }
@@ -1071,17 +1071,17 @@ LayerManagerComposite::ComputeRenderInte
   FrameMetrics rootMetrics = LayerMetricsWrapper::TopmostScrollableMetrics(root);
   if (!rootMetrics.IsScrollable()) {
     // The root may not have any scrollable metrics, in which case rootMetrics
     // will just be an empty FrameMetrics. Instead use the actual metrics from
     // the root layer.
     rootMetrics = LayerMetricsWrapper(root).Metrics();
   }
   ParentLayerIntRect bounds = RoundedToInt(rootMetrics.mCompositionBounds);
-  nsIntRect screenRect(bounds.x,
+  IntRect screenRect(bounds.x,
                        bounds.y,
                        bounds.width,
                        bounds.height);
 
   float lowPrecisionMultiplier = 1.0f;
   float highPrecisionMultiplier = 1.0f;
 
 #ifdef MOZ_WIDGET_ANDROID
@@ -1099,17 +1099,17 @@ LayerManagerComposite::ComputeRenderInte
 
     // Clip the screen rect to the document bounds
     Rect documentBounds =
       transform.TransformBounds(Rect(metrics.GetScrollableRect().x - metrics.GetScrollOffset().x,
                                      metrics.GetScrollableRect().y - metrics.GetScrollOffset().y,
                                      metrics.GetScrollableRect().width,
                                      metrics.GetScrollableRect().height));
     documentBounds.RoundOut();
-    screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y,
+    screenRect = screenRect.Intersect(IntRect(documentBounds.x, documentBounds.y,
                                                 documentBounds.width, documentBounds.height));
 
     // If the screen rect is empty, the user has scrolled entirely into
     // over-scroll and so we can be considered to have full integrity.
     if (screenRect.IsEmpty()) {
       return 1.0f;
     }
 
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -22,17 +22,17 @@
 #include "mozilla/Maybe.h"              // for Maybe
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAString.h"
 #include "nsRefPtr.h"                   // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nscore.h"                     // for nsAString, etc
 #include "LayerTreeInvalidation.h"
 
 class gfxContext;
 
 #ifdef XP_WIN
 #include <windows.h>
@@ -97,24 +97,24 @@ public:
   /**
    * LayerManager implementation.
    */
   virtual LayerManagerComposite* AsLayerManagerComposite() override
   {
     return this;
   }
 
-  void UpdateRenderBounds(const nsIntRect& aRect);
+  void UpdateRenderBounds(const gfx::IntRect& aRect);
 
   virtual void BeginTransaction() override;
   virtual void BeginTransactionWithTarget(gfxContext* aTarget) override
   {
     MOZ_CRASH("Use BeginTransactionWithDrawTarget");
   }
-  void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, const nsIntRect& aRect);
+  void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, const gfx::IntRect& aRect);
 
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override;
   virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT) override;
 
   virtual void SetRoot(Layer* aLayer) override { mRoot = aLayer; }
 
@@ -247,17 +247,17 @@ public:
     mUnusedApzTransformWarning = true;
   }
 
   bool LastFrameMissedHWC() { return mLastFrameMissedHWC; }
 
 private:
   /** Region we're clipping our current drawing to. */
   nsIntRegion mClippingRegion;
-  nsIntRect mRenderBounds;
+  gfx::IntRect mRenderBounds;
 
   /** Current root layer. */
   LayerComposite* RootLayer() const;
 
   /**
    * Recursive helper method for use by ComputeRenderIntegrity. Subtracts
    * any incomplete rendering on aLayer from aScreenRegion. Any low-precision
    * rendering is included in aLowPrecisionScreenRegion. aTransform is the
@@ -279,32 +279,32 @@ private:
   /**
    * Render debug overlays such as the FPS/FrameCounter above the frame.
    */
   void RenderDebugOverlay(const gfx::Rect& aBounds);
 
 
   RefPtr<CompositingRenderTarget> PushGroupForLayerEffects();
   void PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
-                               nsIntRect aClipRect,
+                               gfx::IntRect aClipRect,
                                bool aGrayscaleEffect,
                                bool aInvertEffect,
                                float aContrastEffect);
 
   float mWarningLevel;
   mozilla::TimeStamp mWarnTime;
   bool mUnusedApzTransformWarning;
   RefPtr<Compositor> mCompositor;
   UniquePtr<LayerProperties> mClonedLayerTreeProperties;
 
   /**
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
-  nsIntRect mTargetBounds;
+  gfx::IntRect mTargetBounds;
 
   nsIntRegion mInvalidRegion;
   UniquePtr<FPSState> mFPS;
 
   bool mInTransaction;
   bool mIsCompositorReady;
   bool mDebugOverlayWantsNextFrame;
 
@@ -360,17 +360,17 @@ public:
    * Perform a first pass over the layer tree to render all of the intermediate
    * surfaces that we can. This allows us to avoid framebuffer switches in the
    * middle of our render which is inefficient especially on mobile GPUs. This
    * must be called before RenderLayer.
    */
   virtual void Prepare(const RenderTargetIntRect& aClipRect) {}
 
   // TODO: This should also take RenderTargetIntRect like Prepare.
-  virtual void RenderLayer(const nsIntRect& aClipRect) = 0;
+  virtual void RenderLayer(const gfx::IntRect& aClipRect) = 0;
 
   virtual bool SetCompositableHost(CompositableHost*)
   {
     // We must handle this gracefully, see bug 967824
     NS_WARNING("called SetCompositableHost for a layer type not accepting a compositable");
     return false;
   }
   virtual CompositableHost* GetCompositableHost() = 0;
@@ -416,29 +416,29 @@ public:
     mShadowTransformSetByAnimation = aSetByAnimation;
   }
 
   void SetLayerComposited(bool value)
   {
     mLayerComposited = value;
   }
 
-  void SetClearRect(const nsIntRect& aRect)
+  void SetClearRect(const gfx::IntRect& aRect)
   {
     mClearRect = aRect;
   }
 
   // These getters can be used anytime.
   float GetShadowOpacity() { return mShadowOpacity; }
   const Maybe<ParentLayerIntRect>& GetShadowClipRect() { return mShadowClipRect; }
   const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
   const gfx::Matrix4x4& GetShadowTransform() { return mShadowTransform; }
   bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
   bool HasLayerBeenComposited() { return mLayerComposited; }
-  nsIntRect GetClearRect() { return mClearRect; }
+  gfx::IntRect GetClearRect() { return mClearRect; }
 
   /**
    * Return the part of the visible region that has been fully rendered.
    * While progressive drawing is in progress this region will be
    * a subset of the shadow visible region.
    */
   nsIntRegion GetFullyRenderedRegion();
 
@@ -447,16 +447,16 @@ protected:
   nsIntRegion mShadowVisibleRegion;
   Maybe<ParentLayerIntRect> mShadowClipRect;
   LayerManagerComposite* mCompositeManager;
   RefPtr<Compositor> mCompositor;
   float mShadowOpacity;
   bool mShadowTransformSetByAnimation;
   bool mDestroyed;
   bool mLayerComposited;
-  nsIntRect mClearRect;
+  gfx::IntRect mClearRect;
 };
 
 
 } /* layers */
 } /* mozilla */
 
 #endif /* GFX_LayerManagerComposite_H */
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -1030,39 +1030,39 @@ CompositorD3D11::BeginFrame(const nsIntR
 
   mContext->IASetInputLayout(mAttachments->mInputLayout);
 
   ID3D11Buffer* buffer = mAttachments->mVertexBuffer;
   UINT size = sizeof(Vertex);
   UINT offset = 0;
   mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset);
 
-  nsIntRect intRect = IntRect(IntPoint(0, 0), mSize);
+  IntRect intRect = IntRect(IntPoint(0, 0), mSize);
   // Sometimes the invalid region is larger than we want to draw.
   nsIntRegion invalidRegionSafe;
 
   if (mSize != oldSize) {
     invalidRegionSafe = intRect;
   } else {
     invalidRegionSafe.And(aInvalidRegion, intRect);
   }
 
-  nsIntRect invalidRect = invalidRegionSafe.GetBounds();
+  IntRect invalidRect = invalidRegionSafe.GetBounds();
   mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
   mInvalidRegion = invalidRegionSafe;
 
   if (aClipRectOut) {
     *aClipRectOut = Rect(0, 0, mSize.width, mSize.height);
   }
   if (aRenderBoundsOut) {
     *aRenderBoundsOut = Rect(0, 0, mSize.width, mSize.height);
   }
 
   if (aClipRectIn) {
-    invalidRect.IntersectRect(invalidRect, nsIntRect(aClipRectIn->x, aClipRectIn->y, aClipRectIn->width, aClipRectIn->height));
+    invalidRect.IntersectRect(invalidRect, IntRect(aClipRectIn->x, aClipRectIn->y, aClipRectIn->width, aClipRectIn->height));
   }
 
   mCurrentClip = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
 
   mContext->RSSetState(mAttachments->mRasterizerState);
 
   SetRenderTarget(mDefaultRT);
 
@@ -1107,17 +1107,17 @@ CompositorD3D11::EndFrame()
     if (SUCCEEDED(hr) && chain) {
       DXGI_PRESENT_PARAMETERS params;
       PodZero(&params);
       params.DirtyRectsCount = mInvalidRegion.GetNumRects();
       std::vector<RECT> rects;
       rects.reserve(params.DirtyRectsCount);
 
       nsIntRegionRectIterator iter(mInvalidRegion);
-      const nsIntRect* r;
+      const IntRect* r;
       uint32_t i = 0;
       while ((r = iter.Next()) != nullptr) {
         RECT rect;
         rect.left = r->x;
         rect.top = r->y;
         rect.bottom = r->YMost();
         rect.right = r->XMost();
 
@@ -1161,17 +1161,17 @@ CompositorD3D11::PrepareViewport(const g
   projection._33 = 0.0f;
 
   memcpy(&mVSConstants.projection, &projection, sizeof(mVSConstants.projection));
 }
 
 void
 CompositorD3D11::EnsureSize()
 {
-  nsIntRect rect;
+  IntRect rect;
   mWidget->GetClientBounds(rect);
 
   mSize = rect.Size();
 }
 
 bool
 CompositorD3D11::VerifyBufferSize()
 {
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -845,17 +845,17 @@ DataTextureSourceD3D11::Update(DataSourc
       }
     }
 
     DataSourceSurface::MappedSurface map;
     aSurface->Map(DataSourceSurface::MapType::READ, &map);
 
     if (aDestRegion) {
       nsIntRegionRectIterator iter(*aDestRegion);
-      const nsIntRect *iterRect;
+      const IntRect *iterRect;
       while ((iterRect = iter.Next())) {
         D3D11_BOX box;
         box.front = 0;
         box.back = 1;
         box.left = iterRect->x;
         box.top = iterRect->y;
         box.right = iterRect->XMost();
         box.bottom = iterRect->YMost();
@@ -919,21 +919,21 @@ DataTextureSourceD3D11::Reset()
 }
 
 IntRect
 DataTextureSourceD3D11::GetTileRect(uint32_t aIndex) const
 {
   return GetTileRectD3D11(aIndex, mSize, mCompositor->GetMaxTextureSize());
 }
 
-nsIntRect
+IntRect
 DataTextureSourceD3D11::GetTileRect()
 {
   IntRect rect = GetTileRect(mCurrentTile);
-  return nsIntRect(rect.x, rect.y, rect.width, rect.height);
+  return IntRect(rect.x, rect.y, rect.width, rect.height);
 }
 
 void
 DataTextureSourceD3D11::SetCompositor(Compositor* aCompositor)
 {
   MOZ_ASSERT(aCompositor);
   CompositorD3D11* d3dCompositor = static_cast<CompositorD3D11*>(aCompositor);
   if (mCompositor && mCompositor != d3dCompositor) {
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -204,17 +204,17 @@ public:
   // BigImageIterator
 
   virtual BigImageIterator* AsBigImageIterator() override { return mIsTiled ? this : nullptr; }
 
   virtual size_t GetTileCount() override { return mTileTextures.size(); }
 
   virtual bool NextTile() override { return (++mCurrentTile < mTileTextures.size()); }
 
-  virtual nsIntRect GetTileRect() override;
+  virtual gfx::IntRect GetTileRect() override;
 
   virtual void EndBigImageIteration() override { mIterating = false; }
 
   virtual void BeginBigImageIteration() override
   {
     mIterating = true;
     mCurrentTile = 0;
   }
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -702,17 +702,17 @@ CompositorD3D9::PrepareViewport(const gf
   if (FAILED(hr)) {
     NS_WARNING("Failed to set projection matrix");
   }
 }
 
 void
 CompositorD3D9::EnsureSize()
 {
-  nsIntRect rect;
+  IntRect rect;
   mWidget->GetClientBounds(rect);
 
   mSize = rect.Size();
 }
 
 void
 CompositorD3D9::SetSamplerForFilter(Filter aFilter)
 {
--- a/gfx/layers/d3d9/TextureD3D9.cpp
+++ b/gfx/layers/d3d9/TextureD3D9.cpp
@@ -546,17 +546,17 @@ DataTextureSourceD3D9::GetTileRect(uint3
   uint32_t horizontalTile = aTileIndex % horizontalTiles;
 
   return IntRect(horizontalTile * maxSize,
                  verticalTile * maxSize,
                  horizontalTile < (horizontalTiles - 1) ? maxSize : mSize.width % maxSize,
                  verticalTile < (verticalTiles - 1) ? maxSize : mSize.height % maxSize);
 }
 
-nsIntRect
+IntRect
 DataTextureSourceD3D9::GetTileRect()
 {
   return GetTileRect(mCurrentTile);
 }
 
 CairoTextureClientD3D9::CairoTextureClientD3D9(ISurfaceAllocator* aAllocator,
                                                gfx::SurfaceFormat aFormat,
                                                TextureFlags aFlags)
@@ -875,17 +875,17 @@ DataTextureSourceD3D9::UpdateFromTexture
   }
   hr = mTexture->GetSurfaceLevel(0, byRef(dstSurface));
   if (FAILED(hr)) {
     return false;
   }
 
   if (aRegion) {
     nsIntRegionRectIterator iter(*aRegion);
-    const nsIntRect *iterRect;
+    const IntRect *iterRect;
     while ((iterRect = iter.Next())) {
       RECT rect;
       rect.left = iterRect->x;
       rect.top = iterRect->y;
       rect.right = iterRect->XMost();
       rect.bottom = iterRect->YMost();
 
       POINT point;
--- a/gfx/layers/d3d9/TextureD3D9.h
+++ b/gfx/layers/d3d9/TextureD3D9.h
@@ -142,17 +142,17 @@ public:
   // BigImageIterator
 
   virtual BigImageIterator* AsBigImageIterator() override { return mIsTiled ? this : nullptr; }
 
   virtual size_t GetTileCount() override { return mTileTextures.size(); }
 
   virtual bool NextTile() override { return (++mCurrentTile < mTileTextures.size()); }
 
-  virtual nsIntRect GetTileRect() override;
+  virtual gfx::IntRect GetTileRect() override;
 
   virtual void EndBigImageIteration() override { mIterating = false; }
 
   virtual void BeginBigImageIteration() override
   {
     mIterating = true;
     mCurrentTile = 0;
   }
--- a/gfx/layers/ipc/CompositorBench.cpp
+++ b/gfx/layers/ipc/CompositorBench.cpp
@@ -395,20 +395,20 @@ static void RunCompositorBench(Composito
     BenchTest* test = tests[i];
     std::vector<TimeDuration> results;
     int testsOverThreshold = 0;
     PROFILER_MARKER(test->ToString());
     for (size_t j = 0; j < TEST_STEPS; j++) {
       test->Setup(aCompositor, j);
 
       TimeStamp start = TimeStamp::Now();
-      nsIntRect screenRect(aScreenRect.x, aScreenRect.y,
+      IntRect screenRect(aScreenRect.x, aScreenRect.y,
                            aScreenRect.width, aScreenRect.height);
       aCompositor->BeginFrame(
-        nsIntRect(screenRect.x, screenRect.y,
+        IntRect(screenRect.x, screenRect.y,
                   screenRect.width, screenRect.height),
         nullptr, aScreenRect, nullptr, nullptr);
 
       test->DrawFrame(aCompositor, aScreenRect, j);
 
       aCompositor->EndFrame();
       results.push_back(TimeStamp::Now() - start);
 
@@ -442,12 +442,12 @@ void CompositorBench(Compositor* aCompos
   static bool sRanBenchmark = false;
   bool wantBenchmark = gfxPrefs::LayersBenchEnabled();
   if (wantBenchmark && !sRanBenchmark) {
     RunCompositorBench(aCompositor, aScreenRect);
   }
   sRanBenchmark = wantBenchmark;
 }
 
-}
-}
+} // namespace layers
+} // namespace mozilla
 #endif
 
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -203,46 +203,46 @@ CompositorChild::RecvInvalidateAll()
 {
   if (mLayerManager) {
     FrameLayerBuilder::InvalidateAllLayers(mLayerManager);
   }
   return true;
 }
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
-static void CalculatePluginClip(const nsIntRect& aBounds,
-                                const nsTArray<nsIntRect>& aPluginClipRects,
+static void CalculatePluginClip(const gfx::IntRect& aBounds,
+                                const nsTArray<gfx::IntRect>& aPluginClipRects,
                                 const nsIntPoint& aContentOffset,
                                 const nsIntRegion& aParentLayerVisibleRegion,
-                                nsTArray<nsIntRect>& aResult,
-                                nsIntRect& aVisibleBounds,
+                                nsTArray<gfx::IntRect>& aResult,
+                                gfx::IntRect& aVisibleBounds,
                                 bool& aPluginIsVisible)
 {
   aPluginIsVisible = true;
   // aBounds (content origin)
   nsIntRegion contentVisibleRegion(aBounds);
   // aPluginClipRects (plugin widget origin)
   for (uint32_t idx = 0; idx < aPluginClipRects.Length(); idx++) {
-    nsIntRect rect = aPluginClipRects[idx];
+    gfx::IntRect rect = aPluginClipRects[idx];
     // shift to content origin
     rect.MoveBy(aBounds.x, aBounds.y);
     contentVisibleRegion.AndWith(rect);
   }
   // apply layers clip (window origin)
   nsIntRegion region = aParentLayerVisibleRegion;
   region.MoveBy(-aContentOffset.x, -aContentOffset.y);
   contentVisibleRegion.AndWith(region);
   if (contentVisibleRegion.IsEmpty()) {
     aPluginIsVisible = false;
     return;
   }
   // shift to plugin widget origin
   contentVisibleRegion.MoveBy(-aBounds.x, -aBounds.y);
   nsIntRegionRectIterator iter(contentVisibleRegion);
-  for (const nsIntRect* rgnRect = iter.Next(); rgnRect; rgnRect = iter.Next()) {
+  for (const gfx::IntRect* rgnRect = iter.Next(); rgnRect; rgnRect = iter.Next()) {
     aResult.AppendElement(*rgnRect);
     aVisibleBounds.UnionRect(aVisibleBounds, *rgnRect);
   }
 }
 #endif
 
 bool
 CompositorChild::RecvUpdatePluginConfigurations(const nsIntPoint& aContentOffset,
@@ -267,29 +267,29 @@ CompositorChild::RecvUpdatePluginConfigu
     nsIWidget* widget =
       nsIWidget::LookupRegisteredPluginWindow(aPlugins[pluginsIdx].windowId());
     if (!widget) {
       NS_WARNING("Unexpected, plugin id not found!");
       continue;
     }
     bool isVisible = aPlugins[pluginsIdx].visible();
     if (widget && !widget->Destroyed()) {
-      nsIntRect bounds;
-      nsIntRect visibleBounds;
+      gfx::IntRect bounds;
+      gfx::IntRect visibleBounds;
       // If the plugin is visible update it's geometry.
       if (isVisible) {
         // bounds (content origin) - don't pass true to Resize, it triggers a
         // sync paint update to the plugin process on Windows, which happens
         // prior to clipping information being applied.
         bounds = aPlugins[pluginsIdx].bounds();
         rv = widget->Resize(aContentOffset.x + bounds.x,
                             aContentOffset.y + bounds.y,
                             bounds.width, bounds.height, false);
         NS_ASSERTION(NS_SUCCEEDED(rv), "widget call failure");
-        nsTArray<nsIntRect> rectsOut;
+        nsTArray<gfx::IntRect> rectsOut;
         // This call may change the value of isVisible
         CalculatePluginClip(bounds, aPlugins[pluginsIdx].clip(),
                             aContentOffset, aParentLayerVisibleRegion,
                             rectsOut, visibleBounds, isVisible);
         // content clipping region (widget origin)
         rv = widget->SetWindowClipRegion(rectsOut, false);
         NS_ASSERTION(NS_SUCCEEDED(rv), "widget call failure");
       }
@@ -299,18 +299,18 @@ CompositorChild::RecvUpdatePluginConfigu
 
       // visible state - updated after clipping, prior to invalidating
       rv = widget->Show(isVisible);
       NS_ASSERTION(NS_SUCCEEDED(rv), "widget call failure");
 
       // Handle invalidation, this can be costly, avoid if it is not needed.
       if (isVisible) {
         // invalidate region (widget origin)
-        nsIntRect bounds = aPlugins[pluginsIdx].bounds();
-        nsIntRect rect(0, 0, bounds.width, bounds.height);
+        gfx::IntRect bounds = aPlugins[pluginsIdx].bounds();
+        gfx::IntRect rect(0, 0, bounds.width, bounds.height);
 #if defined(XP_WIN)
         // Work around for flash's crummy sandbox. See bug 762948. This call
         // digs down into the window hirearchy, invalidating regions on
         // windows owned by other processes.
         mozilla::widget::WinUtils::InvalidatePluginAsWorkaround(widget, visibleBounds);
 #else
         rv = widget->Invalidate(visibleBounds);
         NS_ASSERTION(NS_SUCCEEDED(rv), "widget call failure");
@@ -565,17 +565,17 @@ CompositorChild::SendAdoptChild(const ui
   MOZ_ASSERT(mCanSend);
   if (!mCanSend) {
     return true;
   }
   return PCompositorChild::SendAdoptChild(id);
 }
 
 bool
-CompositorChild::SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const nsIntRect& dirtyRect)
+CompositorChild::SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const gfx::IntRect& dirtyRect)
 {
   MOZ_ASSERT(mCanSend);
   if (!mCanSend) {
     return true;
   }
   return PCompositorChild::SendMakeSnapshot(inSnapshot, dirtyRect);
 }
 
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -103,17 +103,17 @@ public:
   // send a message) and forward the call to the super-class's equivalent method.
   // This means that it is correct to call directly the super-class methods, but
   // you won't get the extra safety provided here.
   bool SendWillStop();
   bool SendPause();
   bool SendResume();
   bool SendNotifyChildCreated(const uint64_t& id);
   bool SendAdoptChild(const uint64_t& id);
-  bool SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const nsIntRect& dirtyRect);
+  bool SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const gfx::IntRect& dirtyRect);
   bool SendFlushRendering();
   bool SendGetTileSize(int32_t* tileWidth, int32_t* tileHeight);
   bool SendStartFrameTimeRecording(const int32_t& bufferSize, uint32_t* startIndex);
   bool SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals);
   bool SendNotifyRegionInvalidated(const nsIntRegion& region);
   bool SendRequestNotifyAfterRemotePaint();
 
 private:
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -249,24 +249,24 @@ CompositorScheduler::ScheduleTask(Cancel
 void
 CompositorScheduler::ResumeComposition()
 {
   mLastCompose = TimeStamp::Now();
   ComposeToTarget(nullptr);
 }
 
 void
-CompositorScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect)
+CompositorScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
 {
   mLastCompose = TimeStamp::Now();
   ComposeToTarget(aTarget, aRect);
 }
 
 void
-CompositorScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect)
+CompositorScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
 {
   MOZ_ASSERT(CompositorParent::IsInCompositorThread());
   MOZ_ASSERT(mCompositorParent);
   mCompositorParent->CompositeToTarget(aTarget, aRect);
 }
 
 void
 CompositorScheduler::Destroy()
@@ -535,17 +535,17 @@ CompositorVsyncScheduler::OnForceCompose
    * free and this oscillating behavior causes a performance hit. In order to avoid this problem,
    * we reset the mVsyncNotificationsSkipped counter to keep vsync enabled.
    */
   MOZ_ASSERT(CompositorParent::IsInCompositorThread());
   mVsyncNotificationsSkipped = 0;
 }
 
 void
-CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect)
+CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
 {
   OnForceComposeToTarget();
   CompositorScheduler::ForceComposeToTarget(aTarget, aRect);
 }
 
 bool
 CompositorVsyncScheduler::NeedsComposite()
 {
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -95,18 +95,18 @@ public:
   explicit CompositorScheduler(CompositorParent* aCompositorParent);
 
   virtual void ScheduleComposition() = 0;
   virtual void CancelCurrentCompositeTask();
   virtual bool NeedsComposite() = 0;
   virtual void Composite(TimeStamp aTimestamp) = 0;
   virtual void ScheduleTask(CancelableTask*, int);
   virtual void ResumeComposition();
-  virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect);
-  virtual void ComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect = nullptr);
+  virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect);
+  virtual void ComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
   virtual void Destroy();
 
   const TimeStamp& GetLastComposeTime()
   {
     return mLastCompose;
   }
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
@@ -157,17 +157,17 @@ public:
   void SetNeedsComposite(bool aSchedule);
   void OnForceComposeToTarget();
 
   // from CompositorScheduler
   virtual void ScheduleComposition() override;
   virtual void CancelCurrentCompositeTask() override;
   virtual bool NeedsComposite() override;
   virtual void Composite(TimeStamp aVsyncTimestamp) override;
-  virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect) override;
+  virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect) override;
   virtual void Destroy() override;
 
 private:
   virtual ~CompositorVsyncScheduler();
 
   void NotifyCompositeTaskExecuted();
   void ObserveVsync();
   void UnobserveVsync();
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -521,16 +521,29 @@ ImageBridgeChild::EndTransaction()
     }
     default:
       NS_RUNTIMEABORT("not reached");
     }
   }
   SendPendingAsyncMessges();
 }
 
+void
+ImageBridgeChild::SendImageBridgeThreadId()
+{
+#ifdef MOZ_WIDGET_GONK
+  SendImageBridgeThreadId(gettid());
+#endif
+}
+
+static void CallSendImageBridgeThreadId(ImageBridgeChild* aImageBridgeChild)
+{
+  MOZ_ASSERT(InImageBridgeChildThread());
+  aImageBridgeChild->SendImageBridgeThreadId();
+}
 
 PImageBridgeChild*
 ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
                                         ProcessId aOtherPid)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   gfxPlatform::GetPlatform();
@@ -540,16 +553,20 @@ ImageBridgeChild::StartUpInChildProcess(
     return nullptr;
   }
 
   sImageBridgeChildSingleton = new ImageBridgeChild();
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(ConnectImageBridgeInChildProcess,
                         aTransport, aOtherPid));
+  sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
+    FROM_HERE,
+    NewRunnableFunction(CallSendImageBridgeThreadId,
+                        sImageBridgeChildSingleton.get()));
 
   return sImageBridgeChildSingleton;
 }
 
 void ImageBridgeChild::ShutDown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (ImageBridgeChild::IsCreated()) {
@@ -593,16 +610,20 @@ bool ImageBridgeChild::StartUpOnThread(T
     sImageBridgeChildThread = aThread;
     if (!aThread->IsRunning()) {
       aThread->Start();
     }
     sImageBridgeChildSingleton = new ImageBridgeChild();
     sImageBridgeParentSingleton = new ImageBridgeParent(
       CompositorParent::CompositorLoop(), nullptr, base::GetCurrentProcId());
     sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
+    sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
+      FROM_HERE,
+      NewRunnableFunction(CallSendImageBridgeThreadId,
+                          sImageBridgeChildSingleton.get()));
     return true;
   } else {
     return false;
   }
 }
 
 bool InImageBridgeChildThread()
 {
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -147,16 +147,19 @@ public:
   static ImageBridgeChild* GetSingleton();
 
 
   /**
    * Dispatches a task to the ImageBridgeChild thread to do the connection
    */
   void ConnectAsync(ImageBridgeParent* aParent);
 
+  using PImageBridgeChild::SendImageBridgeThreadId;
+  void SendImageBridgeThreadId();
+
   static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier);
 
   void BeginTransaction();
   void EndTransaction();
 
   /**
    * Returns the ImageBridgeChild's thread.
    *
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -7,16 +7,18 @@
 #include "ImageBridgeParent.h"
 #include <stdint.h>                     // for uint64_t, uint32_t
 #include "CompositableHost.h"           // for CompositableParent, Create
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/gfx/Point.h"                   // for IntSize
+#include "mozilla/Hal.h"                // for hal::SetCurrentThreadPriority()
+#include "mozilla/HalTypes.h"           // for hal::THREAD_PRIORITY_COMPOSITOR
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/layers/CompositableTransactionParent.h"
 #include "mozilla/layers/CompositorParent.h"  // for CompositorParent
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply
 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferParent
@@ -48,16 +50,17 @@ MessageLoop* ImageBridgeParent::sMainLoo
 // defined in CompositorParent.cpp
 CompositorThreadHolder* GetCompositorThreadHolder();
 
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
                                      Transport* aTransport,
                                      ProcessId aChildProcessId)
   : mMessageLoop(aLoop)
   , mTransport(aTransport)
+  , mSetChildThreadPriority(false)
   , mCompositorThreadHolder(GetCompositorThreadHolder())
 {
   MOZ_ASSERT(NS_IsMainThread());
   sMainLoop = MessageLoop::current();
 
   // top-level actors must be destroyed on the main thread.
   SetMessageLoopToPostDestructionTo(sMainLoop);
 
@@ -90,16 +93,30 @@ ImageBridgeParent::GetCompositorBackendT
 void
 ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
 }
 
+bool
+ImageBridgeParent::RecvImageBridgeThreadId(const PlatformThreadId& aThreadId)
+{
+  MOZ_ASSERT(!mSetChildThreadPriority);
+  if (mSetChildThreadPriority) {
+    return false;
+  }
+  mSetChildThreadPriority = true;
+#ifdef MOZ_WIDGET_GONK
+  hal::SetThreadPriority(aThreadId, hal::THREAD_PRIORITY_COMPOSITOR);
+#endif
+  return true;
+}
+
 class MOZ_STACK_CLASS AutoImageBridgeParentAsyncMessageSender
 {
 public:
   explicit AutoImageBridgeParentAsyncMessageSender(ImageBridgeParent* aImageBridge)
     : mImageBridge(aImageBridge) {}
 
   ~AutoImageBridgeParentAsyncMessageSender()
   {
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -62,16 +62,17 @@ public:
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   virtual base::ProcessId GetChildProcessId() override
   {
     return OtherPid();
   }
 
   // PImageBridge
+  virtual bool RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override;
   virtual bool RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply) override;
   virtual bool RecvUpdateNoSwap(EditArray&& aEdits) override;
 
   virtual bool IsAsync() const override { return true; }
 
   PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
                                                 uint64_t*) override;
   bool DeallocPCompositableParent(PCompositableParent* aActor) override;
@@ -138,23 +139,24 @@ public:
   // Overriden from IToplevelProtocol
   IToplevelProtocol*
   CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
                 base::ProcessHandle aPeerProcess,
                 mozilla::ipc::ProtocolCloneContext* aCtx) override;
 
 private:
   void DeferredDestroy();
-
   MessageLoop* mMessageLoop;
   Transport* mTransport;
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   nsRefPtr<ImageBridgeParent> mSelfRef;
 
+  bool mSetChildThreadPriority;
+
   /**
    * Map of all living ImageBridgeParent instances
    */
   static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
 
   static MessageLoop* sMainLoop;
 
   nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -10,16 +10,18 @@ include protocol PLayer;
 include protocol PTexture;
 include ProtocolTypes;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
 
+using PlatformThreadId from "base/platform_thread.h";
+
 namespace mozilla {
 namespace layers {
 
 /**
  * The PImageBridge protocol is used to allow isolated threads or processes to push
  * frames directly to the compositor thread/process without relying on the main thread
  * which might be too busy dealing with content script.
  */
@@ -28,16 +30,18 @@ sync protocol PImageBridge
   manages PCompositable;
   manages PTexture;
 
 child:
   async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
 
 parent:
 
+  async ImageBridgeThreadId(PlatformThreadId aTreahdId);
+
   sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
   async UpdateNoSwap(CompositableOperation[] ops);
 
   // First step of the destruction sequence. This puts ImageBridge
   // in a state in which it can't send asynchronous messages
   // so as to not race with the upcomming Stop message and destruction.
   // In the child side, the Stop message is not sent right after WillStop,
   // it is scheduled in the ImageBridgeChild's message queue in order to ensure
--- a/gfx/layers/ipc/SharedRGBImage.cpp
+++ b/gfx/layers/ipc/SharedRGBImage.cpp
@@ -12,17 +12,17 @@
 #include "mozilla/layers/ImageDataSerializer.h"  // for ImageDataSerializer
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
 #include "mozilla/layers/TextureClient.h"  // for BufferTextureClient, etc
 #include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::AddRef, etc
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsSize.h"                     // for nsIntSize
 
 // Just big enough for a 1080p RGBA32 frame
 #define MAX_FRAME_SIZE (16 * 1024 * 1024)
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -30,17 +30,17 @@
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureSourceOGL, etc
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAppRunner.h"
 #include "nsAString.h"
 #include "nsIConsoleService.h"          // for nsIConsoleService, etc
 #include "nsIWidget.h"                  // for nsIWidget
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsMathUtils.h"                // for NS_roundf
-#include "nsRect.h"                     // for nsIntRect
+#include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsString, nsAutoCString, etc
 #include "ScopedGLHelpers.h"
 #include "GLReadTexImageHelper.h"
 #include "GLBlitTextureImageHelper.h"
 #include "TiledLayerBuffer.h"           // for TiledLayerComposer
 #include "HeapCopyOfStackArray.h"
 
@@ -1223,19 +1223,19 @@ CompositorOGL::EndFrame()
 {
   PROFILER_LABEL("CompositorOGL", "EndFrame",
     js::ProfileEntry::Category::GRAPHICS);
 
   MOZ_ASSERT(mCurrentRenderTarget == mWindowRenderTarget, "Rendering target not properly restored");
 
 #ifdef MOZ_DUMP_PAINTING
   if (gfxUtils::sDumpPainting) {
-    nsIntRect rect;
+    IntRect rect;
     if (mUseExternalSurfaceSize) {
-      rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
+      rect = IntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
     } else {
       mWidget->GetBounds(rect);
     }
     RefPtr<DrawTarget> target = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(rect.width, rect.height), SurfaceFormat::B8G8R8A8);
     if (target) {
       CopyToTarget(target, nsIntPoint(), Matrix());
       WriteSnapshotToDumpFile(this, target);
     }
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -900,18 +900,18 @@ TEST_F(APZCBasicTester, ComplexTransform
   // CSS pixels). The displayport is 1 extra CSS pixel on all
   // sides.
 
   nsRefPtr<TestAsyncPanZoomController> childApzc = new TestAsyncPanZoomController(0, mcc, tm);
 
   const char* layerTreeSyntax = "c(c)";
   // LayerID                     0 1
   nsIntRegion layerVisibleRegion[] = {
-    nsIntRegion(nsIntRect(0, 0, 300, 300)),
-    nsIntRegion(nsIntRect(0, 0, 150, 300)),
+    nsIntRegion(IntRect(0, 0, 300, 300)),
+    nsIntRegion(IntRect(0, 0, 150, 300)),
   };
   Matrix4x4 transforms[] = {
     Matrix4x4(),
     Matrix4x4(),
   };
   transforms[0].PostScale(0.5f, 0.5f, 1.0f); // this results from the 2.0 resolution on the root layer
   transforms[1].PostScale(2.0f, 1.0f, 1.0f); // this is the 2.0 x-axis CSS transform on the child layer
 
@@ -1860,30 +1860,30 @@ protected:
 
   nsRefPtr<TestAPZCTreeManager> manager;
 
 protected:
   static void SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
                                         CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) {
     FrameMetrics metrics;
     metrics.SetScrollId(aScrollId);
-    nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds();
+    IntRect layerBound = aLayer->GetVisibleRegion().GetBounds();
     metrics.mCompositionBounds = ParentLayerRect(layerBound.x, layerBound.y,
                                                  layerBound.width, layerBound.height);
     metrics.SetScrollableRect(aScrollableRect);
     metrics.SetScrollOffset(CSSPoint(0, 0));
     aLayer->SetFrameMetrics(metrics);
     aLayer->SetClipRect(Some(ViewAs<ParentLayerPixel>(layerBound)));
     if (!aScrollableRect.IsEqualEdges(CSSRect(-1, -1, -1, -1))) {
       // The purpose of this is to roughly mimic what layout would do in the
       // case of a scrollable frame with the event regions and clip. This lets
       // us exercise the hit-testing code in APZCTreeManager
       EventRegions er = aLayer->GetEventRegions();
-      nsIntRect scrollRect = LayerIntRect::ToUntyped(RoundedToInt(aScrollableRect * metrics.LayersPixelsPerCSSPixel()));
-      er.mHitRegion = nsIntRegion(nsIntRect(layerBound.TopLeft(), scrollRect.Size()));
+      IntRect scrollRect = LayerIntRect::ToUntyped(RoundedToInt(aScrollableRect * metrics.LayersPixelsPerCSSPixel()));
+      er.mHitRegion = nsIntRegion(IntRect(layerBound.TopLeft(), scrollRect.Size()));
       aLayer->SetEventRegions(er);
     }
   }
 
   void SetScrollHandoff(Layer* aChild, Layer* aParent) {
     FrameMetrics metrics = aChild->GetFrameMetrics(0);
     metrics.SetScrollParentId(aParent->GetFrameMetrics(0).GetScrollId());
     aChild->SetFrameMetrics(metrics);
@@ -1892,29 +1892,29 @@ protected:
   static TestAsyncPanZoomController* ApzcOf(Layer* aLayer) {
     EXPECT_EQ(1u, aLayer->GetFrameMetricsCount());
     return (TestAsyncPanZoomController*)aLayer->GetAsyncPanZoomController(0);
   }
 
   void CreateSimpleScrollingLayer() {
     const char* layerTreeSyntax = "t";
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0,0,200,200)),
+      nsIntRegion(IntRect(0,0,200,200)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 500, 500));
   }
 
   void CreateSimpleMultiLayerTree() {
     const char* layerTreeSyntax = "c(tt)";
     // LayerID                     0 12
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0,0,100,100)),
-      nsIntRegion(nsIntRect(0,0,100,50)),
-      nsIntRegion(nsIntRect(0,50,100,50)),
+      nsIntRegion(IntRect(0,0,100,100)),
+      nsIntRegion(IntRect(0,0,100,50)),
+      nsIntRegion(IntRect(0,50,100,50)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
   }
 
   void CreatePotentiallyLeakingTree() {
     const char* layerTreeSyntax = "c(c(c(t))c(c(t)))";
     // LayerID                     0 1 2 3  4 5 6
     root = CreateLayerTree(layerTreeSyntax, nullptr, nullptr, lm, layers);
@@ -1940,33 +1940,33 @@ protected:
     return hit.forget();
   }
 
 protected:
   void CreateHitTesting1LayerTree() {
     const char* layerTreeSyntax = "c(tttt)";
     // LayerID                     0 1234
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0,0,100,100)),
-      nsIntRegion(nsIntRect(0,0,100,100)),
-      nsIntRegion(nsIntRect(10,10,20,20)),
-      nsIntRegion(nsIntRect(10,10,20,20)),
-      nsIntRegion(nsIntRect(5,5,20,20)),
+      nsIntRegion(IntRect(0,0,100,100)),
+      nsIntRegion(IntRect(0,0,100,100)),
+      nsIntRegion(IntRect(10,10,20,20)),
+      nsIntRegion(IntRect(10,10,20,20)),
+      nsIntRegion(IntRect(5,5,20,20)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
   }
 
   void CreateHitTesting2LayerTree() {
     const char* layerTreeSyntax = "c(tc(t))";
     // LayerID                     0 12 3
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0,0,100,100)),
-      nsIntRegion(nsIntRect(10,10,40,40)),
-      nsIntRegion(nsIntRect(10,60,40,40)),
-      nsIntRegion(nsIntRect(10,60,40,40)),
+      nsIntRegion(IntRect(0,0,100,100)),
+      nsIntRegion(IntRect(10,10,40,40)),
+      nsIntRegion(IntRect(10,60,40,40)),
+      nsIntRegion(IntRect(10,60,40,40)),
     };
     Matrix4x4 transforms[] = {
       Matrix4x4(),
       Matrix4x4(),
       Matrix4x4::Scaling(2, 1, 1),
       Matrix4x4(),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, lm, layers);
@@ -1975,43 +1975,43 @@ protected:
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80));
     SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80));
   }
 
   void CreateComplexMultiLayerTree() {
     const char* layerTreeSyntax = "c(tc(t)tc(c(t)tt))";
     // LayerID                     0 12 3 45 6 7 89
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0,0,300,400)),      // root(0)
-      nsIntRegion(nsIntRect(0,0,100,100)),      // thebes(1) in top-left
-      nsIntRegion(nsIntRect(50,50,200,300)),    // container(2) centered in root(0)
-      nsIntRegion(nsIntRect(50,50,200,300)),    // thebes(3) fully occupying parent container(2)
-      nsIntRegion(nsIntRect(0,200,100,100)),    // thebes(4) in bottom-left
-      nsIntRegion(nsIntRect(200,0,100,400)),    // container(5) along the right 100px of root(0)
-      nsIntRegion(nsIntRect(200,0,100,200)),    // container(6) taking up the top half of parent container(5)
-      nsIntRegion(nsIntRect(200,0,100,200)),    // thebes(7) fully occupying parent container(6)
-      nsIntRegion(nsIntRect(200,200,100,100)),  // thebes(8) in bottom-right (below (6))
-      nsIntRegion(nsIntRect(200,300,100,100)),  // thebes(9) in bottom-right (below (8))
+      nsIntRegion(IntRect(0,0,300,400)),      // root(0)
+      nsIntRegion(IntRect(0,0,100,100)),      // thebes(1) in top-left
+      nsIntRegion(IntRect(50,50,200,300)),    // container(2) centered in root(0)
+      nsIntRegion(IntRect(50,50,200,300)),    // thebes(3) fully occupying parent container(2)
+      nsIntRegion(IntRect(0,200,100,100)),    // thebes(4) in bottom-left
+      nsIntRegion(IntRect(200,0,100,400)),    // container(5) along the right 100px of root(0)
+      nsIntRegion(IntRect(200,0,100,200)),    // container(6) taking up the top half of parent container(5)
+      nsIntRegion(IntRect(200,0,100,200)),    // thebes(7) fully occupying parent container(6)
+      nsIntRegion(IntRect(200,200,100,100)),  // thebes(8) in bottom-right (below (6))
+      nsIntRegion(IntRect(200,300,100,100)),  // thebes(9) in bottom-right (below (8))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID);
     SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID);
     SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1);
     SetScrollableFrameMetrics(layers[6], FrameMetrics::START_SCROLL_ID + 1);
     SetScrollableFrameMetrics(layers[7], FrameMetrics::START_SCROLL_ID + 2);
     SetScrollableFrameMetrics(layers[8], FrameMetrics::START_SCROLL_ID + 1);
     SetScrollableFrameMetrics(layers[9], FrameMetrics::START_SCROLL_ID + 3);
   }
 
   void CreateBug1148350LayerTree() {
     const char* layerTreeSyntax = "c(t)";
     // LayerID                     0 1
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0,0,200,200)),
-      nsIntRegion(nsIntRect(0,0,200,200)),
+      nsIntRegion(IntRect(0,0,200,200)),
+      nsIntRegion(IntRect(0,0,200,200)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID);
   }
 };
 
 // A simple hit testing test that doesn't involve any transforms on layers.
 TEST_F(APZHitTestingTester, HitTesting1) {
@@ -2418,51 +2418,51 @@ TEST_F(APZHitTestingTester, Bug1148350) 
 
   uint64_t blockId;
   TouchDown(manager, 100, 100, time, &blockId);
   if (gfxPrefs::TouchActionEnabled()) {
     SetDefaultAllowedTouchBehavior(manager, blockId);
   }
   time += 100;
 
-  layers[0]->SetVisibleRegion(nsIntRegion(nsIntRect(0,50,200,150)));
+  layers[0]->SetVisibleRegion(nsIntRegion(IntRect(0,50,200,150)));
   layers[0]->SetBaseTransform(Matrix4x4::Translation(0, 50, 0));
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
 
   TouchUp(manager, 100, 100, time);
   mcc->RunThroughDelayedTasks();
   check.Call("Tapped with interleaved transform");
 }
 
 class APZOverscrollHandoffTester : public APZCTreeManagerTester {
 protected:
   UniquePtr<ScopedLayerTreeRegistration> registration;
   TestAsyncPanZoomController* rootApzc;
 
   void CreateOverscrollHandoffLayerTree1() {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 50, 100, 50))
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 50, 100, 50))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
     SetScrollHandoff(layers[1], root);
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
   }
 
   void CreateOverscrollHandoffLayerTree2() {
     const char* layerTreeSyntax = "c(c(t))";
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 50, 100, 50))
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 50, 100, 50))
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 2, CSSRect(-100, -100, 200, 200));
     SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
     SetScrollHandoff(layers[1], root);
     SetScrollHandoff(layers[2], layers[1]);
     // No ScopedLayerTreeRegistration as that just needs to be done once per test
@@ -2470,38 +2470,38 @@ protected:
     MOZ_ASSERT(registration);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
   }
 
   void CreateOverscrollHandoffLayerTree3() {
     const char* layerTreeSyntax = "c(c(t)c(t))";
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),  // root
-      nsIntRegion(nsIntRect(0, 0, 100, 50)),   // scrolling parent 1
-      nsIntRegion(nsIntRect(0, 0, 100, 50)),   // scrolling child 1
-      nsIntRegion(nsIntRect(0, 50, 100, 50)),  // scrolling parent 2
-      nsIntRegion(nsIntRect(0, 50, 100, 50))   // scrolling child 2
+      nsIntRegion(IntRect(0, 0, 100, 100)),  // root
+      nsIntRegion(IntRect(0, 0, 100, 50)),   // scrolling parent 1
+      nsIntRegion(IntRect(0, 0, 100, 50)),   // scrolling child 1
+      nsIntRegion(IntRect(0, 50, 100, 50)),  // scrolling parent 2
+      nsIntRegion(IntRect(0, 50, 100, 50))   // scrolling child 2
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, 100));
     SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 100));
     SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 50, 100, 100));
     SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 3, CSSRect(0, 50, 100, 100));
     SetScrollHandoff(layers[2], layers[1]);
     SetScrollHandoff(layers[4], layers[3]);
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
   }
 
   void CreateScrollgrabLayerTree() {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),  // scroll-grabbing parent
-      nsIntRegion(nsIntRect(0, 20, 100, 80))   // child
+      nsIntRegion(IntRect(0, 0, 100, 100)),  // scroll-grabbing parent
+      nsIntRegion(IntRect(0, 20, 100, 80))   // child
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers);
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 100, 120));
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 100, 200));
     SetScrollHandoff(layers[1], root);
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
@@ -2693,111 +2693,111 @@ TEST_F(APZOverscrollHandoffTester, Scrol
 class APZEventRegionsTester : public APZCTreeManagerTester {
 protected:
   UniquePtr<ScopedLayerTreeRegistration> registration;
   TestAsyncPanZoomController* rootApzc;
 
   void CreateEventRegionsLayerTree1() {
     const char* layerTreeSyntax = "c(tt)";
     nsIntRegion layerVisibleRegions[] = {
-      nsIntRegion(nsIntRect(0, 0, 200, 200)),     // root
-      nsIntRegion(nsIntRect(0, 0, 100, 200)),     // left half
-      nsIntRegion(nsIntRect(0, 100, 200, 100)),   // bottom half
+      nsIntRegion(IntRect(0, 0, 200, 200)),     // root
+      nsIntRegion(IntRect(0, 0, 100, 200)),     // left half
+      nsIntRegion(IntRect(0, 100, 200, 100)),   // bottom half
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
     SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 2);
     SetScrollHandoff(layers[1], root);
     SetScrollHandoff(layers[2], root);
 
     // Set up the event regions over a 200x200 area. The root layer has the
     // whole 200x200 as the hit region; layers[1] has the left half and
     // layers[2] has the bottom half. The bottom-left 100x100 area is also
     // in the d-t-c region for both layers[1] and layers[2] (but layers[2] is
     // on top so it gets the events by default if the main thread doesn't
     // respond).
-    EventRegions regions(nsIntRegion(nsIntRect(0, 0, 200, 200)));
+    EventRegions regions(nsIntRegion(IntRect(0, 0, 200, 200)));
     root->SetEventRegions(regions);
-    regions.mDispatchToContentHitRegion = nsIntRegion(nsIntRect(0, 100, 100, 100));
-    regions.mHitRegion = nsIntRegion(nsIntRect(0, 0, 100, 200));
+    regions.mDispatchToContentHitRegion = nsIntRegion(IntRect(0, 100, 100, 100));
+    regions.mHitRegion = nsIntRegion(IntRect(0, 0, 100, 200));
     layers[1]->SetEventRegions(regions);
-    regions.mHitRegion = nsIntRegion(nsIntRect(0, 100, 200, 100));
+    regions.mHitRegion = nsIntRegion(IntRect(0, 100, 200, 100));
     layers[2]->SetEventRegions(regions);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
   }
 
   void CreateEventRegionsLayerTree2() {
     const char* layerTreeSyntax = "c(t)";
     nsIntRegion layerVisibleRegions[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 500)),
-      nsIntRegion(nsIntRect(0, 150, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 100, 500)),
+      nsIntRegion(IntRect(0, 150, 100, 100)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
 
     // Set up the event regions so that the child thebes layer is positioned far
     // away from the scrolling container layer.
-    EventRegions regions(nsIntRegion(nsIntRect(0, 0, 100, 100)));
+    EventRegions regions(nsIntRegion(IntRect(0, 0, 100, 100)));
     root->SetEventRegions(regions);
-    regions.mHitRegion = nsIntRegion(nsIntRect(0, 150, 100, 100));
+    regions.mHitRegion = nsIntRegion(IntRect(0, 150, 100, 100));
     layers[1]->SetEventRegions(regions);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
   }
 
   void CreateObscuringLayerTree() {
     const char* layerTreeSyntax = "c(c(t)t)";
     // LayerID                     0 1 2 3
     // 0 is the root.
     // 1 is a parent scrollable layer.
     // 2 is a child scrollable layer.
     // 3 is the Obscurer, who ruins everything.
     nsIntRegion layerVisibleRegions[] = {
         // x coordinates are uninteresting
-        nsIntRegion(nsIntRect(0,   0, 200, 200)),  // [0, 200]
-        nsIntRegion(nsIntRect(0,   0, 200, 200)),  // [0, 200]
-        nsIntRegion(nsIntRect(0, 100, 200,  50)),  // [100, 150]
-        nsIntRegion(nsIntRect(0, 100, 200, 100))   // [100, 200]
+        nsIntRegion(IntRect(0,   0, 200, 200)),  // [0, 200]
+        nsIntRegion(IntRect(0,   0, 200, 200)),  // [0, 200]
+        nsIntRegion(IntRect(0, 100, 200,  50)),  // [100, 150]
+        nsIntRegion(IntRect(0, 100, 200, 100))   // [100, 200]
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
 
     SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 200, 300));
     SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 200, 100));
     SetScrollHandoff(layers[2], layers[1]);
     SetScrollHandoff(layers[1], root);
 
-    EventRegions regions(nsIntRegion(nsIntRect(0, 0, 200, 200)));
+    EventRegions regions(nsIntRegion(IntRect(0, 0, 200, 200)));
     root->SetEventRegions(regions);
-    regions.mHitRegion = nsIntRegion(nsIntRect(0, 0, 200, 300));
+    regions.mHitRegion = nsIntRegion(IntRect(0, 0, 200, 300));
     layers[1]->SetEventRegions(regions);
-    regions.mHitRegion = nsIntRegion(nsIntRect(0, 100, 200, 100));
+    regions.mHitRegion = nsIntRegion(IntRect(0, 100, 200, 100));
     layers[2]->SetEventRegions(regions);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
     rootApzc = ApzcOf(root);
   }
 
   void CreateBug1119497LayerTree() {
     const char* layerTreeSyntax = "c(tt)";
     // LayerID                     0 12
     // 0 is the root and doesn't have an APZC
     // 1 is behind 2 and does have an APZC
     // 2 entirely covers 1 and should take all the input events
     nsIntRegion layerVisibleRegions[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
 
     SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
   }
@@ -2807,36 +2807,36 @@ protected:
     // LayerID                     0 1 2 3
     // 0 is the root
     // 1 is a container layer whose sole purpose to make a non-empty ancestor
     //   transform for 2, so that 2's screen-to-apzc and apzc-to-gecko
     //   transforms are different from 3's.
     // 2 is a small layer that is the actual target
     // 3 is a big layer obscuring 2 with a dispatch-to-content region
     nsIntRegion layerVisibleRegions[] = {
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 0, 0, 0)),
-      nsIntRegion(nsIntRect(0, 0, 10, 10)),
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 0, 0, 0)),
+      nsIntRegion(IntRect(0, 0, 10, 10)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
     };
     Matrix4x4 layerTransforms[] = {
       Matrix4x4(),
       Matrix4x4::Translation(50, 0, 0),
       Matrix4x4(),
       Matrix4x4(),
     };
     root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, layerTransforms, lm, layers);
 
     SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 10, 10));
     SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 100, 100));
 
-    EventRegions regions(nsIntRegion(nsIntRect(0, 0, 10, 10)));
+    EventRegions regions(nsIntRegion(IntRect(0, 0, 10, 10)));
     layers[2]->SetEventRegions(regions);
-    regions.mHitRegion = nsIntRegion(nsIntRect(0, 0, 100, 100));
-    regions.mDispatchToContentHitRegion = nsIntRegion(nsIntRect(0, 0, 100, 100));
+    regions.mHitRegion = nsIntRegion(IntRect(0, 0, 100, 100));
+    regions.mDispatchToContentHitRegion = nsIntRegion(IntRect(0, 0, 100, 100));
     layers[3]->SetEventRegions(regions);
 
     registration = MakeUnique<ScopedLayerTreeRegistration>(0, root, mcc);
     manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
   }
 };
 
 TEST_F(APZEventRegionsTester, HitRegionImmediateResponse) {
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -28,52 +28,52 @@ using namespace mozilla::gl;
 
 class MockWidget : public nsBaseWidget
 {
 public:
   MockWidget() {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_IMETHOD              GetClientBounds(nsIntRect &aRect) override {
-    aRect = nsIntRect(0, 0, gCompWidth, gCompHeight);
+  NS_IMETHOD              GetClientBounds(IntRect &aRect) override {
+    aRect = IntRect(0, 0, gCompWidth, gCompHeight);
     return NS_OK;
   }
-  NS_IMETHOD              GetBounds(nsIntRect &aRect) override { return GetClientBounds(aRect); }
+  NS_IMETHOD              GetBounds(IntRect &aRect) override { return GetClientBounds(aRect); }
 
   void* GetNativeData(uint32_t aDataType) override {
     if (aDataType == NS_NATIVE_OPENGL_CONTEXT) {
       mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGB();
       caps.preserve = false;
       caps.bpp16 = false;
       nsRefPtr<GLContext> context = GLContextProvider::CreateOffscreen(
         gfxIntSize(gCompWidth, gCompHeight), caps, true);
       return context.forget().take();
     }
     return nullptr;
   }
 
   NS_IMETHOD              Create(nsIWidget *aParent,
                                  nsNativeWidget aNativeParent,
-                                 const nsIntRect &aRect,
+                                 const IntRect &aRect,
                                  nsWidgetInitData *aInitData = nullptr) override { return NS_OK; }
   NS_IMETHOD              Show(bool aState) override { return NS_OK; }
   virtual bool            IsVisible() const override { return true; }
   NS_IMETHOD              ConstrainPosition(bool aAllowSlop,
                                             int32_t *aX, int32_t *aY) override { return NS_OK; }
   NS_IMETHOD              Move(double aX, double aY) override { return NS_OK; }
   NS_IMETHOD              Resize(double aWidth, double aHeight, bool aRepaint) override { return NS_OK; }
   NS_IMETHOD              Resize(double aX, double aY,
                                  double aWidth, double aHeight, bool aRepaint) override { return NS_OK; }
 
   NS_IMETHOD              Enable(bool aState) override { return NS_OK; }
   virtual bool            IsEnabled() const override { return true; }
   NS_IMETHOD              SetFocus(bool aRaise) override { return NS_OK; }
   virtual nsresult        ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override { return NS_OK; }
-  NS_IMETHOD              Invalidate(const nsIntRect &aRect) override { return NS_OK; }
+  NS_IMETHOD              Invalidate(const IntRect &aRect) override { return NS_OK; }
   NS_IMETHOD              SetTitle(const nsAString& title) override { return NS_OK; }
   virtual LayoutDeviceIntPoint WidgetToScreenOffset() override { return LayoutDeviceIntPoint(0, 0); }
   NS_IMETHOD              DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
                                         nsEventStatus& aStatus) override { return NS_OK; }
   NS_IMETHOD              CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture) override { return NS_OK; }
   NS_IMETHOD_(void)       SetInputContext(const InputContext& aContext,
                                           const InputContextAction& aAction) override {}
   NS_IMETHOD_(InputContext) GetInputContext() override { abort(); }
@@ -177,17 +177,17 @@ static TemporaryRef<DrawTarget> CreateDT
 
   return dt;
 }
 
 static bool CompositeAndCompare(nsRefPtr<LayerManagerComposite> layerManager, DrawTarget* refDT)
 {
   RefPtr<DrawTarget> drawTarget = CreateDT();
 
-  layerManager->BeginTransactionWithDrawTarget(drawTarget, nsIntRect(0, 0, gCompWidth, gCompHeight));
+  layerManager->BeginTransactionWithDrawTarget(drawTarget, IntRect(0, 0, gCompWidth, gCompHeight));
   layerManager->EndEmptyTransaction();
 
   RefPtr<SourceSurface> ss = drawTarget->Snapshot();
   RefPtr<DataSourceSurface> dss = ss->GetDataSurface();
   uint8_t* bitmap = dss->GetData();
 
   RefPtr<SourceSurface> ssRef = refDT->Snapshot();
   RefPtr<DataSourceSurface> dssRef = ssRef->GetDataSurface();
@@ -226,20 +226,20 @@ TEST(Gfx, CompositorConstruct)
 TEST(Gfx, CompositorSimpleTree)
 {
   auto layerManagers = GetLayerManagers(GetPlatformBackends());
   for (size_t i = 0; i < layerManagers.size(); i++) {
     nsRefPtr<LayerManagerComposite> layerManager = layerManagers[i].mLayerManager;
     nsRefPtr<LayerManager> lmBase = layerManager.get();
     nsTArray<nsRefPtr<Layer>> layers;
     nsIntRegion layerVisibleRegion[] = {
-      nsIntRegion(nsIntRect(0, 0, gCompWidth, gCompHeight)),
-      nsIntRegion(nsIntRect(0, 0, gCompWidth, gCompHeight)),
-      nsIntRegion(nsIntRect(0, 0, 100, 100)),
-      nsIntRegion(nsIntRect(0, 50, 100, 100)),
+      nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
+      nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
+      nsIntRegion(IntRect(0, 0, 100, 100)),
+      nsIntRegion(IntRect(0, 50, 100, 100)),
     };
     nsRefPtr<Layer> root = CreateLayerTree("c(ooo)", layerVisibleRegion, nullptr, lmBase, layers);
 
     { // background
       ColorLayer* colorLayer = layers[1]->AsColorLayer();
       colorLayer->SetColor(gfxRGBA(1.f, 0.f, 1.f, 1.f));
       colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds());
     }
--- a/gfx/tests/gtest/TestLayers.cpp
+++ b/gfx/tests/gtest/TestLayers.cpp
@@ -243,20 +243,20 @@ already_AddRefed<Layer> CreateLayerTree(
     }
   }
   return rootLayer.forget();
 }
 
 TEST(Layers, LayerTree) {
   const char* layerTreeSyntax = "c(c(tt))";
   nsIntRegion layerVisibleRegion[] = {
-    nsIntRegion(nsIntRect(0,0,100,100)),
-    nsIntRegion(nsIntRect(0,0,100,100)),
-    nsIntRegion(nsIntRect(0,0,100,100)),
-    nsIntRegion(nsIntRect(10,10,20,20)),
+    nsIntRegion(IntRect(0,0,100,100)),
+    nsIntRegion(IntRect(0,0,100,100)),
+    nsIntRegion(IntRect(0,0,100,100)),
+    nsIntRegion(IntRect(10,10,20,20)),
   };
   Matrix4x4 transforms[] = {
     Matrix4x4(),
     Matrix4x4(),
     Matrix4x4(),
     Matrix4x4(),
   };
   nsTArray<nsRefPtr<Layer> > layers;
--- a/gfx/tests/gtest/TestRegion.cpp
+++ b/gfx/tests/gtest/TestRegion.cpp
@@ -138,42 +138,42 @@ TEST(Gfx, RegionScaleToInside) {
     EXPECT_TRUE(result.IsEqual(scaled)) <<
       "scaled result incorrect";
   }
 
   { // one rectangle
     nsRegion r(nsRect(0,44760,19096,264));
 
     nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
-    nsIntRegion result(nsIntRect(0,746,318,4));
+    nsIntRegion result(mozilla::gfx::IntRect(0,746,318,4));
 
     EXPECT_TRUE(result.IsEqual(scaled)) <<
       "scaled result incorrect";
   }
 
 
   { // the first rectangle gets adjusted
     nsRegion r(nsRect(0,44760,19096,264));
     r.Or(r, nsRect(0,45024,19360,1056));
 
     nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
-    nsIntRegion result(nsIntRect(0,746,318,5));
-    result.Or(result, nsIntRect(0,751,322,17));
+    nsIntRegion result(mozilla::gfx::IntRect(0,746,318,5));
+    result.Or(result, mozilla::gfx::IntRect(0,751,322,17));
 
     EXPECT_TRUE(result.IsEqual(scaled)) <<
       "scaled result incorrect";
   }
 
   { // the second rectangle gets adjusted
     nsRegion r(nsRect(0,44760,19360,264));
     r.Or(r, nsRect(0,45024,19096,1056));
 
     nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
-    nsIntRegion result(nsIntRect(0,746,322,4));
-    result.Or(result, nsIntRect(0,750,318,18));
+    nsIntRegion result(mozilla::gfx::IntRect(0,746,322,4));
+    result.Or(result, mozilla::gfx::IntRect(0,750,318,18));
 
     EXPECT_TRUE(result.IsEqual(scaled)) <<
       "scaled result incorrect";
   }
 
 }
 
 
--- a/gfx/tests/gtest/TestTiledLayerBuffer.cpp
+++ b/gfx/tests/gtest/TestTiledLayerBuffer.cpp
@@ -76,16 +76,16 @@ TEST(TiledLayerBuffer, TileStart) {
   ASSERT_EQ(buffer.RoundDownToTileEdge(-10, 256), -256);
 }
 
 TEST(TiledLayerBuffer, EmptyUpdate) {
   gfxPlatform::GetPlatform()->ComputeTileSize();
 
   TestTiledLayerBuffer buffer;
 
-  nsIntRegion validRegion(nsIntRect(0, 0, 10, 10));
+  nsIntRegion validRegion(gfx::IntRect(0, 0, 10, 10));
   buffer.TestUpdate(validRegion, validRegion);
 
   ASSERT_EQ(buffer.GetValidRegion(), validRegion);
 }
 
 }
 }
--- a/gfx/thebes/gfx2DGlue.h
+++ b/gfx/thebes/gfx2DGlue.h
@@ -20,17 +20,17 @@ namespace mozilla {
 namespace gfx {
 
 inline Rect ToRect(const gfxRect &aRect)
 {
   return Rect(Float(aRect.x), Float(aRect.y),
               Float(aRect.width), Float(aRect.height));
 }
 
-inline Rect ToRect(const nsIntRect &aRect)
+inline Rect ToRect(const IntRect &aRect)
 {
   return Rect(aRect.x, aRect.y, aRect.width, aRect.height);
 }
 
 inline Color ToColor(const gfxRGBA &aRGBA)
 {
   return Color(Float(aRGBA.r), Float(aRGBA.g),
                Float(aRGBA.b), Float(aRGBA.a));
--- a/gfx/thebes/gfxGdkNativeRenderer.cpp
+++ b/gfx/thebes/gfxGdkNativeRenderer.cpp
@@ -11,17 +11,17 @@
 #include <gdk/gdkx.h>
 #include "cairo-xlib.h"
 #include "gfxXlibSurface.h"
 
 #if (MOZ_WIDGET_GTK == 2)
 nsresult
 gfxGdkNativeRenderer::DrawWithXlib(cairo_surface_t* surface,
                                    nsIntPoint offset,
-                                   nsIntRect* clipRects, uint32_t numClipRects)
+                                   mozilla::gfx::IntRect* clipRects, uint32_t numClipRects)
 {
     GdkDrawable *drawable = gfxPlatformGtk::GetGdkDrawable(surface);
     if (!drawable) {
         int depth = cairo_xlib_surface_get_depth(surface);
         GdkScreen* screen = gdk_colormap_get_screen(mColormap);
         drawable =
             gdk_pixmap_foreign_new_for_screen(screen, cairo_xlib_surface_get_drawable(surface),
                                               cairo_xlib_surface_get_width(surface),
--- a/gfx/thebes/gfxGdkNativeRenderer.h
+++ b/gfx/thebes/gfxGdkNativeRenderer.h
@@ -72,17 +72,17 @@ public:
               uint32_t flags, GdkColormap* colormap);
 #endif
 
 private:
 #ifdef MOZ_X11
     // for gfxXlibNativeRenderer:
     virtual nsresult DrawWithXlib(cairo_surface_t* surface,
                                   nsIntPoint offset,
-                                  nsIntRect* clipRects, uint32_t numClipRects) override;
+                                  mozilla::gfx::IntRect* clipRects, uint32_t numClipRects) override;
 
 #if (MOZ_WIDGET_GTK == 2)
     GdkColormap *mColormap;
 #endif
 #endif
 };
 
 #endif /*GFXGDKNATIVERENDER_H_*/
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -583,20 +583,20 @@ public:
 
     virtual int GetScreenDepth() const;
 
     /**
      * Return the layer debugging options to use browser-wide.
      */
     mozilla::layers::DiagnosticTypes GetLayerDiagnosticTypes();
 
-    static nsIntRect FrameCounterBounds() {
+    static mozilla::gfx::IntRect FrameCounterBounds() {
       int bits = 16;
       int sizeOfBit = 3;
-      return nsIntRect(0, 0, bits * sizeOfBit, sizeOfBit);
+      return mozilla::gfx::IntRect(0, 0, bits * sizeOfBit, sizeOfBit);
     }
 
     mozilla::gl::SkiaGLGlue* GetSkiaGLGlue();
     void PurgeSkiaCache();
 
     virtual bool IsInGonkEmulator() const { return false; }
 
     static bool UsesOffMainThreadCompositing();
--- a/gfx/thebes/gfxRect.h
+++ b/gfx/thebes/gfxRect.h
@@ -58,17 +58,17 @@ struct gfxRect :
     public mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> {
     typedef mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super;
 
     gfxRect() : Super() {}
     gfxRect(const gfxPoint& aPos, const gfxSize& aSize) :
         Super(aPos, aSize) {}
     gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) :
         Super(aX, aY, aWidth, aHeight) {}
-    MOZ_IMPLICIT gfxRect(const nsIntRect& aRect) :
+    MOZ_IMPLICIT gfxRect(const mozilla::gfx::IntRect& aRect) :
         Super(aRect.x, aRect.y, aRect.width, aRect.height) {}
 
     /**
      * Return true if all components of this rect are within
      * aEpsilon of integer coordinates, defined as
      *   |round(coord) - coord| <= |aEpsilon|
      * for x,y,width,height.
      */
--- a/gfx/thebes/gfxSVGGlyphs.cpp
+++ b/gfx/thebes/gfxSVGGlyphs.cpp
@@ -142,17 +142,17 @@ gfxSVGGlyphsDocument::SetupPresentation(
 
     nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory = do_GetService(contractId);
     NS_ASSERTION(docLoaderFactory, "Couldn't get DocumentLoaderFactory");
 
     nsCOMPtr<nsIContentViewer> viewer;
     rv = docLoaderFactory->CreateInstanceForDocument(nullptr, mDocument, nullptr, getter_AddRefs(viewer));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = viewer->Init(nullptr, nsIntRect(0, 0, 1000, 1000));
+    rv = viewer->Init(nullptr, gfx::IntRect(0, 0, 1000, 1000));
     if (NS_SUCCEEDED(rv)) {
         rv = viewer->Open(nullptr, nullptr);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     nsCOMPtr<nsIPresShell> presShell;
     rv = viewer->GetPresShell(getter_AddRefs(presShell));
     NS_ENSURE_SUCCESS(rv, rv);
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -859,16 +859,23 @@ SetProcessPriority(int aPid, ProcessPrio
 }
 
 void
 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
 {
   PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
 }
 
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                  hal::ThreadPriority aThreadPriority)
+{
+  PROXY_IF_SANDBOXED(SetThreadPriority(aThreadId, aThreadPriority));
+}
+
 // From HalTypes.h.
 const char*
 ProcessPriorityToString(ProcessPriority aPriority)
 {
   switch (aPriority) {
   case PROCESS_PRIORITY_MASTER:
     return "MASTER";
   case PROCESS_PRIORITY_PREALLOC:
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_Hal_h
 #define mozilla_Hal_h
 
 #include "mozilla/hal_sandbox/PHal.h"
 #include "mozilla/HalTypes.h"
 #include "base/basictypes.h"
+#include "base/platform_thread.h"
 #include "mozilla/Observer.h"
 #include "mozilla/Types.h"
 #include "nsTArray.h"
 #include "mozilla/dom/MozPowerManagerBinding.h"
 #include "mozilla/dom/battery/Types.h"
 #include "mozilla/dom/network/Types.h"
 #include "mozilla/dom/power/Types.h"
 #include "mozilla/dom/ScreenOrientation.h"
@@ -481,16 +482,24 @@ void SetProcessPriority(int aPid,
 /**
  * Set the current thread's priority to appropriate platform-specific value for
  * given functionality. Instead of providing arbitrary priority numbers you
  * must specify a type of function like THREAD_PRIORITY_COMPOSITOR.
  */
 void SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority);
 
 /**
+ * Set a thread priority to appropriate platform-specific value for
+ * given functionality. Instead of providing arbitrary priority numbers you
+ * must specify a type of function like THREAD_PRIORITY_COMPOSITOR.
+ */
+void SetThreadPriority(PlatformThreadId aThreadId,
+                       hal::ThreadPriority aThreadPriority);
+
+/**
  * Register an observer for the FM radio.
  */
 void RegisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
 
 /**
  * Unregister the observer for the FM radio.
  */
 void UnregisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
--- a/hal/fallback/FallbackThreadPriority.cpp
+++ b/hal/fallback/FallbackThreadPriority.cpp
@@ -12,10 +12,18 @@ namespace hal_impl {
 
 void
 SetCurrentThreadPriority(ThreadPriority aPriority)
 {
   HAL_LOG("FallbackThreadPriority - SetCurrentThreadPriority(%d)\n",
           ThreadPriorityToString(aPriority));
 }
 
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                  ThreadPriority aPriority)
+{
+  HAL_LOG("FallbackThreadPriority - SetThreadPriority(%d, %d)\n",
+          aThreadId, ThreadPriorityToString(aPriority));
+}
+
 } // hal_impl
 } // namespace mozilla
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -1909,17 +1909,17 @@ EnsureThreadPriorityPrefs(ThreadPriority
     Preferences::AddIntVarCache(&prefs->priorities[i].realTime,
                                 realTimeStr.get());
   }
 
   prefs->initialized = true;
 }
 
 static void
-SetThreadPriority(pid_t aTid, hal::ThreadPriority aThreadPriority)
+DoSetThreadPriority(pid_t aTid, hal::ThreadPriority aThreadPriority)
 {
   // See bug 999115, we can only read preferences on the main thread otherwise
   // we create a race condition in HAL
   MOZ_ASSERT(NS_IsMainThread(), "Can only set thread priorities on main thread");
   MOZ_ASSERT(aThreadPriority >= 0);
 
   static ThreadPriorityPrefs prefs = { 0 };
   EnsureThreadPriorityPrefs(&prefs);
@@ -1960,35 +1960,42 @@ public:
   SetThreadPriorityRunnable(pid_t aThreadId, hal::ThreadPriority aThreadPriority)
     : mThreadId(aThreadId)
     , mThreadPriority(aThreadPriority)
   { }
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(NS_IsMainThread(), "Can only set thread priorities on main thread");
-    hal_impl::SetThreadPriority(mThreadId, mThreadPriority);
+    hal_impl::DoSetThreadPriority(mThreadId, mThreadPriority);
     return NS_OK;
   }
 
 private:
   pid_t mThreadId;
   hal::ThreadPriority mThreadPriority;
 };
 
 } // anonymous namespace
 
 void
 SetCurrentThreadPriority(ThreadPriority aThreadPriority)
 {
+  pid_t threadId = gettid();
+  hal_impl::SetThreadPriority(threadId, aThreadPriority);
+}
+
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                         ThreadPriority aThreadPriority)
+{
   switch (aThreadPriority) {
     case THREAD_PRIORITY_COMPOSITOR: {
-      pid_t threadId = gettid();
       nsCOMPtr<nsIRunnable> runnable =
-        new SetThreadPriorityRunnable(threadId, aThreadPriority);
+        new SetThreadPriorityRunnable(aThreadId, aThreadPriority);
       NS_DispatchToMainThread(runnable);
       break;
     }
     default:
       HAL_LOG("Unrecognized thread priority %d; Doing nothing",
               aThreadPriority);
       return;
   }
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -351,16 +351,23 @@ void
 SetProcessPriority(int aPid, ProcessPriority aPriority, uint32_t aLRU)
 {
   NS_RUNTIMEABORT("Only the main process may set processes' priorities.");
 }
 
 void
 SetCurrentThreadPriority(ThreadPriority aThreadPriority)
 {
+  NS_RUNTIMEABORT("Setting current thread priority cannot be called from sandboxed contexts.");
+}
+
+void
+SetThreadPriority(PlatformThreadId aThreadId,
+                  ThreadPriority aThreadPriority)
+{
   NS_RUNTIMEABORT("Setting thread priority cannot be called from sandboxed contexts.");
 }
 
 void
 EnableFMRadio(const hal::FMRadioSettings& aSettings)
 {
   NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
 }
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -217,16 +217,18 @@ class JS_FRIEND_API(GCCellPtr)
     }
     // Inline mark bitmap access requires direct pointer arithmetic.
     uintptr_t unsafeAsUIntPtr() const {
         MOZ_ASSERT(asCell());
         MOZ_ASSERT(!js::gc::IsInsideNursery(asCell()));
         return reinterpret_cast<uintptr_t>(asCell());
     }
 
+    bool mayBeOwnedByOtherRuntime() const;
+
   private:
     uintptr_t checkedCast(void* p, JSGCTraceKind traceKind) {
         js::gc::Cell* cell = static_cast<js::gc::Cell*>(p);
         MOZ_ASSERT((uintptr_t(p) & JSTRACE_OUTOFLINE) == 0);
         AssertGCThingHasType(cell, traceKind);
         // Note: the JSTRACE_OUTOFLINE bits are set on all out-of-line kinds
         // so that we can mask instead of branching.
         MOZ_ASSERT_IF(traceKind >= JSTRACE_OUTOFLINE,
@@ -360,16 +362,18 @@ ScriptIsMarkedGray(JSScript* script)
     return js::gc::detail::CellIsMarkedGray(reinterpret_cast<js::gc::Cell*>(script));
 }
 
 static MOZ_ALWAYS_INLINE bool
 GCThingIsMarkedGray(GCCellPtr thing)
 {
     if (js::gc::IsInsideNursery(thing.asCell()))
         return false;
+    if (thing.mayBeOwnedByOtherRuntime())
+        return false;
     return js::gc::detail::CellIsMarkedGray(thing.asCell());
 }
 
 } /* namespace JS */
 
 namespace js {
 namespace gc {
 
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -744,16 +744,17 @@ typedef HeapPtr<jsid> HeapId;
 
 typedef ImmutableTenuredPtr<PropertyName*> ImmutablePropertyNamePtr;
 typedef ImmutableTenuredPtr<JS::Symbol*> ImmutableSymbolPtr;
 
 typedef ReadBarriered<DebugScopeObject*> ReadBarrieredDebugScopeObject;
 typedef ReadBarriered<GlobalObject*> ReadBarrieredGlobalObject;
 typedef ReadBarriered<JSFunction*> ReadBarrieredFunction;
 typedef ReadBarriered<JSObject*> ReadBarrieredObject;
+typedef ReadBarriered<JSScript*> ReadBarrieredScript;
 typedef ReadBarriered<ScriptSourceObject*> ReadBarrieredScriptSourceObject;
 typedef ReadBarriered<Shape*> ReadBarrieredShape;
 typedef ReadBarriered<UnownedBaseShape*> ReadBarrieredUnownedBaseShape;
 typedef ReadBarriered<jit::JitCode*> ReadBarrieredJitCode;
 typedef ReadBarriered<ObjectGroup*> ReadBarrieredObjectGroup;
 typedef ReadBarriered<JSAtom*> ReadBarrieredAtom;
 typedef ReadBarriered<JS::Symbol*> ReadBarrieredSymbol;
 
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -808,19 +808,16 @@ LazyScript::traceChildren(JSTracer* trc)
         TraceEdge(trc, &function_, "function");
 
     if (sourceObject_)
         TraceEdge(trc, &sourceObject_, "sourceObject");
 
     if (enclosingScope_)
         TraceEdge(trc, &enclosingScope_, "enclosingScope");
 
-    if (script_)
-        TraceEdge(trc, &script_, "realScript");
-
     // We rely on the fact that atoms are always tenured.
     FreeVariable* freeVariables = this->freeVariables();
     for (auto i : MakeRange(numFreeVariables())) {
         JSAtom* atom = freeVariables[i].atom();
         TraceManuallyBarrieredEdge(trc, &atom, "lazyScriptFreeVariable");
     }
 
     HeapPtrFunction* innerFunctions = this->innerFunctions();
@@ -834,19 +831,16 @@ js::GCMarker::eagerlyMarkChildren(LazySc
         traverse(thing, static_cast<JSObject*>(thing->function_));
 
     if (thing->sourceObject_)
         traverse(thing, static_cast<JSObject*>(thing->sourceObject_));
 
     if (thing->enclosingScope_)
         traverse(thing, static_cast<JSObject*>(thing->enclosingScope_));
 
-    if (thing->script_)
-        traverse(thing, static_cast<JSScript*>(thing->script_));
-
     // We rely on the fact that atoms are always tenured.
     LazyScript::FreeVariable* freeVariables = thing->freeVariables();
     for (auto i : MakeRange(thing->numFreeVariables()))
         traverse(thing, static_cast<JSString*>(freeVariables[i].atom()));
 
     HeapPtrFunction* innerFunctions = thing->innerFunctions();
     for (auto i : MakeRange(thing->numInnerFunctions()))
         traverse(thing, static_cast<JSObject*>(innerFunctions[i]));
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -320,16 +320,17 @@ struct DagChildEdge {
  * empty. Timings for these phases are thus exclusive of any other phase.
  */
 
 static const PhaseInfo phases[] = {
     { PHASE_MUTATOR, "Mutator Running", PHASE_NO_PARENT },
     { PHASE_GC_BEGIN, "Begin Callback", PHASE_NO_PARENT },
     { PHASE_WAIT_BACKGROUND_THREAD, "Wait Background Thread", PHASE_NO_PARENT },
     { PHASE_MARK_DISCARD_CODE, "Mark Discard Code", PHASE_NO_PARENT },
+    { PHASE_RELAZIFY_FUNCTIONS, "Relazify Functions", PHASE_NO_PARENT },
     { PHASE_PURGE, "Purge", PHASE_NO_PARENT },
     { PHASE_MARK, "Mark", PHASE_NO_PARENT },
         { PHASE_UNMARK, "Unmark", PHASE_MARK },
         /* PHASE_MARK_ROOTS */
         { PHASE_MARK_DELAYED, "Mark Delayed", PHASE_MARK },
     { PHASE_SWEEP, "Sweep", PHASE_NO_PARENT },
         { PHASE_SWEEP_MARK, "Mark During Sweeping", PHASE_SWEEP },
             { PHASE_SWEEP_MARK_TYPES, "Mark Types During Sweeping", PHASE_SWEEP_MARK },
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -24,16 +24,17 @@ class GCParallelTask;
 
 namespace gcstats {
 
 enum Phase {
     PHASE_MUTATOR,
     PHASE_GC_BEGIN,
     PHASE_WAIT_BACKGROUND_THREAD,
     PHASE_MARK_DISCARD_CODE,
+    PHASE_RELAZIFY_FUNCTIONS,
     PHASE_PURGE,
     PHASE_MARK,
     PHASE_UNMARK,
     PHASE_MARK_DELAYED,
     PHASE_SWEEP,
     PHASE_SWEEP_MARK,
     PHASE_SWEEP_MARK_TYPES,
     PHASE_SWEEP_MARK_INCOMING_BLACK,
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/bug1161298.js
@@ -0,0 +1,13 @@
+// The length exceeds INT32_MAX and should be rejected.
+
+if (!this.SharedArrayBuffer)
+    quit(0);
+
+var failed = false;
+try {
+    var sab = new SharedArrayBuffer((2147483648));
+}
+catch (e) {
+    failed = true;
+}
+assertEq(failed, true);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1161762.js
@@ -0,0 +1,24 @@
+
+for (var actual = .5; actual < 100; actual++) {
+  var test2 = {
+    test4: actual + 6,
+    test2: actual + 9,
+    printStatus: actual + 10,
+    isPrototypeOf: actual + 12,
+    expect: actual + 14,
+    printErr: actual + 17,
+    ret2: actual + 19,
+    printBugNumber: actual + 32,
+    test3: actual + 33,
+    String: actual + 34,
+    summary: actual + 40,
+    test1: actual + 42,
+    Array: actual + 43,
+    BUGNUMBER: actual + 44,
+    assertEq: actual + 45,
+    __call__: actual + 47,
+    x: actual + 48,
+    test0: actual + 49,
+    res: actual + 50
+  };
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1161303.js
@@ -0,0 +1,7 @@
+function f(x) {
+    for (var i = 0; i < 100000; i++ ) {
+        [(x, 2)];
+        try { g(); } catch (t) {}
+    }
+}
+f(2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1161968.js
@@ -0,0 +1,15 @@
+// This test case is a simplified version of debug/Source-invisible.js.
+
+if (!'gczeal' in this)
+    quit();
+
+gczeal(2,21);
+
+var gi = newGlobal();
+gi.eval('function f() {}');
+
+var gv = newGlobal();
+gv.f = gi.f;
+gv.eval('f = clone(f);');
+
+var dbg = new Debugger;
--- a/js/src/jit-test/tests/xdr/lazy.js
+++ b/js/src/jit-test/tests/xdr/lazy.js
@@ -153,8 +153,12 @@ evalWithCache(test, { assertEqBytecode: 
 var g1 = newGlobal();
 var g2 = newGlobal();
 var res = "function f(){}";
 var code = cacheEntry(res + "; f();");
 evaluate(code, {global:g1, compileAndGo: true, saveBytecode: {value: true}});
 evaluate(code, {global:g2, loadBytecode: true});
 gc();
 assertEq(g2.f.toString(), res);
+
+// Another relazification case.
+var src = "function f() { return 3; }; f(); relazifyFunctions(); 4";
+evalWithCache(src, {assertEqBytecode: true, assertEqResult: true});
--- a/js/src/jit/BaselineDebugModeOSR.cpp
+++ b/js/src/jit/BaselineDebugModeOSR.cpp
@@ -761,17 +761,17 @@ CloneOldBaselineStub(JSContext* cx, Debu
 
     // Clone the existing stub into the recompiled IC.
     //
     // Note that since JitCode is a GC thing, cloning an ICStub with the same
     // JitCode ensures it won't be collected.
     switch (oldStub->kind()) {
 #define CASE_KIND(kindName)                                                  \
       case ICStub::kindName:                                                 \
-        entry.newStub = IC##kindName::Clone(stubSpace, firstMonitorStub,     \
+        entry.newStub = IC##kindName::Clone(cx, stubSpace, firstMonitorStub, \
                                             *oldStub->to##kindName());       \
         break;
         PATCHABLE_ICSTUB_KIND_LIST(CASE_KIND)
 #if JS_HAS_NO_SUCH_METHOD
         PATCHABLE_NSM_ICSTUB_KIND_LIST(CASE_KIND)
 #endif
 #undef CASE_KIND
 
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1770,17 +1770,17 @@ DoNewObject(JSContext* cx, BaselineFrame
                 !templateObject->as<PlainObject>().hasDynamicSlots())
             {
                 JitCode* code = GenerateNewObjectWithTemplateCode(cx, templateObject);
                 if (!code)
                     return false;
 
                 ICStubSpace* space =
                     ICStubCompiler::StubSpaceForKind(ICStub::NewObject_WithTemplate, script);
-                ICStub* templateStub = ICStub::New<ICNewObject_WithTemplate>(space, code);
+                ICStub* templateStub = ICStub::New<ICNewObject_WithTemplate>(cx, space, code);
                 if (!templateStub)
                     return false;
 
                 stub->addNewStub(templateStub);
             }
 
             stub->setTemplateObject(templateObject);
         }
@@ -7890,24 +7890,24 @@ ICGetProp_Primitive::Compiler::generateS
 ICGetPropNativeStub*
 ICGetPropNativeCompiler::getStub(ICStubSpace* space)
 {
     ReceiverGuard guard(obj_);
 
     switch (kind) {
       case ICStub::GetProp_Native: {
         MOZ_ASSERT(obj_ == holder_);
-        return ICStub::New<ICGetProp_Native>(space, getStubCode(), firstMonitorStub_, guard, offset_);
+        return newStub<ICGetProp_Native>(space, getStubCode(), firstMonitorStub_, guard, offset_);
       }
 
       case ICStub::GetProp_NativePrototype: {
         MOZ_ASSERT(obj_ != holder_);
         Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-        return ICStub::New<ICGetProp_NativePrototype>(space, getStubCode(), firstMonitorStub_, guard,
-                                                      offset_, holder_, holderShape);
+        return newStub<ICGetProp_NativePrototype>(space, getStubCode(), firstMonitorStub_, guard,
+                                                  offset_, holder_, holderShape);
       }
 
       default:
         MOZ_CRASH("Bad stub kind");
     }
 }
 
 static void
@@ -8410,32 +8410,32 @@ ICGetPropCallDOMProxyNativeCompiler::get
         expandoVal = expandoAndGeneration->expando;
         generation = expandoAndGeneration->generation;
     }
 
     if (expandoVal.isObject())
         expandoShape = expandoVal.toObject().as<NativeObject>().lastProperty();
 
     if (kind == ICStub::GetProp_CallDOMProxyNative) {
-        return ICStub::New<ICGetProp_CallDOMProxyNative>(
+        return newStub<ICGetProp_CallDOMProxyNative>(
             space, getStubCode(), firstMonitorStub_, shape,
             expandoShape, holder_, holderShape, getter_, pcOffset_);
     }
 
-    return ICStub::New<ICGetProp_CallDOMProxyWithGenerationNative>(
+    return newStub<ICGetProp_CallDOMProxyWithGenerationNative>(
         space, getStubCode(), firstMonitorStub_, shape,
         expandoAndGeneration, generation, expandoShape, holder_, holderShape, getter_,
         pcOffset_);
 }
 
 ICStub*
 ICGetProp_DOMProxyShadowed::Compiler::getStub(ICStubSpace* space)
 {
     RootedShape shape(cx, proxy_->maybeShape());
-    return New<ICGetProp_DOMProxyShadowed>(space, getStubCode(), firstMonitorStub_, shape,
+    return New<ICGetProp_DOMProxyShadowed>(cx, space, getStubCode(), firstMonitorStub_, shape,
                                            proxy_->handler(), name_, pcOffset_);
 }
 
 static bool
 ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp)
 {
     RootedId id(cx, NameToId(name));
     return Proxy::get(cx, proxy, proxy, id, vp);
@@ -8576,20 +8576,20 @@ ICGetProp_ArgumentsCallee::Compiler::gen
     EmitEnterTypeMonitorIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
 /* static */ ICGetProp_Generic*
-ICGetProp_Generic::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_Generic::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                          ICGetProp_Generic& other)
 {
-    return New<ICGetProp_Generic>(space, other.jitCode(), firstMonitorStub);
+    return New<ICGetProp_Generic>(cx, space, other.jitCode(), firstMonitorStub);
 }
 
 static bool
 DoGetPropGeneric(JSContext* cx, BaselineFrame* frame, ICGetProp_Generic* stub, MutableHandleValue val, MutableHandleValue res)
 {
     jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(frame->script());
     JSOp op = JSOp(*pc);
     RootedPropertyName name(cx, frame->script()->getName(pc));
@@ -11883,17 +11883,17 @@ ICTableSwitch::Compiler::getStub(ICStubS
         int32_t off = GET_JUMP_OFFSET(pc);
         if (off)
             table[i] = pc_ + off;
         else
             table[i] = defaultpc;
         pc += JUMP_OFFSET_LEN;
     }
 
-    return ICStub::New<ICTableSwitch>(space, code, table, low, length, defaultpc);
+    return newStub<ICTableSwitch>(space, code, table, low, length, defaultpc);
 }
 
 void
 ICTableSwitch::fixupJumpTable(JSScript* script, BaselineScript* baseline)
 {
     defaultTarget_ = baseline->nativeCodeForPC(script, (jsbytecode*) defaultTarget_);
 
     for (int32_t i = 0; i < length_; i++)
@@ -12494,75 +12494,77 @@ ICGetElemNativePrototypeCallStub::ICGetE
                                 uint32_t pcOffset, JSObject* holder, Shape* holderShape)
   : ICGetElemNativeGetterStub(kind, stubCode, firstMonitorStub, shape, name, acctype, needsAtomize,
                               getter, pcOffset),
     holder_(holder),
     holderShape_(holderShape)
 {}
 
 /* static */ ICGetElem_NativePrototypeCallNative*
-ICGetElem_NativePrototypeCallNative::Clone(ICStubSpace* space,
+ICGetElem_NativePrototypeCallNative::Clone(JSContext* cx,
+                                           ICStubSpace* space,
                                            ICStub* firstMonitorStub,
                                            ICGetElem_NativePrototypeCallNative& other)
 {
-    return New<ICGetElem_NativePrototypeCallNative>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetElem_NativePrototypeCallNative>(cx, space, other.jitCode(), firstMonitorStub,
                                                     other.shape(), other.name(), other.accessType(),
                                                     other.needsAtomize(), other.getter(), other.pcOffset_,
                                                     other.holder(), other.holderShape());
 }
 
 /* static */ ICGetElem_NativePrototypeCallScripted*
-ICGetElem_NativePrototypeCallScripted::Clone(ICStubSpace* space,
+ICGetElem_NativePrototypeCallScripted::Clone(JSContext* cx,
+                                             ICStubSpace* space,
                                              ICStub* firstMonitorStub,
                                              ICGetElem_NativePrototypeCallScripted& other)
 {
-    return New<ICGetElem_NativePrototypeCallScripted>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetElem_NativePrototypeCallScripted>(cx, space, other.jitCode(), firstMonitorStub,
                                                       other.shape(), other.name(),
                                                       other.accessType(), other.needsAtomize(), other.getter(),
                                                       other.pcOffset_, other.holder(), other.holderShape());
 }
 
 ICGetElem_Dense::ICGetElem_Dense(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape)
     : ICMonitoredStub(GetElem_Dense, stubCode, firstMonitorStub),
       shape_(shape)
 { }
 
 /* static */ ICGetElem_Dense*
-ICGetElem_Dense::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetElem_Dense::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                        ICGetElem_Dense& other)
 {
-    return New<ICGetElem_Dense>(space, other.jitCode(), firstMonitorStub, other.shape_);
+    return New<ICGetElem_Dense>(cx, space, other.jitCode(), firstMonitorStub, other.shape_);
 }
 
 ICGetElem_UnboxedArray::ICGetElem_UnboxedArray(JitCode* stubCode, ICStub* firstMonitorStub,
                                                ObjectGroup *group)
   : ICMonitoredStub(GetElem_UnboxedArray, stubCode, firstMonitorStub),
     group_(group)
 { }
 
 /* static */ ICGetElem_UnboxedArray*
-ICGetElem_UnboxedArray::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetElem_UnboxedArray::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                               ICGetElem_UnboxedArray& other)
 {
-    return New<ICGetElem_UnboxedArray>(space, other.jitCode(), firstMonitorStub, other.group_);
+    return New<ICGetElem_UnboxedArray>(cx, space, other.jitCode(), firstMonitorStub, other.group_);
 }
 
 ICGetElem_TypedArray::ICGetElem_TypedArray(JitCode* stubCode, Shape* shape, Scalar::Type type)
   : ICStub(GetElem_TypedArray, stubCode),
     shape_(shape)
 {
     extra_ = uint16_t(type);
     MOZ_ASSERT(extra_ == type);
 }
 
 /* static */ ICGetElem_Arguments*
-ICGetElem_Arguments::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetElem_Arguments::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                            ICGetElem_Arguments& other)
 {
-    return New<ICGetElem_Arguments>(space, other.jitCode(), firstMonitorStub, other.which());
+    return New<ICGetElem_Arguments>(cx, space, other.jitCode(), firstMonitorStub, other.which());
 }
 
 ICSetElem_DenseOrUnboxedArray::ICSetElem_DenseOrUnboxedArray(JitCode* stubCode, Shape* shape, ObjectGroup* group)
   : ICUpdatedStub(SetElem_DenseOrUnboxedArray, stubCode),
     shape_(shape),
     group_(group)
 { }
 
@@ -12578,17 +12580,17 @@ ICSetElem_DenseOrUnboxedArrayAdd::ICSetE
 template <size_t ProtoChainDepth>
 ICUpdatedStub*
 ICSetElemDenseOrUnboxedArrayAddCompiler::getStubSpecific(ICStubSpace* space, const AutoShapeVector* shapes)
 {
     RootedObjectGroup group(cx, obj_->getGroup(cx));
     if (!group)
         return nullptr;
     Rooted<JitCode*> stubCode(cx, getStubCode());
-    return ICStub::New<ICSetElem_DenseOrUnboxedArrayAddImpl<ProtoChainDepth>>(space, stubCode, group, shapes);
+    return newStub<ICSetElem_DenseOrUnboxedArrayAddImpl<ProtoChainDepth>>(space, stubCode, group, shapes);
 }
 
 ICSetElem_TypedArray::ICSetElem_TypedArray(JitCode* stubCode, Shape* shape, Scalar::Type type,
                                            bool expectOutOfBounds)
   : ICStub(SetElem_TypedArray, stubCode),
     shape_(shape)
 {
     extra_ = uint8_t(type);
@@ -12692,36 +12694,36 @@ ICGetPropNativeStub::ICGetPropNativeStub
                                          ICStub* firstMonitorStub,
                                          ReceiverGuard guard, uint32_t offset)
   : ICMonitoredStub(kind, stubCode, firstMonitorStub),
     receiverGuard_(guard),
     offset_(offset)
 { }
 
 /* static */ ICGetProp_Native*
-ICGetProp_Native::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_Native::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                         ICGetProp_Native& other)
 {
-    return New<ICGetProp_Native>(space, other.jitCode(), firstMonitorStub, other.receiverGuard(),
-                                 other.offset());
+    return New<ICGetProp_Native>(cx, space, other.jitCode(), firstMonitorStub,
+                                 other.receiverGuard(), other.offset());
 }
 
 ICGetProp_NativePrototype::ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub,
                                                      ReceiverGuard guard, uint32_t offset,
                                                      JSObject* holder, Shape* holderShape)
   : ICGetPropNativeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, guard, offset),
     holder_(holder),
     holderShape_(holderShape)
 { }
 
 /* static */ ICGetProp_NativePrototype*
-ICGetProp_NativePrototype::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_NativePrototype::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                  ICGetProp_NativePrototype& other)
 {
-    return New<ICGetProp_NativePrototype>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetProp_NativePrototype>(cx, space, other.jitCode(), firstMonitorStub,
                                           other.receiverGuard(), other.offset(),
                                           other.holder_, other.holderShape_);
 }
 
 ICGetProp_NativeDoesNotExist::ICGetProp_NativeDoesNotExist(
     JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
     size_t protoChainDepth)
   : ICMonitoredStub(GetProp_NativeDoesNotExist, stubCode, firstMonitorStub),
@@ -12784,30 +12786,30 @@ ICInstanceOf_Function::ICInstanceOf_Func
                                              JSObject* prototypeObj, uint32_t slot)
   : ICStub(InstanceOf_Function, stubCode),
     shape_(shape),
     prototypeObj_(prototypeObj),
     slot_(slot)
 { }
 
 /* static */ ICGetProp_CallScripted*
-ICGetProp_CallScripted::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_CallScripted::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                               ICGetProp_CallScripted& other)
 {
-    return New<ICGetProp_CallScripted>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetProp_CallScripted>(cx, space, other.jitCode(), firstMonitorStub,
                                        other.receiverGuard(),
                                        other.holder_, other.holderShape_,
                                        other.getter_, other.pcOffset_);
 }
 
 /* static */ ICGetProp_CallNative*
-ICGetProp_CallNative::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_CallNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                             ICGetProp_CallNative& other)
 {
-    return New<ICGetProp_CallNative>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetProp_CallNative>(cx, space, other.jitCode(), firstMonitorStub,
                                      other.receiverGuard(), other.holder_,
                                      other.holderShape_, other.getter_, other.pcOffset_);
 }
 
 ICSetProp_Native::ICSetProp_Native(JitCode* stubCode, ObjectGroup* group, Shape* shape,
                                    uint32_t offset)
   : ICUpdatedStub(SetProp_Native, stubCode),
     group_(group),
@@ -12818,17 +12820,17 @@ ICSetProp_Native::ICSetProp_Native(JitCo
 ICSetProp_Native*
 ICSetProp_Native::Compiler::getStub(ICStubSpace* space)
 {
     RootedObjectGroup group(cx, obj_->getGroup(cx));
     if (!group)
         return nullptr;
 
     RootedShape shape(cx, LastPropertyForSetProp(obj_));
-    ICSetProp_Native* stub = ICStub::New<ICSetProp_Native>(space, getStubCode(), group, shape, offset_);
+    ICSetProp_Native* stub = newStub<ICSetProp_Native>(space, getStubCode(), group, shape, offset_);
     if (!stub || !stub->initUpdatingChain(cx, space))
         return nullptr;
     return stub;
 }
 
 ICSetProp_NativeAdd::ICSetProp_NativeAdd(JitCode* stubCode, ObjectGroup* group,
                                          size_t protoChainDepth,
                                          Shape* newShape,
@@ -12884,49 +12886,52 @@ ICSetPropCallSetter::ICSetPropCallSetter
     holderShape_(holderShape),
     setter_(setter),
     pcOffset_(pcOffset)
 {
     MOZ_ASSERT(kind == ICStub::SetProp_CallScripted || kind == ICStub::SetProp_CallNative);
 }
 
 /* static */ ICSetProp_CallScripted*
-ICSetProp_CallScripted::Clone(ICStubSpace* space, ICStub*, ICSetProp_CallScripted& other)
-{
-    return New<ICSetProp_CallScripted>(space, other.jitCode(), other.guard(), other.holder_,
+ICSetProp_CallScripted::Clone(JSContext* cx, ICStubSpace* space, ICStub*,
+                              ICSetProp_CallScripted& other)
+{
+    return New<ICSetProp_CallScripted>(cx, space, other.jitCode(), other.guard(), other.holder_,
                                        other.holderShape_, other.setter_, other.pcOffset_);
 }
 
 /* static */ ICSetProp_CallNative*
-ICSetProp_CallNative::Clone(ICStubSpace* space, ICStub*, ICSetProp_CallNative& other)
-{
-    return New<ICSetProp_CallNative>(space, other.jitCode(), other.guard(), other.holder_,
+ICSetProp_CallNative::Clone(JSContext* cx, ICStubSpace* space, ICStub*, ICSetProp_CallNative& other)
+{
+    return New<ICSetProp_CallNative>(cx, space, other.jitCode(), other.guard(), other.holder_,
                                      other.holderShape_, other.setter_, other.pcOffset_);
 }
 
 ICCall_Scripted::ICCall_Scripted(JitCode* stubCode, ICStub* firstMonitorStub,
                                  JSFunction* callee, JSObject* templateObject,
                                  uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_Scripted, stubCode, firstMonitorStub),
     callee_(callee),
     templateObject_(templateObject),
     pcOffset_(pcOffset)
 { }
 
 /* static */ ICCall_Scripted*
-ICCall_Scripted::Clone(ICStubSpace* space, ICStub* firstMonitorStub, ICCall_Scripted& other)
-{
-    return New<ICCall_Scripted>(space, other.jitCode(), firstMonitorStub, other.callee_,
+ICCall_Scripted::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                       ICCall_Scripted& other)
+{
+    return New<ICCall_Scripted>(cx, space, other.jitCode(), firstMonitorStub, other.callee_,
                                 other.templateObject_, other.pcOffset_);
 }
 
 /* static */ ICCall_AnyScripted*
-ICCall_AnyScripted::Clone(ICStubSpace* space, ICStub* firstMonitorStub, ICCall_AnyScripted& other)
-{
-    return New<ICCall_AnyScripted>(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
+ICCall_AnyScripted::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                          ICCall_AnyScripted& other)
+{
+    return New<ICCall_AnyScripted>(cx, space, other.jitCode(), firstMonitorStub, other.pcOffset_);
 }
 
 ICCall_Native::ICCall_Native(JitCode* stubCode, ICStub* firstMonitorStub,
                              JSFunction* callee, JSObject* templateObject,
                              uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_Native, stubCode, firstMonitorStub),
     callee_(callee),
     templateObject_(templateObject),
@@ -12937,19 +12942,20 @@ ICCall_Native::ICCall_Native(JitCode* st
     // instruction to handle them. To make this work, we store the redirected
     // pointer in the stub.
     native_ = Simulator::RedirectNativeFunction(JS_FUNC_TO_DATA_PTR(void*, callee->native()),
                                                 Args_General3);
 #endif
 }
 
 /* static */ ICCall_Native*
-ICCall_Native::Clone(ICStubSpace* space, ICStub* firstMonitorStub, ICCall_Native& other)
-{
-    return New<ICCall_Native>(space, other.jitCode(), firstMonitorStub, other.callee_,
+ICCall_Native::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                     ICCall_Native& other)
+{
+    return New<ICCall_Native>(cx, space, other.jitCode(), firstMonitorStub, other.callee_,
                               other.templateObject_, other.pcOffset_);
 }
 
 ICCall_ClassHook::ICCall_ClassHook(JitCode* stubCode, ICStub* firstMonitorStub,
                                    const Class* clasp, Native native,
                                    JSObject* templateObject, uint32_t pcOffset)
   : ICMonitoredStub(ICStub::Call_ClassHook, stubCode, firstMonitorStub),
     clasp_(clasp),
@@ -12961,48 +12967,51 @@ ICCall_ClassHook::ICCall_ClassHook(JitCo
     // The simulator requires VM calls to be redirected to a special swi
     // instruction to handle them. To make this work, we store the redirected
     // pointer in the stub.
     native_ = Simulator::RedirectNativeFunction(native_, Args_General3);
 #endif
 }
 
 /* static */ ICCall_ClassHook*
-ICCall_ClassHook::Clone(ICStubSpace* space, ICStub* firstMonitorStub, ICCall_ClassHook& other)
-{
-    ICCall_ClassHook* res = New<ICCall_ClassHook>(space, other.jitCode(), firstMonitorStub,
+ICCall_ClassHook::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                        ICCall_ClassHook& other)
+{
+    ICCall_ClassHook* res = New<ICCall_ClassHook>(cx, space, other.jitCode(), firstMonitorStub,
                                                   other.clasp(), nullptr, other.templateObject_,
                                                   other.pcOffset_);
     if (res)
         res->native_ = other.native();
     return res;
 }
 
 /* static */ ICCall_ScriptedApplyArray*
-ICCall_ScriptedApplyArray::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICCall_ScriptedApplyArray::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                  ICCall_ScriptedApplyArray& other)
 {
-    return New<ICCall_ScriptedApplyArray>(space, other.jitCode(), firstMonitorStub,
+    return New<ICCall_ScriptedApplyArray>(cx, space, other.jitCode(), firstMonitorStub,
                                           other.pcOffset_);
 }
 
 /* static */ ICCall_ScriptedApplyArguments*
-ICCall_ScriptedApplyArguments::Clone(ICStubSpace* space,
+ICCall_ScriptedApplyArguments::Clone(JSContext* cx,
+                                     ICStubSpace* space,
                                      ICStub* firstMonitorStub,
                                      ICCall_ScriptedApplyArguments& other)
 {
-    return New<ICCall_ScriptedApplyArguments>(space, other.jitCode(), firstMonitorStub,
+    return New<ICCall_ScriptedApplyArguments>(cx, space, other.jitCode(), firstMonitorStub,
                                               other.pcOffset_);
 }
 
 /* static */ ICCall_ScriptedFunCall*
-ICCall_ScriptedFunCall::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICCall_ScriptedFunCall::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                               ICCall_ScriptedFunCall& other)
 {
-    return New<ICCall_ScriptedFunCall>(space, other.jitCode(), firstMonitorStub, other.pcOffset_);
+    return New<ICCall_ScriptedFunCall>(cx, space, other.jitCode(), firstMonitorStub,
+                                       other.pcOffset_);
 }
 
 ICGetPropCallDOMProxyNativeStub::ICGetPropCallDOMProxyNativeStub(Kind kind, JitCode* stubCode,
                                                                  ICStub* firstMonitorStub,
                                                                  Shape* shape,
                                                                  Shape* expandoShape,
                                                                  JSObject* holder,
                                                                  Shape* holderShape,
@@ -13028,31 +13037,33 @@ ICGetPropCallDOMProxyNativeCompiler::ICG
     pcOffset_(pcOffset)
 {
     MOZ_ASSERT(kind == ICStub::GetProp_CallDOMProxyNative ||
                kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
     MOZ_ASSERT(proxy_->handler()->family() == GetDOMProxyHandlerFamily());
 }
 
 /* static */ ICGetProp_CallDOMProxyNative*
-ICGetProp_CallDOMProxyNative::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_CallDOMProxyNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                     ICGetProp_CallDOMProxyNative& other)
 {
-    return New<ICGetProp_CallDOMProxyNative>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetProp_CallDOMProxyNative>(cx, space, other.jitCode(), firstMonitorStub,
                                              other.receiverGuard_.shape(), other.expandoShape_,
                                              other.holder_, other.holderShape_, other.getter_,
                                              other.pcOffset_);
 }
 
 /* static */ ICGetProp_CallDOMProxyWithGenerationNative*
-ICGetProp_CallDOMProxyWithGenerationNative::Clone(ICStubSpace* space,
+ICGetProp_CallDOMProxyWithGenerationNative::Clone(JSContext* cx,
+                                                  ICStubSpace* space,
                                                   ICStub* firstMonitorStub,
                                                   ICGetProp_CallDOMProxyWithGenerationNative& other)
 {
-    return New<ICGetProp_CallDOMProxyWithGenerationNative>(space, other.jitCode(), firstMonitorStub,
+    return New<ICGetProp_CallDOMProxyWithGenerationNative>(cx, space, other.jitCode(),
+                                                           firstMonitorStub,
                                                            other.receiverGuard_.shape(),
                                                            other.expandoAndGeneration_,
                                                            other.generation_,
                                                            other.expandoShape_, other.holder_,
                                                            other.holderShape_, other.getter_,
                                                            other.pcOffset_);
 }
 
@@ -13065,21 +13076,22 @@ ICGetProp_DOMProxyShadowed::ICGetProp_DO
   : ICMonitoredStub(ICStub::GetProp_DOMProxyShadowed, stubCode, firstMonitorStub),
     shape_(shape),
     proxyHandler_(proxyHandler),
     name_(name),
     pcOffset_(pcOffset)
 { }
 
 /* static */ ICGetProp_DOMProxyShadowed*
-ICGetProp_DOMProxyShadowed::Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+ICGetProp_DOMProxyShadowed::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                   ICGetProp_DOMProxyShadowed& other)
 {
-    return New<ICGetProp_DOMProxyShadowed>(space, other.jitCode(), firstMonitorStub, other.shape_,
-                                           other.proxyHandler_, other.name_, other.pcOffset_);
+    return New<ICGetProp_DOMProxyShadowed>(cx, space, other.jitCode(), firstMonitorStub,
+                                           other.shape_, other.proxyHandler_, other.name_,
+                                           other.pcOffset_);
 }
 
 //
 // Rest_Fallback
 //
 
 static bool DoRestFallback(JSContext* cx, ICRest_Fallback* stub,
                            BaselineFrame* frame, MutableHandleValue res)
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -632,20 +632,23 @@ class ICStub
         Updated             = 0x4
     };
 
     void markCode(JSTracer* trc, const char* name);
     void updateCode(JitCode* stubCode);
     void trace(JSTracer* trc);
 
     template <typename T, typename... Args>
-    static T* New(ICStubSpace* space, JitCode* code, Args&&... args) {
+    static T* New(JSContext* cx, ICStubSpace* space, JitCode* code, Args&&... args) {
         if (!code)
             return nullptr;
-        return space->allocate<T>(code, mozilla::Forward<Args>(args)...);
+        T* result = space->allocate<T>(code, mozilla::Forward<Args>(args)...);
+        if (!result)
+            ReportOutOfMemory(cx);
+        return result;
     }
 
   protected:
     // The raw jitcode to call for this stub.
     uint8_t* stubCode_;
 
     // Pointer to next IC stub.  This is null for the last IC stub, which should
     // either be a fallback or inert IC stub.
@@ -1079,17 +1082,16 @@ class ICUpdatedStub : public ICStub
 };
 
 // Base class for stubcode compilers.
 class ICStubCompiler
 {
     // Prevent GC in the middle of stub compilation.
     js::gc::AutoSuppressGC suppressGC;
 
-
   protected:
     JSContext* cx;
     ICStub::Kind kind;
 #ifdef DEBUG
     bool entersStubFrame_;
 #endif
 
     // By default the stubcode key is just the kind.
@@ -1163,16 +1165,21 @@ class ICStubCompiler
         }
 
         return regs;
     }
 
     inline bool emitPostWriteBarrierSlot(MacroAssembler& masm, Register obj, ValueOperand val,
                                          Register scratch, LiveGeneralRegisterSet saveRegs);
 
+    template <typename T, typename... Args>
+    T* newStub(Args&&... args) {
+        return ICStub::New<T>(cx, mozilla::Forward<Args>(args)...);
+    }
+
   public:
     virtual ICStub* getStub(ICStubSpace* space) = 0;
 
     static ICStubSpace* StubSpaceForKind(ICStub::Kind kind, JSScript* script) {
         if (ICStub::CanMakeCalls(kind))
             return script->baselineScript()->fallbackStubSpace();
         return script->zone()->jitZone()->optimizedStubSpace();
     }
@@ -1217,17 +1224,17 @@ class ICWarmUpCounter_Fallback : public 
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::WarmUpCounter_Fallback)
         { }
 
         ICWarmUpCounter_Fallback* getStub(ICStubSpace* space) {
-            return ICStub::New<ICWarmUpCounter_Fallback>(space, getStubCode());
+            return newStub<ICWarmUpCounter_Fallback>(space, getStubCode());
         }
     };
 };
 
 
 // TypeCheckPrimitiveSetStub
 //   Base class for IC stubs (TypeUpdate or TypeMonitor) that check that a given
 //   value's type falls within a set of primitive types.
@@ -1464,17 +1471,17 @@ class ICTypeMonitor_Fallback : public IC
 
         Compiler(JSContext* cx, uint32_t argumentIndex)
           : ICStubCompiler(cx, ICStub::TypeMonitor_Fallback),
             mainFallbackStub_(nullptr),
             argumentIndex_(argumentIndex)
         { }
 
         ICTypeMonitor_Fallback* getStub(ICStubSpace* space) {
-            return ICStub::New<ICTypeMonitor_Fallback>(space, getStubCode(), mainFallbackStub_,
+            return newStub<ICTypeMonitor_Fallback>(space, getStubCode(), mainFallbackStub_,
                                                        argumentIndex_);
         }
     };
 };
 
 class ICTypeMonitor_PrimitiveSet : public TypeCheckPrimitiveSetStub
 {
     friend class ICStubSpace;
@@ -1498,17 +1505,17 @@ class ICTypeMonitor_PrimitiveSet : publi
                 this->TypeCheckPrimitiveSetStub::Compiler::updateStub();
             if (!stub)
                 return nullptr;
             return stub->toMonitorStub();
         }
 
         ICTypeMonitor_PrimitiveSet* getStub(ICStubSpace* space) {
             MOZ_ASSERT(!existingStub_);
-            return ICStub::New<ICTypeMonitor_PrimitiveSet>(space, getStubCode(), flags_);
+            return newStub<ICTypeMonitor_PrimitiveSet>(space, getStubCode(), flags_);
         }
     };
 };
 
 class ICTypeMonitor_SingleObject : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1532,17 +1539,17 @@ class ICTypeMonitor_SingleObject : publi
 
       public:
         Compiler(JSContext* cx, HandleObject obj)
           : ICStubCompiler(cx, TypeMonitor_SingleObject),
             obj_(obj)
         { }
 
         ICTypeMonitor_SingleObject* getStub(ICStubSpace* space) {
-            return ICStub::New<ICTypeMonitor_SingleObject>(space, getStubCode(), obj_);
+            return newStub<ICTypeMonitor_SingleObject>(space, getStubCode(), obj_);
         }
     };
 };
 
 class ICTypeMonitor_ObjectGroup : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1566,17 +1573,17 @@ class ICTypeMonitor_ObjectGroup : public
 
       public:
         Compiler(JSContext* cx, HandleObjectGroup group)
           : ICStubCompiler(cx, TypeMonitor_ObjectGroup),
             group_(group)
         { }
 
         ICTypeMonitor_ObjectGroup* getStub(ICStubSpace* space) {
-            return ICStub::New<ICTypeMonitor_ObjectGroup>(space, getStubCode(), group_);
+            return newStub<ICTypeMonitor_ObjectGroup>(space, getStubCode(), group_);
         }
     };
 };
 
 // TypeUpdate
 
 extern const VMFunction DoTypeUpdateFallbackInfo;
 
@@ -1597,17 +1604,17 @@ class ICTypeUpdate_Fallback : public ICS
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::TypeUpdate_Fallback)
         { }
 
         ICTypeUpdate_Fallback* getStub(ICStubSpace* space) {
-            return ICStub::New<ICTypeUpdate_Fallback>(space, getStubCode());
+            return newStub<ICTypeUpdate_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICTypeUpdate_PrimitiveSet : public TypeCheckPrimitiveSetStub
 {
     friend class ICStubSpace;
 
@@ -1630,17 +1637,17 @@ class ICTypeUpdate_PrimitiveSet : public
                 this->TypeCheckPrimitiveSetStub::Compiler::updateStub();
             if (!stub)
                 return nullptr;
             return stub->toUpdateStub();
         }
 
         ICTypeUpdate_PrimitiveSet* getStub(ICStubSpace* space) {
             MOZ_ASSERT(!existingStub_);
-            return ICStub::New<ICTypeUpdate_PrimitiveSet>(space, getStubCode(), flags_);
+            return newStub<ICTypeUpdate_PrimitiveSet>(space, getStubCode(), flags_);
         }
     };
 };
 
 // Type update stub to handle a singleton object.
 class ICTypeUpdate_SingleObject : public ICStub
 {
     friend class ICStubSpace;
@@ -1665,17 +1672,17 @@ class ICTypeUpdate_SingleObject : public
 
       public:
         Compiler(JSContext* cx, HandleObject obj)
           : ICStubCompiler(cx, TypeUpdate_SingleObject),
             obj_(obj)
         { }
 
         ICTypeUpdate_SingleObject* getStub(ICStubSpace* space) {
-            return ICStub::New<ICTypeUpdate_SingleObject>(space, getStubCode(), obj_);
+            return newStub<ICTypeUpdate_SingleObject>(space, getStubCode(), obj_);
         }
     };
 };
 
 // Type update stub to handle a single ObjectGroup.
 class ICTypeUpdate_ObjectGroup : public ICStub
 {
     friend class ICStubSpace;
@@ -1700,17 +1707,17 @@ class ICTypeUpdate_ObjectGroup : public 
 
       public:
         Compiler(JSContext* cx, HandleObjectGroup group)
           : ICStubCompiler(cx, TypeUpdate_ObjectGroup),
             group_(group)
         { }
 
         ICTypeUpdate_ObjectGroup* getStub(ICStubSpace* space) {
-            return ICStub::New<ICTypeUpdate_ObjectGroup>(space, getStubCode(), group_);
+            return newStub<ICTypeUpdate_ObjectGroup>(space, getStubCode(), group_);
         }
     };
 };
 
 // This
 //      JSOP_THIS
 
 class ICThis_Fallback : public ICFallbackStub
@@ -1726,17 +1733,17 @@ class ICThis_Fallback : public ICFallbac
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::This_Fallback) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICThis_Fallback>(space, getStubCode());
+            return newStub<ICThis_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICNewArray_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
@@ -1758,17 +1765,17 @@ class ICNewArray_Fallback : public ICFal
 
       public:
         Compiler(JSContext* cx, ObjectGroup* templateGroup)
           : ICStubCompiler(cx, ICStub::NewArray_Fallback),
             templateGroup(cx, templateGroup)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICNewArray_Fallback>(space, getStubCode(), templateGroup);
+            return newStub<ICNewArray_Fallback>(space, getStubCode(), templateGroup);
         }
     };
 
     HeapPtrObject& templateObject() {
         return templateObject_;
     }
 
     void setTemplateObject(JSObject* obj) {
@@ -1796,17 +1803,17 @@ class ICNewObject_Fallback : public ICFa
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::NewObject_Fallback)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICNewObject_Fallback>(space, getStubCode());
+            return newStub<ICNewObject_Fallback>(space, getStubCode());
         }
     };
 
     HeapPtrObject& templateObject() {
         return templateObject_;
     }
 
     void setTemplateObject(JSObject* obj) {
@@ -1850,17 +1857,17 @@ class ICCompare_Fallback : public ICFall
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::Compare_Fallback) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_Fallback>(space, getStubCode());
+            return newStub<ICCompare_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1873,17 +1880,17 @@ class ICCompare_Int32 : public ICStub
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Int32, op) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_Int32>(space, getStubCode());
+            return newStub<ICCompare_Int32>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Double : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1897,17 +1904,17 @@ class ICCompare_Double : public ICStub
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Double, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_Double>(space, getStubCode());
+            return newStub<ICCompare_Double>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_NumberWithUndefined : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1936,17 +1943,18 @@ class ICCompare_NumberWithUndefined : pu
 
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind)
                  | (static_cast<int32_t>(op) << 16)
                  | (static_cast<int32_t>(lhsIsUndefined) << 24);
         }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_NumberWithUndefined>(space, getStubCode(), lhsIsUndefined);
+            return newStub<ICCompare_NumberWithUndefined>(space, getStubCode(),
+                                                              lhsIsUndefined);
         }
     };
 };
 
 class ICCompare_String : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1960,17 +1968,17 @@ class ICCompare_String : public ICStub
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_String, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_String>(space, getStubCode());
+            return newStub<ICCompare_String>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Boolean : public ICStub
 {
     friend class ICStubSpace;
 
@@ -1984,17 +1992,17 @@ class ICCompare_Boolean : public ICStub
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Boolean, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_Boolean>(space, getStubCode());
+            return newStub<ICCompare_Boolean>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Object : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2008,17 +2016,17 @@ class ICCompare_Object : public ICStub
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::Compare_Object, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_Object>(space, getStubCode());
+            return newStub<ICCompare_Object>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_ObjectWithUndefined : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2044,17 +2052,17 @@ class ICCompare_ObjectWithUndefined : pu
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind)
                  | (static_cast<int32_t>(op) << 16)
                  | (static_cast<int32_t>(lhsIsUndefined) << 24)
                  | (static_cast<int32_t>(compareWithNull) << 25);
         }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_ObjectWithUndefined>(space, getStubCode());
+            return newStub<ICCompare_ObjectWithUndefined>(space, getStubCode());
         }
     };
 };
 
 class ICCompare_Int32WithBoolean : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2084,17 +2092,17 @@ class ICCompare_Int32WithBoolean : publi
       public:
         Compiler(JSContext* cx, JSOp op, bool lhsIsInt32)
           : ICStubCompiler(cx, ICStub::Compare_Int32WithBoolean),
             op_(op),
             lhsIsInt32_(lhsIsInt32)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICCompare_Int32WithBoolean>(space, getStubCode(), lhsIsInt32_);
+            return newStub<ICCompare_Int32WithBoolean>(space, getStubCode(), lhsIsInt32_);
         }
     };
 };
 
 // ToBool
 //      JSOP_IFNE
 
 class ICToBool_Fallback : public ICFallbackStub
@@ -2112,17 +2120,17 @@ class ICToBool_Fallback : public ICFallb
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToBool_Fallback) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToBool_Fallback>(space, getStubCode());
+            return newStub<ICToBool_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2135,17 +2143,17 @@ class ICToBool_Int32 : public ICStub
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToBool_Int32) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToBool_Int32>(space, getStubCode());
+            return newStub<ICToBool_Int32>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_String : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2158,17 +2166,17 @@ class ICToBool_String : public ICStub
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToBool_String) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToBool_String>(space, getStubCode());
+            return newStub<ICToBool_String>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_NullUndefined : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2181,17 +2189,17 @@ class ICToBool_NullUndefined : public IC
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToBool_NullUndefined) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToBool_NullUndefined>(space, getStubCode());
+            return newStub<ICToBool_NullUndefined>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_Double : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2204,17 +2212,17 @@ class ICToBool_Double : public ICStub
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToBool_Double) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToBool_Double>(space, getStubCode());
+            return newStub<ICToBool_Double>(space, getStubCode());
         }
     };
 };
 
 class ICToBool_Object : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2227,17 +2235,17 @@ class ICToBool_Object : public ICStub
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToBool_Object) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToBool_Object>(space, getStubCode());
+            return newStub<ICToBool_Object>(space, getStubCode());
         }
     };
 };
 
 // ToNumber
 //     JSOP_POS
 
 class ICToNumber_Fallback : public ICFallbackStub
@@ -2253,17 +2261,17 @@ class ICToNumber_Fallback : public ICFal
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::ToNumber_Fallback) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICToNumber_Fallback>(space, getStubCode());
+            return newStub<ICToNumber_Fallback>(space, getStubCode());
         }
     };
 };
 
 // BinaryArith
 //      JSOP_ADD
 //      JSOP_BITAND, JSOP_BITXOR, JSOP_BITOR
 //      JSOP_LSH, JSOP_RSH, JSOP_URSH
@@ -2302,17 +2310,17 @@ class ICBinaryArith_Fallback : public IC
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::BinaryArith_Fallback) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_Fallback>(space, getStubCode());
+            return newStub<ICBinaryArith_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICBinaryArith_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2342,17 +2350,17 @@ class ICBinaryArith_Int32 : public ICStu
         }
 
       public:
         Compiler(JSContext* cx, JSOp op, bool allowDouble)
           : ICStubCompiler(cx, ICStub::BinaryArith_Int32),
             op_(op), allowDouble_(allowDouble) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_Int32>(space, getStubCode(), allowDouble_);
+            return newStub<ICBinaryArith_Int32>(space, getStubCode(), allowDouble_);
         }
     };
 };
 
 class ICBinaryArith_StringConcat : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2366,17 +2374,17 @@ class ICBinaryArith_StringConcat : publi
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::BinaryArith_StringConcat)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_StringConcat>(space, getStubCode());
+            return newStub<ICBinaryArith_StringConcat>(space, getStubCode());
         }
     };
 };
 
 class ICBinaryArith_StringObjectConcat : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2402,17 +2410,18 @@ class ICBinaryArith_StringObjectConcat :
 
       public:
         Compiler(JSContext* cx, bool lhsIsString)
           : ICStubCompiler(cx, ICStub::BinaryArith_StringObjectConcat),
             lhsIsString_(lhsIsString)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_StringObjectConcat>(space, getStubCode(), lhsIsString_);
+            return newStub<ICBinaryArith_StringObjectConcat>(space, getStubCode(),
+                                                                 lhsIsString_);
         }
     };
 };
 
 class ICBinaryArith_Double : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2426,17 +2435,17 @@ class ICBinaryArith_Double : public ICSt
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::BinaryArith_Double, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_Double>(space, getStubCode());
+            return newStub<ICBinaryArith_Double>(space, getStubCode());
         }
     };
 };
 
 class ICBinaryArith_BooleanWithInt32 : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2479,17 +2488,17 @@ class ICBinaryArith_BooleanWithInt32 : p
             op_(op), lhsIsBool_(lhsIsBool), rhsIsBool_(rhsIsBool)
         {
             MOZ_ASSERT(op_ == JSOP_ADD || op_ == JSOP_SUB || op_ == JSOP_BITOR ||
                        op_ == JSOP_BITAND || op_ == JSOP_BITXOR);
             MOZ_ASSERT(lhsIsBool_ || rhsIsBool_);
         }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_BooleanWithInt32>(space, getStubCode(),
+            return newStub<ICBinaryArith_BooleanWithInt32>(space, getStubCode(),
                                                                lhsIsBool_, rhsIsBool_);
         }
     };
 };
 
 class ICBinaryArith_DoubleWithInt32 : public ICStub
 {
     friend class ICStubSpace;
@@ -2517,17 +2526,18 @@ class ICBinaryArith_DoubleWithInt32 : pu
 
       public:
         Compiler(JSContext* cx, JSOp op, bool lhsIsDouble)
           : ICMultiStubCompiler(cx, ICStub::BinaryArith_DoubleWithInt32, op),
             lhsIsDouble_(lhsIsDouble)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBinaryArith_DoubleWithInt32>(space, getStubCode(), lhsIsDouble_);
+            return newStub<ICBinaryArith_DoubleWithInt32>(space, getStubCode(),
+                                                              lhsIsDouble_);
         }
     };
 };
 
 // UnaryArith
 //     JSOP_BITNOT
 //     JSOP_NEG
 
@@ -2557,17 +2567,17 @@ class ICUnaryArith_Fallback : public ICF
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::UnaryArith_Fallback)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICUnaryArith_Fallback>(space, getStubCode());
+            return newStub<ICUnaryArith_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICUnaryArith_Int32 : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2581,17 +2591,17 @@ class ICUnaryArith_Int32 : public ICStub
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICUnaryArith_Int32>(space, getStubCode());
+            return newStub<ICUnaryArith_Int32>(space, getStubCode());
         }
     };
 };
 
 class ICUnaryArith_Double : public ICStub
 {
     friend class ICStubSpace;
 
@@ -2605,17 +2615,17 @@ class ICUnaryArith_Double : public ICStu
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, JSOp op)
           : ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICUnaryArith_Double>(space, getStubCode());
+            return newStub<ICUnaryArith_Double>(space, getStubCode());
         }
     };
 };
 
 // GetElem
 //      JSOP_GETELEM
 
 class ICGetElem_Fallback : public ICMonitoredFallbackStub
@@ -2652,17 +2662,17 @@ class ICGetElem_Fallback : public ICMoni
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetElem_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            ICGetElem_Fallback* stub = ICStub::New<ICGetElem_Fallback>(space, getStubCode());
+            ICGetElem_Fallback* stub = newStub<ICGetElem_Fallback>(space, getStubCode());
             if (!stub)
                 return nullptr;
             if (!stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
@@ -2838,17 +2848,17 @@ class ICGetElem_NativePrototypeCallNativ
                                         JSObject* holder, Shape* holderShape)
       : ICGetElemNativePrototypeCallStub(GetElem_NativePrototypeCallNative,
                                          stubCode, firstMonitorStub, shape, name,
                                          acctype, needsAtomize, getter, pcOffset, holder,
                                          holderShape)
     {}
 
   public:
-    static ICGetElem_NativePrototypeCallNative* Clone(ICStubSpace* space,
+    static ICGetElem_NativePrototypeCallNative* Clone(JSContext* cx, ICStubSpace* space,
                                                       ICStub* firstMonitorStub,
                                                       ICGetElem_NativePrototypeCallNative& other);
 };
 
 class ICGetElem_NativePrototypeCallScripted : public ICGetElemNativePrototypeCallStub
 {
     friend class ICStubSpace;
 
@@ -2860,17 +2870,17 @@ class ICGetElem_NativePrototypeCallScrip
       : ICGetElemNativePrototypeCallStub(GetElem_NativePrototypeCallScripted,
                                          stubCode, firstMonitorStub, shape, name,
                                          acctype, needsAtomize, getter, pcOffset, holder,
                                          holderShape)
     {}
 
   public:
     static ICGetElem_NativePrototypeCallScripted*
-    Clone(ICStubSpace* space,
+    Clone(JSContext* cx, ICStubSpace* space,
           ICStub* firstMonitorStub,
           ICGetElem_NativePrototypeCallScripted& other);
 };
 
 // Compiler for GetElem_NativeSlot and GetElem_NativePrototypeSlot stubs.
 class ICGetElemNativeCompiler : public ICStubCompiler
 {
     bool isCallElem_;
@@ -2935,38 +2945,38 @@ class ICGetElemNativeCompiler : public I
         getter_(getter),
         pcOffset_(pcOffset)
     {}
 
     ICStub* getStub(ICStubSpace* space) {
         RootedShape shape(cx, obj_->as<NativeObject>().lastProperty());
         if (kind == ICStub::GetElem_NativeSlot) {
             MOZ_ASSERT(obj_ == holder_);
-            return ICStub::New<ICGetElem_NativeSlot>(
+            return newStub<ICGetElem_NativeSlot>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     offset_);
         }
 
         MOZ_ASSERT(obj_ != holder_);
         RootedShape holderShape(cx, holder_->as<NativeObject>().lastProperty());
         if (kind == ICStub::GetElem_NativePrototypeSlot) {
-            return ICStub::New<ICGetElem_NativePrototypeSlot>(
+            return newStub<ICGetElem_NativePrototypeSlot>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     offset_, holder_, holderShape);
         }
 
         if (kind == ICStub::GetElem_NativePrototypeCallNative) {
-            return ICStub::New<ICGetElem_NativePrototypeCallNative>(
+            return newStub<ICGetElem_NativePrototypeCallNative>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     getter_, pcOffset_, holder_, holderShape);
         }
 
         MOZ_ASSERT(kind == ICStub::GetElem_NativePrototypeCallScripted);
         if (kind == ICStub::GetElem_NativePrototypeCallScripted) {
-            return ICStub::New<ICGetElem_NativePrototypeCallScripted>(
+            return newStub<ICGetElem_NativePrototypeCallScripted>(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     getter_, pcOffset_, holder_, holderShape);
         }
 
         MOZ_CRASH("Invalid kind.");
     }
 };
 
@@ -2983,31 +2993,31 @@ class ICGetElem_String : public ICStub
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetElem_String) {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetElem_String>(space, getStubCode());
+            return newStub<ICGetElem_String>(space, getStubCode());
         }
     };
 };
 
 class ICGetElem_Dense : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
     HeapPtrShape shape_;
 
     ICGetElem_Dense(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape);
 
   public:
-    static ICGetElem_Dense* Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+    static ICGetElem_Dense* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                   ICGetElem_Dense& other);
 
     static size_t offsetOfShape() {
         return offsetof(ICGetElem_Dense, shape_);
     }
 
     HeapPtrShape& shape() {
         return shape_;
@@ -3033,32 +3043,32 @@ class ICGetElem_Dense : public ICMonitor
         Compiler(JSContext* cx, ICStub* firstMonitorStub, Shape* shape, bool isCallElem)
           : ICStubCompiler(cx, ICStub::GetElem_Dense),
             firstMonitorStub_(firstMonitorStub),
             shape_(cx, shape),
             isCallElem_(isCallElem)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetElem_Dense>(space, getStubCode(), firstMonitorStub_, shape_);
+            return newStub<ICGetElem_Dense>(space, getStubCode(), firstMonitorStub_, shape_);
         }
     };
 };
 
 class ICGetElem_UnboxedArray : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
     HeapPtrObjectGroup group_;
 
     ICGetElem_UnboxedArray(JitCode* stubCode, ICStub* firstMonitorStub, ObjectGroup* group);
 
   public:
-    static ICGetElem_UnboxedArray* Clone(ICStubSpace* space, ICStub* firstMonitorStub,
-                                         ICGetElem_UnboxedArray& other);
+    static ICGetElem_UnboxedArray* Clone(JSContext* cx, ICStubSpace* space,
+                                         ICStub* firstMonitorStub, ICGetElem_UnboxedArray& other);
 
     static size_t offsetOfGroup() {
         return offsetof(ICGetElem_UnboxedArray, group_);
     }
 
     HeapPtrObjectGroup& group() {
         return group_;
     }
@@ -3080,18 +3090,17 @@ class ICGetElem_UnboxedArray : public IC
         Compiler(JSContext* cx, ICStub* firstMonitorStub, ObjectGroup* group)
           : ICStubCompiler(cx, ICStub::GetElem_UnboxedArray),
             firstMonitorStub_(firstMonitorStub),
             group_(cx, group),
             elementType_(group->unboxedLayout().elementType())
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetElem_UnboxedArray>(space, getStubCode(), firstMonitorStub_,
-                                                       group_);
+            return newStub<ICGetElem_UnboxedArray>(space, getStubCode(), firstMonitorStub_, group_);
         }
     };
 };
 
 // Enum for stubs handling a combination of typed arrays and typed objects.
 enum TypedThingLayout {
     Layout_TypedArray,
     Layout_OutlineTypedObject,
@@ -3147,17 +3156,17 @@ class ICGetElem_TypedArray : public ICSt
         Compiler(JSContext* cx, Shape* shape, Scalar::Type type)
           : ICStubCompiler(cx, ICStub::GetElem_TypedArray),
             shape_(cx, shape),
             type_(type),
             layout_(GetTypedThingLayout(shape->getObjectClass()))
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetElem_TypedArray>(space, getStubCode(), shape_, type_);
+            return newStub<ICGetElem_TypedArray>(space, getStubCode(), shape_, type_);
         }
     };
 };
 
 class ICGetElem_Arguments : public ICMonitoredStub
 {
     friend class ICStubSpace;
   public:
@@ -3166,17 +3175,17 @@ class ICGetElem_Arguments : public ICMon
   private:
     ICGetElem_Arguments(JitCode* stubCode, ICStub* firstMonitorStub, Which which)
       : ICMonitoredStub(ICStub::GetElem_Arguments, stubCode, firstMonitorStub)
     {
         extra_ = static_cast<uint16_t>(which);
     }
 
   public:
-    static ICGetElem_Arguments* Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+    static ICGetElem_Arguments* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                       ICGetElem_Arguments& other);
 
     Which which() const {
         return static_cast<Which>(extra_);
     }
 
     class Compiler : public ICStubCompiler {
       ICStub* firstMonitorStub_;
@@ -3200,17 +3209,17 @@ class ICGetElem_Arguments : public ICMon
         Compiler(JSContext* cx, ICStub* firstMonitorStub, Which which, bool isCallElem)
           : ICStubCompiler(cx, ICStub::GetElem_Arguments),
             firstMonitorStub_(firstMonitorStub),
             which_(which),
             isCallElem_(isCallElem)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetElem_Arguments>(space, getStubCode(), firstMonitorStub_, which_);
+            return newStub<ICGetElem_Arguments>(space, getStubCode(), firstMonitorStub_, which_);
         }
     };
 };
 
 // SetElem
 //      JSOP_SETELEM
 //      JSOP_INITELEM
 
@@ -3238,17 +3247,17 @@ class ICSetElem_Fallback : public ICFall
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::SetElem_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICSetElem_Fallback>(space, getStubCode());
+            return newStub<ICSetElem_Fallback>(space, getStubCode());
         }
     };
 };
 
 class ICSetElem_DenseOrUnboxedArray : public ICUpdatedStub
 {
     friend class ICStubSpace;
 
@@ -3289,17 +3298,17 @@ class ICSetElem_DenseOrUnboxedArray : pu
           : ICStubCompiler(cx, ICStub::SetElem_DenseOrUnboxedArray),
             shape_(cx, shape),
             group_(cx, group),
             unboxedType_(shape ? JSVAL_TYPE_MAGIC : group->unboxedLayout().elementType())
         {}
 
         ICUpdatedStub* getStub(ICStubSpace* space) {
             ICSetElem_DenseOrUnboxedArray* stub =
-                ICStub::New<ICSetElem_DenseOrUnboxedArray>(space, getStubCode(), shape_, group_);
+                newStub<ICSetElem_DenseOrUnboxedArray>(space, getStubCode(), shape_, group_);
             if (!stub || !stub->initUpdatingChain(cx, space))
                 return nullptr;
             return stub;
         }
 
         bool needsUpdateStubs() {
             return unboxedType_ == JSVAL_TYPE_MAGIC || unboxedType_ == JSVAL_TYPE_OBJECT;
         }
@@ -3462,18 +3471,18 @@ class ICSetElem_TypedArray : public ICSt
           : ICStubCompiler(cx, ICStub::SetElem_TypedArray),
             shape_(cx, shape),
             type_(type),
             layout_(GetTypedThingLayout(shape->getObjectClass())),
             expectOutOfBounds_(expectOutOfBounds)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICSetElem_TypedArray>(space, getStubCode(), shape_, type_,
-                                                     expectOutOfBounds_);
+            return newStub<ICSetElem_TypedArray>(space, getStubCode(), shape_, type_,
+                                                 expectOutOfBounds_);
         }
     };
 };
 
 // In
 //      JSOP_IN
 class ICIn_Fallback : public ICFallbackStub
 {
@@ -3491,17 +3500,17 @@ class ICIn_Fallback : public ICFallbackS
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::In_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICIn_Fallback>(space, getStubCode());
+            return newStub<ICIn_Fallback>(space, getStubCode());
         }
     };
 };
 
 // Base class for In_Native and In_NativePrototype stubs.
 class ICInNativeStub : public ICStub
 {
     HeapPtrShape shape_;
@@ -3582,24 +3591,24 @@ class ICInNativeCompiler : public ICStub
         holder_(cx, holder),
         name_(cx, name)
     {}
 
     ICStub* getStub(ICStubSpace* space) {
         RootedShape shape(cx, obj_->as<NativeObject>().lastProperty());
         if (kind == ICStub::In_Native) {
             MOZ_ASSERT(obj_ == holder_);
-            return ICStub::New<ICIn_Native>(space, getStubCode(), shape, name_);
+            return newStub<ICIn_Native>(space, getStubCode(), shape, name_);
         }
 
         MOZ_ASSERT(obj_ != holder_);
         MOZ_ASSERT(kind == ICStub::In_NativePrototype);
         RootedShape holderShape(cx, holder_->as<NativeObject>().lastProperty());
-        return ICStub::New<ICIn_NativePrototype>(space, getStubCode(), shape, name_, holder_,
-                                                 holderShape);
+        return newStub<ICIn_NativePrototype>(space, getStubCode(), shape, name_, holder_,
+                                             holderShape);
     }
 };
 
 template <size_t ProtoChainDepth> class ICIn_NativeDoesNotExistImpl;
 
 class ICIn_NativeDoesNotExist : public ICStub
 {
     friend class ICStubSpace;
@@ -3674,19 +3683,18 @@ class ICInNativeDoesNotExistCompiler : p
     bool generateStubCode(MacroAssembler& masm);
 
   public:
     ICInNativeDoesNotExistCompiler(JSContext* cx, HandleObject obj, HandlePropertyName name,
                                    size_t protoChainDepth);
 
     template <size_t ProtoChainDepth>
     ICStub* getStubSpecific(ICStubSpace* space, const AutoShapeVector* shapes) {
-        return ICStub::New<ICIn_NativeDoesNotExistImpl<ProtoChainDepth>>(space, getStubCode(),
-                                                                         shapes, name_);
-    }
+        return newStub<ICIn_NativeDoesNotExistImpl<ProtoChainDepth>>(space, getStubCode(), shapes,
+                                                                     name_);}
 
     ICStub* getStub(ICStubSpace* space);
 };
 
 class ICIn_Dense : public ICStub
 {
     friend class ICStubSpace;
 
@@ -3710,17 +3718,17 @@ class ICIn_Dense : public ICStub
 
       public:
         Compiler(JSContext* cx, Shape* shape)
           : ICStubCompiler(cx, ICStub::In_Dense),
             shape_(cx, shape)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICIn_Dense>(space, getStubCode(), shape_);
+            return newStub<ICIn_Dense>(space, getStubCode(), shape_);
         }
     };
 };
 
 // GetName
 //      JSOP_GETNAME
 //      JSOP_GETGNAME
 class ICGetName_Fallback : public ICMonitoredFallbackStub
@@ -3747,17 +3755,17 @@ class ICGetName_Fallback : public ICMoni
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetName_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            ICGetName_Fallback* stub = ICStub::New<ICGetName_Fallback>(space, getStubCode());
+            ICGetName_Fallback* stub = newStub<ICGetName_Fallback>(space, getStubCode());
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 // Optimized GETGNAME/CALLGNAME stub.
@@ -3794,18 +3802,18 @@ class ICGetName_Global : public ICMonito
         Compiler(JSContext* cx, ICStub* firstMonitorStub, Shape* shape, uint32_t slot)
           : ICStubCompiler(cx, ICStub::GetName_Global),
             firstMonitorStub_(firstMonitorStub),
             shape_(cx, shape),
             slot_(slot)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, shape_,
-                                                 slot_);
+            return newStub<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, shape_,
+                                             slot_);
         }
     };
 };
 
 // Optimized GETNAME/CALLNAME stub, making a variable number of hops to get an
 // 'own' property off some scope object. Unlike GETPROP on an object's
 // prototype, there is no teleporting optimization to take advantage of and
 // shape checks are required all along the scope chain.
@@ -3861,17 +3869,18 @@ class ICGetName_Scope : public ICMonitor
             firstMonitorStub_(firstMonitorStub),
             shapes_(shapes),
             isFixedSlot_(isFixedSlot),
             offset_(offset)
         {
         }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetName_Scope>(space, getStubCode(), firstMonitorStub_, shapes_, offset_);
+            return newStub<ICGetName_Scope>(space, getStubCode(), firstMonitorStub_, shapes_,
+                                            offset_);
         }
     };
 };
 
 // BindName
 //      JSOP_BINDNAME
 class ICBindName_Fallback : public ICFallbackStub
 {
@@ -3887,17 +3896,17 @@ class ICBindName_Fallback : public ICFal
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::BindName_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICBindName_Fallback>(space, getStubCode());
+            return newStub<ICBindName_Fallback>(space, getStubCode());
         }
     };
 };
 
 // GetIntrinsic
 //      JSOP_GETINTRINSIC
 class ICGetIntrinsic_Fallback : public ICMonitoredFallbackStub
 {
@@ -3914,17 +3923,17 @@ class ICGetIntrinsic_Fallback : public I
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetIntrinsic_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
             ICGetIntrinsic_Fallback* stub =
-                ICStub::New<ICGetIntrinsic_Fallback>(space, getStubCode());
+                newStub<ICGetIntrinsic_Fallback>(space, getStubCode());
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 // Stub that loads the constant result of a GETINTRINSIC operation.
@@ -3952,17 +3961,17 @@ class ICGetIntrinsic_Constant : public I
 
       public:
         Compiler(JSContext* cx, HandleValue value)
           : ICStubCompiler(cx, ICStub::GetIntrinsic_Constant),
             value_(value)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetIntrinsic_Constant>(space, getStubCode(), value_);
+            return newStub<ICGetIntrinsic_Constant>(space, getStubCode(), value_);
         }
     };
 };
 
 class ICGetProp_Fallback : public ICMonitoredFallbackStub
 {
     friend class ICStubSpace;
 
@@ -3996,17 +4005,17 @@ class ICGetProp_Fallback : public ICMoni
         bool postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetProp_Fallback)
         { }
 
         ICStub* getStub(ICStubSpace* space) {
-            ICGetProp_Fallback* stub = ICStub::New<ICGetProp_Fallback>(space, getStubCode());
+            ICGetProp_Fallback* stub = newStub<ICGetProp_Fallback>(space, getStubCode());
             if (!stub || !stub->initMonitoringChain(cx, space))
                 return nullptr;
             return stub;
         }
     };
 };
 
 // Stub for sites, which are too polymorphic (i.e. MAX_OPTIMIZED_STUBS was reached)
@@ -4014,31 +4023,31 @@ class ICGetProp_Generic : public ICMonit
 {
     friend class ICStubSpace;
 
   protected:
     explicit ICGetProp_Generic(JitCode* stubCode, ICStub* firstMonitorStub)
       : ICMonitoredStub(ICStub::GetProp_Generic, stubCode, firstMonitorStub) {}
 
   public:
-    static ICGetProp_Generic* Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+    static ICGetProp_Generic* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                     ICGetProp_Generic& other);
 
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler& masm);
         ICStub* firstMonitorStub_;
       public:
         explicit Compiler(JSContext* cx, ICStub* firstMonitorStub)
           : ICStubCompiler(cx, ICStub::GetProp_Generic),
             firstMonitorStub_(firstMonitorStub)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
+            return newStub<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
         }
     };
 };
 
 // Stub for accessing a dense array's length.
 class ICGetProp_ArrayLength : public ICStub
 {
     friend class ICStubSpace;
@@ -4052,17 +4061,17 @@ class ICGetProp_ArrayLength : public ICS
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetProp_ArrayLength)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetProp_ArrayLength>(space, getStubCode());
+            return newStub<ICGetProp_ArrayLength>(space, getStubCode());
         }
     };
 };
 
 // Stub for accessing an unboxed array's length.
 class ICGetProp_UnboxedArrayLength : public ICStub
 {
     friend class ICStubSpace;
@@ -4076,17 +4085,17 @@ class ICGetProp_UnboxedArrayLength : pub
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetProp_UnboxedArrayLength)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetProp_UnboxedArrayLength>(space, getStubCode());
+            return newStub<ICGetProp_UnboxedArrayLength>(space, getStubCode());
         }
     };
 };
 
 // Stub for accessing a property on a primitive's prototype.
 class ICGetProp_Primitive : public ICMonitoredStub
 {
     friend class ICStubSpace;
@@ -4138,18 +4147,18 @@ class ICGetProp_Primitive : public ICMon
             primitiveType_(primitiveType),
             prototype_(cx, prototype),
             isFixedSlot_(isFixedSlot),
             offset_(offset)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             RootedShape protoShape(cx, prototype_->as<NativeObject>().lastProperty());
-            return ICStub::New<ICGetProp_Primitive>(space, getStubCode(), firstMonitorStub_,
-                                                    protoShape, offset_);
+            return newStub<ICGetProp_Primitive>(space, getStubCode(), firstMonitorStub_,
+                                                protoShape, offset_);
         }
     };
 };
 
 // Stub for accessing a string's length.
 class ICGetProp_StringLength : public ICStub
 {
     friend class ICStubSpace;
@@ -4163,17 +4172,17 @@ class ICGetProp_StringLength : public IC
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         explicit Compiler(JSContext* cx)
           : ICStubCompiler(cx, ICStub::GetProp_StringLength)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetProp_StringLength>(space, getStubCode());
+            return newStub<ICGetProp_StringLength>(space, getStubCode());
         }
     };
 };
 
 // Base class for native GetProp stubs.
 class ICGetPropNativeStub : public ICMonitoredStub
 {
     // Object shape/group.
@@ -4215,17 +4224,17 @@ class ICGetProp_Native : public ICGetPro
     friend class ICStubSpace;
 
     ICGetProp_Native(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
                      uint32_t offset)
       : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, guard, offset)
     {}
 
   public:
-    static ICGetProp_Native* Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+    static ICGetProp_Native* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                    ICGetProp_Native& other);
 };
 
 // Stub for accessing a property on the native prototype of a native or unboxed
 // object. Note that due to the shape teleporting optimization, we only have to
 // guard on the object's shape/group and the holder's shape.
 class ICGetProp_NativePrototype : public ICGetPropNativeStub
 {
@@ -4236,17 +4245,18 @@ class ICGetProp_NativePrototype : public
     HeapPtrObject holder_;
     HeapPtrShape holderShape_;
 
     ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub,
                               ReceiverGuard guard,
                               uint32_t offset, JSObject* holder, Shape* holderShape);
 
   public:
-    static ICGetProp_NativePrototype* Clone(ICStubSpace* space,
+    static ICGetProp_NativePrototype* Clone(JSContext* cx,
+                                            ICStubSpace* space,
                                             ICStub* firstMonitorStub,
                                             ICGetProp_NativePrototype& other);
 
   public:
     HeapPtrObject& holder() {
         return holder_;
     }
     HeapPtrShape& holderShape() {
@@ -4384,17 +4394,17 @@ class ICGetPropNativeDoesNotExistCompile
 
   public:
     ICGetPropNativeDoesNotExistCompiler(JSContext* cx, ICStub* firstMonitorStub,
                                         HandleObject obj, size_t protoChainDepth);
 
     template <size_t ProtoChainDepth>
     ICStub* getStubSpecific(ICStubSpace* space, const AutoShapeVector* shapes) {
         ReceiverGuard guard(obj_);
-        return ICStub::New<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth> >
+        return newStub<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>>
             (space, getStubCode(), firstMonitorStub_, guard, shapes);
     }
 
     ICStub* getStub(ICStubSpace* space);
 };
 
 class ICGetProp_Unboxed : public ICMonitoredStub
 {
@@ -4442,18 +4452,18 @@ class ICGetProp_Unboxed : public ICMonit
           : ICStubCompiler(cx, ICStub::GetProp_Unboxed),
             firstMonitorStub_(firstMonitorStub),
             group_(cx, group),
             fieldOffset_(fieldOffset),
             fieldType_(fieldType)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetProp_Unboxed>(space, getStubCode(), firstMonitorStub_,
-                                                  group_, fieldOffset_);
+            return newStub<ICGetProp_Unboxed>(space, getStubCode(), firstMonitorStub_, group_,
+                                              fieldOffset_);
         }
     };
 };
 
 static uint32_t
 SimpleTypeDescrKey(SimpleTypeDescr* descr)
 {
     if (descr->is<ScalarTypeDescr>())
@@ -4511,18 +4521,18 @@ class ICGetProp_TypedObject : public ICM
             firstMonitorStub_(firstMonitorStub),
             shape_(cx, shape),
             fieldOffset_(fieldOffset),
             layout_(GetTypedThingLayout(shape->getObjectClass())),
             fieldDescr_(cx, fieldDescr)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
-            return ICStub::New<ICGetProp_TypedObject>(space, getStubCode(), firstMonitorStub_,
-                                                      shape_, fieldOffset_);
+            return newStub<ICGetProp_TypedObject>(space, getStubCode(), firstMonitorStub_, shape_,
+                                                  fieldOffset_);
         }
     };
 };
 
 class ICGetPropCallGetter : public ICMonitoredStub
 {
     friend class ICStubSpace;
 
@@ -4633,17 +4643,17 @@ class ICGetProp_CallScripted : public IC
                            ReceiverGuard receiverGuard,
                            JSObject* holder, Shape* holderShape,
                            JSFunction* getter, uint32_t pcOffset)
       : ICGetPropCallGetter(GetProp_CallScripted, stubCode, firstMonitorStub,
                             receiverGuard, holder, holderShape, getter, pcOffset)
     {}
 
   public:
-    static ICGetProp_CallScripted* Clone(ICStubSpace* space,
+    static ICGetProp_CallScripted* Clone(JSContext* cx, ICStubSpace* space,
                                          ICStub* firstMonitorStub, ICGetProp_CallScripted& other);
 
     class Compiler : public ICGetPropCallGetter::Compiler {
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
       public:
         Compiler(JSContext* cx, ICStub* firstMonitorStub, HandleObject obj,
@@ -4651,17 +4661,17 @@ class ICGetProp_CallScripted : public IC
           : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallScripted,
                                           firstMonitorStub, obj, holder,
                                           getter, pcOffset, /* outerClass = */ nullptr)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             ReceiverGuard guard(receiver_);
             Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-            return ICStub::New<ICGetProp_CallScripted>(space, getStubCode(), firstMonitorStub_,
+            return newStub<ICGetProp_CallScripted>(space, getStubCode(), firstMonitorStub_,
                                                        guard, holder_, holderShape, getter_,
                                                        pcOffset_);
         }
     };
 };
 
 // Stub for calling a native getter on a native object.
 class ICGetProp_CallNative : public ICGetPropCallGetter
@@ -4674,17 +4684,17 @@ class ICGetProp_CallNative : public ICGe
                          ReceiverGuard receiverGuard,
                          JSObject* holder, Shape* holderShape,
                          JSFunction* getter, uint32_t pcOffset)
       : ICGetPropCallGetter(GetProp_CallNative, stubCode, firstMonitorStub,
                             receiverGuard, holder, holderShape, getter, pcOffset)
     {}
 
   public:
-    static ICGetProp_CallNative* Clone(ICStubSpace* space, ICStub* firstMonitorStub,
+    static ICGetProp_CallNative* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                                        ICGetProp_CallNative& other);
 
     class Compiler : public ICGetPropCallGetter::Compiler
     {
         bool inputDefinitelyObject_;
       protected:
         bool generateStubCode(MacroAssembler& masm);
 
@@ -4702,17 +4712,17 @@ class ICGetProp_CallNative : public ICGe
                                           firstMonitorStub, receiver, holder,
                                           getter, pcOffset, outerClass),
             inputDefinitelyObject_(inputDefinitelyObject)
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             ReceiverGuard guard(receiver_);
             Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-            return ICStub::New<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
+            return newStub<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
                                                      guard, holder_, holderShape,
                                                      getter_, pcOffset_);
         }
     };
 };
 
 class ICGetPropCallDOMProxyNativeStub : public ICGetPropCallGetter
 {
@@ -4744,17 +4754,18 @@ class ICGetProp_CallDOMProxyNative : pub
                                  JSObject* holder, Shape* holderShape,
                                  JSFunction* getter, uint32_t pcOffset)
       : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyNative, stubCode,
                                         firstMonitorStub, shape, expandoShape,
                                         holder, holderShape, getter, pcOffset)
     {}
 
   public:
-    static ICGetProp_CallDOMProxyNative* Clone(ICStubSpace* space,
+    static ICGetProp_CallDOMProxyNative* Clone(JSContext* cx,
+                                               ICStubSpace* space,
                                                ICStub* firstMonitorStub,
                                                ICGetProp_CallDOMProxyNative& other);
 };
 
 class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyNativeStub
 {
   protected:
     ExpandoAndGeneration* expandoAndGeneration_;
@@ -4771,17 +4782,17 @@ class ICGetProp_CallDOMProxyWithGenerati
                                         stubCode, firstMonitorStub, shape,
                                         expandoShape, holder, holderShape, getter, pcOffset),
         expandoAndGeneration_(expandoAndGeneration),
         generation_(generation)
     {
     }
 
     static ICGetProp_CallDOMProxyWithGenerationNative*