Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 23 Sep 2013 23:05:11 -0400
changeset 162187 1fda74e33e0610130db0e14f8812933f69143d81
parent 162165 322ba35765715e57c59787befb5fc57359a209b6 (current diff)
parent 162186 bf05c838f1d9ec4c4df7b881c7fc7e7611b52d16 (diff)
child 162188 3eb8450ae7d6396f2c039416f5ae196acea561a0
child 162194 400260c0b569f313ddd0399006e0973e7a2e73c7
child 162226 14b57090e67e4f5e721a74f53d9428ebe80ab0ce
child 163467 f4c7f26b1bf0a793ef06824aa3394e86ed2cbf90
child 170353 ea4363ac93eaf1f7e2a0920f4916ce699a2d28e2
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
1fda74e33e06 / 27.0a1 / 20130924030202 / files
nightly linux64
1fda74e33e06 / 27.0a1 / 20130924030202 / files
nightly mac
1fda74e33e06 / 27.0a1 / 20130924030202 / files
nightly win32
1fda74e33e06 / 27.0a1 / 20130924030202 / files
nightly win64
1fda74e33e06 / 27.0a1 / 20130924030202 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
toolkit/components/telemetry/Histograms.json
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -18,16 +18,17 @@
 #include "nsMaiHyperlink.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "prprf.h"
 #include "nsStateMap.h"
 #include "Relation.h"
 #include "RootAccessible.h"
 #include "States.h"
+#include "nsISimpleEnumerator.h"
 
 #include "mozilla/Util.h"
 #include "nsXPCOMStrings.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIPersistentProperties2.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -13,17 +13,17 @@
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleHyperLink.h"
 #include "nsIAccessibleSelectable.h"
 #include "nsIAccessibleValue.h"
 #include "nsIAccessibleStates.h"
 
 #include "nsIContent.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "nsRefPtrHashtable.h"
 
 struct nsRoleMapEntry;
 
 struct nsRect;
 class nsIFrame;
 class nsIAtom;
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -69,20 +69,21 @@ static const uint32_t kRelationAttrsLen 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor/desctructor
 
 DocAccessible::
   DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
                   nsIPresShell* aPresShell) :
   HyperTextAccessibleWrap(aRootContent, this),
-  mDocumentNode(aDocument), mScrollPositionChangedTicks(0),
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessibleCache(kDefaultCacheSize),
   mNodeToAccessibleMap(kDefaultCacheSize),
+  mDocumentNode(aDocument),
+  mScrollPositionChangedTicks(0),
   mLoadState(eTreeConstructionPending), mDocFlags(0), mLoadEventType(0),
   mVirtualCursor(nullptr),
   mPresShell(aPresShell)
 {
   mGenericTypes |= eDocument;
   mStateFlags |= eNotNodeMapEntry;
 
   MOZ_ASSERT(mPresShell, "should have been given a pres shell");
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -493,120 +493,57 @@ var Output = {
 
       return braille;
     }
   },
 
   speechHelper: {
     EARCONS: ['chrome://global/content/accessibility/tick.wav'],
 
-    delayedActions: [],
-
-    earconsToLoad: -1, // -1: not inited, 1 or more: initing, 0: inited
-
     earconBuffers: {},
 
-    webaudioEnabled: false,
+    inited: false,
 
     webspeechEnabled: false,
 
-    doDelayedActionsIfLoaded: function doDelayedActionsIfLoaded(aToLoadCount) {
-      if (aToLoadCount === 0) {
-        this.outputActions(this.delayedActions);
-        this.delayedActions = [];
-        return true;
-      }
-
-      return false;
-    },
-
     init: function init() {
-      if (this.earconsToLoad === 0) {
-        // Already inited.
-        return;
-      }
-
       let window = Utils.win;
-      this.webaudioEnabled = !!window.AudioContext;
       this.webspeechEnabled = !!window.speechSynthesis;
 
-      this.earconsToLoad = this.webaudioEnabled ? this.EARCONS.length : 0;
-
-      if (this.doDelayedActionsIfLoaded(this.earconsToLoad)) {
-        // Nothing to load
-        return;
+      for (let earcon of this.EARCONS) {
+        let earconName = /.*\/(.*)\..*$/.exec(earcon)[1];
+        this.earconBuffers[earconName] = new WeakMap();
+        this.earconBuffers[earconName].set(window, new window.Audio(earcon));
       }
 
-      this.audioContext = new window.AudioContext();
-
-      for (let earcon of this.EARCONS) {
-        let xhr = new window.XMLHttpRequest();
-        xhr.open('GET', earcon);
-        xhr.responseType = 'arraybuffer';
-        xhr.onerror = () => {
-          Logger.error('Error getting earcon:', xhr.statusText);
-          this.doDelayedActionsIfLoaded(--this.earconsToLoad);
-        };
-        xhr.onload = () => {
-          this.audioContext.decodeAudioData(
-            xhr.response,
-            (audioBuffer) => {
-              try {
-                let earconName = /.*\/(.*)\..*$/.exec(earcon)[1];
-                this.earconBuffers[earconName] = new WeakMap();
-                this.earconBuffers[earconName].set(window, audioBuffer);
-                this.doDelayedActionsIfLoaded(--this.earconsToLoad);
-              } catch (x) {
-                Logger.logException(x);
-              }
-            },
-            () => {
-              this.doDelayedActionsIfLoaded(--this.earconsToLoad);
-              Logger.error('Error decoding earcon');
-            });
-        };
-        xhr.send();
-      }
+      this.inited = true;
     },
 
     output: function output(aActions) {
-      if (this.earconsToLoad !== 0) {
-        // We did not load the earcons yet.
-        this.delayedActions.push.apply(this.delayedActions, aActions);
-        if (this.earconsToLoad < 0) {
-          // Loading did not start yet, start it.
-          this.init();
-        }
-        return;
+      if (!this.inited) {
+        this.init();
       }
 
-      this.outputActions(aActions);
-    },
-
-    outputActions: function outputActions(aActions) {
       for (let action of aActions) {
         let window = Utils.win;
         Logger.info('tts.' + action.method,
                     '"' + action.data + '"',
                     JSON.stringify(action.options));
 
         if (!action.options.enqueue && this.webspeechEnabled) {
           window.speechSynthesis.cancel();
         }
 
         if (action.method === 'speak' && this.webspeechEnabled) {
           window.speechSynthesis.speak(
             new window.SpeechSynthesisUtterance(action.data));
-        } else if (action.method === 'playEarcon' && this.webaudioEnabled) {
+        } else if (action.method === 'playEarcon') {
           let audioBufferWeakMap = this.earconBuffers[action.data];
           if (audioBufferWeakMap) {
-            let node = this.audioContext.createBufferSource();
-            node.connect(this.audioContext.destination);
-            node.buffer = audioBufferWeakMap.get(window);
-            node.start(0);
+            audioBufferWeakMap.get(window).cloneNode(false).play();
           }
         }
       }
     }
   },
 
   start: function start() {
     Cu.import('resource://gre/modules/Geometry.jsm');
@@ -793,16 +730,19 @@ var Input = {
         this.sendContextMenuMessage();
         break;
       case 'swiperight1':
         this.moveCursor('moveNext', 'Simple', 'gestures');
         break;
       case 'swipeleft1':
         this.moveCursor('movePrevious', 'Simple', 'gesture');
         break;
+      case 'exploreend1':
+        this.activateCurrent(null, true);
+        break;
       case 'swiperight2':
         this.sendScrollMessage(-1, true);
         break;
       case 'swipedown2':
         this.sendScrollMessage(-1);
         break;
       case 'swipeleft2':
         this.sendScrollMessage(1, true);
@@ -933,22 +873,23 @@ var Input = {
     }
 
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     let type = this.editState.editing ? 'AccessFu:MoveCaret' :
                                         'AccessFu:MoveByGranularity';
     mm.sendAsyncMessage(type, aDetails);
   },
 
-  activateCurrent: function activateCurrent(aData) {
+  activateCurrent: function activateCurrent(aData, aActivateIfKey = false) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     let offset = aData && typeof aData.keyIndex === 'number' ?
                  aData.keyIndex - Output.brailleState.startOffset : -1;
 
-    mm.sendAsyncMessage('AccessFu:Activate', {offset: offset});
+    mm.sendAsyncMessage('AccessFu:Activate',
+                        {offset: offset, activateIfKey: aActivateIfKey});
   },
 
   sendContextMenuMessage: function sendContextMenuMessage() {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     mm.sendAsyncMessage('AccessFu:ContextMenu', {});
   },
 
   activateContextMenu: function activateContextMenu(aDetails) {
--- a/accessible/src/jsat/TouchAdapter.jsm
+++ b/accessible/src/jsat/TouchAdapter.jsm
@@ -423,20 +423,20 @@ TouchPoint.prototype = {
       }
 
       this.finish();
 
       return swipeGesture;
     }
 
     // To be considered an explore...
-    if (!this.done &&
-        duration > TouchAdapter.SWIPE_MAX_DURATION &&
+    if (duration > TouchAdapter.SWIPE_MAX_DURATION &&
         (this.distanceTraveled / this.dpi) > TouchAdapter.TAP_MAX_RADIUS) {
-      return {type: 'explore', x: this.x, y: this.y};
+      return {type: this.done ? 'exploreend' : 'explore',
+              x: this.x, y: this.y};
     }
 
     return null;
   },
 
   get directDistanceTraveled() {
     return this.getDistanceToCoord(this.startX, this.startY);
   }
--- a/accessible/src/jsat/TraversalRules.jsm
+++ b/accessible/src/jsat/TraversalRules.jsm
@@ -26,16 +26,17 @@ const ROLE_RADIOBUTTON = Ci.nsIAccessibl
 const ROLE_COMBOBOX = Ci.nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_PROGRESSBAR = Ci.nsIAccessibleRole.ROLE_PROGRESSBAR;
 const ROLE_BUTTONDROPDOWN = Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWN;
 const ROLE_BUTTONMENU = Ci.nsIAccessibleRole.ROLE_BUTTONMENU;
 const ROLE_CHECK_MENU_ITEM = Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM;
 const ROLE_PASSWORD_TEXT = Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT;
 const ROLE_RADIO_MENU_ITEM = Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM;
 const ROLE_TOGGLE_BUTTON = Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
+const ROLE_KEY = Ci.nsIAccessibleRole.ROLE_KEY;
 const ROLE_ENTRY = Ci.nsIAccessibleRole.ROLE_ENTRY;
 const ROLE_LIST = Ci.nsIAccessibleRole.ROLE_LIST;
 const ROLE_DEFINITION_LIST = Ci.nsIAccessibleRole.ROLE_DEFINITION_LIST;
 const ROLE_LISTITEM = Ci.nsIAccessibleRole.ROLE_LISTITEM;
 const ROLE_BUTTONDROPDOWNGRID = Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
 const ROLE_LISTBOX = Ci.nsIAccessibleRole.ROLE_LISTBOX;
 const ROLE_SLIDER = Ci.nsIAccessibleRole.ROLE_SLIDER;
 const ROLE_HEADING = Ci.nsIAccessibleRole.ROLE_HEADING;
@@ -99,16 +100,17 @@ var gSimpleTraversalRoles =
    ROLE_PROGRESSBAR,
    ROLE_BUTTONDROPDOWN,
    ROLE_BUTTONMENU,
    ROLE_CHECK_MENU_ITEM,
    ROLE_PASSWORD_TEXT,
    ROLE_RADIO_MENU_ITEM,
    ROLE_TOGGLE_BUTTON,
    ROLE_ENTRY,
+   ROLE_KEY,
    ROLE_HEADER,
    ROLE_HEADING,
    // Used for traversing in to child OOP frames.
    ROLE_INTERNAL_FRAME];
 
 this.TraversalRules = {
   Simple: new BaseTraversalRule(
     gSimpleTraversalRoles,
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -159,16 +159,22 @@ function forwardToChild(aMessage, aListe
   }
   mm.sendAsyncMessage(aMessage.name, newJSON);
   return true;
 }
 
 function activateCurrent(aMessage) {
   Logger.debug('activateCurrent');
   function activateAccessible(aAccessible) {
+    if (aMessage.json.activateIfKey &&
+        aAccessible.role != Ci.nsIAccessibleRole.ROLE_KEY) {
+      // Only activate keys, don't do anything on other objects.
+      return;
+    }
+
     if (aAccessible.actionCount > 0) {
       aAccessible.doAction(0);
     } else {
       // XXX Some mobile widget sets do not expose actions properly
       // (via ARIA roles, etc.), so we need to generate a click.
       // Could possibly be made simpler in the future. Maybe core
       // engine could expose nsCoreUtiles::DispatchMouseEvent()?
       let docAcc = Utils.AccRetrieval.getAccessibleFor(content.document);
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/AccessibleWrap.cpp
@@ -39,16 +39,17 @@
 #include "mozilla/Preferences.h"
 
 #include "Accessible2_i.c"
 #include "AccessibleRole.h"
 #include "AccessibleStates.h"
 #include "oleacc.h"
 #include "nsIAccessibleTypes.h"
 #include "nsIPersistentProperties2.h"
+#include "nsISimpleEnumerator.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 const uint32_t USE_ROLE_STRING = 0;
 
 /* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -373,16 +373,18 @@
 @BINPATH@/components/passwordmgr.manifest
 @BINPATH@/components/nsLoginInfo.js
 @BINPATH@/components/nsLoginManager.js
 @BINPATH@/components/nsLoginManagerPrompter.js
 #ifdef MOZ_WEBRTC
 @BINPATH@/components/PeerConnection.js
 @BINPATH@/components/PeerConnection.manifest
 #endif
+@BINPATH@/components/HttpDataUsage.manifest
+@BINPATH@/components/HttpDataUsage.js
 @BINPATH@/components/SiteSpecificUserAgent.js
 @BINPATH@/components/SiteSpecificUserAgent.manifest
 @BINPATH@/components/storage-Legacy.js
 @BINPATH@/components/storage-mozStorage.js
 @BINPATH@/components/crypto-SDR.js
 @BINPATH@/components/jsconsole-clhandler.manifest
 @BINPATH@/components/jsconsole-clhandler.js
 @BINPATH@/components/nsHelperAppDlg.manifest
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -539,16 +539,19 @@
 @BINPATH@/components/AppProtocolHandler.js
 @BINPATH@/components/AppProtocolHandler.manifest
 
 #ifdef MOZ_WEBRTC
 @BINPATH@/components/PeerConnection.js
 @BINPATH@/components/PeerConnection.manifest
 #endif
 
+@BINPATH@/components/HttpDataUsage.manifest
+@BINPATH@/components/HttpDataUsage.js
+
 @BINPATH@/chrome/marionette@JAREXT@
 @BINPATH@/chrome/marionette.manifest
 @BINPATH@/components/MarionetteComponents.manifest
 @BINPATH@/components/marionettecomponent.js
 
 #ifdef MOZ_WEBSPEECH
 @BINPATH@/components/dom_webspeechsynth.xpt
 #endif
--- a/chrome/src/RegistryMessageUtils.h
+++ b/chrome/src/RegistryMessageUtils.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 mozilla_RegistryMessageUtils_h
 #define mozilla_RegistryMessageUtils_h
 
 #include "ipc/IPCMessageUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 struct SerializedURI
 {
   nsCString spec;
   nsCString charset;
 };
 
 struct ChromePackage
--- a/chrome/src/nsChromeProtocolHandler.cpp
+++ b/chrome/src/nsChromeProtocolHandler.cpp
@@ -5,42 +5,30 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
 
   A protocol handler for ``chrome:''
 
 */
 
-#include "nsAutoPtr.h"
 #include "nsChromeProtocolHandler.h"
 #include "nsChromeRegistry.h"
 #include "nsCOMPtr.h"
-#include "nsContentCID.h"
-#include "nsCRT.h"
 #include "nsThreadUtils.h"
 #include "nsIChannel.h"
 #include "nsIChromeRegistry.h"
-#include "nsIComponentManager.h"
 #include "nsIFile.h"
-#include "nsIFileURL.h"
 #include "nsIFileChannel.h"
 #include "nsIIOService.h"
-#include "nsIJARChannel.h"
-#include "nsIJARURI.h"
 #include "nsILoadGroup.h"
-#include "nsIObjectOutputStream.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsIServiceManager.h"
 #include "nsIStandardURL.h"
-#include "nsIStreamListener.h"
 #include "nsNetUtil.h"
-#include "nsXPIDLString.h"
 #include "nsString.h"
-#include "prlog.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS2(nsChromeProtocolHandler,
                    nsIProtocolHandler,
                    nsISupportsWeakReference)
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -3,43 +3,33 @@
 /* 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 "nsChromeRegistry.h"
 #include "nsChromeRegistryChrome.h"
 #include "nsChromeRegistryContent.h"
 
-#include <string.h>
-
-#include "prio.h"
 #include "prprf.h"
 
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsEscape.h"
-#include "nsLayoutCID.h"
 #include "nsNetUtil.h"
 #include "nsString.h"
-#include "nsUnicharUtils.h"
 
 #include "nsCSSStyleSheet.h"
 #include "nsIConsoleService.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
-#include "nsIDocShell.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMLocation.h"
 #include "nsIDOMWindowCollection.h"
 #include "nsIDOMWindow.h"
-#include "nsIIOService.h"
-#include "nsIJARProtocolHandler.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
-#include "nsIProtocolHandler.h"
 #include "nsIScriptError.h"
 #include "nsIWindowMediator.h"
 
 nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 void
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -1,41 +1,34 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsChromeRegistry_h
 #define nsChromeRegistry_h
 
-#include "nsIChromeRegistry.h"
 #include "nsIToolkitChromeRegistry.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
-#include "nsIPrefBranch.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULOverlayProvider.h"
 #endif
 
-#include "pldhash.h"
-
-#include "nsCOMArray.h"
 #include "nsString.h"
-#include "nsTHashtable.h"
 #include "nsURIHashKey.h"
 #include "nsInterfaceHashtable.h"
 #include "nsXULAppAPI.h"
-#include "nsIResProtocolHandler.h"
 #include "nsIXPConnect.h"
 
-#include "mozilla/Omnijar.h"
 #include "mozilla/FileLocation.h"
 
 class nsIDOMWindow;
+class nsIPrefBranch;
 class nsIURL;
 
 // The chrome registry is actually split between nsChromeRegistryChrome and
 // nsChromeRegistryContent. The work/data that is common to both resides in
 // the shared nsChromeRegistry implementation, with operations that only make
 // sense for one side erroring out in the other.
 
 // for component registration
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -8,45 +8,37 @@
 #include "nsResProtocolHandler.h"
 
 #include "nsChromeRegistryChrome.h"
 
 #if defined(XP_WIN)
 #include <windows.h>
 #elif defined(XP_MACOSX)
 #include <CoreServices/CoreServices.h>
-#elif defined(MOZ_WIDGET_GTK)
-#include <gtk/gtk.h>
 #endif
 
 #include "nsArrayEnumerator.h"
-#include "nsAppDirectoryServiceDefs.h"
 #include "nsComponentManager.h"
 #include "nsEnumeratorUtils.h"
 #include "nsNetUtil.h"
 #include "nsStringEnumerator.h"
 #include "nsTextFormatter.h"
-#include "nsUnicharUtils.h"
 #include "nsXPCOMCIDInternal.h"
-#include "nsZipArchive.h"
 
 #include "mozilla/LookAndFeel.h"
 
 #include "nsICommandLine.h"
 #include "nsILocaleService.h"
-#include "nsIFile.h"
 #include "nsIObserverService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "mozilla/Preferences.h"
 #include "nsIResProtocolHandler.h"
 #include "nsIScriptError.h"
-#include "nsIVersionComparator.h"
 #include "nsIXPConnect.h"
-#include "nsIXULAppInfo.h"
 #include "nsIXULRuntime.h"
 
 #define UILOCALE_CMD_LINE_ARG "UILocale"
 
 #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
 #define SELECTED_LOCALE_PREF "general.useragent.locale"
 #define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
 #define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
--- a/chrome/src/nsChromeRegistryChrome.h
+++ b/chrome/src/nsChromeRegistryChrome.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsChromeRegistryChrome_h
 #define nsChromeRegistryChrome_h
 
+#include "nsCOMArray.h"
 #include "nsChromeRegistry.h"
 #include "nsVoidArray.h"
 #include "mozilla/Move.h"
 
 namespace mozilla {
 namespace dom {
 class PContentParent;
 }
--- a/chrome/src/nsChromeRegistryContent.cpp
+++ b/chrome/src/nsChromeRegistryContent.cpp
@@ -1,19 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RegistryMessageUtils.h"
-#include "nsChromeRegistry.h"
 #include "nsChromeRegistryContent.h"
 #include "nsString.h"
 #include "nsNetUtil.h"
-#include "nsResProtocolHandler.h"
+#include "nsIResProtocolHandler.h"
 
 nsChromeRegistryContent::nsChromeRegistryContent()
 {
 }
 
 void
 nsChromeRegistryContent::RegisterRemoteChrome(
     const InfallibleTArray<ChromePackage>& aPackages,
--- a/chrome/src/nsChromeRegistryContent.h
+++ b/chrome/src/nsChromeRegistryContent.h
@@ -2,20 +2,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsChromeRegistryContent_h
 #define nsChromeRegistryContent_h
 
 #include "nsChromeRegistry.h"
-#include "nsTArray.h"
 #include "nsClassHashtable.h"
 
-class nsCString;
 struct ChromePackage;
 struct ResourceMapping;
 struct OverrideMapping;
 
 class nsChromeRegistryContent : public nsChromeRegistry
 {
  public:
   nsChromeRegistryContent();
--- a/content/base/src/DOMImplementation.h
+++ b/content/base/src/DOMImplementation.h
@@ -11,17 +11,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocument.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIURI.h"
 #include "nsIWeakReferenceUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 class nsIDOMDocument;
 
 namespace mozilla {
 namespace dom {
 class DocumentType;
 
 class DOMImplementation MOZ_FINAL : public nsIDOMDOMImplementation
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -7,17 +7,17 @@
  * A struct that represents the value (type and actual data) of an
  * attribute.
  */
 
 #ifndef nsAttrValue_h___
 #define nsAttrValue_h___
 
 #include "nscore.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsStringBuffer.h"
 #include "nsColor.h"
 #include "nsCaseTreatment.h"
 #include "nsMargin.h"
 #include "nsCOMPtr.h"
 #include "SVGAttrValueWrapper.h"
 #include "nsTArrayForwardDeclare.h"
 #include "nsIAtom.h"
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -11,17 +11,17 @@
 
 #ifndef nsContentList_h___
 #define nsContentList_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContentListDeclarations.h"
 #include "nsISupports.h"
 #include "nsTArray.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsIHTMLCollection.h"
 #include "nsIDOMNodeList.h"
 #include "nsINodeList.h"
 #include "nsStubMutationObserver.h"
 #include "nsIAtom.h"
 #include "nsINameSpaceManager.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.cpp
@@ -34,16 +34,17 @@
 #include "nsIDOMNode.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIHTMLDocument.h"
 #include "nsGkAtoms.h"
 #include "nsGUIEvent.h"
 #include "nsIFrame.h"
 #include "nsIURI.h"
+#include "nsISimpleEnumerator.h"
 
 // image copy stuff
 #include "nsIImageLoadingContent.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsContentUtils.h"
 #include "nsContentCID.h"
 
 #include "mozilla/dom/Element.h"
--- a/content/base/src/nsDOMAttributeMap.h
+++ b/content/base/src/nsDOMAttributeMap.h
@@ -11,17 +11,17 @@
 #define nsDOMAttributeMap_h
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Attr.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMMozNamedAttrMap.h"
 #include "nsRefPtrHashtable.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsWrapperCache.h"
 
 class nsIAtom;
 class nsINodeInfo;
 class nsIDocument;
 
 /**
  * Structure used as a key for caching Attrs in nsDOMAttributeMap's mAttributeCache.
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -15,16 +15,17 @@
 #include "nsComponentManagerUtils.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsFrameLoader.h"
 #include "xpcpublic.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsDOMClassInfoID.h"
 #include "mozilla/dom/StructuredCloneUtils.h"
+#include "js/StructuredClone.h"
 
 using mozilla::dom::StructuredCloneData;
 using mozilla::dom::StructuredCloneClosure;
 
 bool
 nsInProcessTabChildGlobal::DoSendSyncMessage(JSContext* aCx,
                                              const nsAString& aMessage,
                                              const mozilla::dom::StructuredCloneData& aData,
--- a/content/media/webspeech/synth/pico/nsPicoService.cpp
+++ b/content/media/webspeech/synth/pico/nsPicoService.cpp
@@ -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/. */
 
 #include "nsISupports.h"
 #include "nsPicoService.h"
 #include "nsPrintfCString.h"
 #include "nsIWeakReferenceUtils.h"
 #include "SharedBuffer.h"
+#include "nsISimpleEnumerator.h"
 
 #include "mozilla/dom/nsSynthVoiceRegistry.h"
 #include "mozilla/dom/nsSpeechTask.h"
 
 #include "nsIFile.h"
 #include "nsThreadUtils.h"
 #include "prenv.h"
 
--- a/content/svg/content/src/SVGAttrValueWrapper.h
+++ b/content/svg/content/src/SVGAttrValueWrapper.h
@@ -7,17 +7,17 @@
 #ifndef MOZILLA_SVGATTRVALUEWRAPPER_H__
 #define MOZILLA_SVGATTRVALUEWRAPPER_H__
 
 /**
  * Utility wrapper for handling SVG types used inside nsAttrValue so that these
  * types don't need to be exported outside the SVG module.
  */
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 class nsSVGAngle;
 class nsSVGIntegerPair;
 class nsSVGLength2;
 class nsSVGNumberPair;
 class nsSVGViewBox;
 
 namespace mozilla {
--- a/content/svg/content/src/nsSVGDataParser.h
+++ b/content/svg/content/src/nsSVGDataParser.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 __NS_SVGDATAPARSER_H__
 #define __NS_SVGDATAPARSER_H__
 
 #include "nsError.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 //----------------------------------------------------------------------
 // helper macros
 #define ENSURE_MATCHED(exp) { nsresult rv = exp; if (NS_FAILED(rv)) return rv; }
 
 ////////////////////////////////////////////////////////////////////////
 // nsSVGDataParser: a simple abstract class for parsing values
 // for path and transform values.
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -29,17 +29,17 @@
 #include "nsIInterfaceInfoManager.h"
 #include "nsIDocumentObserver.h"
 #include "nsGkAtoms.h"
 #include "nsXBLProtoImpl.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsTextFragment.h"
 #include "nsTextNode.h"
-
+#include "nsIInterfaceInfo.h"
 #include "nsIScriptError.h"
 
 #include "nsIStyleRuleProcessor.h"
 #include "nsXBLResourceLoader.h"
 #include "mozilla/dom/CDATASection.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/Element.h"
 
--- a/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
+++ b/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
@@ -13,16 +13,17 @@
 #include "txIFunctionEvaluationContext.h"
 #include "txIXPathContext.h"
 #include "txNodeSetAdaptor.h"
 #include "txXPathTreeWalker.h"
 #include "xptcall.h"
 #include "txXPathObjectAdaptor.h"
 #include "mozilla/Attributes.h"
 #include "nsIClassInfo.h"
+#include "nsIInterfaceInfo.h"
 
 NS_IMPL_ISUPPORTS1(txXPathObjectAdaptor, txIXPathObject)
 
 class txFunctionEvaluationContext MOZ_FINAL : public txIFunctionEvaluationContext
 {
 public:
     txFunctionEvaluationContext(txIEvalContext *aContext, nsISupports *aState);
 
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -17,16 +17,17 @@
 
 #include "nsIURIFixup.h"
 #include "nsDefaultURIFixup.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "nsIObserverService.h"
+#include "nsXULAppAPI.h"
 
 using namespace mozilla;
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS1(nsDefaultURIFixup, nsIURIFixup)
 
 nsDefaultURIFixup::nsDefaultURIFixup()
 {
--- a/dom/base/Crypto.cpp
+++ b/dom/base/Crypto.cpp
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "Crypto.h"
 #include "jsfriendapi.h"
 #include "nsCOMPtr.h"
 #include "nsIRandomGenerator.h"
 #include "nsPIDOMWindow.h"
+#include "MainThreadUtils.h"
+#include "nsXULAppAPI.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/CryptoBinding.h"
 
 using mozilla::dom::ContentChild;
 
 using namespace js::ArrayBufferView;
 
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/Util.h"
 #include "mozilla/dom/Exceptions.h"
 #include "nsContentUtils.h"
 #include "nsCOMPtr.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIDocument.h"
 #include "nsIDOMDOMException.h"
 #include "nsIException.h"
+#include "nsIProgrammingLanguage.h"
 #include "nsMemory.h"
 #include "prprf.h"
 #include "xpcprivate.h"
 
 #include "mozilla/dom/DOMExceptionBinding.h"
 
 using namespace mozilla;
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -36,16 +36,17 @@
 #include "nsIPrincipal.h"
 #include "nsIObserverService.h"
 #include "nsIObjectFrame.h"
 #include "nsBindingManager.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
 #include <algorithm>
 
 #ifdef MOZ_XUL
 #include "nsIDOMXULTextboxElement.h"
 #include "nsIDOMXULMenuListElement.h"
 #endif
 
 #ifdef ACCESSIBILITY
--- a/dom/base/nsIDOMScriptObjectFactory.h
+++ b/dom/base/nsIDOMScriptObjectFactory.h
@@ -3,17 +3,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 nsIDOMScriptObjectFactory_h__
 #define nsIDOMScriptObjectFactory_h__
 
 #include "nsISupports.h"
 #include "nsIDOMClassInfo.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #define NS_IDOM_SCRIPT_OBJECT_FACTORY_IID \
 { 0x2a50e17c, 0x46ff, 0x4150, \
   { 0xbb, 0x46, 0xd8, 0x07, 0xb3, 0x36, 0xde, 0xab } }
 
 class nsIScriptContext;
 class nsIScriptGlobalObject;
 class nsIDOMEventListener;
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.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 nsIScriptContext_h__
 #define nsIScriptContext_h__
 
 #include "nscore.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsISupports.h"
 #include "nsCOMPtr.h"
 #include "nsIProgrammingLanguage.h"
 #include "jspubtd.h"
 #include "js/GCAPI.h"
 
 class nsIScriptGlobalObject;
 class nsIScriptSecurityManager;
--- a/dom/base/nsScriptNameSpaceManager.cpp
+++ b/dom/base/nsScriptNameSpaceManager.cpp
@@ -21,16 +21,17 @@
 #include "xptinfo.h"
 #include "nsXPIDLString.h"
 #include "nsPrintfCString.h"
 #include "nsReadableUtils.h"
 #include "nsHashKeys.h"
 #include "nsDOMClassInfo.h"
 #include "nsCRT.h"
 #include "nsIObserverService.h"
+#include "nsISimpleEnumerator.h"
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 
 #define NS_INTERFACE_PREFIX "nsI"
 #define NS_DOM_INTERFACE_PREFIX "nsIDOM"
 
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -6,17 +6,17 @@
 #ifndef mozilla_dom_DOMJSProxyHandler_h
 #define mozilla_dom_DOMJSProxyHandler_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Likely.h"
 
 #include "jsapi.h"
 #include "jsproxy.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #define DOM_PROXY_OBJECT_SLOT js::PROXY_PRIVATE_SLOT
 
 namespace mozilla {
 namespace dom {
 
 class DOMClass;
 
--- a/dom/bluetooth/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/BluetoothA2dpManager.cpp
@@ -14,16 +14,17 @@
 #include "BluetoothSocket.h"
 #include "BluetoothUtils.h"
 
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIAudioManager.h"
 #include "nsIObserverService.h"
+#include "MainThreadUtils.h"
 
 
 using namespace mozilla;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
   StaticRefPtr<BluetoothA2dpManager> sBluetoothA2dpManager;
   bool sInShutdown = false;
--- a/dom/bluetooth/BluetoothCommon.h
+++ b/dom/bluetooth/BluetoothCommon.h
@@ -4,17 +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 mozilla_dom_bluetooth_bluetoothcommon_h__
 #define mozilla_dom_bluetooth_bluetoothcommon_h__
 
 #include "mozilla/Observer.h"
 #include "nsPrintfCString.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 extern bool gBluetoothDebugFlag;
 
 #define SWITCH_BT_DEBUG(V) (gBluetoothDebugFlag = V)
 
 #undef BT_LOG
 #if defined(MOZ_WIDGET_GONK)
--- a/dom/bluetooth/BluetoothHidManager.cpp
+++ b/dom/bluetooth/BluetoothHidManager.cpp
@@ -12,16 +12,17 @@
 #include "BluetoothService.h"
 #include "BluetoothProfileController.h"
 #include "BluetoothUtils.h"
 
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIObserverService.h"
+#include "MainThreadUtils.h"
 
 using namespace mozilla;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
   StaticRefPtr<BluetoothHidManager> sBluetoothHidManager;
   bool sInShutdown = false;
 } // anonymous namespace
--- a/dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
+++ b/dom/bluetooth/ipc/BluetoothServiceChildProcess.cpp
@@ -7,16 +7,17 @@
 #include "base/basictypes.h"
 
 #include "BluetoothServiceChildProcess.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/ContentChild.h"
 
 #include "BluetoothChild.h"
+#include "MainThreadUtils.h"
 
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
 
 BluetoothChild* gBluetoothChild;
 
 inline
--- a/dom/devicestorage/DeviceStorageRequestParent.cpp
+++ b/dom/devicestorage/DeviceStorageRequestParent.cpp
@@ -8,16 +8,17 @@
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
 #include "mozilla/unused.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "ContentParent.h"
 #include "nsProxyRelease.h"
 #include "AppProcessChecker.h"
 #include "mozilla/Preferences.h"
+#include "nsNetCID.h"
 
 namespace mozilla {
 namespace dom {
 namespace devicestorage {
 
 DeviceStorageRequestParent::DeviceStorageRequestParent(
   const DeviceStorageParams& aParams)
   : mParams(aParams)
--- a/dom/file/FileCommon.h
+++ b/dom/file/FileCommon.h
@@ -7,17 +7,17 @@
 #ifndef mozilla_dom_file_filecommon_h__
 #define mozilla_dom_file_filecommon_h__
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsDebug.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 #define BEGIN_FILE_NAMESPACE \
   namespace mozilla { namespace dom { namespace file {
 #define END_FILE_NAMESPACE \
   } /* namespace file */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_FILE_NAMESPACE \
   using namespace mozilla::dom::file;
--- a/dom/indexedDB/Client.cpp
+++ b/dom/indexedDB/Client.cpp
@@ -8,16 +8,17 @@
 
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/dom/quota/UsageInfo.h"
 #include "mozilla/dom/quota/Utilities.h"
 
 #include "IDBDatabase.h"
 #include "IndexedDatabaseManager.h"
 #include "TransactionThreadPool.h"
+#include "nsISimpleEnumerator.h"
 
 USING_INDEXEDDB_NAMESPACE
 using mozilla::dom::quota::AssertIsOnIOThread;
 using mozilla::dom::quota::QuotaManager;
 
 namespace {
 
 bool
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -39,16 +39,17 @@
 #include "CheckPermissionsHelper.h"
 #include "DatabaseInfo.h"
 #include "IDBDatabase.h"
 #include "IDBEvents.h"
 #include "IDBKeyRange.h"
 #include "IndexedDatabaseManager.h"
 #include "Key.h"
 #include "ProfilerHelpers.h"
+#include "nsNetUtil.h"
 
 #include "ipc/IndexedDBChild.h"
 
 #define PREF_INDEXEDDB_ENABLED "dom.indexedDB.enabled"
 
 USING_INDEXEDDB_NAMESPACE
 USING_QUOTA_NAMESPACE
 
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -13,17 +13,17 @@
 #include "nsComponentManagerUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsEventDispatcher.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsWrapperCacheInlines.h"
 
 #include "AsyncConnectionHelper.h"
 #include "IDBCursor.h"
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IDBIndex.h"
--- a/dom/indexedDB/IndexedDatabase.h
+++ b/dom/indexedDB/IndexedDatabase.h
@@ -10,17 +10,17 @@
 #include "nsIProgrammingLanguage.h"
 
 #include "mozilla/Attributes.h"
 #include "js/StructuredClone.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsError.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "nsIInputStream.h"
 
 #define BEGIN_INDEXEDDB_NAMESPACE \
   namespace mozilla { namespace dom { namespace indexedDB {
 
 #define END_INDEXEDDB_NAMESPACE \
   } /* namespace indexedDB */ } /* namepsace dom */ } /* namespace mozilla */
--- a/dom/ipc/AppProcessChecker.cpp
+++ b/dom/ipc/AppProcessChecker.cpp
@@ -1,25 +1,27 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=8 et :
  */
 /* 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 "AppProcessChecker.h"
+#ifdef MOZ_CHILD_PERMISSIONS
 #include "ContentParent.h"
 #include "mozIApplication.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "nsIDOMApplicationRegistry.h"
 #include "TabParent.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::services;
+#endif
 
 namespace mozilla {
 
 #ifdef MOZ_CHILD_PERMISSIONS
 
 bool
 AssertAppProcess(PBrowserParent* aActor,
                  AssertAppProcessType aType,
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -23,16 +23,17 @@
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "nsDOMFile.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 #include "jsapi.h"
 
 #include "ContentChild.h"
 #include "ContentParent.h"
+#include "nsNetCID.h"
 
 #define PRIVATE_REMOTE_INPUT_STREAM_IID \
   {0x30c7699f, 0x51d2, 0x48c8, {0xad, 0x56, 0xc0, 0x16, 0xd7, 0x6f, 0x71, 0x27}}
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::ipc;
 
--- a/dom/ipc/Blob.h
+++ b/dom/ipc/Blob.h
@@ -7,26 +7,23 @@
 #ifndef mozilla_dom_ipc_Blob_h
 #define mozilla_dom_ipc_Blob_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/PBlobChild.h"
 #include "mozilla/dom/PBlobParent.h"
 #include "mozilla/dom/PBlobStreamChild.h"
 #include "mozilla/dom/PBlobStreamParent.h"
-#include "mozilla/dom/PContent.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
-#include "nsThreadUtils.h"
 
 class nsIDOMBlob;
-class nsIIPCSerializableInputStream;
-class nsIInputStream;
+template<class T> class nsRevocableEventPtr;
 
 namespace mozilla {
 namespace dom {
 
 class ContentParent;
 class ContentChild;
 
 namespace ipc {
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -15,68 +15,64 @@
 #include "ContentChild.h"
 #include "CrashReporterChild.h"
 #include "TabChild.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/ExternalHelperAppChild.h"
 #include "mozilla/dom/PCrashReporterChild.h"
 #include "mozilla/dom/DOMStorageIPC.h"
-#include "mozilla/Hal.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/TestShellChild.h"
-#include "mozilla/ipc/XPCShellEnvironment.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/PCompositorChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/Preferences.h"
 #ifdef MOZ_CONTENT_SANDBOX
 #include "mozilla/Sandbox.h"
 #endif
 #include "mozilla/unused.h"
 
+#include "nsIConsoleListener.h"
+#include "nsIInterfaceRequestorUtils.h"
 #include "nsIMemoryReporter.h"
 #include "nsIMemoryInfoDumper.h"
 #include "nsIMutable.h"
 #include "nsIObserverService.h"
-#include "nsTObserverArray.h"
 #include "nsIObserver.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
 #include "nsXULAppAPI.h"
-#include "nsWeakReference.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsJSEnvironment.h"
 #include "SandboxHal.h"
 #include "nsDebugImpl.h"
 #include "nsHashPropertyBag.h"
 #include "nsLayoutStylesheetCache.h"
 #include "nsIJSRuntimeService.h"
 
 #include "IHistory.h"
-#include "nsDocShellCID.h"
 #include "nsNetUtil.h"
 
 #include "base/message_loop.h"
 #include "base/process_util.h"
 #include "base/task.h"
 
 #include "nsChromeRegistryContent.h"
-#include "mozilla/chrome/RegistryMessageUtils.h"
 #include "nsFrameMessageManager.h"
 
 #include "nsIGeolocationProvider.h"
-#include "JavaScriptParent.h"
 #include "mozilla/dom/PMemoryReportRequestChild.h"
 
 #ifdef MOZ_PERMISSIONS
+#include "nsIScriptSecurityManager.h"
 #include "nsPermission.h"
 #include "nsPermissionManager.h"
 #endif
 
 #if defined(MOZ_WIDGET_ANDROID)
 #include "APKOpen.h"
 #endif
 
@@ -91,38 +87,36 @@
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #endif
 
 #include "mozilla/dom/indexedDB/PIndexedDBChild.h"
 #include "mozilla/dom/mobilemessage/SmsChild.h"
-#include "mozilla/dom/telephony/TelephonyChild.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
 #include "mozilla/dom/bluetooth/PBluetoothChild.h"
 #include "mozilla/dom/PFMRadioChild.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/PSpeechSynthesisChild.h"
 #endif
 
 #include "nsDOMFile.h"
 #include "nsIRemoteBlob.h"
 #include "ProcessUtils.h"
 #include "StructuredCloneUtils.h"
 #include "URIUtils.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsIPrincipal.h"
 #include "nsDeviceStorage.h"
 #include "AudioChannelService.h"
 #include "JavaScriptChild.h"
-#include "ProcessPriorityManager.h"
+#include "mozilla/dom/telephony/PTelephonyChild.h"
 
 using namespace base;
 using namespace mozilla;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::dom::mobilemessage;
@@ -504,24 +498,24 @@ ContentChild::RecvDumpGCAndCCLogsToFile(
 {
     nsCOMPtr<nsIMemoryInfoDumper> dumper = do_GetService("@mozilla.org/memory-info-dumper;1");
 
     dumper->DumpGCAndCCLogsToFile(aIdentifier, aDumpAllTraces,
                                   aDumpChildProcesses);
     return true;
 }
 
-PCompositorChild*
+bool
 ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
                                     base::ProcessId aOtherProcess)
 {
     return CompositorChild::Create(aTransport, aOtherProcess);
 }
 
-PImageBridgeChild*
+bool
 ContentChild::AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
                                      base::ProcessId aOtherProcess)
 {
     return ImageBridgeChild::StartUpInChildProcess(aTransport, aOtherProcess);
 }
 
 bool
 ContentChild::RecvSetProcessPrivileges(const ChildPrivileges& aPrivs)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -4,21 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_ContentChild_h
 #define mozilla_dom_ContentChild_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/PContentChild.h"
-#include "mozilla/dom/TabContext.h"
 #include "mozilla/dom/ipc/Blob.h"
-
-#include "nsTArray.h"
-#include "nsIConsoleListener.h"
+#include "nsWeakPtr.h"
 
 struct ChromePackage;
 class nsIDOMBlob;
 class nsIObserver;
 struct ResourceMapping;
 struct OverrideMapping;
 
 namespace mozilla {
@@ -75,20 +72,20 @@ public:
 
     const AppInfo& GetAppInfo() {
         return mAppInfo;
     }
 
     void SetProcessName(const nsAString& aName);
     const void GetProcessName(nsAString& aName);
 
-    PCompositorChild*
+    bool
     AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
                           base::ProcessId aOtherProcess) MOZ_OVERRIDE;
-    PImageBridgeChild*
+    bool
     AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
                            base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual bool RecvSetProcessPrivileges(const ChildPrivileges& aPrivs);
 
     virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext &aContext,
                                               const uint32_t &chromeFlags);
     virtual bool DeallocPBrowserChild(PBrowserChild*);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -32,87 +32,80 @@
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/dom/bluetooth/PBluetoothParent.h"
 #include "mozilla/dom/PFMRadioParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "mozilla/dom/GeolocationBinding.h"
 #include "mozilla/dom/telephony/TelephonyParent.h"
 #include "SmsParent.h"
-#include "mozilla/Hal.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsAppDirectoryServiceDefs.h"
 #include "nsAppRunner.h"
 #include "nsAutoPtr.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsCExternalHandlerService.h"
 #include "nsCOMPtr.h"
 #include "nsChromeRegistryChrome.h"
 #include "nsConsoleMessage.h"
 #include "nsConsoleService.h"
 #include "nsDebugImpl.h"
-#include "nsDirectoryServiceDefs.h"
 #include "nsDOMFile.h"
-#include "nsExternalHelperAppService.h"
 #include "nsFrameMessageManager.h"
 #include "nsHashPropertyBag.h"
 #include "nsIAlertsService.h"
 #include "nsIAppsService.h"
 #include "nsIClipboard.h"
 #include "nsIDOMApplicationRegistry.h"
 #include "nsIDOMGeoGeolocation.h"
 #include "nsIDOMWakeLock.h"
 #include "nsIDOMWindow.h"
+#include "nsIExternalProtocolService.h"
 #include "nsIFilePicker.h"
 #include "nsIMemoryReporter.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsIMutable.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIRemoteBlob.h"
 #include "nsIScriptError.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsIStyleSheet.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIURIFixup.h"
 #include "nsIWindowWatcher.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
-#include "nsSystemInfo.h"
 #include "nsThreadUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
 #include "PreallocatedProcessManager.h"
 #include "ProcessPriorityManager.h"
 #include "SandboxHal.h"
 #include "StructuredCloneUtils.h"
 #include "TabParent.h"
 #include "URIUtils.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIDocShell.h"
 
+#if defined(ANDROID) || defined(LINUX)
+#include "nsSystemInfo.h"
+#endif
+
 #ifdef ANDROID
 # include "gfxAndroidPlatform.h"
 #endif
 
-#ifdef MOZ_CRASHREPORTER
-# include "nsExceptionHandler.h"
-# include "nsICrashReporter.h"
-#endif
-
 #ifdef MOZ_PERMISSIONS
 # include "nsPermissionManager.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 # include "AndroidBridge.h"
 #endif
 
@@ -1777,24 +1770,24 @@ ContentParent::Observe(nsISupports* aSub
              !strcmp(aTopic, "a11y-init-or-shutdown")) {
         unused << SendActivateA11y();
     }
 #endif
 
     return NS_OK;
 }
 
-PCompositorParent*
+bool
 ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
                                       base::ProcessId aOtherProcess)
 {
     return CompositorParent::Create(aTransport, aOtherProcess);
 }
 
-PImageBridgeParent*
+bool
 ContentParent::AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
                                        base::ProcessId aOtherProcess)
 {
     return ImageBridgeParent::Create(aTransport, aOtherProcess);
 }
 
 bool
 ContentParent::RecvGetProcessAttributes(uint64_t* aId,
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -2,45 +2,37 @@
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_ContentParent_h
 #define mozilla_dom_ContentParent_h
 
-#include "base/waitable_event_watcher.h"
-
 #include "mozilla/dom/PContentParent.h"
-#include "mozilla/dom/PMemoryReportRequestParent.h"
-#include "mozilla/dom/TabContext.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/HalTypes.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/StaticPtr.h"
 
 #include "nsFrameMessageManager.h"
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
-#include "nsNetUtil.h"
-#include "nsIPermissionManager.h"
 #include "nsIDOMGeoPositionCallback.h"
-#include "nsCOMArray.h"
-#include "nsDataHashtable.h"
-#include "nsHashKeys.h"
 #include "PermissionMessageUtils.h"
 
 #define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
 
 class mozIApplication;
 class nsConsoleService;
 class nsIDOMBlob;
 class nsIMemoryReporter;
+template<class KeyClass,class DataType> class nsDataHashtable;
 
 namespace mozilla {
 
 namespace ipc {
 class OptionalURIParams;
 class URIParams;
 class TestShellParent;
 } // namespace ipc
@@ -54,16 +46,18 @@ class PCompositorParent;
 } // namespace layers
 
 namespace dom {
 
 class Element;
 class TabParent;
 class PStorageParent;
 class ClonedMessageData;
+class MemoryReport;
+class TabContext;
 
 class ContentParent : public PContentParent
                     , public nsIObserver
                     , public nsIThreadObserver
                     , public nsIDOMGeoPositionCallback
                     , public mozilla::dom::ipc::MessageManagerCallback
                     , public mozilla::LinkedListElement<ContentParent>
 {
@@ -251,20 +245,20 @@ private:
      *
      * If aCloseWithError is true and this is the first call to
      * ShutDownProcess, then we'll close our channel using CloseWithError()
      * rather than vanilla Close().  CloseWithError() indicates to IPC that this
      * is an abnormal shutdown (e.g. a crash).
      */
     void ShutDownProcess(bool aCloseWithError);
 
-    PCompositorParent*
+    bool
     AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
                            base::ProcessId aOtherProcess) MOZ_OVERRIDE;
-    PImageBridgeParent*
+    bool
     AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
                             base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual bool RecvGetProcessAttributes(uint64_t* aId,
                                           bool* aIsForApp,
                                           bool* aIsForBrowser) MOZ_OVERRIDE;
     virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline) MOZ_OVERRIDE;
 
--- a/dom/ipc/CrashReporterChild.h
+++ b/dom/ipc/CrashReporterChild.h
@@ -3,20 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CrashReporterChild_h
 #define mozilla_dom_CrashReporterChild_h
 
 #include "mozilla/dom/PCrashReporterChild.h"
-#ifdef MOZ_CRASHREPORTER
-#include "nsExceptionHandler.h"
-#include "nsXULAppAPI.h"
-#endif
 
 namespace mozilla {
 namespace dom {
 class CrashReporterChild :
     public PCrashReporterChild
 {
  public:
     CrashReporterChild() {
--- a/dom/ipc/CrashReporterParent.cpp
+++ b/dom/ipc/CrashReporterParent.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set sw=4 ts=8 et 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 "CrashReporterParent.h"
-
-#include "base/process_util.h"
+#include "nsXULAppAPI.h"
 
 #include <time.h>
 
 using namespace base;
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/ipc/CrashReporterParent.h
+++ b/dom/ipc/CrashReporterParent.h
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set sw=4 ts=8 et 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 "mozilla/dom/PCrashReporterParent.h"
 #include "mozilla/dom/TabMessageUtils.h"
-#include "nsXULAppAPI.h"
 #include "nsIFile.h"
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #include "nsDataHashtable.h"
 #endif
 
 namespace mozilla {
 namespace dom {
--- a/dom/ipc/PreallocatedProcessManager.cpp
+++ b/dom/ipc/PreallocatedProcessManager.cpp
@@ -3,16 +3,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/. */
 
 #include "mozilla/PreallocatedProcessManager.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ContentParent.h"
+#include "nsIPropertyBag2.h"
 
 using namespace mozilla;
 using namespace mozilla::hal;
 using namespace mozilla::dom;
 
 namespace {
 
 /**
--- a/dom/ipc/PreallocatedProcessManager.h
+++ b/dom/ipc/PreallocatedProcessManager.h
@@ -3,20 +3,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_PreallocatedProcessManager_h
 #define mozilla_PreallocatedProcessManager_h
 
 #include "base/basictypes.h"
-#include "mozilla/StaticPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIObserver.h"
-#include "nsAutoPtr.h"
 
 namespace mozilla {
 namespace dom {
 class ContentParent;
 }
 
 /**
  * This class manages a ContentParent that it starts up ahead of any particular
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -11,35 +11,24 @@
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/Hal.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "AudioChannelService.h"
 #include "prlog.h"
 #include "nsPrintfCString.h"
-#include "nsWeakPtr.h"
 #include "nsXULAppAPI.h"
 #include "nsIFrameLoader.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsITimer.h"
-#include "nsIObserver.h"
 #include "nsIObserverService.h"
-#include "nsIDocument.h"
-#include "nsIDOMEventListener.h"
-#include "nsIDOMWindow.h"
-#include "nsIDOMEvent.h"
-#include "nsIDOMDocument.h"
-#include "nsPIDOMWindow.h"
 #include "StaticPtr.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
-#include "nsPrintfCString.h"
-#include "prlog.h"
+#include "nsIPropertyBag2.h"
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #else
 #include <unistd.h>
 #endif
 
--- a/dom/ipc/ProcessPriorityManager.h
+++ b/dom/ipc/ProcessPriorityManager.h
@@ -3,19 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ProcessPriorityManager_h_
 #define mozilla_ProcessPriorityManager_h_
 
 #include "mozilla/HalTypes.h"
-#include "mozilla/StaticPtr.h"
-#include "nsIObserver.h"
-#include "nsDataHashtable.h"
 
 namespace mozilla {
 namespace dom {
 class ContentParent;
 }
 
 /**
  * This class sets the priority of subprocesses in response to explicit
--- a/dom/ipc/StructuredCloneUtils.cpp
+++ b/dom/ipc/StructuredCloneUtils.cpp
@@ -8,17 +8,17 @@
 
 #include "nsIDOMFile.h"
 #include "nsIDOMDOMException.h"
 #include "nsIMutable.h"
 #include "nsIXPConnect.h"
 
 #include "nsContentUtils.h"
 #include "nsJSEnvironment.h"
-#include "nsThreadUtils.h"
+#include "MainThreadUtils.h"
 #include "StructuredCloneTags.h"
 #include "jsapi.h"
 
 using namespace mozilla::dom;
 
 namespace {
 
 void
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -4,92 +4,68 @@
  * 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 "base/basictypes.h"
 
 #include "TabChild.h"
 
 #include "Layers.h"
-#include "Blob.h"
 #include "ContentChild.h"
 #include "IndexedDBChild.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/IntentionalCrash.h"
 #include "mozilla/docshell/OfflineCacheUpdateChild.h"
-#include "mozilla/dom/PContentChild.h"
 #include "mozilla/dom/PContentDialogChild.h"
 #include "mozilla/ipc/DocumentRendererChild.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/layers/AsyncPanZoomController.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/ImageBridgeChild.h"
-#include "mozilla/layers/PLayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layout/RenderFrameChild.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "mozIApplication.h"
-#include "nsComponentManagerUtils.h"
-#include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsEmbedCID.h"
 #include "nsEventListenerManager.h"
 #include <algorithm>
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 #include "mozilla/dom/Element.h"
-#include "nsIAppsService.h"
 #include "nsIBaseWindow.h"
 #include "nsICachedFileDescriptorListener.h"
-#include "nsIComponentManager.h"
+#include "nsIDialogParamBlock.h"
 #include "nsIDocumentInlines.h"
-#include "nsIDOMClassInfo.h"
-#include "nsIDOMElement.h"
+#include "nsIDocShellTreeOwner.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDocShell.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsIJSRuntimeService.h"
-#include "nsISSLStatusProvider.h"
-#include "nsIScriptContext.h"
-#include "nsIScriptGlobalObject.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsISecureBrowserUI.h"
-#include "nsIServiceManager.h"
-#include "nsISupportsImpl.h"
 #include "nsIURI.h"
 #include "nsIURIFixup.h"
 #include "nsCDefaultURIFixup.h"
-#include "nsView.h"
 #include "nsIWebBrowser.h"
 #include "nsIWebBrowserFocus.h"
 #include "nsIWebBrowserSetup.h"
 #include "nsIWebProgress.h"
-#include "nsIXPCSecurityManager.h"
 #include "nsInterfaceHashtable.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
-#include "nsGlobalWindow.h"
 #include "nsLayoutUtils.h"
-#include "nsPresContext.h"
 #include "nsPrintfCString.h"
-#include "nsScriptLoader.h"
-#include "nsSerializationHelper.h"
 #include "nsThreadUtils.h"
 #include "nsWeakReference.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "PuppetWidget.h"
 #include "StructuredCloneUtils.h"
-#include "xpcpublic.h"
 #include "nsViewportInfo.h"
 #include "JavaScriptChild.h"
 #include "APZCCallbackHelper.h"
 
 #define BROWSER_ELEMENT_CHILD_SCRIPT \
     NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
 
 using namespace mozilla;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -13,41 +13,33 @@
 #endif /* DEBUG */
 #include "nsIWebNavigation.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsEventDispatcher.h"
 #include "nsIWebBrowserChrome2.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsIWebBrowserChromeFocus.h"
-#include "nsIWidget.h"
 #include "nsIDOMEventListener.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIWindowProvider.h"
 #include "nsIDOMWindow.h"
 #include "nsIDocShell.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
-#include "nsNetUtil.h"
+#include "nsIInterfaceRequestorUtils.h"
 #include "nsFrameMessageManager.h"
 #include "nsIWebProgressListener.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIDialogCreator.h"
-#include "nsIDialogParamBlock.h"
 #include "nsIPresShell.h"
-#include "nsIPrincipal.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsWeakReference.h"
 #include "nsITabChild.h"
 #include "mozilla/Attributes.h"
-#include "FrameMetrics.h"
-#include "ProcessUtils.h"
 #include "mozilla/dom/TabContext.h"
-#include "mozilla/dom/ContentChild.h"
 
 struct gfxMatrix;
 class nsICachedFileDescriptorListener;
 class nsIDOMWindowUtils;
 
 namespace mozilla {
 namespace layout {
 class RenderFrameChild;
--- a/dom/ipc/TabContext.cpp
+++ b/dom/ipc/TabContext.cpp
@@ -1,18 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et 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 "mozilla/dom/TabContext.h"
+#include "mozilla/dom/PTabContext.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/TabChild.h"
 #include "nsIAppsService.h"
+#include "nsIScriptSecurityManager.h"
 
 #define NO_APP_ID (nsIScriptSecurityManager::NO_APP_ID)
 
 using namespace mozilla::dom::ipc;
 using namespace mozilla::layout;
 
 namespace mozilla {
 namespace dom {
--- a/dom/ipc/TabContext.h
+++ b/dom/ipc/TabContext.h
@@ -2,26 +2,25 @@
 /* vim: set sw=2 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_TabContext_h
 #define mozilla_dom_TabContext_h
 
-#include "mozilla/Assertions.h"
-#include "mozilla/dom/PContent.h"
-#include "mozilla/dom/PBrowser.h"
 #include "mozilla/layout/RenderFrameUtils.h"
-#include "nsIScriptSecurityManager.h"
 #include "mozIApplication.h"
+#include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 
+struct IPCTabContext;
+
 /**
  * TabContext encapsulates information about an iframe that may be a mozbrowser
  * or mozapp.  You can ask whether a TabContext corresponds to a mozbrowser or
  * mozapp, get the app that contains the browser, and so on.
  *
  * TabParent and TabChild both inherit from TabContext, and you can also have
  * standalone TabContext objects.
  *
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3,65 +3,60 @@
 /* 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 "base/basictypes.h"
 
 #include "TabParent.h"
 
-#include "Blob.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
 #include "mozIApplication.h"
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/docshell/OfflineCacheUpdateParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/Hal.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsCOMPtr.h"
 #include "nsContentPermissionHelper.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
-#include "nsEventDispatcher.h"
 #include "nsEventStateManager.h"
 #include "nsFocusManager.h"
 #include "nsFrameLoader.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
-#include "nsIDOMApplicationRegistry.h"
+#include "nsIDocShellTreeOwner.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
-#include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDialogCreator.h"
+#include "nsIInterfaceRequestorUtils.h"
 #include "nsIPromptFactory.h"
 #include "nsIURI.h"
-#include "nsIMozBrowserFrame.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIXULWindow.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
-#include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
-#include "nsSerializationHelper.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "private/pprio.h"
 #include "StructuredCloneUtils.h"
 #include "JavaScriptParent.h"
 #include "TabChild.h"
+#include "nsNetCID.h"
 #include <algorithm>
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::services;
 using namespace mozilla::widget;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -2,35 +2,29 @@
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_tabs_TabParent_h
 #define mozilla_tabs_TabParent_h
 
-#include "base/basictypes.h"
-
-#include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/dom/PContentDialogParent.h"
 #include "mozilla/dom/TabContext.h"
-#include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "nsCOMPtr.h"
 #include "nsIAuthPromptProvider.h"
 #include "nsIBrowserDOMWindow.h"
 #include "nsIDialogParamBlock.h"
 #include "nsISecureBrowserUI.h"
 #include "nsITabParent.h"
-#include "nsWeakReference.h"
 #include "Units.h"
 #include "js/TypeDecls.h"
 
 struct gfxMatrix;
-class mozIApplication;
 class nsFrameLoader;
 class nsIURI;
 class CpowHolder;
 
 namespace mozilla {
 
 namespace layers {
 struct FrameMetrics;
@@ -39,16 +33,17 @@ struct TextureFactoryIdentifier;
 
 namespace layout {
 class RenderFrameParent;
 }
 
 namespace dom {
 
 class ClonedMessageData;
+class ContentParent;
 class Element;
 struct StructuredCloneData;
 
 class ContentDialogParent : public PContentDialogParent {};
 
 class TabParent : public PBrowserParent 
                 , public nsITabParent 
                 , public nsIAuthPromptProvider
--- a/dom/media/MediaPermissionGonk.cpp
+++ b/dom/media/MediaPermissionGonk.cpp
@@ -13,16 +13,17 @@
 #include "nsISupportsArray.h"
 #include "nsPIDOMWindow.h"
 #include "nsTArray.h"
 #include "GetUserMediaRequest.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "mozilla/dom/PBrowserChild.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/MediaStreamTrackBinding.h"
+#include "nsISupportsPrimitives.h"
 
 #define AUDIO_PERMISSION_NAME "audio-capture"
 
 namespace mozilla {
 
 static MediaPermissionManager *gMediaPermMgr = nullptr;
 
 // Helper function for notifying permission granted
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -108,28 +108,42 @@ function getUserMedia(constraints, onSuc
  * Setup any Mochitest for WebRTC by enabling the preference for
  * peer connections. As by bug 797979 it will also enable mozGetUserMedia()
  * and disable the mozGetUserMedia() permission checking.
  *
  * @param {Function} aCallback
  *        Test method to execute after initialization
  */
 function runTest(aCallback) {
-  SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({'set': [
-    ['media.peerconnection.enabled', true],
-    ['media.navigator.permission.disabled', true]]
-  }, function () {
-    try {
-      aCallback();
-    }
-    catch (err) {
-      unexpectedCallbackAndFinish()(err);
-    }
-  });
+  if (window.SimpleTest) {
+    // Running as a Mochitest.
+    SimpleTest.waitForExplicitFinish();
+    SpecialPowers.pushPrefEnv({'set': [
+      ['media.peerconnection.enabled', true],
+      ['media.navigator.permission.disabled', true]]
+    }, function () {
+      try {
+        aCallback();
+      }
+      catch (err) {
+        unexpectedCallbackAndFinish()(err);
+      }
+    });
+  } else {
+    // Steeplechase, let it call the callback.
+    window.run_test = function(is_initiator) {
+      var options = {is_local: is_initiator,
+                     is_remote: !is_initiator};
+      aCallback(options);
+    };
+    // Also load the steeplechase test code.
+    var s = document.createElement("script");
+    s.src = "/test.js";
+    document.head.appendChild(s);
+  }
 }
 
 /**
  * Checks that the media stream tracks have the expected amount of tracks
  * with the correct kind and id based on the type and constraints given.
  *
  * @param {Object} constraints specifies whether the stream should have
  *                             audio, video, or both
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -219,16 +219,30 @@ CommandChain.prototype = {
    *        Identifier of the command
    * @returns {object[]} Removed commands
    */
   replaceBefore : function (id, commands) {
     var oldCommands = this.removeBefore(id);
     this.insertBefore(id, commands);
 
     return oldCommands;
+  },
+
+  /**
+   * Remove all commands whose identifiers match the specified regex.
+   *
+   * @param {regex} id_match
+   *        Regular expression to match command identifiers.
+   */
+  filterOut : function (id_match) {
+    for (var i = this._commands.length - 1; i >= 0; i--) {
+      if (id_match.test(this._commands[i][0])) {
+        this._commands.splice(i, 1);
+      }
+    }
   }
 };
 
 /**
  * This class provides a state checker for media elements which store
  * a media stream to check for media attribute state and events fired.
  * When constructed by a caller, an object instance is created with
  * a media element, event state checkers for canplaythrough, timeupdate, and
@@ -313,54 +327,75 @@ MediaElementChecker.prototype = {
 /**
  * This class handles tests for peer connections.
  *
  * @constructor
  * @param {object} [options={}]
  *        Optional options for the peer connection test
  * @param {object} [options.commands=commandsPeerConnection]
  *        Commands to run for the test
+ * @param {bool}   [options.is_local=true]
+ *        true if this test should run the tests for the "local" side.
+ * @param {bool}   [options.is_remote=true]
+ *        true if this test should run the tests for the "remote" side.
  * @param {object} [options.config_pc1=undefined]
  *        Configuration for the local peer connection instance
  * @param {object} [options.config_pc2=undefined]
  *        Configuration for the remote peer connection instance. If not defined
  *        the configuration from the local instance will be used
  */
 function PeerConnectionTest(options) {
   // If no options are specified make it an empty object
   options = options || { };
   options.commands = options.commands || commandsPeerConnection;
+  options.is_local = "is_local" in options ? options.is_local : true;
+  options.is_remote = "is_remote" in options ? options.is_remote : true;
 
-  this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_pc1);
-  this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_pc2 || options.config_pc1);
+  if (options.is_local)
+    this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_pc1);
+  else
+    this.pcLocal = null;
+
+  if (options.is_remote)
+    this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_pc2 || options.config_pc1);
+  else
+    this.pcRemote = null;
 
   this.connected = false;
 
   // Create command chain instance and assign default commands
   this.chain = new CommandChain(this, options.commands);
+  if (!options.is_local) {
+    this.chain.filterOut(/^PC_LOCAL/);
+  }
+  if (!options.is_remote) {
+    this.chain.filterOut(/^PC_REMOTE/);
+  }
 
   var self = this;
   this.chain.onFinished = function () {
     self.teardown();
-  }
+  };
 }
 
 /**
  * Closes the peer connection if it is active
  *
  * @param {Function} onSuccess
  *        Callback to execute when the peer connection has been closed successfully
  */
 PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
   info("Closing peer connections. Connection state=" + this.connected);
 
   // There is no onclose event for the remote peer existent yet. So close it
   // side-by-side with the local peer.
-  this.pcLocal.close();
-  this.pcRemote.close();
+  if (this.pcLocal)
+    this.pcLocal.close();
+  if (this.pcRemote)
+    this.pcRemote.close();
   this.connected = false;
 
   onSuccess();
 };
 
 /**
  * Executes the next command.
  */
@@ -439,28 +474,31 @@ function PCT_setLocalDescription(peer, d
  * Sets the media constraints for both peer connection instances.
  *
  * @param {object} constraintsLocal
  *        Media constrains for the local peer connection instance
  * @param constraintsRemote
  */
 PeerConnectionTest.prototype.setMediaConstraints =
 function PCT_setMediaConstraints(constraintsLocal, constraintsRemote) {
-  this.pcLocal.constraints = constraintsLocal;
-  this.pcRemote.constraints = constraintsRemote;
+  if (this.pcLocal)
+    this.pcLocal.constraints = constraintsLocal;
+  if (this.pcRemote)
+    this.pcRemote.constraints = constraintsRemote;
 };
 
 /**
  * Sets the media constraints used on a createOffer call in the test.
  *
  * @param {object} constraints the media constraints to use on createOffer
  */
 PeerConnectionTest.prototype.setOfferConstraints =
 function PCT_setOfferConstraints(constraints) {
-  this.pcLocal.offerConstraints = constraints;
+  if (this.pcLocal)
+    this.pcLocal.offerConstraints = constraints;
 };
 
 /**
  * Sets the remote description for the specified peer connection instance
  * and automatically handles the failure case.
  *
  * @param {PeerConnectionWrapper} peer
           The peer connection wrapper to run the command on
@@ -501,17 +539,20 @@ PeerConnectionTest.prototype.run = funct
 };
 
 /**
  * Clean up the objects used by the test
  */
 PeerConnectionTest.prototype.teardown = function PCT_teardown() {
   this.close(function () {
     info("Test finished");
-    SimpleTest.finish();
+    if (window.SimpleTest)
+      SimpleTest.finish();
+    else
+      finish();
   });
 };
 
 /**
  * This class handles tests for data channels.
  *
  * @constructor
  * @param {object} [options={}]
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -14,69 +14,117 @@ var commandsPeerConnection = [
     'PC_REMOTE_GUM',
     function (test) {
       test.pcRemote.getAllUserMedia(function () {
         test.next();
       });
     }
   ],
   [
-    'PC_CHECK_INITIAL_SIGNALINGSTATE',
+    'PC_LOCAL_CHECK_INITIAL_SIGNALINGSTATE',
     function (test) {
       is(test.pcLocal.signalingState, "stable",
          "Initial local signalingState is 'stable'");
+      test.next();
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE',
+    function (test) {
       is(test.pcRemote.signalingState, "stable",
          "Initial remote signalingState is 'stable'");
       test.next();
     }
   ],
   [
     'PC_LOCAL_CREATE_OFFER',
     function (test) {
       test.createOffer(test.pcLocal, function () {
         is(test.pcLocal.signalingState, "stable",
            "Local create offer does not change signaling state");
+        if (!test.pcRemote) {
+          send_message({"offer": test.pcLocal._last_offer,
+                        "media_constraints": test.pcLocal.constraints});
+        }
         test.next();
       });
     }
   ],
   [
     'PC_LOCAL_SET_LOCAL_DESCRIPTION',
     function (test) {
       test.setLocalDescription(test.pcLocal, test.pcLocal._last_offer, function () {
         is(test.pcLocal.signalingState, "have-local-offer",
            "signalingState after local setLocalDescription is 'have-local-offer'");
         test.next();
       });
     }
   ],
   [
+    'PC_REMOTE_GET_OFFER',
+    function (test) {
+      if (test.pcLocal) {
+        test._local_offer = test.pcLocal._last_offer;
+        test._local_constraints = test.pcLocal.constraints;
+        test.next();
+      } else {
+        wait_for_message().then(function(message) {
+          ok("offer" in message, "Got an offer message");
+          test._local_offer = new mozRTCSessionDescription(message.offer);
+          test._local_constraints = message.media_constraints;
+          test.next();
+        });
+      }
+    }
+  ],
+  [
     'PC_REMOTE_SET_REMOTE_DESCRIPTION',
     function (test) {
-      test.setRemoteDescription(test.pcRemote, test.pcLocal._last_offer, function () {
+      test.setRemoteDescription(test.pcRemote, test._local_offer, function () {
         is(test.pcRemote.signalingState, "have-remote-offer",
            "signalingState after remote setRemoteDescription is 'have-remote-offer'");
         test.next();
       });
     }
   ],
   [
     'PC_REMOTE_CREATE_ANSWER',
     function (test) {
       test.createAnswer(test.pcRemote, function () {
         is(test.pcRemote.signalingState, "have-remote-offer",
            "Remote createAnswer does not change signaling state");
+        if (!test.pcLocal) {
+          send_message({"answer": test.pcRemote._last_answer,
+                        "media_constraints": test.pcRemote.constraints});
+        }
         test.next();
       });
     }
   ],
   [
+    'PC_LOCAL_GET_ANSWER',
+    function (test) {
+      if (test.pcRemote) {
+        test._remote_answer = test.pcRemote._last_answer;
+        test._remote_constraints = test.pcRemote.constraints;
+        test.next();
+      } else {
+        wait_for_message().then(function(message) {
+          ok("answer" in message, "Got an answer message");
+          test._remote_answer = new mozRTCSessionDescription(message.answer);
+          test._remote_constraints = message.media_constraints;
+          test.next();
+        });
+      }
+    }
+  ],
+  [
     'PC_LOCAL_SET_REMOTE_DESCRIPTION',
     function (test) {
-      test.setRemoteDescription(test.pcLocal, test.pcRemote._last_answer, function () {
+      test.setRemoteDescription(test.pcLocal, test._remote_answer, function () {
         is(test.pcLocal.signalingState, "stable",
            "signalingState after local setRemoteDescription is 'stable'");
         test.next();
       });
     }
   ],
   [
     'PC_REMOTE_SET_LOCAL_DESCRIPTION',
@@ -86,24 +134,24 @@ var commandsPeerConnection = [
            "signalingState after remote setLocalDescription is 'stable'");
         test.next();
       });
     }
   ],
   [
     'PC_LOCAL_CHECK_MEDIA_STREAMS',
     function (test) {
-      test.pcLocal.checkMediaStreams(test.pcRemote.constraints);
+      test.pcLocal.checkMediaStreams(test._remote_constraints);
       test.next();
     }
   ],
   [
     'PC_REMOTE_CHECK_MEDIA_STREAMS',
     function (test) {
-      test.pcRemote.checkMediaStreams(test.pcLocal.constraints);
+      test.pcRemote.checkMediaStreams(test._local_constraints);
       test.next();
     }
   ],
   [
     'PC_LOCAL_CHECK_MEDIA_FLOW_PRESENT',
     function (test) {
       test.pcLocal.checkMediaFlowPresent(function () {
         test.next();
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudio.html
@@ -12,17 +12,17 @@
 <pre id="test">
 <script type="application/javascript">
   createHTML({
     bug: "796892",
     title: "Basic audio-only peer connection"
   });
 
   var test;
-  runTest(function () {
-    test = new PeerConnectionTest();
+  runTest(function (options) {
+    test = new PeerConnectionTest(options);
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/mobilemessage/src/ipc/SmsChild.cpp
+++ b/dom/mobilemessage/src/ipc/SmsChild.cpp
@@ -6,16 +6,17 @@
 #include "SmsMessage.h"
 #include "MmsMessage.h"
 #include "SmsSegmentInfo.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
 #include "MobileMessageThread.h"
+#include "MainThreadUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::mobilemessage;
 
 namespace {
 
 already_AddRefed<nsISupports>
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -9,16 +9,17 @@
 #include "nsIDOMTCPSocket.h"
 #include "nsCxPusher.h"
 #include "mozilla/unused.h"
 #include "mozilla/AppProcessChecker.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "mozilla/net/PNeckoParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/TabParent.h"
+#include "nsIScriptSecurityManager.h"
 
 namespace IPC {
 
 //Defined in TCPSocketChild.cpp
 extern bool
 DeserializeArrayBuffer(JS::Handle<JSObject*> aObj,
                        const InfallibleTArray<uint8_t>& aBuffer,
                        JS::MutableHandle<JS::Value> aVal);
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -8,17 +8,17 @@
 
 #include "mozilla/Attributes.h"
 #include "nscore.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIPluginTag.h"
 #include "nsITimer.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 class nsPluginHost;
 struct PRLibrary;
 struct nsPluginInfo;
 class nsNPAPIPlugin;
 
 // A linked-list of plugin information that is used for instantiating plugins
 // and reflecting plugin information into JavaScript.
--- a/dom/plugins/base/nsPluginsDirUnix.cpp
+++ b/dom/plugins/base/nsPluginsDirUnix.cpp
@@ -6,16 +6,17 @@
 #include "nsNPAPIPlugin.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIMemory.h"
 #include "nsPluginsDir.h"
 #include "nsPluginsDirUtils.h"
 #include "prmem.h"
 #include "prenv.h"
 #include "prerror.h"
+#include "prio.h"
 #include <sys/stat.h>
 #include "nsString.h"
 #include "nsIFile.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 
 #define LOCAL_PLUGIN_DLL_SUFFIX ".so"
 #if defined(__hpux)
--- a/dom/plugins/ipc/PluginIdentifierChild.h
+++ b/dom/plugins/ipc/PluginIdentifierChild.h
@@ -6,17 +6,17 @@
 
 #ifndef dom_plugins_PluginIdentifierChild_h
 #define dom_plugins_PluginIdentifierChild_h
 
 #include "mozilla/plugins/PPluginIdentifierChild.h"
 #include "npapi.h"
 #include "npruntime.h"
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 namespace mozilla {
 namespace plugins {
 
 class PluginModuleChild;
 
 /**
  * Plugin identifiers may be "temporary", see the comment on the
--- a/dom/plugins/ipc/PluginMessageUtils.h
+++ b/dom/plugins/ipc/PluginMessageUtils.h
@@ -13,17 +13,17 @@
 #include "mozilla/ipc/RPCChannel.h"
 #include "mozilla/ipc/CrossProcessMutex.h"
 #include "gfxipc/ShadowLayerUtils.h"
 
 #include "npapi.h"
 #include "npruntime.h"
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "prlog.h"
 #include "nsHashKeys.h"
 #ifdef MOZ_CRASHREPORTER
 #  include "nsExceptionHandler.h"
 #endif
 #ifdef XP_MACOSX
 #include "PluginInterposeOSX.h"
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -488,29 +488,20 @@ PluginModuleParent::TerminateChildProces
     if (!GetProcessCpuUsage(processHandles, mPluginCpuUsageOnHang)) {
       mPluginCpuUsageOnHang.Clear();
     }
 #endif
 
     // this must run before the error notification from the channel,
     // or not at all
     bool isFromHangUI = aMsgLoop != MessageLoop::current();
-    if (isFromHangUI) {
-        // If we're posting from a different thread we can't create
-        // the task via mTaskFactory
-        aMsgLoop->PostTask(FROM_HERE,
-                           NewRunnableMethod(this,
-                               &PluginModuleParent::CleanupFromTimeout,
-                               isFromHangUI));
-    } else {
-        aMsgLoop->PostTask(
-            FROM_HERE,
-            mTaskFactory.NewRunnableMethod(
-                &PluginModuleParent::CleanupFromTimeout, isFromHangUI));
-    }
+    aMsgLoop->PostTask(
+        FROM_HERE,
+        mTaskFactory.NewRunnableMethod(
+            &PluginModuleParent::CleanupFromTimeout, isFromHangUI));
 
     if (!KillProcess(OtherProcess(), 1, false))
         NS_WARNING("failed to kill subprocess!");
 }
 
 #ifdef XP_WIN
 void
 PluginModuleParent::EvaluateHangUIState(const bool aReset)
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_plugins_PluginModuleParent_h
 #define mozilla_plugins_PluginModuleParent_h
 
 #include "base/process.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/PluginLibrary.h"
+#include "mozilla/plugins/ScopedMethodFactory.h"
 #include "mozilla/plugins/PluginProcessParent.h"
 #include "mozilla/plugins/PPluginModuleParent.h"
 #include "npapi.h"
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIObserver.h"
@@ -297,17 +298,17 @@ private:
     // the plugin thread in mSubprocess
     NativeThreadId mPluginThread;
     bool mShutdown;
     bool mClearSiteDataSupported;
     bool mGetSitesWithDataSupported;
     const NPNetscapeFuncs* mNPNIface;
     nsDataHashtable<nsPtrHashKey<void>, PluginIdentifierParent*> mIdentifiers;
     nsNPAPIPlugin* mPlugin;
-    ScopedRunnableMethodFactory<PluginModuleParent> mTaskFactory;
+    ScopedMethodFactory<PluginModuleParent> mTaskFactory;
     nsString mPluginDumpID;
     nsString mBrowserDumpID;
     nsString mHangID;
     nsRefPtr<nsIObserver> mProfilerObserver;
 #ifdef XP_WIN
     InfallibleTArray<float> mPluginCpuUsageOnHang;
     PluginHangUIParent *mHangUIParent;
     bool mHangUIEnabled;
new file mode 100644
--- /dev/null
+++ b/dom/plugins/ipc/ScopedMethodFactory.h
@@ -0,0 +1,87 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_plugins_ScopedMethodFactory_h
+#define mozilla_plugins_ScopedMethodFactory_h
+
+#include <base/task.h>
+
+/*
+ * This is based on the ScopedRunnableMethodFactory from ipc/chromium/src/base/task.h
+ * Chromiums factories assert if tasks are created and run on different threads,
+ * which is something we need to do in PluginModuleParent (hang UI vs. main thread).
+ * ScopedMethodFactory just provides cancellable tasks that don't assert this.
+ */
+
+namespace mozilla {
+namespace plugins {
+
+template<class T>
+class ScopedMethodFactory : public RevocableStore
+{
+private:
+  template<class TaskType>
+  class TaskWrapper : public TaskType
+  {
+  public:
+    explicit TaskWrapper(RevocableStore* store) : revocable_(store) { }
+
+    virtual void Run() {
+      if (!revocable_.revoked())
+        TaskType::Run();
+    }
+
+  private:
+    Revocable revocable_;
+  };
+
+public:
+  explicit ScopedMethodFactory(T* object) : object_(object) { }
+
+  template <class Method>
+  inline Task* NewRunnableMethod(Method method) {
+    typedef TaskWrapper<RunnableMethod<Method, Tuple0> > TaskWrapper;
+
+    TaskWrapper* task = new TaskWrapper(this);
+    task->Init(object_, method, MakeTuple());
+    return task;
+  }
+
+  template <class Method, class A>
+  inline Task* NewRunnableMethod(Method method, const A& a) {
+    typedef TaskWrapper<RunnableMethod<Method, Tuple1<A> > > TaskWrapper;
+
+    TaskWrapper* task = new TaskWrapper(this);
+    task->Init(object_, method, MakeTuple(a));
+    return task;
+  }
+
+protected:
+  template <class Method, class Params>
+  class RunnableMethod : public Task {
+   public:
+    RunnableMethod() { }
+
+    void Init(T* obj, Method meth, const Params& params) {
+      obj_ = obj;
+      meth_ = meth;
+      params_ = params;
+    }
+
+    virtual void Run() { DispatchToMethod(obj_, meth_, params_); }
+
+   private:
+    T* obj_;
+    Method meth_;
+    Params params_;
+  };
+
+private:
+  T* object_;
+};
+
+} // namespace plugins
+} // namespace mozilla
+
+#endif // mozilla_plugins_ScopedMethodFactory_h
--- a/dom/plugins/ipc/moz.build
+++ b/dom/plugins/ipc/moz.build
@@ -34,16 +34,17 @@ EXPORTS.mozilla.plugins += [
     'PluginProcessParent.h',
     'PluginScriptableObjectChild.h',
     'PluginScriptableObjectParent.h',
     'PluginScriptableObjectUtils-inl.h',
     'PluginScriptableObjectUtils.h',
     'PluginStreamChild.h',
     'PluginStreamParent.h',
     'PluginUtilsOSX.h',
+    'ScopedMethodFactory.h',
     'StreamNotifyChild.h',
     'StreamNotifyParent.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS.mozilla.plugins += [
         'PluginSurfaceParent.h',
     ]
--- a/dom/power/WakeLock.cpp
+++ b/dom/power/WakeLock.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/HalWakeLock.h"
 #include "nsDOMClassInfoID.h"
 #include "nsDOMEvent.h"
 #include "nsError.h"
 #include "nsIDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMEvent.h"
 #include "nsPIDOMWindow.h"
+#include "nsIPropertyBag2.h"
 
 DOMCI_DATA(MozWakeLock, mozilla::dom::power::WakeLock)
 
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace dom {
 namespace power {
--- a/dom/quota/FileStreams.cpp
+++ b/dom/quota/FileStreams.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=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 "FileStreams.h"
 
 #include "QuotaManager.h"
+#include "prio.h"
 
 USING_QUOTA_NAMESPACE
 
 template <class FileStreamBase>
 NS_IMETHODIMP
 FileQuotaStream<FileStreamBase>::SetEOF()
 {
   nsresult rv = FileStreamBase::SetEOF();
--- a/dom/quota/QuotaCommon.h
+++ b/dom/quota/QuotaCommon.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_quota_quotacommon_h__
 #define mozilla_dom_quota_quotacommon_h__
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 #define BEGIN_QUOTA_NAMESPACE \
   namespace mozilla { namespace dom { namespace quota {
 #define END_QUOTA_NAMESPACE \
   } /* namespace quota */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_QUOTA_NAMESPACE \
   using namespace mozilla::dom::quota;
--- a/dom/src/notification/DesktopNotification.cpp
+++ b/dom/src/notification/DesktopNotification.cpp
@@ -7,16 +7,17 @@
 #include "nsXULAppAPI.h"
 #include "mozilla/dom/PBrowserChild.h"
 #include "nsIDOMDesktopNotification.h"
 #include "TabChild.h"
 #include "mozilla/Preferences.h"
 #include "nsGlobalWindow.h"
 #include "nsIAppsService.h"
 #include "PCOMContentPermissionRequestChild.h"
+#include "nsIScriptSecurityManager.h"
 
 namespace mozilla {
 namespace dom {
 
 /*
  * Simple Request
  */
 class DesktopNotificationRequest : public nsIContentPermissionRequest,
--- a/dom/src/notification/Notification.cpp
+++ b/dom/src/notification/Notification.cpp
@@ -12,16 +12,17 @@
 #include "nsIAlertsService.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsIDocument.h"
 #include "nsIPermissionManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsGlobalWindow.h"
 #include "nsDOMJSUtils.h"
+#include "nsIScriptSecurityManager.h"
 #ifdef MOZ_B2G
 #include "nsIDOMDesktopNotification.h"
 #include "nsIAppsService.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 
--- a/dom/src/storage/DOMStorageIPC.cpp
+++ b/dom/src/storage/DOMStorageIPC.cpp
@@ -5,16 +5,17 @@
 
 #include "DOMStorageIPC.h"
 
 #include "DOMStorageManager.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/unused.h"
 #include "nsIDiskSpaceWatcher.h"
+#include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 // ----------------------------------------------------------------------------
 // Child
 // ----------------------------------------------------------------------------
 
--- a/dom/system/gonk/SystemWorkerManager.h
+++ b/dom/system/gonk/SystemWorkerManager.h
@@ -20,17 +20,17 @@
 
 #include "nsIInterfaceRequestor.h"
 #include "nsISystemWorkerManager.h"
 #include "nsIObserver.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsDOMEventTargetHelper.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 class nsIWorkerHolder;
 
 namespace mozilla {
 
 namespace ipc {
   class RilConsumer;
--- a/dom/system/gonk/nsVolumeMountLock.cpp
+++ b/dom/system/gonk/nsVolumeMountLock.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/Services.h"
 
 #include "nsIObserverService.h"
 #include "nsIPowerManagerService.h"
 #include "nsIVolume.h"
 #include "nsIVolumeService.h"
 #include "nsString.h"
+#include "nsXULAppAPI.h"
 
 #define VOLUME_MANAGER_LOG_TAG  "nsVolumeMountLock"
 #include "VolumeManagerLog.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::services;
 
 namespace mozilla {
--- a/dom/telephony/TelephonyCommon.h
+++ b/dom/telephony/TelephonyCommon.h
@@ -9,17 +9,17 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsDOMEventTargetHelper.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 #define BEGIN_TELEPHONY_NAMESPACE \
   namespace mozilla { namespace dom { namespace telephony {
 #define END_TELEPHONY_NAMESPACE \
   } /* namespace telephony */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_TELEPHONY_NAMESPACE \
   using namespace mozilla::dom::telephony;
--- a/dom/workers/ChromeWorkerScope.cpp
+++ b/dom/workers/ChromeWorkerScope.cpp
@@ -4,17 +4,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ChromeWorkerScope.h"
 
 #include "jsapi.h"
 
 #include "nsXPCOM.h"
 #include "nsNativeCharsetUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #include "WorkerPrivate.h"
 
 using namespace mozilla::dom;
 USING_WORKERS_NAMESPACE
 
 namespace {
 
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -9,17 +9,17 @@
 #include "nsIDOMFile.h"
 #include "nsDOMBlobBuilder.h"
 #include "nsError.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "nsCOMPtr.h"
 #include "nsJSUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #include "mozilla/dom/Exceptions.h"
 #include "WorkerInlines.h"
 #include "WorkerPrivate.h"
 
 USING_WORKERS_NAMESPACE
 using mozilla::dom::Throw;
 
--- a/dom/workers/FileReaderSync.h
+++ b/dom/workers/FileReaderSync.h
@@ -6,17 +6,17 @@
 
 #ifndef mozilla_dom_workers_filereadersync_h__
 #define mozilla_dom_workers_filereadersync_h__
 
 #include "Workers.h"
 #include "mozilla/dom/workers/bindings/DOMBindingBase.h"
 
 #include "nsICharsetDetectionObserver.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "mozilla/Attributes.h"
 
 class nsIInputStream;
 class nsIDOMBlob;
 
 namespace mozilla {
 class ErrorResult;
 
--- a/dom/workers/Navigator.h
+++ b/dom/workers/Navigator.h
@@ -3,17 +3,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 mozilla_dom_workers_navigator_h__
 #define mozilla_dom_workers_navigator_h__
 
 #include "Workers.h"
 #include "mozilla/dom/workers/bindings/DOMBindingBase.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 BEGIN_WORKERS_NAMESPACE
 
 class WorkerNavigator MOZ_FINAL : public DOMBindingBase
 {
   nsString mAppName;
   nsString mAppVersion;
   nsString mPlatform;
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -13,17 +13,17 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsCOMPtr.h"
 #include "nsHashKeys.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 class nsIThread;
 class nsITimer;
 class nsPIDOMWindow;
 
 BEGIN_WORKERS_NAMESPACE
 
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -20,17 +20,17 @@
 #include "nsChannelPolicy.h"
 #include "nsError.h"
 #include "nsContentPolicyUtils.h"
 #include "nsContentUtils.h"
 #include "nsDocShellCID.h"
 #include "nsISupportsPrimitives.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 #include "xpcpublic.h"
 
 #include "mozilla/dom/Exceptions.h"
 #include "Principal.h"
 #include "WorkerFeature.h"
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -17,17 +17,17 @@
 
 #include "mozilla/Assertions.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsEventQueue.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "nsTPriorityQueue.h"
 #include "StructuredCloneTags.h"
 
 #include "EventTarget.h"
 #include "Queue.h"
 #include "WorkerFeature.h"
 
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -8,17 +8,17 @@
 
 #include "jsapi.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 #include <stdint.h>
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #define BEGIN_WORKERS_NAMESPACE \
   namespace mozilla { namespace dom { namespace workers {
 #define END_WORKERS_NAMESPACE \
   } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_WORKERS_NAMESPACE \
   using namespace mozilla::dom::workers;
 
--- a/embedding/browser/webBrowser/nsEmbedStream.cpp
+++ b/embedding/browser/webBrowser/nsEmbedStream.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
 #include "nsIDocShell.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPipe.h"
 
 #include "nsEmbedStream.h"
 #include "nsError.h"
 #include "nsString.h"
 
--- a/embedding/components/appstartup/src/nsAppStartupNotifier.cpp
+++ b/embedding/components/appstartup/src/nsAppStartupNotifier.cpp
@@ -6,17 +6,17 @@
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsXPIDLString.h"
 #include "nsIServiceManager.h"
 #include "nsICategoryManager.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsAppStartupNotifier.h"
-
+#include "nsISimpleEnumerator.h"
 
 NS_IMPL_ISUPPORTS1(nsAppStartupNotifier, nsIObserver)
 
 nsAppStartupNotifier::nsAppStartupNotifier()
 {
 }
 
 nsAppStartupNotifier::~nsAppStartupNotifier()
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -4,16 +4,17 @@
 
 
 #include "mozSpellChecker.h"
 #include "nsIServiceManager.h"
 #include "mozISpellI18NManager.h"
 #include "nsIStringEnumerator.h"
 #include "nsICategoryManager.h"
 #include "nsISupportsPrimitives.h"
+#include "nsISimpleEnumerator.h"
 
 #define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(mozSpellChecker)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(mozSpellChecker)
 
 NS_INTERFACE_MAP_BEGIN(mozSpellChecker)
   NS_INTERFACE_MAP_ENTRY(nsISpellChecker)
--- a/extensions/spellcheck/src/mozSpellCheckerFactory.cpp
+++ b/extensions/spellcheck/src/mozSpellCheckerFactory.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/ModuleUtils.h"
 #include "mozHunspell.h"
 #include "mozHunspellDirProvider.h"
 #include "mozSpellChecker.h"
 #include "mozInlineSpellChecker.h"
 #include "nsTextServicesCID.h"
 #include "mozPersonalDictionary.h"
 #include "mozSpellI18NManager.h"
+#include "nsIFile.h"
 
 #define NS_SPELLCHECKER_CID         \
 { /* 8227f019-afc7-461e-b030-9f185d7a0e29 */    \
 0x8227F019, 0xAFC7, 0x461e,                     \
 { 0xB0, 0x30, 0x9F, 0x18, 0x5D, 0x7A, 0x0E, 0x29} }
 
 #define MOZ_INLINESPELLCHECKER_CID         \
 { /* 9FE5D975-09BD-44aa-A01A-66402EA28657 */    \
--- a/extensions/widgetutils/src/nsWidgetUtils.cpp
+++ b/extensions/widgetutils/src/nsWidgetUtils.cpp
@@ -18,17 +18,17 @@
 #include "nsIObserver.h"
 #include "nsIPresShell.h"
 #include "nsIStyleSheetService.h"
 #include "nsIWebProgress.h"
 #include "nsIWebProgressListener.h"
 #include "nsIWindowWatcher.h"
 #include "nsNetUtil.h"
 #include "nsRect.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsWeakReference.h"
 #include "nsIWebBrowser.h"
 #include "nsIObserverService.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMCompositionListener.h"
 #include "nsIDOMTextListener.h"
 #include "nsIDOMMouseEvent.h"
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -46,36 +46,37 @@ CompositorChild::Destroy()
   while (size_t len = ManagedPLayerTransactionChild().Length()) {
     LayerTransactionChild* layers =
       static_cast<LayerTransactionChild*>(ManagedPLayerTransactionChild()[len - 1]);
     layers->Destroy();
   }
   SendStop();
 }
 
-/*static*/ PCompositorChild*
+/*static*/ bool
 CompositorChild::Create(Transport* aTransport, ProcessId aOtherProcess)
 {
   // There's only one compositor per child process.
   MOZ_ASSERT(!sCompositor);
 
   nsRefPtr<CompositorChild> child(new CompositorChild(nullptr));
   ProcessHandle handle;
   if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
     // We can't go on without a compositor.
     NS_RUNTIMEABORT("Couldn't OpenProcessHandle() to parent process.");
-    return nullptr;
+    return false;
   }
   if (!child->Open(aTransport, handle, XRE_GetIOMessageLoop(),
                 AsyncChannel::Child)) {
     NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
-    return nullptr;
+    return false;
   }
   // We release this ref in ActorDestroy().
-  return sCompositor = child.forget().get();
+  sCompositor = child.forget().get();
+  return true;
 }
 
 /*static*/ PCompositorChild*
 CompositorChild::Get()
 {
   // This is only expected to be used in child processes.
   MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Default);
   return sCompositor;
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -33,17 +33,17 @@ public:
 
   void Destroy();
 
   /**
    * We're asked to create a new Compositor in response to an Opens()
    * or Bridge() request from our parent process.  The Transport is to
    * the compositor's context.
    */
-  static PCompositorChild*
+  static bool
   Create(Transport* aTransport, ProcessId aOtherProcess);
 
   static PCompositorChild* Get();
 
   static bool ChildProcessHasCompositor() { return sCompositor != nullptr; }
 protected:
   virtual PLayerTransactionChild*
     AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -900,34 +900,32 @@ static void
 OpenCompositor(CrossProcessCompositorParent* aCompositor,
                Transport* aTransport, ProcessHandle aHandle,
                MessageLoop* aIOLoop)
 {
   DebugOnly<bool> ok = aCompositor->Open(aTransport, aHandle, aIOLoop);
   MOZ_ASSERT(ok);
 }
 
-/*static*/ PCompositorParent*
+/*static*/ bool
 CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
 {
   nsRefPtr<CrossProcessCompositorParent> cpcp =
     new CrossProcessCompositorParent(aTransport);
   ProcessHandle handle;
   if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
     // XXX need to kill |aOtherProcess|, it's boned
-    return nullptr;
+    return false;
   }
   cpcp->mSelfRef = cpcp;
   CompositorLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(OpenCompositor, cpcp.get(),
                         aTransport, handle, XRE_GetIOMessageLoop()));
-  // The return value is just compared to null for success checking,
-  // we're not sharing a ref.
-  return cpcp.get();
+  return true;
 }
 
 static void
 UpdateIndirectTree(uint64_t aId, Layer* aRoot, const TargetConfig& aTargetConfig)
 {
   sIndirectLayerTrees[aId].mRoot = aRoot;
   sIndirectLayerTrees[aId].mTargetConfig = aTargetConfig;
 }
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -167,17 +167,17 @@ public:
    * pan/zoom-related events can be sent.
    */
   static APZCTreeManager* GetAPZCTreeManager(uint64_t aLayersId);
 
   /**
    * A new child process has been configured to push transactions
    * directly to us.  Transport is to its thread context.
    */
-  static PCompositorParent*
+  static bool
   Create(Transport* aTransport, ProcessId aOtherProcess);
 
   /**
    * Setup external message loop and thread ID for Compositor.
    * Should be used when CompositorParent should work in existing thread/MessageLoop,
    * for example moving Compositor into native toolkit main thread will allow to avoid
    * extra synchronization and call ::Composite() right from toolkit::Paint event
    */
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -516,39 +516,39 @@ ImageBridgeChild::EndTransaction()
     }
     default:
       NS_RUNTIMEABORT("not reached");
     }
   }
 }
 
 
-PImageBridgeChild*
+bool
 ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
                                         ProcessId aOtherProcess)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
 
   ProcessHandle processHandle;
   if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    return nullptr;
+    return false;
   }
 
   sImageBridgeChildThread = new Thread("ImageBridgeChild");
   if (!sImageBridgeChildThread->Start()) {
-    return nullptr;
+    return false;
   }
 
   sImageBridgeChildSingleton = new ImageBridgeChild();
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(ConnectImageBridgeInChildProcess,
                         aTransport, processHandle));
 
-  return sImageBridgeChildSingleton;
+  return true;
 }
 
 void ImageBridgeChild::ShutDown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
   if (ImageBridgeChild::IsCreated()) {
     ImageBridgeChild::DestroyBridge();
     delete sImageBridgeChildThread;
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -109,17 +109,17 @@ public:
   /**
    * Creates the image bridge with a dedicated thread for ImageBridgeChild.
    *
    * We may want to use a specifi thread in the future. In this case, use
    * CreateWithThread instead.
    */
   static void StartUp();
 
-  static PImageBridgeChild*
+  static bool
   StartUpInChildProcess(Transport* aTransport, ProcessId aOtherProcess);
 
   /**
    * Destroys the image bridge by calling DestroyBridge, and destroys the
    * ImageBridge's thread.
    *
    * If you don't want to destroy the thread, call DestroyBridge directly
    * instead.
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -98,31 +98,31 @@ static void
 ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
                                   Transport* aTransport,
                                   ProcessHandle aOtherProcess)
 {
   aBridge->Open(aTransport, aOtherProcess,
                 XRE_GetIOMessageLoop(), AsyncChannel::Parent);
 }
 
-/*static*/ PImageBridgeParent*
+/*static*/ bool
 ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
 {
   ProcessHandle processHandle;
   if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    return nullptr;
+    return false;
   }
 
   MessageLoop* loop = CompositorParent::CompositorLoop();
   nsRefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport);
   bridge->mSelfRef = bridge;
   loop->PostTask(FROM_HERE,
                  NewRunnableFunction(ConnectImageBridgeInParentProcess,
                                      bridge.get(), aTransport, processHandle));
-  return bridge.get();
+  return true;
 }
 
 bool ImageBridgeParent::RecvStop()
 {
   return true;
 }
 
 static  uint64_t GenImageContainerID() {
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -39,17 +39,17 @@ public:
   typedef InfallibleTArray<CompositableOperation> EditArray;
   typedef InfallibleTArray<EditReply> EditReplyArray;
 
   ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport);
   ~ImageBridgeParent();
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
-  static PImageBridgeParent*
+  static bool
   Create(Transport* aTransport, ProcessId aOtherProcess);
 
   virtual PGrallocBufferParent*
   AllocPGrallocBufferParent(const gfxIntSize&, const uint32_t&, const uint32_t&,
                             MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPGrallocBufferParent(PGrallocBufferParent* actor) MOZ_OVERRIDE;
--- a/gfx/src/gfxCrashReporterUtils.cpp
+++ b/gfx/src/gfxCrashReporterUtils.cpp
@@ -20,17 +20,17 @@
 #include "nsError.h"                    // for NS_OK, NS_FAILED, nsresult
 #include "nsExceptionHandler.h"         // for AppendAppNotesToCrashReport
 #include "nsID.h"
 #include "nsIEventTarget.h"             // for NS_DISPATCH_NORMAL
 #include "nsIObserver.h"                // for nsIObserver, etc
 #include "nsIObserverService.h"         // for nsIObserverService
 #include "nsIRunnable.h"                // for nsIRunnable
 #include "nsISupports.h"
-#include "nsStringGlue.h"               // for nsAutoCString, nsCString, etc
+#include "nsString.h"               // for nsAutoCString, nsCString, etc
 #include "nsTArray.h"                   // for nsTArray
 #include "nsThreadUtils.h"              // for NS_DispatchToMainThread, etc
 #include "nscore.h"                     // for NS_IMETHOD, NS_IMETHODIMP, etc
 
 namespace mozilla {
 
 static nsTArray<nsCString> *gFeaturesAlreadyReported = nullptr;
 
--- a/gfx/src/nsColor.cpp
+++ b/gfx/src/nsColor.cpp
@@ -7,17 +7,17 @@
 
 #include "nsColor.h"
 #include <sys/types.h>                  // for int32_t
 #include "mozilla/Util.h"               // for ArrayLength
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsColorNames.h"               // for nsColorNames
 #include "nsDebug.h"                    // for NS_ASSERTION, etc
 #include "nsStaticNameTable.h"
-#include "nsStringGlue.h"               // for nsAutoCString, nsString, etc
+#include "nsString.h"               // for nsAutoCString, nsString, etc
 #include "nscore.h"                     // for nsAString, etc
 
 using namespace mozilla;
 
 // define an array of all color names
 #define GFX_COLOR(_name, _value) #_name,
 static const char* const kColorNames[] = {
 #include "nsColorNameList.h"
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -25,17 +25,17 @@
 #include "nsIObserverService.h"         // for nsIObserverService
 #include "nsIScreen.h"                  // for nsIScreen
 #include "nsIScreenManager.h"           // for nsIScreenManager
 #include "nsISupportsUtils.h"           // for NS_ADDREF, NS_RELEASE
 #include "nsIWidget.h"                  // for nsIWidget, NS_NATIVE_WINDOW
 #include "nsRect.h"                     // for nsRect
 #include "nsRenderingContext.h"         // for nsRenderingContext
 #include "nsServiceManagerUtils.h"      // for do_GetService
-#include "nsStringGlue.h"               // for nsDependentString
+#include "nsString.h"               // for nsDependentString
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "nsThreadUtils.h"              // for NS_IsMainThread
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 
 #if !XP_MACOSX
 #include "gfxPDFSurface.h"
 #endif
 
--- a/gfx/src/nsFont.h
+++ b/gfx/src/nsFont.h
@@ -8,17 +8,17 @@
 
 #include <stdint.h>                     // for uint8_t, uint16_t
 #include <sys/types.h>                  // for int16_t
 #include "gfxCore.h"                    // for NS_GFX
 #include "gfxFontFeatures.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCoord.h"                    // for nscoord
 #include "nsStringFwd.h"                // for nsSubstring
-#include "nsStringGlue.h"               // for nsString
+#include "nsString.h"               // for nsString
 #include "nsTArray.h"                   // for nsTArray
 
 struct gfxFontStyle;
 
 // XXX we need a method to enumerate all of the possible fonts on the
 // system across family, weight, style, size, etc. But not here!
 
 // Enumerator callback function. Return false to stop
--- a/gfx/src/nsFontMetrics.cpp
+++ b/gfx/src/nsFontMetrics.cpp
@@ -11,17 +11,17 @@
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxTypes.h"                   // for gfxFloat
 #include "nsBoundingMetrics.h"          // for nsBoundingMetrics
 #include "nsDebug.h"                    // for NS_ERROR, NS_ABORT_IF_FALSE
 #include "nsDeviceContext.h"            // for nsDeviceContext
 #include "nsIAtom.h"                    // for nsIAtom
 #include "nsMathUtils.h"                // for NS_round
 #include "nsRenderingContext.h"         // for nsRenderingContext
-#include "nsStringGlue.h"               // for nsString
+#include "nsString.h"               // for nsString
 #include "nsStyleConsts.h"              // for NS_STYLE_HYPHENS_NONE
 
 class gfxUserFontSet;
 
 namespace {
 
 class AutoTextRun {
 public:
--- a/gfx/src/nsRect.cpp
+++ b/gfx/src/nsRect.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsRect.h"
 #include "mozilla/gfx/Types.h"          // for NS_SIDE_BOTTOM, etc
 #include "nsDeviceContext.h"            // for nsDeviceContext
-#include "nsStringGlue.h"               // for nsAutoString, etc
+#include "nsString.h"               // for nsAutoString, etc
 #include "prtypes.h"                    // for PR_STATIC_ASSERT
 #include "nsMargin.h"                   // for nsMargin
 
 // the mozilla::css::Side sequence must match the nsMargin nscoord sequence
 PR_STATIC_ASSERT((NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3));
 
 #ifdef DEBUG
 // Diagnostics
--- a/gfx/src/nsRegion.h
+++ b/gfx/src/nsRegion.h
@@ -9,17 +9,17 @@
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint32_t, uint64_t
 #include <sys/types.h>                  // for int32_t
 #include "gfxCore.h"                    // for NS_GFX
 #include "nsCoord.h"                    // for nscoord
 #include "nsError.h"                    // for nsresult
 #include "nsPoint.h"                    // for nsIntPoint, nsPoint
 #include "nsRect.h"                     // for nsIntRect, nsRect
-#include "nsStringGlue.h"               // for nsCString
+#include "nsString.h"               // for nsCString
 #include "xpcom-config.h"               // for CPP_THROW_NEW
 
 class nsIntRegion;
 
 /**
  * Implementation of regions.
  * A region is represented as circular double-linked list of nsRegion::RgnRect structures.
  * Rectangles in this list do not overlap and are sorted by (y, x) coordinates.
--- a/gfx/src/nsRenderingContext.h
+++ b/gfx/src/nsRenderingContext.h
@@ -13,17 +13,17 @@
 #include "mozilla/gfx/UserData.h"       // for UserData, UserDataKey
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsBoundingMetrics.h"          // for nsBoundingMetrics
 #include "nsColor.h"                    // for nscolor
 #include "nsCoord.h"                    // for nscoord, NSToIntRound
 #include "nsDeviceContext.h"            // for nsDeviceContext
 #include "nsFontMetrics.h"              // for nsFontMetrics
 #include "nsISupports.h"                // for NS_INLINE_DECL_REFCOUNTING, etc
-#include "nsStringGlue.h"               // for nsString
+#include "nsString.h"               // for nsString
 #include "nscore.h"                     // for PRUnichar
 
 class gfxASurface;
 class nsIntRegion;
 struct nsPoint;
 struct nsRect;
 
 typedef enum {
--- a/gfx/src/nsThebesFontEnumerator.cpp
+++ b/gfx/src/nsThebesFontEnumerator.cpp
@@ -8,17 +8,17 @@
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsDebug.h"                    // for NS_ENSURE_ARG_POINTER
 #include "nsError.h"                    // for NS_OK, NS_FAILED, nsresult
 #include "nsIAtom.h"                    // for nsIAtom, do_GetAtom
 #include "nsID.h"
 #include "nsMemory.h"                   // for nsMemory
-#include "nsStringGlue.h"               // for nsAutoCString, nsAutoString, etc
+#include "nsString.h"               // for nsAutoCString, nsAutoString, etc
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "nscore.h"                     // for PRUnichar, NS_IMETHODIMP
 
 NS_IMPL_ISUPPORTS1(nsThebesFontEnumerator, nsIFontEnumerator)
 
 nsThebesFontEnumerator::nsThebesFontEnumerator()
 {
 }
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -44,17 +44,17 @@
 #include <limits.h>
 
 #include "imgIEncoder.h"
 #include "nsComponentManagerUtils.h"
 #include "nsISupportsUtils.h"
 #include "nsCOMPtr.h"
 #include "nsIConsoleService.h"
 #include "nsServiceManagerUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsIClipboardHelper.h"
 
 using namespace mozilla;
 
 static cairo_user_data_key_t gfxasurface_pointer_key;
 
 // Surfaces use refcounting that's tied to the cairo surface refcnt, to avoid
 // refcount mismatch issues.
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -3,17 +3,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 GFX_PLATFORM_H
 #define GFX_PLATFORM_H
 
 #include "prlog.h"
 #include "nsTArray.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsIObserver.h"
 
 #include "gfxTypes.h"
 #include "gfxASurface.h"
 #include "gfxColor.h"
 
 #include "qcms.h"
 
--- a/image/decoders/icon/nsIconURI.h
+++ b/image/decoders/icon/nsIconURI.h
@@ -4,17 +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 nsMozIconURI_h__
 #define nsMozIconURI_h__
 
 #include "nsIIconURI.h"
 #include "nsCOMPtr.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #define NS_MOZICONURI_CID                            \
 {                                                    \
     0x43a88e0e,                                      \
     0x2d37,                                          \
     0x11d5,                                          \
     { 0x99, 0x7, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b }   \
 }
--- a/image/src/imgRequest.h
+++ b/image/src/imgRequest.h
@@ -9,17 +9,17 @@
 
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIStreamListener.h"
 #include "nsIPrincipal.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsError.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 
 class imgCacheValidator;
 class imgStatusTracker;
 class imgLoader;
 class imgRequestProxy;
 class imgCacheEntry;
--- a/intl/locale/public/nsCharsetAlias.h
+++ b/intl/locale/public/nsCharsetAlias.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 nsCharsetAlias_h___
 #define nsCharsetAlias_h___
 
 #include "nscore.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 class nsCharsetConverterManager;
 class nsScriptableUnicodeConverter;
 
 class nsCharsetAlias
 {
    friend class nsCharsetConverterManager;
    friend class nsScriptableUnicodeConverter;
--- a/intl/locale/public/nsIDateTimeFormat.h
+++ b/intl/locale/public/nsIDateTimeFormat.h
@@ -5,17 +5,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 nsIDateTimeFormat_h__
 #define nsIDateTimeFormat_h__
 
 
 #include "nsISupports.h"
 #include "nscore.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsILocale.h"
 #include "nsIScriptableDateFormat.h"
 #include "prtime.h"
 #include <time.h>
 
 
 // {2BBAA0B0-A591-11d2-9119-006008A6EDF6}
 #define NS_IDATETIMEFORMAT_IID \
--- a/intl/locale/public/nsIPlatformCharset.h
+++ b/intl/locale/public/nsIPlatformCharset.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIPlatformCharset_h__
 #define nsIPlatformCharset_h__
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsISupports.h"
 
 // Interface ID for our nsIPlatformCharset interface
 
 /* 778859d5-fc01-4f4b-bfaa-3c0d1b6c81d6 */
 #define NS_IPLATFORMCHARSET_IID \
 {   0x778859d5, \
     0xfc01, \
--- a/intl/uconv/idl/nsICharsetConverterManager.idl
+++ b/intl/uconv/idl/nsICharsetConverterManager.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIAtom.idl"
 
 %{ C++
 #include "nsIUnicodeDecoder.h"
 #include "nsIUnicodeEncoder.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 
 // XXX change to NS_CHARSETCONVERTERMANAGER_CID
 #define NS_ICHARSETCONVERTERMANAGER_CID \
   {0x3c1c0163, 0x9bd0, 0x11d3, { 0x9d, 0x9, 0x0, 0x50, 0x4, 0x0, 0x7, 0xb2}}
 
 // XXX change to NS_CHARSETCONVERTERMANAGER_PID
 #define NS_CHARSETCONVERTERMANAGER_CONTRACTID "@mozilla.org/charset-converter-manager;1"
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -15,17 +15,17 @@
 #include "mozilla/TimeStamp_windows.h"
 #endif
 #include "mozilla/Util.h"
 
 #include <stdint.h>
 
 #include "nsID.h"
 #include "nsMemory.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "js/StructuredClone.h"
 #include "nsCSSProperty.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
 
--- a/ipc/glue/MessagePump.cpp
+++ b/ipc/glue/MessagePump.cpp
@@ -1,17 +1,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/. */
 
 #include "MessagePump.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "prthread.h"
 
 #include "base/logging.h"
 #include "base/scoped_nsautorelease_pool.h"
 
 #ifdef MOZ_WIDGET_ANDROID
--- a/ipc/glue/ScopedXREEmbed.cpp
+++ b/ipc/glue/ScopedXREEmbed.cpp
@@ -6,17 +6,17 @@
 
 #include "base/command_line.h"
 #include "base/string_util.h"
 
 #include "nsIFile.h"
 
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsXULAppAPI.h"
 
 using mozilla::ipc::ScopedXREEmbed;
 
 ScopedXREEmbed::ScopedXREEmbed()
 : mShouldKillEmbedding(false)
 {
   NS_LogInit();
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -7,17 +7,17 @@
 
 #include "mozilla/DebugOnly.h"
 
 #include "WindowsMessageLoop.h"
 #include "RPCChannel.h"
 
 #include "nsAutoPtr.h"
 #include "nsServiceManagerUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsIXULAppInfo.h"
 
 #include "mozilla/PaintTracker.h"
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 using namespace mozilla::ipc::windows;
 
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -2713,17 +2713,17 @@ class _GenerateProtocolActorCode(ipdl.as
         for actor in channelOpenedActors:
             # add the Alloc interface for actors created when a
             # new channel is opened
             actortype = _cxxBareType(actor.asType(), actor.side)
             self.cls.addstmt(StmtDecl(MethodDecl(
                 _allocMethod(actor.ptype, actor.side).name,
                 params=[ Decl(Type('Transport', ptr=1), 'transport'),
                          Decl(Type('ProcessId'), 'otherProcess') ],
-                ret=actortype,
+                ret=Type.BOOL,
                 virtual=1, pure=1)))
 
         # optional ActorDestroy() method; default is no-op
         self.cls.addstmts([
             Whitespace.NL,
             MethodDefn(MethodDecl(
                 _destroyMethod().name,
                 params=[ Decl(_DestroyReason.Type(), 'why') ],
--- a/ipc/ipdl/test/cxx/TestBridgeMain.cpp
+++ b/ipc/ipdl/test/cxx/TestBridgeMain.cpp
@@ -20,30 +20,31 @@ namespace _ipdltest {
 // main process
 void
 TestBridgeMainParent::Main()
 {
     if (!SendStart())
         fail("sending Start");
 }
 
-PTestBridgeMainSubParent*
+bool
 TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport,
                                                     ProcessId otherProcess)
 {
     ProcessHandle h;
     if (!base::OpenProcessHandle(otherProcess, &h)) {
         return nullptr;
     }
 
     nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport));
     if (!a->Open(transport, h, XRE_GetIOMessageLoop(), AsyncChannel::Parent)) {
         return nullptr;
     }
-    return a.forget();
+    a.forget();
+    return true;
 }
 
 void
 TestBridgeMainParent::ActorDestroy(ActorDestroyReason why)
 {
     if (NormalShutdown != why)
         fail("unexpected destruction!");  
     passed("ok");
@@ -171,34 +172,35 @@ TestBridgeSubChild::TestBridgeSubChild()
 bool
 TestBridgeSubChild::RecvPing()
 {
     if (!SendBridgeEm())
         fail("sending BridgeEm");
     return true;
 }
 
-PTestBridgeMainSubChild*
+bool
 TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport,
                                                  ProcessId otherProcess)
 {
     ProcessHandle h;
     if (!base::OpenProcessHandle(otherProcess, &h)) {
-        return nullptr;
+        return false;
     }
 
     nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport));
     if (!a->Open(transport, h, XRE_GetIOMessageLoop(), AsyncChannel::Child)) {
-        return nullptr;
+        return false;
     }
 
     if (!a->SendHello())
         fail("sending Hello");
 
-    return a.forget();
+    a.forget();
+    return true;
 }
 
 void
 TestBridgeSubChild::ActorDestroy(ActorDestroyReason why)
 {
     if (NormalShutdown != why)
         fail("unexpected destruction!");
     QuitChild();
--- a/ipc/ipdl/test/cxx/TestBridgeMain.h
+++ b/ipc/ipdl/test/cxx/TestBridgeMain.h
@@ -26,17 +26,17 @@ public:
     virtual ~TestBridgeMainParent() {}
 
     static bool RunTestInProcesses() { return true; }
     static bool RunTestInThreads() { return false; }
 
     void Main();
 
 protected:
-    virtual PTestBridgeMainSubParent*
+    virtual bool
     AllocPTestBridgeMainSubParent(Transport* transport,
                                   ProcessId otherProcess) MOZ_OVERRIDE;
 
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 };
 
 class TestBridgeMainSubParent :
     public PTestBridgeMainSubParent
@@ -100,17 +100,17 @@ class TestBridgeSubChild :
 {
 public:
     TestBridgeSubChild();
     virtual ~TestBridgeSubChild() {}
 
 protected:
     virtual bool RecvPing() MOZ_OVERRIDE;
 
-    virtual PTestBridgeMainSubChild*
+    virtual bool
     AllocPTestBridgeMainSubChild(Transport* transport,
                                  ProcessId otherProcess) MOZ_OVERRIDE;
 
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 };
 
 class TestBridgeMainSubChild :
     public PTestBridgeMainSubChild
--- a/ipc/ipdl/test/cxx/TestOpens.cpp
+++ b/ipc/ipdl/test/cxx/TestOpens.cpp
@@ -59,37 +59,37 @@ OpenParent(TestOpensOpenedParent* aParen
     // Open the actor on the off-main thread to park it there.
     // Messages will be delivered to this thread's message loop
     // instead of the main thread's.
     if (!aParent->Open(aTransport, aOtherProcess,
                        XRE_GetIOMessageLoop(), AsyncChannel::Parent))
         fail("opening Parent");
 }
 
-PTestOpensOpenedParent*
+bool
 TestOpensParent::AllocPTestOpensOpenedParent(Transport* transport,
                                              ProcessId otherProcess)
 {
     gMainThread = MessageLoop::current();
 
     ProcessHandle h;
     if (!base::OpenProcessHandle(otherProcess, &h)) {
-        return nullptr;
+        return false;
     }
 
     gParentThread = new Thread("ParentThread");
     if (!gParentThread->Start())
         fail("starting parent thread");
 
     TestOpensOpenedParent* a = new TestOpensOpenedParent(transport);
     gParentThread->message_loop()->PostTask(
         FROM_HERE,
         NewRunnableFunction(OpenParent, a, transport, h));
 
-    return a;
+    return true;
 }
 
 void
 TestOpensParent::ActorDestroy(ActorDestroyReason why)
 {
     // Stops the thread and joins it
     delete gParentThread;
 
@@ -172,37 +172,37 @@ OpenChild(TestOpensOpenedChild* aChild,
                       XRE_GetIOMessageLoop(), AsyncChannel::Child))
         fail("opening Child");
 
     // Kick off the unit tests
     if (!aChild->SendHello())
         fail("sending Hello");
 }
 
-PTestOpensOpenedChild*
+bool
 TestOpensChild::AllocPTestOpensOpenedChild(Transport* transport,
                                            ProcessId otherProcess)
 {
     gMainThread = MessageLoop::current();
 
     ProcessHandle h;
     if (!base::OpenProcessHandle(otherProcess, &h)) {
-        return nullptr;
+        return false;
     }
 
     gChildThread = new Thread("ChildThread");
     if (!gChildThread->Start())
         fail("starting child thread");
 
     TestOpensOpenedChild* a = new TestOpensOpenedChild(transport);
     gChildThread->message_loop()->PostTask(
         FROM_HERE,
         NewRunnableFunction(OpenChild, a, transport, h));
 
-    return a;
+    return true;
 }
 
 void
 TestOpensChild::ActorDestroy(ActorDestroyReason why)
 {
     // Stops the thread and joins it
     delete gChildThread;
 
--- a/ipc/ipdl/test/cxx/TestOpens.h
+++ b/ipc/ipdl/test/cxx/TestOpens.h
@@ -22,17 +22,17 @@ public:
     virtual ~TestOpensParent() {}
 
     static bool RunTestInProcesses() { return true; }
     static bool RunTestInThreads() { return false; }
 
     void Main();
 
 protected:
-    virtual PTestOpensOpenedParent*
+    virtual bool
     AllocPTestOpensOpenedParent(Transport* transport, ProcessId otherProcess) MOZ_OVERRIDE;
 
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 };
 
 } // namespace _ipdltest
 
 namespace _ipdltest2 {
@@ -65,17 +65,17 @@ class TestOpensChild : public PTestOpens
 {
 public:
     TestOpensChild();
     virtual ~TestOpensChild() {}
 
 protected:
     virtual bool RecvStart() MOZ_OVERRIDE;
 
-    virtual PTestOpensOpenedChild*
+    virtual bool
     AllocPTestOpensOpenedChild(Transport* transport, ProcessId otherProcess) MOZ_OVERRIDE;
 
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 };
 
 } // namespace _ipdltest
 
 namespace _ipdltest2 {
--- a/ipc/testshell/TestShellParent.h
+++ b/ipc/testshell/TestShellParent.h
@@ -8,17 +8,17 @@
 #ifndef ipc_testshell_TestShellParent_h
 #define ipc_testshell_TestShellParent_h 1
 
 #include "mozilla/ipc/PTestShellParent.h"
 #include "mozilla/ipc/PTestShellCommandParent.h"
 
 #include "js/TypeDecls.h"
 #include "nsAutoJSValHolder.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 namespace mozilla {
 
 namespace ipc {
 
 class TestShellCommandParent;
 
 class TestShellParent : public PTestShellParent
--- a/ipc/testshell/XPCShellEnvironment.h
+++ b/ipc/testshell/XPCShellEnvironment.h
@@ -8,17 +8,17 @@
 #include "base/basictypes.h"
 
 #include <string>
 #include <stdio.h>
 
 #include "nsAutoJSValHolder.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsJSPrincipals.h"
 #include "nsContentUtils.h"
 #include "js/TypeDecls.h"
 
 struct JSPrincipals;
 
 namespace mozilla {
 namespace ipc {
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -710,22 +710,25 @@ class MOZ_STACK_CLASS Rooted : public js
     Rooted(JSRuntime *rt, T initial
            MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
       : ptr(initial)
     {
         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         init(js::PerThreadDataFriendFields::getMainThread(rt));
     }
 
+    // Note that we need to let the compiler generate the default destructor in
+    // non-exact-rooting builds because of a bug in the instrumented PGO builds
+    // using MSVC, see bug 915735 for more details.
+#ifdef JSGC_TRACK_EXACT_ROOTS
     ~Rooted() {
-#ifdef JSGC_TRACK_EXACT_ROOTS
         JS_ASSERT(*stack == reinterpret_cast<Rooted<void*>*>(this));
         *stack = prev;
+    }
 #endif
-    }
 
 #ifdef JSGC_TRACK_EXACT_ROOTS
     Rooted<T> *previous() { return prev; }
 #endif
 
     /*
      * Important: Return a reference here so passing a Rooted<T> to
      * something that takes a |const T&| is not a GC hazard.
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -1307,16 +1307,23 @@ public:
 #endif
     void cmpl_rm(RegisterID reg, const void* addr)
     {
         spew("cmpl       %s, %p",
              nameIReg(4, reg), addr);
         m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
     }
 
+    void cmpl_rm_force32(RegisterID reg, const void* addr)
+    {
+        spew("cmpl       %s, %p",
+             nameIReg(4, reg), addr);
+        m_formatter.oneByteOp_disp32(OP_CMP_EvGv, reg, addr);
+    }
+
     void cmpl_im(int imm, const void* addr)
     {
         spew("cmpl       $0x%x, %p", imm, addr);
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
@@ -3354,16 +3361,23 @@ private:
         }
 
         void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
         {
             m_buffer.ensureSpace(maxInstructionSize);
             m_buffer.putByteUnchecked(opcode);
             memoryModRM(reg, address);
         }
+
+        void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, const void* address)
+        {
+            m_buffer.ensureSpace(maxInstructionSize);
+            m_buffer.putByteUnchecked(opcode);
+            memoryModRM_disp32(reg, address);
+        }
 #if WTF_CPU_X86_64
         void oneByteRipOp(OneByteOpcodeID opcode, int reg, int ripOffset)
         {
             m_buffer.ensureSpace(maxInstructionSize);
             emitRexIfNeeded(reg, 0, 0);
             m_buffer.putByteUnchecked(opcode);
             putModRm(ModRmMemoryNoDisp, reg, noBase);
             m_buffer.putIntUnchecked(ripOffset);
@@ -3882,30 +3896,35 @@ private:
             //
             //   reg := [scaled index] + disp32 + [ebp]
             //
             // See Intel developer manual, Vol 2, 2.1.5, Table 2-3.
             putModRmSib(ModRmMemoryNoDisp, reg, noBase, index, scale);
             m_buffer.putIntUnchecked(offset);
         }
 
-        void memoryModRM(int reg, const void* address)
+        void memoryModRM_disp32(int reg, const void* address)
         {
             int32_t disp = addressImmediate(address);
 
 #if WTF_CPU_X86_64
             // On x64-64, non-RIP-relative absolute mode requires a SIB.
             putModRmSib(ModRmMemoryNoDisp, reg, noBase, noIndex, 0);
 #else
             // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
             putModRm(ModRmMemoryNoDisp, reg, noBase);
 #endif
             m_buffer.putIntUnchecked(disp);
         }
 
+        void memoryModRM(int reg, const void* address)
+        {
+            memoryModRM_disp32(reg, address);
+        }
+
         AssemblerBuffer m_buffer;
     } m_formatter;
 };
 
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER) && CPU(X86)
 
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -7,17 +7,16 @@
 #include "jit/AsmJS.h"
 
 #include "mozilla/Move.h"
 
 #ifdef MOZ_VTUNE
 # include "vtune/VTuneWrapper.h"
 #endif
 
-#include "jsmath.h"
 #include "jsprf.h"
 #include "jsworkers.h"
 #include "prmjtime.h"
 
 #include "frontend/Parser.h"
 #include "jit/AsmJSLink.h"
 #include "jit/AsmJSModule.h"
 #include "jit/AsmJSSignalHandlers.h"
@@ -1767,16 +1766,26 @@ class MOZ_STACK_CLASS ModuleCompiler
         // not need patching after deserialization.
         uint8_t *code = module_->codeBase();
         for (unsigned i = 0; i < globalAccesses_.length(); i++) {
             AsmJSGlobalAccess a = globalAccesses_[i];
             masm_.patchAsmJSGlobalAccess(a.patchAt, code, module_->globalData(), a.globalDataOffset);
         }
 #endif
 
+        // Absolute links
+        for (size_t i = 0; i < masm_.numAsmJSAbsoluteLinks(); i++) {
+            AsmJSAbsoluteLink src = masm_.asmJSAbsoluteLink(i);
+            AsmJSStaticLinkData::AbsoluteLink link;
+            link.patchAt = masm_.actualOffset(src.patchAt.offset());
+            link.target = src.target;
+            if (!linkData->absoluteLinks.append(link))
+                return false;
+        }
+
         *module = module_.forget();
         return true;
     }
 };
 
 } /* anonymous namespace */
 
 /*****************************************************************************/
@@ -2280,17 +2289,17 @@ class FunctionCompiler
         unsigned globalDataOffset = module().exitIndexToGlobalDataOffset(exitIndex);
 
         MAsmJSLoadFFIFunc *ptrFun = MAsmJSLoadFFIFunc::New(globalDataOffset);
         curBlock_->add(ptrFun);
 
         return callPrivate(MAsmJSCall::Callee(ptrFun), call, returnType, def);
     }
 
-    bool builtinCall(void *builtin, const Call &call, MIRType returnType, MDefinition **def)
+    bool builtinCall(AsmJSImmKind builtin, const Call &call, MIRType returnType, MDefinition **def)
     {
         return callPrivate(MAsmJSCall::Callee(builtin), call, returnType, def);
     }
 
     /*********************************************** Control flow generation */
 
     void returnExpr(MDefinition *expr)
     {
@@ -3763,58 +3772,46 @@ CheckFFICall(FunctionCompiler &f, ParseN
 
     if (!f.ffiCall(exitIndex, call, retType.toMIRType(), def))
         return false;
 
     *type = retType.toType();
     return true;
 }
 
-static inline void *
-UnaryMathFunCast(double (*pf)(double))
-{
-    return JS_FUNC_TO_DATA_PTR(void*, pf);
-}
-
-static inline void *
-BinaryMathFunCast(double (*pf)(double, double))
-{
-    return JS_FUNC_TO_DATA_PTR(void*, pf);
-}
-
 static bool
 CheckIsDoublish(FunctionCompiler &f, ParseNode *argNode, Type type)
 {
     if (!type.isDoublish())
         return f.failf(argNode, "%s is not a subtype of doublish", type.toChars());
     return true;
 }
 
 static bool
 CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin mathBuiltin,
                      RetType retType, MDefinition **def, Type *type)
 {
     unsigned arity = 0;
-    void *callee = NULL;
+    AsmJSImmKind callee;
     switch (mathBuiltin) {
       case AsmJSMathBuiltin_imul:  return CheckMathIMul(f, callNode, retType, def, type);
       case AsmJSMathBuiltin_abs:   return CheckMathAbs(f, callNode, retType, def, type);
-      case AsmJSMathBuiltin_sin:   arity = 1; callee = UnaryMathFunCast(sin);        break;
-      case AsmJSMathBuiltin_cos:   arity = 1; callee = UnaryMathFunCast(cos);        break;
-      case AsmJSMathBuiltin_tan:   arity = 1; callee = UnaryMathFunCast(tan);        break;
-      case AsmJSMathBuiltin_asin:  arity = 1; callee = UnaryMathFunCast(asin);       break;
-      case AsmJSMathBuiltin_acos:  arity = 1; callee = UnaryMathFunCast(acos);       break;
-      case AsmJSMathBuiltin_atan:  arity = 1; callee = UnaryMathFunCast(atan);       break;
-      case AsmJSMathBuiltin_ceil:  arity = 1; callee = UnaryMathFunCast(ceil);       break;
-      case AsmJSMathBuiltin_floor: arity = 1; callee = UnaryMathFunCast(floor);      break;
-      case AsmJSMathBuiltin_exp:   arity = 1; callee = UnaryMathFunCast(exp);        break;
-      case AsmJSMathBuiltin_log:   arity = 1; callee = UnaryMathFunCast(log);        break;
       case AsmJSMathBuiltin_sqrt:  return CheckMathSqrt(f, callNode, retType, def, type);
-      case AsmJSMathBuiltin_pow:   arity = 2; callee = BinaryMathFunCast(ecmaPow);   break;
-      case AsmJSMathBuiltin_atan2: arity = 2; callee = BinaryMathFunCast(ecmaAtan2); break;
+      case AsmJSMathBuiltin_sin:   arity = 1; callee = AsmJSImm_SinD;   break;
+      case AsmJSMathBuiltin_cos:   arity = 1; callee = AsmJSImm_CosD;   break;
+      case AsmJSMathBuiltin_tan:   arity = 1; callee = AsmJSImm_TanD;   break;
+      case AsmJSMathBuiltin_asin:  arity = 1; callee = AsmJSImm_ASinD;  break;
+      case AsmJSMathBuiltin_acos:  arity = 1; callee = AsmJSImm_ACosD;  break;
+      case AsmJSMathBuiltin_atan:  arity = 1; callee = AsmJSImm_ATanD;  break;
+      case AsmJSMathBuiltin_ceil:  arity = 1; callee = AsmJSImm_CeilD;  break;
+      case AsmJSMathBuiltin_floor: arity = 1; callee = AsmJSImm_FloorD; break;
+      case AsmJSMathBuiltin_exp:   arity = 1; callee = AsmJSImm_ExpD;   break;
+      case AsmJSMathBuiltin_log:   arity = 1; callee = AsmJSImm_LogD;   break;
+      case AsmJSMathBuiltin_pow:   arity = 2; callee = AsmJSImm_PowD;   break;
+      case AsmJSMathBuiltin_atan2: arity = 2; callee = AsmJSImm_ATan2D; break;
     }
 
     FunctionCompiler::Call call(f, retType);
     if (!CheckCallArgs(f, callNode, CheckIsDoublish, &call))
         return false;
 
     if (call.sig().args().length() != arity)
         return f.failf(callNode, "call passed %u arguments, expected %u", call.sig().args().length(), arity);
@@ -5439,17 +5436,20 @@ static const RegisterSet AllRegsExceptSP
                 FloatRegisterSet(FloatRegisters::AllMask));
 static const RegisterSet NonVolatileRegs =
     RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask),
                 FloatRegisterSet(FloatRegisters::NonVolatileMask));
 
 static void
 LoadAsmJSActivationIntoRegister(MacroAssembler &masm, Register reg)
 {
-    masm.loadPtr(AbsoluteAddress(GetIonContext()->runtime->mainThread.addressOfAsmJSActivationStackReadOnly()), reg);
+    masm.movePtr(AsmJSImm_Runtime, reg);
+    size_t offset = offsetof(JSRuntime, mainThread) +
+                    PerThreadData::offsetOfAsmJSActivationStackReadOnly();
+    masm.loadPtr(Address(reg, offset), reg);
 }
 
 static void
 LoadJSContextFromActivation(MacroAssembler &masm, Register activation, Register dest)
 {
     masm.loadPtr(Address(activation, AsmJSActivation::offsetOfContext()), dest);
 }
 
@@ -5640,34 +5640,36 @@ TryEnablingIon(JSContext *cx, AsmJSModul
     IonScript *ionScript = script->ionScript();
     if (!ionScript->addDependentAsmJSModule(cx, DependentAsmJSModuleExit(&module, exitIndex)))
         return false;
 
     module.exitIndexToGlobalDatum(exitIndex).exit = module.ionExitTrampoline(module.exit(exitIndex));
     return true;
 }
 
-static int32_t
+namespace js {
+
+int32_t
 InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
 {
     AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
 
     RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
     RootedValue fval(cx, ObjectValue(*fun));
     RootedValue rval(cx);
     if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
         return false;
 
     if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
         return false;
 
     return true;
 }
 
-static int32_t
+int32_t
 InvokeFromAsmJS_ToInt32(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
 {
     AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
 
     RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
     RootedValue fval(cx, ObjectValue(*fun));
     RootedValue rval(cx);
     if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
@@ -5679,17 +5681,17 @@ InvokeFromAsmJS_ToInt32(JSContext *cx, i
     int32_t i32;
     if (!ToInt32(cx, rval, &i32))
         return false;
     argv[0] = Int32Value(i32);
 
     return true;
 }
 
-static int32_t
+int32_t
 InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
 {
     AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
 
     RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
     RootedValue fval(cx, ObjectValue(*fun));
     RootedValue rval(cx);
     if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
@@ -5701,16 +5703,18 @@ InvokeFromAsmJS_ToNumber(JSContext *cx, 
     double dbl;
     if (!ToNumber(cx, rval, &dbl))
         return false;
     argv[0] = DoubleValue(dbl);
 
     return true;
 }
 
+}  // namespace js
+
 static void
 FillArgumentArray(ModuleCompiler &m, const VarTypeVector &argTypes,
                   unsigned offsetToArgs, unsigned offsetToCallerStackArgs,
                   Register scratch)
 {
     MacroAssembler &masm = m.masm();
 
     for (ABIArgTypeIter i(argTypes); !i.done(); i++) {
@@ -5818,26 +5822,26 @@ GenerateFFIInterpreterExit(ModuleCompile
     }
     i++;
     JS_ASSERT(i.done());
 
     // Make the call, test whether it succeeded, and extract the return value.
     AssertStackAlignment(masm);
     switch (exit.sig().retType().which()) {
       case RetType::Void:
-        masm.call(ImmPtr(InvokeFromAsmJS_Ignore));
+        masm.call(AsmJSImm_InvokeFromAsmJS_Ignore);
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
         break;
       case RetType::Signed:
-        masm.call(ImmPtr(InvokeFromAsmJS_ToInt32));
+        masm.call(AsmJSImm_InvokeFromAsmJS_ToInt32);
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
         masm.unboxInt32(argv, ReturnReg);
         break;
       case RetType::Double:
-        masm.call(ImmPtr(InvokeFromAsmJS_ToNumber));
+        masm.call(AsmJSImm_InvokeFromAsmJS_ToNumber);
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
         masm.loadDouble(argv, ReturnFloatReg);
         break;
     }
 
     // Note: the caller is IonMonkey code which means there are no non-volatile
     // registers to restore.
     masm.freeStack(stackDec);
@@ -5869,62 +5873,40 @@ GenerateFFIInterpreterExit(ModuleCompile
 
     // argument 3: argv
     Address argv(StackPointer, ShadowStackSpace);
     masm.lea(Operand(argv), IntArgReg3);
 
     AssertStackAlignment(masm);
     switch (exit.sig().retType().which()) {
       case RetType::Void:
-        masm.call(ImmPtr(InvokeFromAsmJS_Ignore));
+        masm.call(AsmJSImm_InvokeFromAsmJS_Ignore);
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
         break;
       case RetType::Signed:
-        masm.call(ImmPtr(InvokeFromAsmJS_ToInt32));
+        masm.call(AsmJSImm_InvokeFromAsmJS_ToInt32);
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
         masm.unboxInt32(argv, ReturnReg);
         break;
       case RetType::Double:
-        masm.call(ImmPtr(InvokeFromAsmJS_ToNumber));
+        masm.call(AsmJSImm_InvokeFromAsmJS_ToNumber);
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
 #if defined(JS_CPU_ARM) && !defined(JS_CPU_ARM_HARDFP)
         masm.loadValue(argv, softfpReturnOperand);
 #else
         masm.loadDouble(argv, ReturnFloatReg);
 #endif
         break;
     }
 
     masm.freeStack(reserveSize + sizeof(int32_t));
     masm.ret();
 #endif
 }
 
-static int32_t
-ValueToInt32(JSContext *cx, MutableHandleValue val)
-{
-    int32_t i32;
-    if (!ToInt32(cx, val, &i32))
-        return false;
-    val.set(Int32Value(i32));
-
-    return true;
-}
-
-static int32_t
-ValueToNumber(JSContext *cx, MutableHandleValue val)
-{
-    double dbl;
-    if (!ToNumber(cx, val, &dbl))
-        return false;
-    val.set(DoubleValue(dbl));
-
-    return true;
-}
-
 static void
 GenerateOOLConvert(ModuleCompiler &m, RetType retType, Label *throwLabel)
 {
     MacroAssembler &masm = m.masm();
 
     MIRType typeArray[] = { MIRType_Pointer,   // cx
                             MIRType_Pointer }; // argv
     MIRTypeVector callArgTypes(m.cx());
@@ -5965,55 +5947,37 @@ GenerateOOLConvert(ModuleCompiler &m, Re
         masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
     }
     i++;
     JS_ASSERT(i.done());
 
     // Call
     switch (retType.which()) {
       case RetType::Signed:
-          masm.call(ImmPtr(ValueToInt32));
+          masm.call(AsmJSImm_CoerceInPlace_ToInt32);
           masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
           masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
           break;
       case RetType::Double:
-          masm.call(ImmPtr(ValueToNumber));
+          masm.call(AsmJSImm_CoerceInPlace_ToNumber);
           masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
 #if defined(JS_CPU_ARM) && !defined(JS_CPU_ARM_HARDFP)
           masm.loadValue(Address(StackPointer, offsetToArgv), softfpReturnOperand);
 #else
           masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnFloatReg);
 #endif
           break;
       default:
           MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
     }
 
     masm.freeStack(stackDec);
 }
 
 static void
-EnableActivation(AsmJSActivation *activation)
-{
-    JSContext *cx = activation->cx();
-    Activation *act = cx->mainThread().activation();
-    JS_ASSERT(act->isJit());
-    act->asJit()->setActive(cx);
-}
-
-static void
-DisableActivation(AsmJSActivation *activation)
-{
-    JSContext *cx = activation->cx();
-    Activation *act = cx->mainThread().activation();
-    JS_ASSERT(act->isJit());
-    act->asJit()->setActive(cx, false);
-}
-
-static void
 GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit,
                          unsigned exitIndex, Label *throwLabel)
 {
     MacroAssembler &masm = m.masm();
     masm.align(CodeAlignment);
     m.setIonExitOffset(exitIndex);
     masm.setFramePushed(0);
 
@@ -6092,17 +6056,17 @@ GenerateFFIIonExit(ModuleCompiler &m, co
 
     masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), scratch);
     masm.loadBaselineOrIonNoArgCheck(scratch, scratch, SequentialExecution, maybeDebugBreakpoint);
 
     LoadAsmJSActivationIntoRegister(masm, callee);
     masm.push(scratch);
     masm.setupUnalignedABICall(1, scratch);
     masm.passABIArg(callee);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, EnableActivation));
+    masm.callWithABI(AsmJSImm_EnableActivationFromAsmJS);
     masm.pop(scratch);
 
     // 2. Call
 #if defined(JS_CPU_ARM) && defined(DEBUG)
     // ARM still needs to push, before stack is aligned
     masm.Push(scratch);
 #endif
     AssertStackAlignment(masm);
@@ -6112,17 +6076,17 @@ GenerateFFIIonExit(ModuleCompiler &m, co
     masm.callIon(scratch);
     masm.freeStack(stackDec - extraBytes);
 
     masm.push(JSReturnReg_Type);
     masm.push(JSReturnReg_Data);
     LoadAsmJSActivationIntoRegister(masm, callee);
     masm.setupUnalignedABICall(1, scratch);
     masm.passABIArg(callee);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, DisableActivation));
+    masm.callWithABI(AsmJSImm_DisableActivationFromAsmJS);
     masm.pop(JSReturnReg_Data);
     masm.pop(JSReturnReg_Type);
 
 #ifdef DEBUG
     masm.branchTestMagicValue(Assembler::Equal, JSReturnOperand, JS_ION_ERROR, throwLabel);
     masm.branchTestMagic(Assembler::Equal, JSReturnOperand, &ionFailed);
 #else
     masm.branchTestMagic(Assembler::Equal, JSReturnOperand, throwLabel);
@@ -6198,18 +6162,17 @@ GenerateStackOverflowExit(ModuleCompiler
 #if defined(JS_CPU_X86)
     LoadAsmJSActivationIntoRegister(masm, eax);
     LoadJSContextFromActivation(masm, eax, eax);
     masm.storePtr(eax, Address(StackPointer, 0));
 #else
     LoadAsmJSActivationIntoRegister(masm, IntArgReg0);
     LoadJSContextFromActivation(masm, IntArgReg0, IntArgReg0);
 #endif
-    void (*reportOverRecursed)(JSContext*) = js_ReportOverRecursed;
-    masm.call(ImmPtr(reportOverRecursed));
+    masm.call(AsmJSImm_ReportOverRecursed);
     masm.jump(throwLabel);
 
     return !masm.oom();
 }
 
 // The operation-callback exit is called from arbitrarily-interrupted asm.js
 // code. That means we must first save *all* registers and restore *all*
 // registers (except the stack pointer) when we resume. The address to resume to
@@ -6256,17 +6219,17 @@ GenerateOperationCallbackExit(ModuleComp
     // argument 0: cx
 #if defined(JS_CPU_X86)
     LoadJSContextFromActivation(masm, activation, scratch);
     masm.storePtr(scratch, Address(StackPointer, 0));
 #elif defined(JS_CPU_X64)
     LoadJSContextFromActivation(masm, activation, IntArgReg0);
 #endif
 
-    masm.call(ImmPtr(js_HandleExecutionInterrupt));
+    masm.call(AsmJSImm_HandleExecutionInterrupt);
     masm.branchIfFalseBool(ReturnReg, throwLabel);
 
     // Restore the StackPointer to it's position before the call.
     masm.mov(ABIArgGenerator::NonVolatileReg, StackPointer);
 
     // Restore the machine state to before the interrupt.
     masm.PopRegsInMask(AllRegsExceptSP); // restore all GP/FP registers (except SP)
     masm.popFlags();              // after this, nothing that sets conditions
@@ -6287,17 +6250,17 @@ GenerateOperationCallbackExit(ModuleComp
     LoadAsmJSActivationIntoRegister(masm, IntArgReg0);
     masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfResumePC()), IntArgReg1);
     masm.storePtr(IntArgReg1, Address(r6, 14 * sizeof(uint32_t*)));
 
     // argument 0: cx
     masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfContext()), IntArgReg0);
 
     masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(0), FloatRegisterSet(FloatRegisters::AllMask)));   // save all FP registers
-    masm.call(ImmPtr(js_HandleExecutionInterrupt));
+    masm.call(AsmJSImm_HandleExecutionInterrupt);
     masm.branchIfFalseBool(ReturnReg, throwLabel);
 
     // Restore the machine state to before the interrupt. this will set the pc!
     masm.PopRegsInMask(RegisterSet(GeneralRegisterSet(0), FloatRegisterSet(FloatRegisters::AllMask)));   // restore all FP registers
     masm.mov(r6,sp);
     masm.as_vmsr(r5);
     masm.as_msr(r4);
     // Restore all GP registers
@@ -6450,17 +6413,17 @@ CheckModule(ExclusiveContext *cx, AsmJSP
     TokenKind tk = PeekToken(m.parser());
     if (tk != TOK_EOF && tk != TOK_RC)
         return m.fail(NULL, "top-level export (return) must be the last statement");
 
     AsmJSStaticLinkData linkData(cx);
     if (!FinishModule(m, module, &linkData))
         return false;
 
-    (*module)->staticallyLink(linkData);
+    (*module)->staticallyLink(linkData, cx);
 
     m.buildCompilationTimeReport(compilationTimeReport);
     return true;
 }
 
 static bool
 Warn(AsmJSParser &parser, int errorNumber, const char *str)
 {
@@ -6484,22 +6447,22 @@ EstablishPreconditions(ExclusiveContext 
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by javascript.options.asmjs in about:config");
 
     if (!parser.options().compileAndGo)
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Temporarily disabled for event-handler and other cloneable scripts");
 
     if (cx->compartment()->debugMode())
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by debugger");
 
-# ifdef JS_WORKER_THREADS
+#ifdef JS_WORKER_THREADS
     if (ParallelCompilationEnabled(cx)) {
         if (!EnsureWorkerThreadsInitialized(cx))
             return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Failed compilation thread initialization");
     }
-# endif
+#endif
 
     return true;
 }
 
 static bool
 NoExceptionPending(ExclusiveContext *cx)
 {
     return !cx->isJSContext() || !cx->asJSContext()->isExceptionPending();
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -6,16 +6,18 @@
 
 #include "jit/AsmJSModule.h"
 #include "jit/IonCode.h"
 
 #ifndef XP_WIN
 # include <sys/mman.h>
 #endif
 
+#include "jslibmath.h"
+#include "jsmath.h"
 #ifdef XP_WIN
 # include "jswin.h"
 #endif
 
 #include "js/MemoryMetrics.h"
 
 #include "jsobjinlines.h"
 
@@ -35,16 +37,17 @@ AsmJSModule::initHeap(Handle<ArrayBuffer
     uint8_t *heapOffset = heap->dataPointer();
     void *heapLength = (void*)heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         const jit::AsmJSHeapAccess &access = heapAccesses_[i];
         if (access.hasLengthCheck())
             JSC::X86Assembler::setPointer(access.patchLengthAt(code_), heapLength);
         void *addr = access.patchOffsetAt(code_);
         uint32_t disp = reinterpret_cast<uint32_t>(JSC::X86Assembler::getPointer(addr));
+        JS_ASSERT(disp <= INT32_MAX);
         JSC::X86Assembler::setPointer(addr, (void *)(heapOffset + disp));
     }
 #elif defined(JS_CPU_ARM)
     uint32_t heapLength = heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         jit::Assembler::updateBoundsCheck(heapLength,
                                           (jit::Instruction*)(heapAccesses_[i].offset() + code_));
     }
@@ -104,28 +107,175 @@ AsmJSModule::allocateAndCopyCode(Exclusi
     if (!code_)
         return false;
 
     JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0);
     masm.executableCopy(code_);
     return true;
 }
 
+static int32_t
+CoerceInPlace_ToInt32(JSContext *cx, MutableHandleValue val)
+{
+    int32_t i32;
+    if (!ToInt32(cx, val, &i32))
+        return false;
+    val.set(Int32Value(i32));
+
+    return true;
+}
+
+static int32_t
+CoerceInPlace_ToNumber(JSContext *cx, MutableHandleValue val)
+{
+    double dbl;
+    if (!ToNumber(cx, val, &dbl))
+        return false;
+    val.set(DoubleValue(dbl));
+
+    return true;
+}
+
+static void
+EnableActivationFromAsmJS(AsmJSActivation *activation)
+{
+    JSContext *cx = activation->cx();
+    Activation *act = cx->mainThread().activation();
+    JS_ASSERT(act->isJit());
+    act->asJit()->setActive(cx);
+}
+
+static void
+DisableActivationFromAsmJS(AsmJSActivation *activation)
+{
+    JSContext *cx = activation->cx();
+    Activation *act = cx->mainThread().activation();
+    JS_ASSERT(act->isJit());
+    act->asJit()->setActive(cx, false);
+}
+
+namespace js {
+
+// Defined in AsmJS.cpp:
+
+int32_t
+InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv);
+
+int32_t
+InvokeFromAsmJS_ToInt32(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv);
+
+int32_t
+InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv);
+
+}
+
+#if defined(JS_CPU_ARM)
+extern "C" {
+
+extern int
+__aeabi_idivmod(int, int);
+
+extern int
+__aeabi_uidivmod(int, int);
+
+}
+#endif
+
+template <class F>
+static inline void *
+FuncCast(F *pf)
+{
+    return JS_FUNC_TO_DATA_PTR(void *, pf);
+}
+
+static void *
+AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
+{
+    switch (kind) {
+      case AsmJSImm_Runtime:
+        return cx->runtimeAddressForJit();
+      case AsmJSImm_StackLimit:
+        return cx->stackLimitAddress(StackForUntrustedScript);
+      case AsmJSImm_ReportOverRecursed:
+        return FuncCast<void (JSContext*)>(js_ReportOverRecursed);
+      case AsmJSImm_HandleExecutionInterrupt:
+        return FuncCast(js_HandleExecutionInterrupt);
+      case AsmJSImm_InvokeFromAsmJS_Ignore:
+        return FuncCast(InvokeFromAsmJS_Ignore);
+      case AsmJSImm_InvokeFromAsmJS_ToInt32:
+        return FuncCast(InvokeFromAsmJS_ToInt32);
+      case AsmJSImm_InvokeFromAsmJS_ToNumber:
+        return FuncCast(InvokeFromAsmJS_ToNumber);
+      case AsmJSImm_CoerceInPlace_ToInt32:
+        return FuncCast(CoerceInPlace_ToInt32);
+      case AsmJSImm_CoerceInPlace_ToNumber:
+        return FuncCast(CoerceInPlace_ToNumber);
+      case AsmJSImm_ToInt32:
+        return FuncCast<int32_t (double)>(js::ToInt32);
+      case AsmJSImm_EnableActivationFromAsmJS:
+        return FuncCast(EnableActivationFromAsmJS);
+      case AsmJSImm_DisableActivationFromAsmJS:
+        return FuncCast(DisableActivationFromAsmJS);
+#if defined(JS_CPU_ARM)
+      case AsmJSImm_aeabi_idivmod:
+        return FuncCast(__aeabi_idivmod);
+      case AsmJSImm_aeabi_uidivmod:
+        return FuncCast(__aeabi_uidivmod);
+#endif
+      case AsmJSImm_ModD:
+        return FuncCast(NumberMod);
+      case AsmJSImm_SinD:
+        return FuncCast<double (double)>(sin);
+      case AsmJSImm_CosD:
+        return FuncCast<double (double)>(cos);
+      case AsmJSImm_TanD:
+        return FuncCast<double (double)>(tan);
+      case AsmJSImm_ASinD:
+        return FuncCast<double (double)>(asin);
+      case AsmJSImm_ACosD:
+        return FuncCast<double (double)>(acos);
+      case AsmJSImm_ATanD:
+        return FuncCast<double (double)>(atan);
+      case AsmJSImm_CeilD:
+        return FuncCast<double (double)>(ceil);
+      case AsmJSImm_FloorD:
+        return FuncCast<double (double)>(floor);
+      case AsmJSImm_ExpD:
+        return FuncCast<double (double)>(exp);
+      case AsmJSImm_LogD:
+        return FuncCast<double (double)>(log);
+      case AsmJSImm_PowD:
+        return FuncCast(ecmaPow);
+      case AsmJSImm_ATan2D:
+        return FuncCast(ecmaAtan2);
+    }
+
+    MOZ_ASSUME_UNREACHABLE("Bad AsmJSImmKind");
+    return NULL;
+}
+
 void
-AsmJSModule::staticallyLink(const AsmJSStaticLinkData &linkData)
+AsmJSModule::staticallyLink(const AsmJSStaticLinkData &linkData, ExclusiveContext *cx)
 {
     // Process AsmJSStaticLinkData:
 
     operationCallbackExit_ = code_ + linkData.operationCallbackExitOffset;
 
     for (size_t i = 0; i < linkData.relativeLinks.length(); i++) {
         AsmJSStaticLinkData::RelativeLink link = linkData.relativeLinks[i];
         *(void **)(code_ + link.patchAtOffset) = code_ + link.targetOffset;
     }
 
+    for (size_t i = 0; i < linkData.absoluteLinks.length(); i++) {
+        AsmJSStaticLinkData::AbsoluteLink link = linkData.absoluteLinks[i];
+        Assembler::patchDataWithValueCheck(code_ + link.patchAt.offset(),
+                                           PatchedImmPtr(AddressOf(link.target, cx)),
+                                           PatchedImmPtr((void*)-1));
+    }
+
     // Initialize global data segment
 
     for (size_t i = 0; i < exits_.length(); i++) {
         exitIndexToGlobalDatum(i).exit = interpExitTrampoline(exits_[i]);
         exitIndexToGlobalDatum(i).fun = NULL;
     }
 }
 
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -49,21 +49,30 @@ struct AsmJSStaticLinkData
     struct RelativeLink
     {
         uint32_t patchAtOffset;
         uint32_t targetOffset;
     };
 
     typedef Vector<RelativeLink> RelativeLinkVector;
 
+    struct AbsoluteLink
+    {
+        jit::CodeOffsetLabel patchAt;
+        jit::AsmJSImmKind target;
+    };
+
+    typedef Vector<AbsoluteLink> AbsoluteLinkVector;
+
     size_t operationCallbackExitOffset;
     RelativeLinkVector relativeLinks;
+    AbsoluteLinkVector absoluteLinks;
 
     AsmJSStaticLinkData(ExclusiveContext *cx)
-      : relativeLinks(cx)
+      : relativeLinks(cx), absoluteLinks(cx)
     {}
 };
 
 // An asm.js module represents the collection of functions nested inside a
 // single outer "use asm" function. For example, this asm.js module:
 //   function() { "use asm"; function f() {} function g() {} return f }
 // contains the functions 'f' and 'g'.
 //
@@ -668,17 +677,17 @@ class AsmJSModule
         if (len > minHeapLength_)
             minHeapLength_ = len;
     }
     uint32_t minHeapLength() const {
         return minHeapLength_;
     }
 
     bool allocateAndCopyCode(ExclusiveContext *cx, jit::MacroAssembler &masm);
-    void staticallyLink(const AsmJSStaticLinkData &linkData);
+    void staticallyLink(const AsmJSStaticLinkData &linkData, ExclusiveContext *cx);
 
     uint8_t *codeBase() const {
         JS_ASSERT(code_);
         JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0);
         return code_;
     }
 
     uint8_t *operationCallbackExit() const {
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -141,16 +141,17 @@ MNewStringObject::templateObj() const {
 CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
   : CodeGeneratorSpecific(gen, graph, masm),
     unassociatedScriptCounts_(NULL)
 {
 }
 
 CodeGenerator::~CodeGenerator()
 {
+    JS_ASSERT_IF(!gen->compilingAsmJS(), masm.numAsmJSAbsoluteLinks() == 0);
     js_delete(unassociatedScriptCounts_);
 }
 
 typedef bool (*StringToNumberFn)(ThreadSafeContext *, JSString *, double *);
 typedef ParallelResult (*StringToNumberParFn)(ForkJoinSlice *, JSString *, double *);
 static const VMFunctionsModal StringToNumberInfo = VMFunctionsModal(
     FunctionInfo<StringToNumberFn>(StringToNumber),
     FunctionInfo<StringToNumberParFn>(StringToNumberPar));
@@ -3827,17 +3828,20 @@ CodeGenerator::visitModD(LModD *ins)
     Register temp = ToRegister(ins->temp());
 
     JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
 
     masm.setupUnalignedABICall(2, temp);
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
 
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MacroAssembler::DOUBLE);
+    if (gen->compilingAsmJS())
+        masm.callWithABI(AsmJSImm_ModD, MacroAssembler::DOUBLE);
+    else
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MacroAssembler::DOUBLE);
     return true;
 }
 
 typedef bool (*BinaryFn)(JSContext *, HandleScript, jsbytecode *,
                          MutableHandleValue, MutableHandleValue, Value *);
 typedef ParallelResult (*BinaryParFn)(ForkJoinSlice *, HandleValue, HandleValue,
                                       Value *);
 
@@ -7388,17 +7392,17 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall
     switch (callee.which()) {
       case MAsmJSCall::Callee::Internal:
         masm.call(callee.internal());
         break;
       case MAsmJSCall::Callee::Dynamic:
         masm.call(ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex())));
         break;
       case MAsmJSCall::Callee::Builtin:
-        masm.call(ImmPtr(callee.builtin()));
+        masm.call(callee.builtin());
         break;
     }
 
     if (mir->spIncrement())
         masm.reserveStack(mir->spIncrement());
 
     postAsmJSCall(ins);
     return true;
@@ -7440,19 +7444,18 @@ CodeGenerator::visitAsmJSVoidReturn(LAsm
     if (current->mir() != *gen->graph().poBegin())
         masm.jump(&returnLabel_);
     return true;
 }
 
 bool
 CodeGenerator::visitAsmJSCheckOverRecursed(LAsmJSCheckOverRecursed *lir)
 {
-    uintptr_t *limitAddr = &GetIonContext()->runtime->mainThread.nativeStackLimit[StackForUntrustedScript];
     masm.branchPtr(Assembler::AboveOrEqual,
-                   AbsoluteAddress(limitAddr),
+                   AsmJSAbsoluteAddress(AsmJSImm_StackLimit),
                    StackPointer,
                    lir->mir()->onError());
     return true;
 }
 
 bool
 CodeGenerator::emitAssertRangeI(const Range *r, Register input)
 {
--- a/js/src/jit/IonLinker.h
+++ b/js/src/jit/IonLinker.h
@@ -27,16 +27,18 @@ class Linker
         js_ReportOutOfMemory(cx);
         return NULL;
     }
 
     IonCode *newCode(JSContext *cx, JSC::ExecutableAllocator *execAlloc, JSC::CodeKind kind) {
         JS_ASSERT(kind == JSC::ION_CODE ||
                   kind == JSC::BASELINE_CODE ||
                   kind == JSC::OTHER_CODE);
+        JS_ASSERT(masm.numAsmJSAbsoluteLinks() == 0);
+
         gc::AutoSuppressGC suppressGC(cx);
         if (masm.oom())
             return fail(cx);
 
         JSC::ExecutablePool *pool;
         size_t bytesNeeded = masm.bytesNeeded() + sizeof(IonCode *) + CodeAlignment;
         if (bytesNeeded >= MAX_BUFFER_SIZE)
             return fail(cx);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -8784,27 +8784,27 @@ class MAsmJSCall MOZ_FINAL : public MIns
     class Callee {
       public:
         enum Which { Internal, Dynamic, Builtin };
       private:
         Which which_;
         union {
             Label *internal_;
             MDefinition *dynamic_;
-            const void *builtin_;
+            AsmJSImmKind builtin_;
         } u;
       public:
         Callee() {}
         Callee(Label *callee) : which_(Internal) { u.internal_ = callee; }
         Callee(MDefinition *callee) : which_(Dynamic) { u.dynamic_ = callee; }
-        Callee(const void *callee) : which_(Builtin) { u.builtin_ = callee; }
+        Callee(AsmJSImmKind callee) : which_(Builtin) { u.builtin_ = callee; }
         Which which() const { return which_; }
         Label *internal() const { JS_ASSERT(which_ == Internal); return u.internal_; }
         MDefinition *dynamic() const { JS_ASSERT(which_ == Dynamic); return u.dynamic_; }
-        const void *builtin() const { JS_ASSERT(which_ == Builtin); return u.builtin_; }
+        AsmJSImmKind builtin() const { JS_ASSERT(which_ == Builtin); return u.builtin_; }
     };
 
   private:
     struct Operand {
         AnyRegister reg;
         MUse use;
     };
 
--- a/js/src/jit/RegisterSets.h
+++ b/js/src/jit/RegisterSets.h
@@ -780,29 +780,34 @@ class ABIArg
     Register gpr() const { JS_ASSERT(kind() == GPR); return Register::FromCode(u.gpr_); }
     FloatRegister fpu() const { JS_ASSERT(kind() == FPU); return FloatRegister::FromCode(u.fpu_); }
     uint32_t offsetFromArgBase() const { JS_ASSERT(kind() == Stack); return u.offset_; }
 
     bool argInRegister() const { return kind() != Stack; }
     AnyRegister reg() const { return kind_ == GPR ? AnyRegister(gpr()) : AnyRegister(fpu()); }
 };
 
+// Summarizes a heap access made by asm.js code that needs to be patched later
+// and/or looked up by the asm.js signal handlers. Different architectures need
+// to know different things (x64: offset and length, ARM: where to patch in
+// heap length, x86: where to patch in heap length and base) hence the massive
+// #ifdefery.
 class AsmJSHeapAccess
 {
     uint32_t offset_;
 #if defined(JS_CPU_X86)
     uint8_t cmpDelta_;  // the number of bytes from the cmp to the load/store instruction
 #endif
 #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     uint8_t opLength_;  // the length of the load/store instruction
     uint8_t isFloat32Load_;
-    jit::AnyRegister::Code loadedReg_ : 8;
+    AnyRegister::Code loadedReg_ : 8;
 #endif
 
-    JS_STATIC_ASSERT(jit::AnyRegister::Total < UINT8_MAX);
+    JS_STATIC_ASSERT(AnyRegister::Total < UINT8_MAX);
 
   public:
 #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     // If 'cmp' equals 'offset' or if it is not supplied then the
     // cmpDelta_ is zero indicating that there is no length to patch.
     AsmJSHeapAccess(uint32_t offset, uint32_t after, ArrayBufferView::ViewType vt,
                     AnyRegister loadedReg, uint32_t cmp = UINT32_MAX)
       : offset_(offset),
@@ -834,17 +839,17 @@ class AsmJSHeapAccess
     bool hasLengthCheck() const { return cmpDelta_ > 0; }
     void *patchLengthAt(uint8_t *code) const { return code + (offset_ - cmpDelta_); }
     void *patchOffsetAt(uint8_t *code) const { return code + (offset_ + opLength_); }
 #endif
 #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     unsigned opLength() const { return opLength_; }
     bool isLoad() const { return loadedReg_ != UINT8_MAX; }
     bool isFloat32Load() const { return isFloat32Load_; }
-    jit::AnyRegister loadedReg() const { return jit::AnyRegister::FromCode(loadedReg_); }
+    AnyRegister loadedReg() const { return AnyRegister::FromCode(loadedReg_); }
 #endif
 };
 
 typedef Vector<AsmJSHeapAccess, 0, IonAllocPolicy> AsmJSHeapAccessVector;
 
 } // namespace jit
 } // namespace js
 
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -2557,33 +2557,40 @@ Assembler::patchWrite_NearCall(CodeLocat
     uint8_t *dest = toCall.raw();
     new (inst) InstBLImm(BOffImm(dest - (uint8_t*)inst) , Always);
     // Ensure everyone sees the code that was just written into memory.
 
     AutoFlushCache::updateTop(uintptr_t(inst), 4);
 
 }
 void
-Assembler::patchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue, ImmPtr expectedValue)
+Assembler::patchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue,
+                                   PatchedImmPtr expectedValue)
 {
     Instruction *ptr = (Instruction *) label.raw();
     InstructionIterator iter(ptr);
     Register dest;
     Assembler::RelocStyle rs;
     DebugOnly<const uint32_t *> val = getPtr32Target(&iter, &dest, &rs);
     JS_ASSERT((uint32_t)(const uint32_t *)val == uint32_t(expectedValue.value));
     reinterpret_cast<MacroAssemblerARM*>(dummy)->ma_movPatchable(Imm32(int32_t(newValue.value)),
                                                                  dest, Always, rs, ptr);
     // L_LDR won't cause any instructions to be updated.
     if (rs != L_LDR) {
         AutoFlushCache::updateTop(uintptr_t(ptr), 4);
         AutoFlushCache::updateTop(uintptr_t(ptr->next()), 4);
     }
 }
 
+void
+Assembler::patchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue, ImmPtr expectedValue)
+{
+    patchDataWithValueCheck(label, PatchedImmPtr(newValue.value), PatchedImmPtr(expectedValue.value));
+}
+
 // This just stomps over memory with 32 bits of raw data. Its purpose is to
 // overwrite the call of JITed code with 32 bits worth of an offset. This will
 // is only meant to function on code that has been invalidated, so it should
 // be totally safe. Since that instruction will never be executed again, a
 // ICache flush should not be necessary
 void
 Assembler::patchWrite_Imm32(CodeLocationLabel label, Imm32 imm) {
     // Raw is going to be the return address.
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1256,16 +1256,17 @@ class Assembler
 
     // TODO: this should actually be a pool-like object
     //       It is currently a big hack, and probably shouldn't exist
     js::Vector<CodeLabel, 0, SystemAllocPolicy> codeLabels_;
     js::Vector<RelativePatch, 8, SystemAllocPolicy> jumps_;
     js::Vector<BufferOffset, 0, SystemAllocPolicy> tmpJumpRelocations_;
     js::Vector<BufferOffset, 0, SystemAllocPolicy> tmpDataRelocations_;
     js::Vector<BufferOffset, 0, SystemAllocPolicy> tmpPreBarriers_;
+    AsmJSAbsoluteLinkVector asmJSAbsoluteLinks_;
 
     CompactBufferWriter jumpRelocations_;
     CompactBufferWriter dataRelocations_;
     CompactBufferWriter relocations_;
     CompactBufferWriter preBarriers_;
 
     bool enoughMemory_;
 
@@ -1377,16 +1378,23 @@ class Assembler
     bool addCodeLabel(CodeLabel label);
     size_t numCodeLabels() const {
         return codeLabels_.length();
     }
     CodeLabel codeLabel(size_t i) {
         return codeLabels_[i];
     }
 
+    size_t numAsmJSAbsoluteLinks() const {
+        return asmJSAbsoluteLinks_.length();
+    }
+    AsmJSAbsoluteLink asmJSAbsoluteLink(size_t i) const {
+        return asmJSAbsoluteLinks_[i];
+    }
+
     // Size of the instruction stream, in bytes.
     size_t size() const;
     // Size of the jump relocation table, in bytes.
     size_t jumpRelocationTableBytes() const;
     size_t dataRelocationTableBytes() const;
     size_t preBarrierTableBytes() const;
 
     // Size of the data table, in bytes.
@@ -1790,16 +1798,18 @@ class Assembler
     static void writePoolHeader(uint8_t *start, Pool *p, bool isNatural);
     static void writePoolFooter(uint8_t *start, Pool *p, bool isNatural);
     static void writePoolGuard(BufferOffset branch, Instruction *inst, BufferOffset dest);
 
 
     static uint32_t patchWrite_NearCallSize();
     static uint32_t nopSize() { return 4; }
     static void patchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall);
+    static void patchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue,
+                                        PatchedImmPtr expectedValue);
     static void patchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
                                         ImmPtr expectedValue);
     static void patchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
     static uint32_t alignDoubleArg(uint32_t offset) {
         return (offset+1)&~1;
     }
     static uint8_t *nextInstruction(uint8_t *instruction, uint32_t *count = NULL);
     // Toggle a jmp or cmp emitted by toggledJump().
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -604,17 +604,20 @@ CodeGeneratorARM::visitSoftDivI(LSoftDiv
 
     Label done;
     if (!divICommon(mir, lhs, rhs, output, ins->snapshot(), done))
         return false;
 
     masm.setupAlignedABICall(2);
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
+    if (gen->compilingAsmJS())
+        masm.callWithABI(AsmJSImm_aeabi_idivmod);
+    else
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
     // idivmod returns the quotient in r0, and the remainder in r1.
     if (!mir->isTruncated()) {
         JS_ASSERT(mir->fallible());
         masm.ma_cmp(r1, Imm32(0));
         if (!bailoutIf(Assembler::NonZero, ins->snapshot()))
             return false;
     }
 
@@ -762,17 +765,20 @@ CodeGeneratorARM::visitSoftModI(LSoftMod
     }
 
     if (!modICommon(mir, lhs, rhs, output, ins->snapshot(), done))
         return false;
 
     masm.setupAlignedABICall(2);
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
+    if (gen->compilingAsmJS())
+        masm.callWithABI(AsmJSImm_aeabi_idivmod);
+    else
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
 
     // If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
     if (mir->isTruncated()) {
         // -0.0|0 == 0
     } else {
         JS_ASSERT(mir->fallible());
         // See if X < 0
         masm.ma_cmp(r1, Imm32(0));
@@ -2032,17 +2038,20 @@ CodeGeneratorARM::visitSoftUDivOrMod(LSo
     masm.ma_b(&notzero, Assembler::NonZero);
     masm.ma_mov(Imm32(0), output);
     masm.ma_b(&afterDiv);
     masm.bind(&notzero);
 
     masm.setupAlignedABICall(2);
     masm.passABIArg(lhs);
     masm.passABIArg(rhs);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_uidivmod));
+    if (gen->compilingAsmJS())
+        masm.callWithABI(AsmJSImm_aeabi_uidivmod);
+    else
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_uidivmod));
 
     masm.bind(&afterDiv);
     return true;
 }
 
 bool
 CodeGeneratorARM::visitEffectiveAddress(LEffectiveAddress *ins)
 {
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -371,18 +371,18 @@ Instruction *
 NextInst(Instruction *i)
 {
     if (i == NULL)
         return NULL;
     return i->next();
 }
 
 void
-MacroAssemblerARM::ma_movPatchable(Imm32 imm_, Register dest,
-                                   Assembler::Condition c, RelocStyle rs, Instruction *i)
+MacroAssemblerARM::ma_movPatchable(Imm32 imm_, Register dest, Assembler::Condition c,
+                                   RelocStyle rs, Instruction *i)
 {
     int32_t imm = imm_.value;
     if (i) {
         // Make sure the current instruction is not an artificial guard
         // inserted by the assembler buffer.
         // The InstructionIterator already does this and handles edge cases,
         // so, just asking an iterator for its current instruction should be
         // enough to make sure we don't accidentally inspect an artificial guard.
@@ -1890,16 +1890,29 @@ MacroAssemblerARMCompat::movePtr(const I
     ma_mov(imm, dest);
 }
 void
 MacroAssemblerARMCompat::movePtr(const ImmPtr &imm, const Register &dest)
 {
     movePtr(ImmWord(uintptr_t(imm.value)), dest);
 }
 void
+MacroAssemblerARMCompat::movePtr(const AsmJSImmPtr &imm, const Register &dest)
+{
+    RelocStyle rs;
+    if (hasMOVWT())
+        rs = L_MOVWT;
+    else
+        rs = L_LDR;
+
+    AsmJSAbsoluteLink link(nextOffset().getOffset(), imm.kind());
+    enoughMemory_ &= asmJSAbsoluteLinks_.append(link);
+    ma_movPatchable(Imm32(-1), dest, Always, rs);
+}
+void
 MacroAssemblerARMCompat::load8ZeroExtend(const Address &address, const Register &dest)
 {
     ma_dataTransferN(IsLoad, 8, false, address.base, Imm32(address.offset), dest);
 }
 
 void
 MacroAssemblerARMCompat::load8ZeroExtend(const BaseIndex &src, const Register &dest)
 {
@@ -2033,16 +2046,22 @@ MacroAssemblerARMCompat::loadPtr(const B
     ma_ldr(DTRAddr(base, DtrRegImmShift(src.index, LSL, scale)), dest);
 }
 void
 MacroAssemblerARMCompat::loadPtr(const AbsoluteAddress &address, const Register &dest)
 {
     movePtr(ImmWord(uintptr_t(address.addr)), ScratchRegister);
     loadPtr(Address(ScratchRegister, 0x0), dest);
 }
+void
+MacroAssemblerARMCompat::loadPtr(const AsmJSAbsoluteAddress &address, const Register &dest)
+{
+    movePtr(AsmJSImmPtr(address.kind()), ScratchRegister);
+    loadPtr(Address(ScratchRegister, 0x0), dest);
+}
 
 Operand payloadOf(const Address &address) {
     return Operand(address.base, address.offset);
 }
 Operand tagOf(const Address &address) {
     return Operand(address.base, address.offset + 4);
 }
 
@@ -3287,25 +3306,25 @@ MacroAssemblerARM::ma_callIonHalfPush(co
     // We push the pc to the stack to align the stack before the call, when we
     // return the pc is poped and the stack is restored to its unaligned state.
     AutoForbidPools afp(this);
     ma_push(pc);
     as_blx(r);
 }
 
 void
-MacroAssemblerARM::ma_call(void *dest)
+MacroAssemblerARM::ma_call(ImmPtr dest)
 {
     RelocStyle rs;
     if (hasMOVWT())
         rs = L_MOVWT;
     else
         rs = L_LDR;
 
-    ma_movPatchable(Imm32((uint32_t) dest), CallReg, Always, rs);
+    ma_movPatchable(dest, CallReg, Always, rs);
     as_blx(CallReg);
 }
 
 void
 MacroAssemblerARMCompat::breakpoint()
 {
     as_bkpt();
 }
@@ -3556,17 +3575,26 @@ MacroAssemblerARMCompat::callWithABIPost
     inCall_ = false;
 }
 
 void
 MacroAssemblerARMCompat::callWithABI(void *fun, Result result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    ma_call(fun);
+    ma_call(ImmPtr(fun));
+    callWithABIPost(stackAdjust, result);
+}
+
+void
+MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, Result result)
+{
+    uint32_t stackAdjust;
+    callWithABIPre(&stackAdjust);
+    call(imm);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerARMCompat::callWithABI(const Address &fun, Result result)
 {
     // Load the callee in r12, no instruction between the ldr and call
     // should clobber it. Note that we can't use fun.base because it may
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -369,17 +369,17 @@ class MacroAssemblerARM : public Assembl
     BufferOffset ma_vstr(VFPRegister src, Register base, Register index, int32_t shift = defaultShift, Condition cc = Always);
     // calls an Ion function, assumes that the stack is untouched (8 byte alinged)
     void ma_callIon(const Register reg);
     // callso an Ion function, assuming that sp has already been decremented
     void ma_callIonNoPush(const Register reg);
     // calls an ion function, assuming that the stack is currently not 8 byte aligned
     void ma_callIonHalfPush(const Register reg);
 
-    void ma_call(void *dest);
+    void ma_call(ImmPtr dest);
 
     // Float registers can only be loaded/stored in continuous runs
     // when using vstm/vldm.
     // This function breaks set into continuous runs and loads/stores
     // them at [rm]. rm will be modified and left in a state logically
     // suitable for the next load/store.
     // Returns the offset from [dm] for the logical next load/store.
     int32_t transferMultipleByRuns(FloatRegisterSet set, LoadStore ls,
@@ -537,40 +537,44 @@ class MacroAssemblerARMCompat : public M
         as_bl(label, Always);
     }
     void call(ImmWord imm) {
         call(ImmPtr((void*)imm.value));
     }
     void call(ImmPtr imm) {
         BufferOffset bo = m_buffer.nextOffset();
         addPendingJump(bo, imm, Relocation::HARDCODED);
-        ma_call(imm.value);
+        ma_call(imm);
+    }
+    void call(AsmJSImmPtr imm) {
+        movePtr(imm, CallReg);
+        call(CallReg);
     }
     void call(IonCode *c) {
         BufferOffset bo = m_buffer.nextOffset();
         addPendingJump(bo, ImmPtr(c->raw()), Relocation::IONCODE);
         RelocStyle rs;
         if (hasMOVWT())
             rs = L_MOVWT;
         else
             rs = L_LDR;
 
-        ma_movPatchable(Imm32((int) c->raw()), ScratchRegister, Always, rs);
+        ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
         ma_callIonHalfPush(ScratchRegister);
     }
     void branch(IonCode *c) {
         BufferOffset bo = m_buffer.nextOffset();
         addPendingJump(bo, ImmPtr(c->raw()), Relocation::IONCODE);
         RelocStyle rs;
         if (hasMOVWT())
             rs = L_MOVWT;
         else
             rs = L_LDR;
 
-        ma_movPatchable(Imm32((int) c->raw()), ScratchRegister, Always, rs);
+        ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
         ma_bx(ScratchRegister);
     }
     void branch(const Register reg) {
         ma_bx(reg);
     }
     void nop() {
         ma_nop();
     }
@@ -930,16 +934,20 @@ class MacroAssemblerARMCompat : public M
         branchPtr(cond, lhs, ScratchRegister, label);
     }
     void branchPtr(Condition cond, Register lhs, ImmWord imm, Label *label) {
         branch32(cond, lhs, Imm32(imm.value), label);
     }
     void branchPtr(Condition cond, Register lhs, ImmPtr imm, Label *label) {
         branchPtr(cond, lhs, ImmWord(uintptr_t(imm.value)), label);
     }
+    void branchPtr(Condition cond, Register lhs, AsmJSImmPtr imm, Label *label) {
+        movePtr(imm, ScratchRegister);
+        branchPtr(cond, lhs, ScratchRegister, label);
+    }
     void decBranchPtr(Condition cond, const Register &lhs, Imm32 imm, Label *label) {
         subPtr(imm, lhs);
         branch32(cond, lhs, Imm32(0), label);
     }
     void moveValue(const Value &val, Register type, Register data);
 
     CodeOffsetJump jumpWithPatch(RepatchLabel *label, Condition cond = Always);
     template <typename T>
@@ -962,18 +970,23 @@ class MacroAssemblerARMCompat : public M
         ma_ldr(addr, secondScratchReg_);
         ma_cmp(secondScratchReg_, ptr);
         ma_b(label, cond);
     }
     void branchPtr(Condition cond, Address addr, ImmPtr ptr, Label *label) {
         branchPtr(cond, addr, ImmWord(uintptr_t(ptr.value)), label);
     }
     void branchPtr(Condition cond, const AbsoluteAddress &addr, const Register &ptr, Label *label) {
-        loadPtr(addr, secondScratchReg_); // ma_cmp will use the scratch register.
-        ma_cmp(secondScratchReg_, ptr);
+        loadPtr(addr, ScratchRegister);
+        ma_cmp(ScratchRegister, ptr);
+        ma_b(label, cond);
+    }
+    void branchPtr(Condition cond, const AsmJSAbsoluteAddress &addr, const Register &ptr, Label *label) {
+        loadPtr(addr, ScratchRegister);
+        ma_cmp(ScratchRegister, ptr);
         ma_b(label, cond);
     }
     void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *label) {
         loadPtr(lhs, secondScratchReg_); // ma_cmp will use the scratch register.
         ma_cmp(secondScratchReg_, rhs);
         ma_b(label, cond);
     }
     void branch32(Condition cond, const AbsoluteAddress &lhs, const Register &rhs, Label *label) {
@@ -1203,16 +1216,17 @@ class MacroAssemblerARMCompat : public M
     void addPtr(const Address &src, Register dest);
 
     void move32(const Imm32 &imm, const Register &dest);
     void move32(const Register &src, const Register &dest);
 
     void movePtr(const Register &src, const Register &dest);
     void movePtr(const ImmWord &imm, const Register &dest);
     void movePtr(const ImmPtr &imm, const Register &dest);
+    void movePtr(const AsmJSImmPtr &imm, const Register &dest);
     void movePtr(const ImmGCPtr &imm, const Register &dest);
 
     void load8SignExtend(const Address &address, const Register &dest);
     void load8SignExtend(const BaseIndex &src, const Register &dest);
 
     void load8ZeroExtend(const Address &address, const Register &dest);
     void load8ZeroExtend(const BaseIndex &src, const Register &dest);
 
@@ -1224,16 +1238,17 @@ class MacroAssemblerARMCompat : public M
 
     void load32(const Address &address, const Register &dest);
     void load32(const BaseIndex &address, const Register &dest);
     void load32(const AbsoluteAddress &address, const Register &dest);
 
     void loadPtr(const Address &address, const Register &dest);
     void loadPtr(const BaseIndex &src, const Register &dest);
     void loadPtr(const AbsoluteAddress &address, const Register &dest);
+    void loadPtr(const AsmJSAbsoluteAddress &address, const Register &dest);
 
     void loadPrivate(const Address &address, const Register &dest);
 
     void loadDouble(const Address &addr, const FloatRegister &dest);
     void loadDouble(const BaseIndex &src, const FloatRegister &dest);
 
     // Load a float value into a register, then expand it to a double.
     void loadFloatAsDouble(const Address &addr, const FloatRegister &dest);
@@ -1378,16 +1393,17 @@ class MacroAssemblerARMCompat : public M
 
   private:
     void callWithABIPre(uint32_t *stackAdjust);
     void callWithABIPost(uint32_t stackAdjust, Result result);
 
   public:
     // Emits a call to a C/C++ function, resolving all argument moves.
     void callWithABI(void *fun, Result result = GENERAL);
+    void callWithABI(AsmJSImmPtr imm, Result result = GENERAL);
     void callWithABI(const Address &fun, Result result = GENERAL);
 
     CodeOffsetLabel labelForPatch() {
         return CodeOffsetLabel(nextOffset().getOffset());
     }
 
     void computeEffectiveAddress(const Address &address, Register dest) {
         ma_add(address.base, Imm32(address.offset), dest, NoSetCond);
--- a/js/src/jit/shared/Assembler-shared.h
+++ b/js/src/jit/shared/Assembler-shared.h
@@ -99,84 +99,131 @@ struct Imm32
 struct ImmWord
 {
     uintptr_t value;
 
     explicit ImmWord(uintptr_t value) : value(value)
     { }
 };
 
+#ifdef DEBUG
+static inline bool
+IsCompilingAsmJS()
+{
+    // asm.js compilation pushes an IonContext with a null JSCompartment.
+    IonContext *ictx = MaybeGetIonContext();
+    return ictx && ictx->compartment == NULL;
+}
+#endif
+
 // Pointer to be embedded as an immediate in an instruction.
 struct ImmPtr
 {
     void *value;
 
     explicit ImmPtr(const void *value) : value(const_cast<void*>(value))
-    { }
+    {
+        // To make code serialization-safe, asm.js compilation should only
+        // compile pointer immediates using AsmJSImmPtr.
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
 
     template <class R>
     explicit ImmPtr(R (*pf)())
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
-    { }
+    {
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
 
     template <class R, class A1>
     explicit ImmPtr(R (*pf)(A1))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
-    { }
+    {
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
 
     template <class R, class A1, class A2>
     explicit ImmPtr(R (*pf)(A1, A2))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
-    { }
+    {
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
 
     template <class R, class A1, class A2, class A3>
     explicit ImmPtr(R (*pf)(A1, A2, A3))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
-    { }
+    {
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
 
     template <class R, class A1, class A2, class A3, class A4>
     explicit ImmPtr(R (*pf)(A1, A2, A3, A4))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
+    {
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
+
+};
+
+// The same as ImmPtr except that the intention is to patch this
+// instruction. The initial value of the immediate is 'addr' and this value is
+// either clobbered or used in the patching process.
+struct PatchedImmPtr {
+    void *value;
+
+    explicit PatchedImmPtr()
+      : value(NULL)
     { }
-
+    explicit PatchedImmPtr(const void *value)
+      : value(const_cast<void*>(value))
+    { }
 };
 
 // Used for immediates which require relocation.
 struct ImmGCPtr
 {
     uintptr_t value;
 
     explicit ImmGCPtr(const gc::Cell *ptr) : value(reinterpret_cast<uintptr_t>(ptr))
     {
         JS_ASSERT(!IsPoisonedPtr(ptr));
         JS_ASSERT_IF(ptr, ptr->isTenured());
+
+        // asm.js shouldn't be creating GC things
+        JS_ASSERT(!IsCompilingAsmJS());
     }
 
   protected:
     ImmGCPtr() : value(0) {}
 };
 
 // Used for immediates which require relocation and may be traced during minor GC.
 struct ImmMaybeNurseryPtr : public ImmGCPtr
 {
     explicit ImmMaybeNurseryPtr(gc::Cell *ptr)
     {
         this->value = reinterpret_cast<uintptr_t>(ptr);
         JS_ASSERT(!IsPoisonedPtr(ptr));
+
+        // asm.js shouldn't be creating GC things
+        JS_ASSERT(!IsCompilingAsmJS());
     }
 };
 
 // Pointer to be embedded as an immediate that is loaded/stored from by an
 // instruction.
 struct AbsoluteAddress {
     void *addr;
 
     explicit AbsoluteAddress(const void *addr)
       : addr(const_cast<void*>(addr))
-    { }
+    {
+        // asm.js shouldn't be creating GC things
+        JS_ASSERT(!IsCompilingAsmJS());
+    }
 
     AbsoluteAddress offset(ptrdiff_t delta) {
         return AbsoluteAddress(((uint8_t *) addr) + delta);
     }
 };
 
 // The same as AbsoluteAddress except that the intention is to patch this
 // instruction. The initial value of the immediate is 'addr' and this value is
@@ -620,13 +667,82 @@ struct AsmJSGlobalAccess
 
     AsmJSGlobalAccess(CodeOffsetLabel patchAt, unsigned globalDataOffset)
       : patchAt(patchAt), globalDataOffset(globalDataOffset)
     {}
 };
 
 typedef Vector<AsmJSGlobalAccess, 0, IonAllocPolicy> AsmJSGlobalAccessVector;
 
+// Describes the intended pointee of an immediate to be embedded in asm.js
+// code. By representing the pointee as a symbolic enum, the pointee can be
+// patched after deserialization when the address of global things has changed.
+enum AsmJSImmKind
+{
+    AsmJSImm_Runtime,
+    AsmJSImm_StackLimit,
+    AsmJSImm_ReportOverRecursed,
+    AsmJSImm_HandleExecutionInterrupt,
+    AsmJSImm_InvokeFromAsmJS_Ignore,
+    AsmJSImm_InvokeFromAsmJS_ToInt32,
+    AsmJSImm_InvokeFromAsmJS_ToNumber,
+    AsmJSImm_CoerceInPlace_ToInt32,
+    AsmJSImm_CoerceInPlace_ToNumber,
+    AsmJSImm_ToInt32,
+    AsmJSImm_EnableActivationFromAsmJS,
+    AsmJSImm_DisableActivationFromAsmJS,
+#if defined(JS_CPU_ARM)
+    AsmJSImm_aeabi_idivmod,
+    AsmJSImm_aeabi_uidivmod,
+#endif
+    AsmJSImm_ModD,
+    AsmJSImm_SinD,
+    AsmJSImm_CosD,
+    AsmJSImm_TanD,
+    AsmJSImm_ASinD,
+    AsmJSImm_ACosD,
+    AsmJSImm_ATanD,
+    AsmJSImm_CeilD,
+    AsmJSImm_FloorD,
+    AsmJSImm_ExpD,
+    AsmJSImm_LogD,
+    AsmJSImm_PowD,
+    AsmJSImm_ATan2D
+};
+
+// Pointer to be embedded as an immediate in asm.js code.
+class AsmJSImmPtr
+{
+    AsmJSImmKind kind_;
+  public:
+    AsmJSImmKind kind() const { return kind_; }
+    AsmJSImmPtr(AsmJSImmKind kind) : kind_(kind) { JS_ASSERT(IsCompilingAsmJS()); }
+    AsmJSImmPtr() {}
+};
+
+// Pointer to be embedded as an immediate that is loaded/stored from by an
+// instruction in asm.js code.
+class AsmJSAbsoluteAddress
+{
+    AsmJSImmKind kind_;
+  public:
+    AsmJSImmKind kind() const { return kind_; }
+    AsmJSAbsoluteAddress(AsmJSImmKind kind) : kind_(kind) { JS_ASSERT(IsCompilingAsmJS()); }
+    AsmJSAbsoluteAddress() {}
+};
+
+// Represents an instruction to be patched and the intended pointee. These
+// links are accumulated in the MacroAssembler, but patching is done outside
+// the MacroAssembler (in AsmJSModule::staticallyLink).
+struct AsmJSAbsoluteLink
+{
+    AsmJSAbsoluteLink(CodeOffsetLabel patchAt, AsmJSImmKind target)
+      : patchAt(patchAt), target(target) {}
+    CodeOffsetLabel patchAt;
+    AsmJSImmKind target;
+};
+
+typedef Vector<AsmJSAbsoluteLink, 0, SystemAllocPolicy> AsmJSAbsoluteLinkVector;
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_shared_Assembler_shared_h */
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -126,16 +126,17 @@ class AssemblerX86Shared
           : offset(offset),
             target(target),
             kind(kind)
         { }
     };
 
     Vector<CodeLabel, 0, SystemAllocPolicy> codeLabels_;
     Vector<RelativePatch, 8, SystemAllocPolicy> jumps_;
+    AsmJSAbsoluteLinkVector asmJSAbsoluteLinks_;
     CompactBufferWriter jumpRelocations_;
     CompactBufferWriter dataRelocations_;
     CompactBufferWriter preBarriers_;
     bool enoughMemory_;
 
     void writeDataRelocation(const Value &val) {
         if (val.isMarkable()) {
             JS_ASSERT(static_cast<gc::Cell*>(val.toGCThing())->isTenured());
@@ -287,16 +288,23 @@ class AssemblerX86Shared
     }
     size_t numCodeLabels() const {
         return codeLabels_.length();
     }
     CodeLabel codeLabel(size_t i) {
         return codeLabels_[i];
     }
 
+    size_t numAsmJSAbsoluteLinks() const {
+        return asmJSAbsoluteLinks_.length();
+    }
+    const AsmJSAbsoluteLink &asmJSAbsoluteLink(size_t i) const {
+        return asmJSAbsoluteLinks_[i];
+    }
+
     // Size of the instruction stream, in bytes.
     size_t size() const {
         return masm.size();
     }
     // Size of the jump relocation table, in bytes.
     size_t jumpRelocationTableBytes() const {
         return jumpRelocations_.length();
     }
@@ -1577,23 +1585,26 @@ class AssemblerX86Shared
         JS_ASSERT(int32_t(offset) == offset);
         *((int32_t *) (start + 1)) = offset;
     }
 
     static void patchWrite_Imm32(CodeLocationLabel dataLabel, Imm32 toWrite) {
         *((int32_t *) dataLabel.raw() - 1) = toWrite.value;
     }
 
-    static void patchDataWithValueCheck(CodeLocationLabel data, ImmPtr newData,
-                                        ImmPtr expectedData) {
+    static void patchDataWithValueCheck(CodeLocationLabel data, PatchedImmPtr newData,
+                                        PatchedImmPtr expectedData) {
         // The pointer given is a pointer to *after* the data.
         uintptr_t *ptr = ((uintptr_t *) data.raw()) - 1;
         JS_ASSERT(*ptr == (uintptr_t)expectedData.value);
         *ptr = (uintptr_t)newData.value;
     }
+    static void patchDataWithValueCheck(CodeLocationLabel data, ImmPtr newData, ImmPtr expectedData) {
+        patchDataWithValueCheck(data, PatchedImmPtr(newData.value), PatchedImmPtr(expectedData.value));
+    }
     static uint32_t nopSize() {
         return 1;
     }
     static uint8_t *nextInstruction(uint8_t *cur, uint32_t *count) {
         MOZ_ASSUME_UNREACHABLE("nextInstruction NYI on x86");
     }
 
     // Toggle a jmp or cmp emitted by toggledJump().
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -701,17 +701,20 @@ CodeGeneratorShared::visitOutOfLineTrunc
 {
     FloatRegister src = ool->src();
     Register dest = ool->dest();
 
     saveVolatile(dest);
 
     masm.setupUnalignedABICall(1, dest);
     masm.passABIArg(src);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
+    if (gen->compilingAsmJS())
+        masm.callWithABI(AsmJSImm_ToInt32);
+    else
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
     masm.storeCallResult(dest);
 
     restoreVolatile(dest);
 
     masm.jump(ool->rejoin());
     return true;
 }
 
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -480,16 +480,21 @@ class Assembler : public AssemblerX86Sha
     }
 
     void mov(ImmWord word, const Register &dest) {
         movq(word, dest);
     }
     void mov(ImmPtr imm, const Register &dest) {
         movq(imm, dest);
     }
+    void mov(AsmJSImmPtr imm, const Register &dest) {
+        masm.movq_i64r(-1, dest.code());
+        AsmJSAbsoluteLink link(masm.currentOffset(), imm.kind());
+        enoughMemory_ &= asmJSAbsoluteLinks_.append(link);
+    }
     void mov(const Imm32 &imm32, const Register &dest) {
         movl(imm32, dest);
     }
     void mov(const Operand &src, const Register &dest) {
         movq(src, dest);
     }
     void mov(const Register &src, const Operand &dest) {
         movq(src, dest);
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -232,16 +232,25 @@ void
 MacroAssemblerX64::callWithABI(void *fun, Result result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
     call(ImmPtr(fun));
     callWithABIPost(stackAdjust, result);
 }
 
+void
+MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, Result result)
+{
+    uint32_t stackAdjust;
+    callWithABIPre(&stackAdjust);
+    call(imm);
+    callWithABIPost(stackAdjust, result);
+}
+
 static bool
 IsIntArgReg(Register reg)
 {
     for (uint32_t i = 0; i < NumIntArgRegs; i++) {
         if (IntArgRegs[i] == reg)
             return true;
     }
 
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -106,16 +106,20 @@ class MacroAssemblerX64 : public MacroAs
     /////////////////////////////////////////////////////////////////
     void call(ImmWord target) {
         mov(target, rax);
         call(rax);
     }
     void call(ImmPtr target) {
         call(ImmWord(uintptr_t(target.value)));
     }
+    void call(AsmJSImmPtr target) {
+        mov(target, rax);
+        call(rax);
+    }
 
     // Refers to the upper 32 bits of a 64-bit Value operand.
     // On x86_64, the upper 32 bits do not necessarily only contain the type.
     Operand ToUpper32(Operand base) {
         switch (base.kind()) {
           case Operand::MEM_REG_DISP:
             return Operand(Register::FromCode(base.base()), base.disp() + 4);
 
@@ -540,16 +544,21 @@ class MacroAssemblerX64 : public MacroAs
         JS_ASSERT(ptr != ScratchReg);
         if (JSC::X86Assembler::isAddressImmediate(addr.addr)) {
             branchPtr(cond, Operand(addr), ptr, label);
         } else {
             mov(ImmPtr(addr.addr), ScratchReg);
             branchPtr(cond, Operand(ScratchReg, 0x0), ptr, label);
         }
     }
+    void branchPtr(Condition cond, const AsmJSAbsoluteAddress &addr, const Register &ptr, Label *label) {
+        JS_ASSERT(ptr != ScratchReg);
+        mov(AsmJSImmPtr(addr.kind()), ScratchReg);
+        branchPtr(cond, Operand(ScratchReg, 0x0), ptr, label);
+    }
 
     void branchPrivatePtr(Condition cond, Address lhs, ImmPtr ptr, Label *label) {
         branchPtr(cond, lhs, ImmWord(uintptr_t(ptr.value) >> 1), label);
     }
 
     void branchPrivatePtr(Condition cond, Address lhs, Register ptr, Label *label) {
         if (ptr != ScratchReg)
             movePtr(ptr, ScratchReg);
@@ -606,16 +615,19 @@ class MacroAssemblerX64 : public MacroAs
         movq(src, dest);
     }
     void movePtr(ImmWord imm, Register dest) {
         mov(imm, dest);
     }
     void movePtr(ImmPtr imm, Register dest) {
         mov(imm, dest);
     }
+    void movePtr(AsmJSImmPtr imm, const Register &dest) {
+        mov(imm, dest);
+    }
     void movePtr(ImmGCPtr imm, Register dest) {
         movq(imm, dest);
     }
     void loadPtr(const AbsoluteAddress &address, Register dest) {
         if (JSC::X86Assembler::isAddressImmediate(address.addr)) {
             movq(Operand(address), dest);
         } else {
             mov(ImmPtr(address.addr), ScratchReg);
@@ -1132,16 +1144,17 @@ class MacroAssemblerX64 : public MacroAs
 
   private:
     void callWithABIPre(uint32_t *stackAdjust);
     void callWithABIPost(uint32_t stackAdjust, Result result);
 
   public:
     // Emits a call to a C/C++ function, resolving all argument moves.
     void callWithABI(void *fun, Result result = GENERAL);
+    void callWithABI(AsmJSImmPtr imm, Result result = GENERAL);
     void callWithABI(Address fun, Result result = GENERAL);
 
     void handleFailureWithHandler(void *handler);
     void handleFailureWithHandlerTail();
 
     void makeFrameDescriptor(Register frameSizeReg, FrameType type) {
         shlq(Imm32(FRAMESIZE_SHIFT), frameSizeReg);
         orq(Imm32(type), frameSizeReg);
--- a/js/src/jit/x86/Assembler-x86.h
+++ b/js/src/jit/x86/Assembler-x86.h
@@ -226,16 +226,21 @@ class Assembler : public AssemblerX86Sha
         movl(ImmWord(uintptr_t(imm.value)), dest);
     }
     void mov(ImmWord imm, Register dest) {
         movl(imm, dest);
     }
     void mov(ImmPtr imm, Register dest) {
         movl(imm, dest);
     }
+    void mov(AsmJSImmPtr imm, Register dest) {
+        masm.movl_i32r(-1, dest.code());
+        AsmJSAbsoluteLink link(masm.currentOffset(), imm.kind());
+        enoughMemory_ &= asmJSAbsoluteLinks_.append(link);
+    }
     void mov(Imm32 imm, Register dest) {
         movl(imm, dest);
     }
     void mov(const Operand &src, const Register &dest) {
         movl(src, dest);
     }
     void mov(const Register &src, const Operand &dest) {
         movl(src, dest);
@@ -286,16 +291,21 @@ class Assembler : public AssemblerX86Sha
           case Operand::MEM_ADDRESS32:
             masm.cmpl_im(imm.value, op.address());
             writeDataRelocation(imm);
             break;
           default:
             MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
+    void cmpl(const AsmJSAbsoluteAddress &lhs, const Register &rhs) {
+        masm.cmpl_rm_force32(rhs.code(), (void*)-1);
+        AsmJSAbsoluteLink link(masm.currentOffset(), lhs.kind());
+        enoughMemory_ &= asmJSAbsoluteLinks_.append(link);
+    }
     CodeOffsetLabel cmplWithPatch(const Register &lhs, Imm32 rhs) {
         masm.cmpl_ir_force32(rhs.value, lhs.code());
         return masm.currentOffset();
     }
 
     void jmp(ImmPtr target, Relocation::Kind reloc = Relocation::HARDCODED) {
         JmpSrc src = masm.jmp();
         addPendingJump(src, target, reloc);
@@ -318,16 +328,23 @@ class Assembler : public AssemblerX86Sha
     }
     void call(ImmWord target) {
         call(ImmPtr((void*)target.value));
     }
     void call(ImmPtr target) {
         JmpSrc src = masm.call();
         addPendingJump(src, target, Relocation::HARDCODED);
     }
+    void call(AsmJSImmPtr target) {
+        // Moving to a register is suboptimal. To fix (use a single
+        // call-immediate instruction) we'll need to distinguish a new type of
+        // relative patch to an absolute address in AsmJSAbsoluteLink.
+        mov(target, eax);
+        call(eax);
+    }
 
     // Emit a CALL or CMP (nop) instruction. ToggleCall can be used to patch
     // this instruction.
     CodeOffsetLabel toggledCall(IonCode *target, bool enabled) {
         CodeOffsetLabel offset(size());
         JmpSrc src = enabled ? masm.call() : masm.cmp_eax();
         addPendingJump(src, ImmPtr(target->raw()), Relocation::IONCODE);
         JS_ASSERT(size() - offset.offset() == ToggledCallSize());
--- a/js/src/jit/x86/CodeGenerator-x86.cpp
+++ b/js/src/jit/x86/CodeGenerator-x86.cpp
@@ -854,17 +854,20 @@ CodeGeneratorX86::visitOutOfLineTruncate
     }
 
     masm.bind(&fail);
     {
         saveVolatile(output);
 
         masm.setupUnalignedABICall(1, output);
         masm.passABIArg(input);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
+        if (gen->compilingAsmJS())
+            masm.callWithABI(AsmJSImm_ToInt32);
+        else
+            masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
         masm.storeCallResult(output);
 
         restoreVolatile(output);
     }
 
     masm.jump(ool->rejoin());
     return true;
 }
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -251,16 +251,25 @@ MacroAssemblerX86::callWithABI(void *fun
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
     call(ImmPtr(fun));
     callWithABIPost(stackAdjust, result);
 }
 
 void
+MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, Result result)
+{
+    uint32_t stackAdjust;
+    callWithABIPre(&stackAdjust);
+    call(fun);
+    callWithABIPost(stackAdjust, result);
+}
+
+void
 MacroAssemblerX86::callWithABI(const Address &fun, Result result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
     call(Operand(fun));
     callWithABIPost(stackAdjust, result);
 }
 
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -553,16 +553,22 @@ class MacroAssemblerX86 : public MacroAs
         cmpl(Operand(lhs), rhs);
         j(cond, label);
     }
     void branch32(Condition cond, const AbsoluteAddress &lhs, Register rhs, Label *label) {
         cmpl(Operand(lhs), rhs);
         j(cond, label);
     }
 
+    // Specialization for AsmJSAbsoluteAddress.
+    void branchPtr(Condition cond, AsmJSAbsoluteAddress lhs, Register ptr, Label *label) {
+        cmpl(lhs, ptr);
+        j(cond, label);
+    }
+
     template <typename T, typename S>
     void branchPtr(Condition cond, T lhs, S ptr, Label *label) {
         cmpl(Operand(lhs), ptr);
         j(cond, label);
     }
 
     void branchPrivatePtr(Condition cond, const Address &lhs, ImmPtr ptr, Label *label) {
         branchPtr(cond, lhs, ptr, label);
@@ -619,16 +625,19 @@ class MacroAssemblerX86 : public MacroAs
     }
 
     void movePtr(ImmWord imm, Register dest) {
         movl(Imm32(imm.value), dest);
     }
     void movePtr(ImmPtr imm, Register dest) {
         movl(imm, dest);
     }
+    void movePtr(AsmJSImmPtr imm, Register dest) {
+        mov(imm, dest);
+    }
     void movePtr(ImmGCPtr imm, Register dest) {
         movl(imm, dest);
     }
     void loadPtr(const Address &address, Register dest) {
         movl(Operand(address), dest);
     }
     void loadPtr(const Operand &src, Register dest) {
         movl(src, dest);
@@ -1023,16 +1032,17 @@ class MacroAssemblerX86 : public MacroAs
 
   private:
     void callWithABIPre(uint32_t *stackAdjust);
     void callWithABIPost(uint32_t stackAdjust, Result result);
 
   public:
     // Emits a call to a C/C++ function, resolving all argument moves.
     void callWithABI(void *fun, Result result = GENERAL);
+    void callWithABI(AsmJSImmPtr fun, Result result = GENERAL);
     void callWithABI(const Address &fun, Result result = GENERAL);
 
     // Used from within an Exit frame to handle a pending exception.
     void handleFailureWithHandler(void *handler);
     void handleFailureWithHandlerTail();
 
     void makeFrameDescriptor(Register frameSizeReg, FrameType type) {
         shll(Imm32(FRAMESIZE_SHIFT), frameSizeReg);
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -263,16 +263,18 @@ struct ThreadSafeContext : ContextFriend
 
     // Accessors for immutable runtime data.
     JSAtomState &names() { return runtime_->atomState; }
     StaticStrings &staticStrings() { return runtime_->staticStrings; }
     PropertyName *emptyString() { return runtime_->emptyString; }
     FreeOp *defaultFreeOp() { return runtime_->defaultFreeOp(); }
     bool useHelperThreads() { return runtime_->useHelperThreads(); }
     size_t helperThreadCount() { return runtime_->helperThreadCount(); }
+    void *runtimeAddressForJit() { return runtime_; }
+    void *stackLimitAddress(StackKind kind) { return &runtime_->mainThread.nativeStackLimit[kind]; }
 
     // GCs cannot happen while non-main threads are running.
     uint64_t gcNumber() { return runtime_->gcNumber; }
     size_t gcSystemPageSize() { return runtime_->gcSystemPageSize; }
     bool isHeapBusy() { return runtime_->isHeapBusy(); }
     bool signalHandlersInstalled() const { return runtime_->signalHandlersInstalled(); }
     bool jitSupportsFloatingPoint() const { return runtime_->jitSupportsFloatingPoint; }
 
--- a/js/src/shell/js-gdb.gdb
+++ b/js/src/shell/js-gdb.gdb
@@ -1,18 +1,18 @@
-afe9b1f9b180define hookpost-run
+define hookpost-run
     if ($sigaction)
         call free($sigaction)
         set $sigaction = 0
     end
 end
 
 catch signal SIGSEGV
 commands
     if !$sigaction
         set $sigaction = malloc(sizeof(sigaction))
     end
-    set $ignored = __GI___sigaction(11, 0, $sigaction)
+    set $ignored = __sigaction(11, 0, $sigaction)
     set $handler = ((struct sigaction *)$sigaction)->__sigaction_handler.sa_handler
     if $handler == AsmJSFaultHandler
         continue
     end
 end
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -532,18 +532,18 @@ class PerThreadData : public PerThreadDa
 
     /* See AsmJSActivation comment. Protected by rt->operationCallbackLock. */
     js::AsmJSActivation *asmJSActivationStack_;
 
   public:
     js::Activation *const *addressOfActivation() const {
         return &activation_;
     }
-    js::AsmJSActivation *const *addressOfAsmJSActivationStackReadOnly() const {
-        return &asmJSActivationStack_;
+    static unsigned offsetOfAsmJSActivationStackReadOnly() {
+        return offsetof(PerThreadData, asmJSActivationStack_);
     }
 
     js::AsmJSActivation *asmJSActivationStackFromAnyThread() const {
         return asmJSActivationStack_;
     }
     js::AsmJSActivation *asmJSActivationStackFromOwnerThread() const {
         return asmJSActivationStack_;
     }
--- a/js/xpconnect/src/XPCString.cpp
+++ b/js/xpconnect/src/XPCString.cpp
@@ -14,17 +14,17 @@
  *
  * Exporting a JSString as an nsAReadable:
  * Wrap the JSString with a root-holding XPCJSReadableStringWrapper, which roots
  * the string and exposes its buffer via the nsAString interface, as
  * well as providing refcounting support.
  */
 
 #include "nscore.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsStringBuffer.h"
 #include "jsapi.h"
 #include "xpcpublic.h"
 
 // One-slot cache, because it turns out it's common for web pages to
 // get the same string a few times in a row.  We get about a 40% cache
 // hit rate on this cache last it was measured.  We'd get about 70%
 // hit rate with a hashtable with removal on finalization, but that
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -155,16 +155,17 @@ nsrefcnt
 nsXPCWrappedJS::AddRef(void)
 {
     if (!MOZ_LIKELY(NS_IsMainThread()))
         MOZ_CRASH();
     nsrefcnt cnt = ++mRefCnt;
     NS_LOG_ADDREF(this, cnt, "nsXPCWrappedJS", sizeof(*this));
 
     if (2 == cnt && IsValid()) {
+        GetJSObject(); // Unmark gray JSObject.
         XPCJSRuntime* rt = mClass->GetRuntime();
         rt->AddWrappedJSRoot(this);
     }
 
     return cnt;
 }
 
 nsrefcnt
@@ -241,17 +242,19 @@ nsXPCWrappedJS::GetWeakReference(nsIWeak
         return mRoot->GetWeakReference(aInstancePtr);
 
     return nsSupportsWeakReference::GetWeakReference(aInstancePtr);
 }
 
 JSObject*
 nsXPCWrappedJS::GetJSObject()
 {
-    JS::ExposeObjectToActiveJS(mJSObj);
+    if (mJSObj) {
+        JS::ExposeObjectToActiveJS(mJSObj);
+    }
     return mJSObj;
 }
 
 static bool
 CheckMainThreadOnly(nsXPCWrappedJS *aWrapper)
 {
     if(aWrapper->IsMainThreadOnly())
         return NS_IsMainThread();
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -151,16 +151,20 @@
 #include "nsIScreen.h"
 #include "nsIScreenManager.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTransitionManager.h"
 #include "RestyleManager.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDragSession.h"
 
+#ifdef ANDROID
+#include "nsIDocShellTreeOwner.h"
+#endif
+
 #define ANCHOR_SCROLL_FLAGS \
   (nsIPresShell::SCROLL_OVERFLOW_HIDDEN | nsIPresShell::SCROLL_NO_PARENT_FRAMES)
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
--- a/layout/ipc/RenderFrameUtils.h
+++ b/layout/ipc/RenderFrameUtils.h
@@ -3,16 +3,18 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layer_RenderFrameUtils_h
 #define mozilla_layer_RenderFrameUtils_h
 
+#include "ipc/IPCMessageUtils.h"
+
 namespace mozilla {
 namespace layout {
 
 enum ScrollingBehavior {
   /**
    * Use default scrolling behavior, which is synchronous: web content
    * is reflowed and repainted for every scroll or zoom.
    */
--- a/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.c
+++ b/media/mtransport/third_party/nICEr/src/stun/stun_server_ctx.c
@@ -229,17 +229,17 @@ int nr_stun_server_process_request(nr_st
   {
     int r,_status;
     char string[256];
     nr_stun_message *req = 0;
     nr_stun_message *res = 0;
     nr_stun_server_client *clnt = 0;
     nr_stun_server_request info;
     int error;
-    int dont_free;
+    int dont_free = 0;
 
     r_log(NR_LOG_STUN,LOG_DEBUG,"STUN-SERVER(%s): Received(my_addr=%s,peer_addr=%s)",ctx->label,ctx->my_addr.as_string,peer_addr->as_string);
 
     snprintf(string, sizeof(string)-1, "STUN-SERVER(%s): Received ", ctx->label);
     r_dump(NR_LOG_STUN, LOG_DEBUG, string, (char*)msg, len);
 
     memset(&info,0,sizeof(info));
 
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -401,16 +401,19 @@
 @BINPATH@/components/TCPServerSocket.js
 @BINPATH@/components/TCPSocket.manifest
 
 #ifdef MOZ_WEBRTC
 @BINPATH@/components/PeerConnection.js
 @BINPATH@/components/PeerConnection.manifest
 #endif
 
+@BINPATH@/components/HttpDataUsage.manifest
+@BINPATH@/components/HttpDataUsage.js
+
 #ifdef MOZ_SERVICES_HEALTHREPORT
 @BINPATH@/components/HealthReportComponents.manifest
 @BINPATH@/components/HealthReportService.js
 #endif
 
 #ifdef MOZ_CAPTIVEDETECT
 @BINPATH@/components/CaptivePortalDetectComponents.manifest
 @BINPATH@/components/captivedetect.js
--- a/modules/libpref/src/Preferences.cpp
+++ b/modules/libpref/src/Preferences.cpp
@@ -40,16 +40,17 @@
 #include "prefapi_private_data.h"
 
 #include "mozilla/Omnijar.h"
 #include "nsZipArchive.h"
 
 #include "nsTArray.h"
 #include "nsRefPtrHashtable.h"
 #include "nsIMemoryReporter.h"
+#include "nsThreadUtils.h"
 
 class PrefCallback;
 
 namespace mozilla {
 
 // Definitions
 #define INITIAL_PREF_FILES 10
 static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
--- a/netwerk/base/src/BackgroundFileSaver.cpp
+++ b/netwerk/base/src/BackgroundFileSaver.cpp
@@ -10,16 +10,17 @@
 
 #include "nsIFile.h"
 #include "nsIPipe.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 
 #include "BackgroundFileSaver.h"
 #include "mozilla/Telemetry.h"
+#include "nsIAsyncInputStream.h"
 
 namespace mozilla {
 namespace net {
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Globals
 
 /**
--- a/netwerk/base/src/nsDirectoryIndexStream.cpp
+++ b/netwerk/base/src/nsDirectoryIndexStream.cpp
@@ -12,16 +12,17 @@
 
   http://www.mozilla.org/projects/netlib/dirindexformat.html
 
  */
 
 #include "nsEscape.h"
 #include "nsDirectoryIndexStream.h"
 #include "prlog.h"
+#include "prtime.h"
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gLog;
 #endif
 
 #include "nsISimpleEnumerator.h"
 #ifdef THREADSAFE_I18N
 #include "nsCollationCID.h"
 #include "nsICollation.h"
--- a/netwerk/cache/nsDeleteDir.cpp
+++ b/netwerk/cache/nsDeleteDir.cpp
@@ -9,16 +9,17 @@
 #include "nsString.h"
 #include "mozilla/Telemetry.h"
 #include "nsITimer.h"
 #include "nsISimpleEnumerator.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "nsISupportsPriority.h"
 #include "nsCacheUtils.h"
+#include "prtime.h"
 #include <time.h>
 
 using namespace mozilla;
 
 class nsBlockOnBackgroundThreadEvent : public nsRunnable {
 public:
   nsBlockOnBackgroundThreadEvent() {}
   NS_IMETHOD Run()
--- a/netwerk/protocol/about/nsAboutCacheEntry.cpp
+++ b/netwerk/protocol/about/nsAboutCacheEntry.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAboutCacheEntry.h"
 #include "nsICacheService.h"
 #include "nsICacheSession.h"
 #include "nsNetUtil.h"
 #include "prprf.h"
 #include "nsEscape.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
 #include <algorithm>
 
 #define HEXDUMP_MAX_ROWS 16
 
 static void
 HexDump(uint32_t *state, const char *buf, int32_t n, nsCString &result)
 {
   char temp[16];
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/HttpDataUsage.js
@@ -0,0 +1,222 @@
+/* -*- indent-tabs-mode: nil -*- */
+/* 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/. */
+
+/* HTTPDATA_* telemetry producer
+   every 3 minutes of idle time we update a data file and report it
+   once a day. this avoids adding io to the shutdown path
+*/
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+const CC = Components.Constructor;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "idleService",
+                                   "@mozilla.org/widget/idleservice;1",
+                                   "nsIIdleService");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+                                  "resource://gre/modules/FileUtils.jsm");
+
+const MB = 1000000;
+
+var gDataUsage;
+function HttpDataUsage() {}
+HttpDataUsage.prototype = {
+    classID: Components.ID("{6d72bfca-2747-4859-887f-6f06d4ce6787}"),
+    QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+    contractID: "@mozilla.org/network/HttpDataUsage;1",
+
+    _isIdleObserver: false,
+    _locked : false,
+    _do_telemetry : false,
+    _idle_timeout : 60 * 3,
+    _quanta : 86400000, // per day
+
+    _logtime : new Date(),
+    _ethernetRead : 0,
+    _ethernetWritten : 0,
+    _cellRead : 0,
+    _cellWritten : 0,
+
+    _dataFile : FileUtils.getFile("ProfD", ["httpDataUsage.dat"], true),
+    _dataUsage : Cc["@mozilla.org/network/protocol;1?name=http"]
+        .getService(Ci.nsIHttpProtocolHandler)
+        .QueryInterface(Ci.nsIHttpDataUsage),
+    _pipe : CC("@mozilla.org/pipe;1", "nsIPipe", "init"),
+    _outputStream : CC("@mozilla.org/network/file-output-stream;1",
+                       "nsIFileOutputStream", "init"),
+
+    setup: function setup() {
+        gDataUsage = this;
+
+        var enabled = false;
+        try {
+            if (Services.prefs.getBoolPref("toolkit.telemetry.enabled"))
+                enabled = true;
+        } catch (e) { }
+        try {
+            if (Services.prefs.getBoolPref("toolkit.telemetry.enabledPreRelease"))
+                enabled = true;
+        } catch (e) { }
+
+        // this isn't important enough to worry about getting a
+        // runtime telemetry config change for
+        if (!enabled)
+            return;
+
+        if (this._dataUsage == null)
+            return;
+
+        idleService.addIdleObserver(this, this._idle_timeout);
+        this._isIdleObserver = true;
+    },
+    
+    shutdown: function shutdown() {
+        if (this._isIdleObserver)
+            idleService.removeIdleObserver(this, this._idle_timeout);
+        this._isIdleObserver = false;
+    },
+
+    sUpdateStats2: function sUpdateStats2(stream, result) {
+        gDataUsage.updateStats2(stream, result);
+    },
+
+    sGatherTelemetry2: function sGatherTelemetry2(stream, result) {
+        gDataUsage.gatherTelemetry2(stream, result);
+    },
+
+    readCounters: function readCounters(stream, result) {
+        if (Components.isSuccessCode(result)) {
+            let count = stream.available();
+            let data = NetUtil.readInputStreamToString(stream, count);
+            var list = data.split(",");
+            if (list.length == 5) {
+                this._logtime = new Date(Number(list[0]));
+                this._ethernetRead = Number(list[1]);
+                this._ethernetWritten = Number(list[2]);
+                this._cellRead = Number(list[3]);
+                this._cellWritten = Number(list[4]);
+            }
+        }
+
+        this._ethernetRead += this._dataUsage.ethernetBytesRead;
+        this._ethernetWritten += this._dataUsage.ethernetBytesWritten;
+        this._cellRead += this._dataUsage.cellBytesRead;
+        this._cellWritten += this._dataUsage.cellBytesWritten;
+        this._dataUsage.resetHttpDataUsage();
+    },
+
+    // writeCounters also releases the lock
+    writeCounters: function writeCounters() {
+        var dataout = this._logtime.getTime().toString() + "," +
+            this._ethernetRead.toString() + "," +
+            this._ethernetWritten.toString() + "," +
+            this._cellRead.toString() + "," +
+            this._cellWritten.toString() + "\n";
+
+        var buffer = new this._pipe(true, false, 4096, 1, null);
+        buffer.outputStream.write(dataout, dataout.length);
+        buffer.outputStream.close();
+        var fileOut = new this._outputStream(this._dataFile, -1, -1, 0);
+
+        NetUtil.asyncCopy(buffer.inputStream, fileOut,
+                          function (result) { gDataUsage.finishedWriting(); });
+    },
+
+    updateStats2: function updateStats2(stream, result) {
+        this.readCounters(stream, result);
+        this.writeCounters();
+    },
+
+    gatherTelemetry2: function gatherTelemetry2(stream, result) {
+        this.readCounters(stream, result);
+
+        var now = new Date();
+        var elapsed = now.getTime() - this._logtime.getTime();
+        // make sure we have at least 1 day of data
+        if (elapsed < this._quanta) {
+            this.finishedWriting();
+            return;
+        }
+
+        var days = elapsed / this._quanta;
+        var eInPerQuanta = Math.floor(this._ethernetRead / days);
+        var eOutPerQuanta = Math.floor(this._ethernetWritten / days);
+        var cInPerQuanta = Math.floor(this._cellRead / days);
+        var cOutPerQuanta = Math.floor(this._cellWritten / days);
+        
+        var histogram;
+
+        while (elapsed >= this._quanta) {
+            histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_ETHERNET_IN");
+            histogram.add(Math.round(eInPerQuanta / MB));
+            histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_ETHERNET_OUT");
+            histogram.add(Math.round(eOutPerQuanta / MB));
+            histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_CELL_IN");
+            histogram.add(Math.round(cInPerQuanta / MB));
+            histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_CELL_OUT");
+            histogram.add(Math.round(cOutPerQuanta / MB));
+
+            elapsed -= this._quanta;
+            this._ethernetRead -= eInPerQuanta;
+            this._ethernetWritten -= eOutPerQuanta;
+            this._cellRead -= cInPerQuanta;
+            this._cellWritten -= cOutPerQuanta;
+        }
+        this._logtime = new Date(now.getTime() - elapsed);
+        
+        this.writeCounters();
+    },
+
+    finishedWriting : function finishedWriting() {
+        this._locked = false;
+        if (this._do_telemetry) {
+            this._do_telemetry = false;
+            this.gatherTelemetry();
+        }
+    },
+
+    updateStats: function updateStats() {
+        if (this._locked)
+            return;
+        this._locked = true;
+        
+        NetUtil.asyncFetch(this._dataFile, this.sUpdateStats2);
+    },
+
+    gatherTelemetry: function gatherTelemetry() {
+        if (this._locked)
+            return; // oh well, maybe next time
+        this._locked = true;
+
+        NetUtil.asyncFetch(this._dataFile, this.sGatherTelemetry2);
+    },
+
+    observe: function (aSubject, aTopic, aData) {
+        switch (aTopic) {
+        case "profile-after-change":
+            this.setup();
+            break;
+        case "gather-telemetry":
+            this._do_telemetry = true;
+            this.updateStats();
+            break;
+        case "idle":
+            this.updateStats();
+            break;
+        case "profile-change-net-teardown":
+            this.shutdown();
+            break;
+        }
+    },
+
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HttpDataUsage]);
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/HttpDataUsage.manifest
@@ -0,0 +1,3 @@
+component {6d72bfca-2747-4859-887f-6f06d4ce6787} HttpDataUsage.js
+contract @mozilla.org/network/HttpDataUsage;1 {6d72bfca-2747-4859-887f-6f06d4ce6787}
+category profile-after-change HttpDataUsage @mozilla.org/network/HttpDataUsage;1
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -8,16 +8,17 @@ XPIDL_SOURCES += [
     'nsIHttpActivityObserver.idl',
     'nsIHttpAuthManager.idl',
     'nsIHttpAuthenticableChannel.idl',
     'nsIHttpAuthenticator.idl',
     'nsIHttpChannel.idl',
     'nsIHttpChannelAuthProvider.idl',
     'nsIHttpChannelChild.idl',
     'nsIHttpChannelInternal.idl',
+    'nsIHttpDataUsage.idl',
     'nsIHttpEventSink.idl',
     'nsIHttpHeaderVisitor.idl',
     'nsIHttpProtocolHandler.idl',
 ]
 
 XPIDL_MODULE = 'necko_http'
 
 MODULE = 'necko'
@@ -76,16 +77,21 @@ CPP_SOURCES += [
 IPDL_SOURCES += [
     'PHttpChannel.ipdl',
 ]
 EXTRA_JS_MODULES += [
     'UserAgentOverrides.jsm',
     'UserAgentUpdates.jsm',
 ]
 
+EXTRA_COMPONENTS += [
+    'HttpDataUsage.js',
+    'HttpDataUsage.manifest',
+]
+
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
 LIBRARY_NAME = 'nkhttp_s'
 
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -41,16 +41,18 @@ nsHttpConnection::nsHttpConnection()
     , mCallbacksLock("nsHttpConnection::mCallbacksLock")
     , mIdleTimeout(0)
     , mConsiderReusedAfterInterval(0)
     , mConsiderReusedAfterEpoch(0)
     , mCurrentBytesRead(0)
     , mMaxBytesRead(0)
     , mTotalBytesRead(0)
     , mTotalBytesWritten(0)
+    , mUnreportedBytesRead(0)
+    , mUnreportedBytesWritten(0)
     , mKeepAlive(true) // assume to keep-alive by default
     , mKeepAliveMask(true)
     , mDontReuse(false)
     , mSupportsPipelining(false) // assume low-grade server
     , mIsReused(false)
     , mCompletedProxyConnect(false)
     , mLastTransactionExpectedNoContent(false)
     , mIdleMonitoring(false)
@@ -70,16 +72,17 @@ nsHttpConnection::nsHttpConnection()
 {
     LOG(("Creating nsHttpConnection @%x\n", this));
 }
 
 nsHttpConnection::~nsHttpConnection()
 {
     LOG(("Destroying nsHttpConnection @%x\n", this));
 
+    ReportDataUsage(false);
     if (!mEverUsedSpdy) {
         LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
              this, mHttp1xTransactionCount));
         Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_CONN,
                               mHttp1xTransactionCount);
     }
 
     if (mTotalBytesRead) {
@@ -1177,16 +1180,18 @@ nsHttpConnection::CloseTransaction(nsAHt
         mTransaction = nullptr;
     }
 
     {
         MutexAutoLock lock(mCallbacksLock);
         mCallbacks = nullptr;
     }
 
+    ReportDataUsage(false);
+
     if (NS_FAILED(reason))
         Close(reason);
 
     // flag the connection as reused here for convenience sake.  certainly
     // it might be going away instead ;-)
     mIsReused = true;
 }
 
@@ -1219,18 +1224,21 @@ nsHttpConnection::OnReadSegment(const ch
     nsresult rv = mSocketOut->Write(buf, count, countRead);
     if (NS_FAILED(rv))
         mSocketOutCondition = rv;
     else if (*countRead == 0)
         mSocketOutCondition = NS_BASE_STREAM_CLOSED;
     else {
         mLastWriteTime = PR_IntervalNow();
         mSocketOutCondition = NS_OK; // reset condition
-        if (!mProxyConnectInProgress)
+        if (!mProxyConnectInProgress) {
             mTotalBytesWritten += *countRead;
+            mUnreportedBytesWritten += *countRead;
+            ReportDataUsage(true);
+        }
     }
 
     return mSocketOutCondition;
 }
 
 nsresult
 nsHttpConnection::OnSocketWritable()
 {
@@ -1438,16 +1446,18 @@ nsHttpConnection::OnSocketReadable()
             // wait for the transaction to call ResumeRecv.
             if (rv == NS_BASE_STREAM_WOULD_BLOCK)
                 rv = NS_OK;
             again = false;
         }
         else {
             mCurrentBytesRead += n;
             mTotalBytesRead += n;
+            mUnreportedBytesRead += n;
+            ReportDataUsage(true);
             if (NS_FAILED(mSocketInCondition)) {
                 // continue waiting for the socket if necessary...
                 if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK)
                     rv = ResumeRecv();
                 else
                     rv = mSocketInCondition;
                 again = false;
             }
@@ -1502,16 +1512,37 @@ nsHttpConnection::SetupProxyConnect()
 
     buf.Truncate();
     request.Flatten(buf, false);
     buf.AppendLiteral("\r\n");
 
     return NS_NewCStringInputStream(getter_AddRefs(mProxyConnectStream), buf);
 }
 
+void
+nsHttpConnection::ReportDataUsage(bool allowDefer)
+{
+    static const uint64_t kDeferThreshold = 128000;
+
+    if (!mUnreportedBytesRead && !mUnreportedBytesWritten)
+        return;
+
+    if (!gHttpHandler->IsTelemetryEnabled())
+        return;
+
+    if (allowDefer &&
+        (mUnreportedBytesRead + mUnreportedBytesWritten) < kDeferThreshold) {
+        return;
+    }
+
+    gHttpHandler->UpdateDataUsage(mCallbacks,
+                                  mUnreportedBytesRead, mUnreportedBytesWritten);
+    mUnreportedBytesRead = mUnreportedBytesWritten = 0;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpConnection::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS4(nsHttpConnection,
                    nsIInputStreamCallback,
                    nsIOutputStreamCallback,
                    nsITransportEventSink,
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -188,16 +188,19 @@ private:
     void     SetupSSL(uint32_t caps);
 
     // Start the Spdy transaction handler when NPN indicates spdy/*
     void     StartSpdy(uint8_t versionLevel);
 
     // Directly Add a transaction to an active connection for SPDY
     nsresult AddTransaction(nsAHttpTransaction *, int32_t);
 
+    // used to inform nsIHttpDataUsage of transfer
+    void ReportDataUsage(bool);
+
 private:
     nsCOMPtr<nsISocketTransport>    mSocketTransport;
     nsCOMPtr<nsIAsyncInputStream>   mSocketIn;
     nsCOMPtr<nsIAsyncOutputStream>  mSocketOut;
 
     nsresult                        mSocketInCondition;
     nsresult                        mSocketOutCondition;
 
@@ -221,16 +224,20 @@ private:
     PRIntervalTime                  mIdleTimeout;    // value of keep-alive: timeout=
     PRIntervalTime                  mConsiderReusedAfterInterval;
     PRIntervalTime                  mConsiderReusedAfterEpoch;
     int64_t                         mCurrentBytesRead;   // data read per activation
     int64_t                         mMaxBytesRead;       // max read in 1 activation
     int64_t                         mTotalBytesRead;     // total data read
     int64_t                         mTotalBytesWritten;  // does not include CONNECT tunnel
 
+    // for nsIHttpDataUsage
+    uint64_t                        mUnreportedBytesRead;     // subset of totalBytesRead
+    uint64_t                        mUnreportedBytesWritten;  // subset of totalBytesWritten
+
     nsRefPtr<nsIAsyncInputStream>   mInputOverflow;
 
     PRIntervalTime                  mRtt;
 
     bool                            mKeepAlive;
     bool                            mKeepAliveMask;
     bool                            mDontReuse;
     bool                            mSupportsPipelining;
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -64,16 +64,20 @@
 #include <CoreServices/CoreServices.h>
 #endif
 
 #if defined(XP_OS2)
 #define INCL_DOSMISC
 #include <os2.h>
 #endif
 
+#if defined(MOZ_WIDGET_GONK)
+#include "nsINetworkManager.h"
+#endif
+
 //-----------------------------------------------------------------------------
 using namespace mozilla;
 using namespace mozilla::net;
 #include "mozilla/net/HttpChannelChild.h"
 
 
 #ifdef DEBUG
 // defined by the socket transport service while active
@@ -193,16 +197,22 @@ nsHttpHandler::nsHttpHandler()
     , mConnectTimeout(90000)
     , mBypassCacheLockThreshold(250.0)
     , mParallelSpeculativeConnectLimit(6)
     , mRequestTokenBucketEnabled(true)
     , mRequestTokenBucketMinParallelism(6)
     , mRequestTokenBucketHz(100)
     , mRequestTokenBucketBurst(32)
     , mCritialRequestPrioritization(true)
+    , mEthernetBytesRead(0)
+    , mEthernetBytesWritten(0)
+    , mCellBytesRead(0)
+    , mCellBytesWritten(0)
+    , mNetworkTypeKnown(false)
+    , mNetworkTypeWasEthernet(true)
 {
 #if defined(PR_LOGGING)
     gHttpLog = PR_NewLogModule("nsHttp");
 #endif
 
     LOG(("Creating nsHttpHandler [this=%p].\n", this));
 
     MOZ_ASSERT(!gHttpHandler, "HTTP handler already created!");
@@ -1500,23 +1510,24 @@ nsHttpHandler::SetAcceptEncodings(const 
     mAcceptEncodings = aAcceptEncodings;
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS6(nsHttpHandler,
+NS_IMPL_ISUPPORTS7(nsHttpHandler,
                    nsIHttpProtocolHandler,
                    nsIProxiedProtocolHandler,
                    nsIProtocolHandler,
                    nsIObserver,
                    nsISupportsWeakReference,
-                   nsISpeculativeConnect)
+                   nsISpeculativeConnect,
+                   nsIHttpDataUsage)
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler::nsIProtocolHandler
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpHandler::GetScheme(nsACString &aScheme)
 {
@@ -1926,55 +1937,258 @@ nsHttpHandler::SpeculativeConnect(nsIURI
         return rv;
 
     nsHttpConnectionInfo *ci =
         new nsHttpConnectionInfo(host, port, nullptr, usingSSL);
 
     return SpeculativeConnect(ci, aCallbacks);
 }
 
+// nsIHttpDataUsage
+
+NS_IMETHODIMP
+nsHttpHandler::GetEthernetBytesRead(uint64_t *aEthernetBytesRead)
+{
+    MOZ_ASSERT(NS_IsMainThread());
+    *aEthernetBytesRead = mEthernetBytesRead;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHttpHandler::GetEthernetBytesWritten(uint64_t *aEthernetBytesWritten)
+{
+    MOZ_ASSERT(NS_IsMainThread());
+    *aEthernetBytesWritten = mEthernetBytesWritten;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHttpHandler::GetCellBytesRead(uint64_t *aCellBytesRead)
+{
+    MOZ_ASSERT(NS_IsMainThread());
+    *aCellBytesRead = mCellBytesRead;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHttpHandler::GetCellBytesWritten(uint64_t *aCellBytesWritten)
+{
+    MOZ_ASSERT(NS_IsMainThread());
+    *aCellBytesWritten = mCellBytesWritten;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHttpHandler::ResetHttpDataUsage()
+{
+    MOZ_ASSERT(NS_IsMainThread());
+    mEthernetBytesRead = mEthernetBytesWritten = 0;
+    mCellBytesRead = mCellBytesWritten = 0;
+    return NS_OK;
+}
+
+class DataUsageEvent : public nsRunnable
+{
+public:
+    explicit DataUsageEvent(nsIInterfaceRequestor *cb,
+                            uint64_t bytesRead,
+                            uint64_t bytesWritten)
+        : mCB(cb), mRead(bytesRead), mWritten(bytesWritten) { }
+    
+  NS_IMETHOD Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    if (gHttpHandler)
+        gHttpHandler->UpdateDataUsage(mCB, mRead, mWritten);
+    return NS_OK;
+  }
+
+private:
+  ~DataUsageEvent() { }
+  nsCOMPtr<nsIInterfaceRequestor> mCB;
+  uint64_t mRead;
+  uint64_t mWritten;
+};
+
 void
-nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb)
+nsHttpHandler::UpdateDataUsage(nsIInterfaceRequestor *cb,
+                               uint64_t bytesRead, uint64_t bytesWritten)
 {
-    if (!cb || !mWifiTickler)
+    if (!IsTelemetryEnabled())
         return;
 
-    // If B2G requires a similar mechanism nsINetworkManager, currently only avail
-    // on B2G, contains the necessary information on wifi and gateway
+    if (!NS_IsMainThread()) {
+        nsRefPtr<nsIRunnable> event = new DataUsageEvent(cb, bytesRead, bytesWritten);
+        NS_DispatchToMainThread(event);
+        return;
+    }
+    
+    bool isEthernet = true;
+
+    if (NS_FAILED(GetNetworkEthernetInfo(cb, &isEthernet))) {
+        // without a window it is hard for android to determine the network type
+        // so on failures we will just use the last value
+        if (!mNetworkTypeKnown)
+            return;
+        isEthernet = mNetworkTypeWasEthernet;
+    }
+
+    if (isEthernet) {
+        mEthernetBytesRead += bytesRead;
+        mEthernetBytesWritten += bytesWritten;
+    } else {
+        mCellBytesRead += bytesRead;
+        mCellBytesWritten += bytesWritten;
+    }
+}
+
+nsresult
+nsHttpHandler::GetNetworkEthernetInfo(nsIInterfaceRequestor *cb,
+                                      bool *aEthernet)
+{
+    NS_ENSURE_ARG_POINTER(aEthernet);
+
+    nsresult rv = GetNetworkEthernetInfoInner(cb, aEthernet);
+    if (NS_SUCCEEDED(rv)) {
+        mNetworkTypeKnown = true;
+        mNetworkTypeWasEthernet = *aEthernet;
+    }
+    return rv;
+}
+
+// aEthernet and aGateway are required out parameters
+// on b2g and desktop gateway cannot be determined yet and
+// this function returns ERROR_NOT_IMPLEMENTED.
+nsresult
+nsHttpHandler::GetNetworkInfo(nsIInterfaceRequestor *cb,
+                              bool *aEthernet,
+                              uint32_t *aGateway)
+{
+    NS_ENSURE_ARG_POINTER(aEthernet);
+    NS_ENSURE_ARG_POINTER(aGateway);
+
+    nsresult rv = GetNetworkInfoInner(cb, aEthernet, aGateway);
+    if (NS_SUCCEEDED(rv)) {
+        mNetworkTypeKnown = true;
+        mNetworkTypeWasEthernet = *aEthernet;
+    }
+    return rv;
+}
+
+nsresult
+nsHttpHandler::GetNetworkInfoInner(nsIInterfaceRequestor *cb,
+                                   bool *aEthernet,
+                                   uint32_t *aGateway)
+{
+    NS_ENSURE_ARG_POINTER(aEthernet);
+    NS_ENSURE_ARG_POINTER(aGateway);
+
+    *aGateway = 0;
+    *aEthernet = true;
+    
+#if defined(MOZ_WIDGET_GONK)
+    // b2g only allows you to ask for ethernet or not right now.
+    return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+
+#if defined(ANDROID)
+    if (!cb)
+        return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIDOMWindow> domWindow;
     cb->GetInterface(NS_GET_IID(nsIDOMWindow), getter_AddRefs(domWindow));
     if (!domWindow)
-        return;
+        return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIDOMNavigator> domNavigator;
     domWindow->GetNavigator(getter_AddRefs(domNavigator));
     nsCOMPtr<nsIMozNavigatorNetwork> networkNavigator =
         do_QueryInterface(domNavigator);
     if (!networkNavigator)
-        return;
+        return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIDOMMozConnection> mozConnection;
     networkNavigator->GetMozConnection(getter_AddRefs(mozConnection));
     nsCOMPtr<nsINetworkProperties> networkProperties =
         do_QueryInterface(mozConnection);
     if (!networkProperties)
+        return NS_ERROR_FAILURE;
+
+    nsresult rv;
+    rv = networkProperties->GetDhcpGateway(aGateway);
+    if (NS_FAILED(rv))
+        return rv;
+
+    return networkProperties->GetIsWifi(aEthernet);
+#endif
+
+    // desktop does not currently know about the gateway
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult
+nsHttpHandler::GetNetworkEthernetInfoInner(nsIInterfaceRequestor *cb,
+                                           bool *aEthernet)
+{
+    *aEthernet = true;
+    
+#if defined(MOZ_WIDGET_GONK)
+    int32_t networkType;
+    nsCOMPtr<nsINetworkManager> networkManager = 
+        do_GetService("@mozilla.org/network/manager;1");
+    if (!networkManager)
+        return NS_ERROR_FAILURE;
+    if (NS_FAILED(networkManager->GetPreferredNetworkType(&networkType)))
+        return NS_ERROR_FAILURE;
+    *aEthernet = networkType == nsINetworkInterface::NETWORK_TYPE_WIFI;
+    return NS_OK;
+#endif
+
+#if defined(ANDROID)
+    if (!cb)
+        return NS_ERROR_FAILURE;
+
+    nsCOMPtr<nsIDOMWindow> domWindow;
+    cb->GetInterface(NS_GET_IID(nsIDOMWindow), getter_AddRefs(domWindow));
+    if (!domWindow)
+        return NS_ERROR_FAILURE;
+
+    nsCOMPtr<nsIDOMNavigator> domNavigator;
+    domWindow->GetNavigator(getter_AddRefs(domNavigator));
+    nsCOMPtr<nsIMozNavigatorNetwork> networkNavigator =
+        do_QueryInterface(domNavigator);
+    if (!networkNavigator)
+        return NS_ERROR_FAILURE;
+
+    nsCOMPtr<nsIDOMMozConnection> mozConnection;
+    networkNavigator->GetMozConnection(getter_AddRefs(mozConnection));
+    nsCOMPtr<nsINetworkProperties> networkProperties =
+        do_QueryInterface(mozConnection);
+    if (!networkProperties)
+        return NS_ERROR_FAILURE;
+
+    return networkProperties->GetIsWifi(aEthernet);
+#endif
+
+    // desktop assumes never on cell data
+    *aEthernet = true;
+    return NS_OK;
+}
+
+void
+nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb)
+{
+    if (!cb || !mWifiTickler)
         return;
 
     uint32_t gwAddress;
     bool isWifi;
-    nsresult rv;
 
-    rv = networkProperties->GetDhcpGateway(&gwAddress);
-    if (NS_SUCCEEDED(rv))
-        rv = networkProperties->GetIsWifi(&isWifi);
-    if (NS_FAILED(rv))
-        return;
-
-    if (!gwAddress || !isWifi)
+    nsresult rv = GetNetworkInfo(cb, &isWifi, &gwAddress);
+    if (NS_FAILED(rv) || !gwAddress || !isWifi)
         return;
 
     mWifiTickler->SetIPV4Address(gwAddress);
     mWifiTickler->Tickle();
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpsHandler implementation
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -10,16 +10,17 @@
 #include "nsHttpAuthCache.h"
 #include "nsHttpConnectionMgr.h"
 #include "ASpdySession.h"
 
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 
+#include "nsIHttpDataUsage.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsIObserver.h"
 #include "nsISpeculativeConnect.h"
 #include "nsICache.h"
 
 class nsHttpConnection;
 class nsHttpConnectionInfo;
 class nsHttpHeaderArray;
@@ -45,24 +46,26 @@ class Tickler;
 //-----------------------------------------------------------------------------
 // nsHttpHandler - protocol handler for HTTP and HTTPS
 //-----------------------------------------------------------------------------
 
 class nsHttpHandler : public nsIHttpProtocolHandler
                     , public nsIObserver
                     , public nsSupportsWeakReference
                     , public nsISpeculativeConnect
+                    , public nsIHttpDataUsage
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIPROTOCOLHANDLER
     NS_DECL_NSIPROXIEDPROTOCOLHANDLER
     NS_DECL_NSIHTTPPROTOCOLHANDLER
     NS_DECL_NSIOBSERVER
     NS_DECL_NSISPECULATIVECONNECT
+    NS_DECL_NSIHTTPDATAUSAGE
 
     nsHttpHandler();
     virtual ~nsHttpHandler();
 
     nsresult Init();
     nsresult AddStandardRequestHeaders(nsHttpHeaderArray *);
     nsresult AddConnectionHeader(nsHttpHeaderArray *,
                                  uint32_t capabilities);
@@ -468,18 +471,40 @@ public:
 
     // Socket thread only
     void SetRequestTokenBucket(mozilla::net::EventTokenBucket *aTokenBucket)
     {
         mRequestTokenBucket = aTokenBucket;
     }
 
 private:
+    // for nsIHttpDataUsage
+    uint64_t mEthernetBytesRead;
+    uint64_t mEthernetBytesWritten;
+    uint64_t mCellBytesRead;
+    uint64_t mCellBytesWritten;
+    bool     mNetworkTypeKnown;
+    bool     mNetworkTypeWasEthernet;
+
     nsRefPtr<mozilla::net::Tickler> mWifiTickler;
+    nsresult GetNetworkEthernetInfo(nsIInterfaceRequestor *cb,
+                                    bool *ethernet);
+    nsresult GetNetworkEthernetInfoInner(nsIInterfaceRequestor *cb,
+                                         bool *ethernet);
+    nsresult GetNetworkInfo(nsIInterfaceRequestor *cb,
+                            bool *ethernet, uint32_t *gw);
+    nsresult GetNetworkInfoInner(nsIInterfaceRequestor *cb,
+                                 bool *ethernet, uint32_t *gw);
     void TickleWifi(nsIInterfaceRequestor *cb);
+
+public:
+    // this is called to update the member variables used for nsIHttpDataUsage
+    // it can be called from any thread
+    void UpdateDataUsage(nsIInterfaceRequestor *cb,
+                         uint64_t bytesRead, uint64_t bytesWritten);
 };
 
 extern nsHttpHandler *gHttpHandler;
 
 //-----------------------------------------------------------------------------
 // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the
 //                  HTTPS handler (even though they share the same impl).
 //-----------------------------------------------------------------------------
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/nsIHttpDataUsage.idl
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * nsIHttpDataUsage contains counters for the amount of HTTP data transferred
+ * in and out of this session since the last time it was reset with the
+ * resetHttpDataUsage() method. These counters are normally reset on each
+ * telemetry ping.
+ *
+ * Data is split into ethernet and cell. ethernet includes wifi.
+ *
+ */
+
+[scriptable, uuid(79dee3eb-9323-4d5c-b0a8-1baa18934d9e)]
+interface nsIHttpDataUsage : nsISupports
+{
+    readonly attribute unsigned long long ethernetBytesRead;
+    readonly attribute unsigned long long ethernetBytesWritten;
+    readonly attribute unsigned long long cellBytesRead;
+    readonly attribute unsigned long long cellBytesWritten;
+    
+    void resetHttpDataUsage();
+};
--- a/netwerk/streamconv/src/nsStreamConverterService.cpp
+++ b/netwerk/streamconv/src/nsStreamConverterService.cpp
@@ -27,16 +27,17 @@
 #include "nsIStreamConverter.h"
 #include "nsICategoryManager.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsServiceManagerUtils.h"
 #include "nsHashtable.h"
+#include "nsISimpleEnumerator.h"
 
 ///////////////////////////////////////////////////////////////////
 // Breadth-First-Search (BFS) algorithm state classes and types.
 
 // used  to establish discovered vertecies.
 enum BFScolors {white, gray, black};
 
 struct BFSState {
--- a/netwerk/test/PropertiesTest.cpp
+++ b/netwerk/test/PropertiesTest.cpp
@@ -12,16 +12,17 @@
 #include "nsIURL.h"
 #include "nsIIOService.h"
 #include "nsNetCID.h"
 #include "nsIChannel.h"
 #include "nsIComponentManager.h"
 #include <stdio.h>
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
+#include "nsISimpleEnumerator.h"
 
 #define TEST_URL "resource:/res/test.properties"
 static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
 
 static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
 
 /***************************************************************************/
 
--- a/parser/htmlparser/public/nsHTMLTags.h
+++ b/parser/htmlparser/public/nsHTMLTags.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsHTMLTags_h___
 #define nsHTMLTags_h___
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "plhash.h"
 
 class nsIAtom;
 
 /*
    Declare the enum list using the magic of preprocessing
    enum values are "eHTMLTag_foo" (where foo is the tag)
 
--- a/parser/htmlparser/public/nsIContentSink.h
+++ b/parser/htmlparser/public/nsIContentSink.h
@@ -12,17 +12,17 @@
  * This pure virtual interface is used as the "glue" that connects the parsing 
  * process to the content model construction process.
  *
  * The icontentsink interface is a very lightweight wrapper that represents the
  * content-sink model building process. There is another one that you may care 
  * about more, which is the IHTMLContentSink interface. (See that file for details).
  */
 #include "nsISupports.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "mozFlushType.h"
 #include "nsIDTD.h"
 
 class nsParserBase;
 
 #define NS_ICONTENT_SINK_IID \
 { 0xcf9a7cbb, 0xfcbc, 0x4e13, \
   { 0x8e, 0xf5, 0x18, 0xef, 0x2d, 0x3d, 0x58, 0x29 } }
--- a/parser/htmlparser/public/nsIDTD.h
+++ b/parser/htmlparser/public/nsIDTD.h
@@ -17,17 +17,17 @@
  *      parser
  *      2) To serve as proxy to represent the containment rules of the
  *      underlying document
  *      3) To offer autodetection services to the parser (mainly for doc
  *      conversion)
  * */
 
 #include "nsISupports.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsITokenizer.h"
 
 #define NS_IDTD_IID \
 { 0x3de05873, 0xefa7, 0x410d, \
   { 0xa4, 0x61, 0x80, 0x33, 0xaf, 0xd9, 0xe3, 0x26 } }
 
 enum eAutoDetectResult {
     eUnknownDetect,
--- a/parser/htmlparser/public/nsIParser.h
+++ b/parser/htmlparser/public/nsIParser.h
@@ -16,17 +16,17 @@
  *
  * Please DO NOT #include this into new files even inside Gecko. It is more
  * likely than not that #including this header is the wrong thing to do.
  */
 
 #include "nsISupports.h"
 #include "nsIStreamListener.h"
 #include "nsIDTD.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "nsIAtom.h"
 #include "nsParserBase.h"
 
 #define NS_IPARSER_IID \
 { 0x2c4ad90a, 0x740e, 0x4212, \
   { 0xba, 0x3f, 0xfe, 0xac, 0xda, 0x4b, 0x92, 0x9e } }
 
--- a/parser/htmlparser/public/nsIParserService.h
+++ b/parser/htmlparser/public/nsIParserService.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 nsIParserService_h__
 #define nsIParserService_h__
 
 #include "nsISupports.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsHTMLTags.h"
 
 class nsIParser;
 
 #define NS_PARSERSERVICE_CONTRACTID "@mozilla.org/parser/parser-service;1"
 
 // {90a92e37-abd6-441b-9b39-4064d98e1ede}
 #define NS_IPARSERSERVICE_IID \
--- a/security/manager/boot/src/nsSiteSecurityService.cpp
+++ b/security/manager/boot/src/nsSiteSecurityService.cpp
@@ -9,17 +9,17 @@
 #include "nsCRTGlue.h"
 #include "nsIPermissionManager.h"
 #include "nsISSLStatus.h"
 #include "nsISSLStatusProvider.h"
 #include "nsSiteSecurityService.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISocketProvider.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LinkedList.h"
 #include "nsSecurityHeaderParser.h"
 
 // A note about the preload list:
 // When a site specifically disables sts by sending a header with
--- a/storage/src/VacuumManager.cpp
+++ b/storage/src/VacuumManager.cpp
@@ -9,16 +9,17 @@
 #include "VacuumManager.h"
 
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 #include "nsIObserverService.h"
 #include "nsIFile.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
+#include "prtime.h"
 
 #include "mozStorageConnection.h"
 #include "mozIStorageStatement.h"
 #include "mozIStorageAsyncStatement.h"
 #include "mozIStoragePendingStatement.h"
 #include "mozIStorageError.h"
 #include "mozStorageHelper.h"
 #include "nsXULAppAPI.h"
--- a/storage/test/test_file_perms.cpp
+++ b/storage/test/test_file_perms.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
  * 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 "storage_test_harness.h"
 #include "nsIFile.h"
+#include "prio.h"
 
 /**
  * This file tests that the file permissions of the sqlite files match what
  * we request they be
  */
 
 void
 test_file_perms()
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -21,16 +21,17 @@
 #include "Helpers.h"
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "prsystem.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
+#include "prtime.h"
 
 // Time between corrupt database backups.
 #define RECENT_BACKUP_TIME_MICROSEC (int64_t)86400 * PR_USEC_PER_SEC // 24H
 
 // Filename of the database.
 #define DATABASE_FILENAME NS_LITERAL_STRING("places.sqlite")
 // Filename used to backup corrupt databases.
 #define DATABASE_CORRUPT_FILENAME NS_LITERAL_STRING("places.sqlite.corrupt")
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -18,17 +18,17 @@
 #include "nsIWebBrowserChrome.h"
 #include "nsIWindowMediator.h"
 #include "nsIWindowWatcher.h"
 #include "nsIXULRuntime.h"
 #include "nsIXULWindow.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsThreadUtils.h"
 #include "nsAutoPtr.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "mozilla/Preferences.h"
 #include "GeckoProfiler.h"
 
 #include "prprf.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShellCID.h"
 #include "nsXPCOMCIDInternal.h"
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -864,16 +864,44 @@
   "HTTP_TRANSACTION_IS_SSL": {
     "kind": "boolean",
     "description": "Whether a HTTP transaction was over SSL or not."
   },
   "HTTP_PAGELOAD_IS_SSL": {
     "kind": "boolean",
     "description": "Whether a HTTP base page load was over SSL or not."
   },
+  "HTTPDATA_DAILY_ETHERNET_IN": {
+    "kind": "exponential",
+    "high": "10000",
+    "n_buckets": 200,
+    "extended_statistics_ok": true,
+    "description": "MB of http ethernet data recvd in one day"
+  },
+  "HTTPDATA_DAILY_ETHERNET_OUT": {
+    "kind": "exponential",
+    "high": "10000",
+    "n_buckets": 200,
+    "extended_statistics_ok": true,
+    "description": "MB of http ethernet data sent in one day"
+  },
+  "HTTPDATA_DAILY_CELL_IN": {
+    "kind": "exponential",
+    "high": "10000",
+    "n_buckets": 200,
+    "extended_statistics_ok": true,
+    "description": "MB of http cell data recvd in one day"
+  },
+  "HTTPDATA_DAILY_CELL_OUT": {
+    "kind": "exponential",
+    "high": "10000",
+    "n_buckets": 200,
+    "extended_statistics_ok": true,
+    "description": "MB of http cell data sent in one day"
+  },
   "SSL_HANDSHAKE_VERSION": {
     "kind": "enumerated",
     "n_values": 16,
     "description": "SSL Version (0=ssl3, 1=tls1, 2=tls1.1, 3=tls1.2)"
   },
   "SSL_TIME_UNTIL_READY": {
     "kind": "exponential",
     "high": "60000",
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -24,17 +24,17 @@
 #include "nsXPCOMPrivate.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsIXPConnect.h"
 #include "mozilla/Services.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/GCAPI.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsITelemetry.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIMemoryReporter.h"
 #include "nsISeekableStream.h"
 #include "Telemetry.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
--- a/toolkit/crashreporter/mac_utils.h
+++ b/toolkit/crashreporter/mac_utils.h
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef toolkit_breakpad_mac_utils_h__
 #define toolkit_breakpad_mac_utils_h__
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 // Given an Objective-C NSException object, put exception info into a string.
 void GetObjCExceptionInfo(void* inException, nsACString& outString);
 
 #endif /* toolkit_breakpad_mac_utils_h__ */
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -6,16 +6,17 @@
 #include "nsExceptionHandler.h"
 #include "nsDataHashtable.h"
 #include "mozilla/dom/CrashReporterChild.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "mozilla/Util.h"
 
 #include "nsThreadUtils.h"
+#include "nsXULAppAPI.h"
 
 #if defined(XP_WIN32)
 #ifdef WIN32_LEAN_AND_MEAN
 #undef WIN32_LEAN_AND_MEAN
 #endif
 
 #include "nsXULAppAPI.h"
 #include "nsIXULAppInfo.h"
--- a/toolkit/identity/IdentityCryptoService.cpp
+++ b/toolkit/identity/IdentityCryptoService.cpp
@@ -7,17 +7,17 @@
 #include "nsIIdentityCryptoService.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsNSSShutDown.h"
 #include "nsIThread.h"
 #include "nsThreadUtils.h"
 #include "nsCOMPtr.h"
 #include "nsProxyRelease.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Util.h" // ArrayLength
 #include "ScopedNSSTypes.h"
 
 #include "nss.h"
 #include "pk11pub.h"
 #include "secmod.h"
 #include "secerr.h"
--- a/toolkit/xre/ProfileReset.cpp
+++ b/toolkit/xre/ProfileReset.cpp
@@ -15,16 +15,17 @@
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsPrintfCString.h"
 #include "nsToolkitCompsCID.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsXREAppData.h"
 
 #include "mozilla/Services.h"
+#include "prtime.h"
 
 extern const nsXREAppData* gAppData;
 
 static const char kProfileProperties[] =
   "chrome://mozapps/locale/profile/profileSelection.properties";
 
 /**
  * Creates a new profile with a timestamp in the name to use for profile reset.
--- a/tools/profiler/JSCustomObjectBuilder.cpp
+++ b/tools/profiler/JSCustomObjectBuilder.cpp
@@ -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/. */
 
 #include "JSCustomObjectBuilder.h"
 
 #include "mozilla/Util.h" // for ArrayLength
 #include "nsDataHashtable.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "nsUTF8Utils.h"
 
 #if _MSC_VER
  #define snprintf _snprintf
 #endif
 
 // These are owned and deleted by JSCustomObject
--- a/tools/profiler/JSObjectBuilder.cpp
+++ b/tools/profiler/JSObjectBuilder.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "JSObjectBuilder.h"
 
 JSObjectBuilder::JSObjectBuilder(JSContext *aCx) : mCx(aCx), mOk(true)
 {}
 
 void
 JSObjectBuilder::DefineProperty(JS::HandleObject aObject, const char *name, JS::HandleObject aValue)
 {
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -8,16 +8,17 @@
 #include <fstream>
 #include <sstream>
 #include "GeckoProfilerImpl.h"
 #include "SaveProfileTask.h"
 #include "ProfileEntry.h"
 #include "platform.h"
 #include "nsThreadUtils.h"
 #include "prenv.h"
+#include "prtime.h"
 #include "shared-libraries.h"
 #include "mozilla/StackWalk.h"
 #include "TableTicker.h"
 #include "nsXULAppAPI.h"
 
 // JSON
 #include "JSObjectBuilder.h"
 #include "JSCustomObjectBuilder.h"
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -11,16 +11,17 @@
 #include "nsCExternalHandlerService.h"
 #include "nsIExternalHelperAppService.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "nsIBrowserDOMWindow.h"
 #include "nsStringStream.h"
 #include "mozilla/ipc/URIUtils.h"
+#include "nsNetUtil.h"
 
 #include "mozilla/unused.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace dom {
 
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -46,17 +46,17 @@ using mozilla::unused;
 
 #include "nsTArray.h"
 
 #include "AndroidBridge.h"
 #include "android_npapi.h"
 
 #include "imgIEncoder.h"
 
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "GeckoProfiler.h" // For PROFILER_LABEL
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::widget;
 using namespace mozilla::layers;
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget)
--- a/widget/gtk/nsGtkIMModule.cpp
+++ b/widget/gtk/nsGtkIMModule.cpp
@@ -3,16 +3,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/. */
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif // MOZ_LOGGING
 #include "prlog.h"
+#include "prtime.h"
 
 #include "nsGtkIMModule.h"
 #include "nsWindow.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -6,17 +6,17 @@
 #ifndef nsGUIEvent_h__
 #define nsGUIEvent_h__
 
 #include "mozilla/MathAlgorithms.h"
 
 #include "nsPoint.h"
 #include "nsRect.h"
 #include "nsEvent.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMWheelEvent.h"
 #include "nsIDOMDataTransfer.h"
 #include "nsWeakPtr.h"
 #include "nsIWidget.h"
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIWidget_h__
 #define nsIWidget_h__
 
 #include "nsISupports.h"
 #include "nsColor.h"
 #include "nsRect.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #include "nsEvent.h"
 #include "nsCOMPtr.h"
 #include "nsWidgetInitData.h"
 #include "nsTArray.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/RefPtr.h"
--- a/widget/qt/faststartupqt/mozqwidgetfast.cpp
+++ b/widget/qt/faststartupqt/mozqwidgetfast.cpp
@@ -3,17 +3,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/. */
 
 #include <QtCore/QUrl>
 #include "mozqwidgetfast.h"
 #include "nsFastStartupQt.h"
 #include "nsIFile.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "BinaryPath.h"
 
 #define TOOLBAR_SPLASH "toolbar_splash.png"
 #define FAVICON_SPLASH "favicon32.png"
 #define DRAWABLE_PATH "res/drawable/"
 
 MozQWidgetFast::MozQWidgetFast(nsWindow* aReceiver, QGraphicsItem* aParent)
 {
--- a/widget/xpwidgets/GfxInfoCollector.cpp
+++ b/widget/xpwidgets/GfxInfoCollector.cpp
@@ -2,17 +2,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GfxInfoCollector.h"
 #include "jsapi.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 using namespace mozilla;
 using namespace widget;
 
 void
 InfoObject::DefineProperty(const char *name, int value)
 {
   if (!mOk)
--- a/xpcom/base/nsConsoleService.cpp
+++ b/xpcom/base/nsConsoleService.cpp
@@ -12,16 +12,17 @@
 
 #include "nsMemory.h"
 #include "nsCOMArray.h"
 #include "nsThreadUtils.h"
 
 #include "nsConsoleService.h"
 #include "nsConsoleMessage.h"
 #include "nsIClassInfoImpl.h"
+#include "nsIConsoleListener.h"
 
 #include "mozilla/Preferences.h"
 
 #if defined(ANDROID)
 #include <android/log.h>
 #endif
 #ifdef XP_WIN
 #include <windows.h>
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -8,17 +8,17 @@
 
 #include "mozilla/Atomics.h"
 
 #include "nsDebugImpl.h"
 #include "nsDebug.h"
 #ifdef MOZ_CRASHREPORTER
 # include "nsExceptionHandler.h"
 #endif
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "prprf.h"
 #include "prlog.h"
 #include "nsError.h"
 #include "prerror.h"
 #include "prerr.h"
 #include "prenv.h"
 
 #ifdef ANDROID
--- a/xpcom/base/nsIConsoleListener.idl
+++ b/xpcom/base/nsIConsoleListener.idl
@@ -3,15 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Used by the console service to notify listeners of new console messages.
  */
 
 #include "nsISupports.idl"
-#include "nsIConsoleMessage.idl"
+
+interface nsIConsoleMessage;
 
 [scriptable, function, uuid(35c400a4-5792-438c-b915-65e30d58d557)]
 interface nsIConsoleListener : nsISupports
 {
     void observe(in nsIConsoleMessage aMessage);
 };
--- a/xpcom/base/nsIConsoleService.idl
+++ b/xpcom/base/nsIConsoleService.idl
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsIConsoleListener.idl"
-#include "nsIConsoleMessage.idl"
+
+interface nsIConsoleListener;
+interface nsIConsoleMessage;
 
 [scriptable, uuid(0eb81d20-c37e-42d4-82a8-ca9ae96bdf52)]
 interface nsIConsoleService : nsISupports
 {
     void logMessage(in nsIConsoleMessage message);
 
     /**
      * Convenience method for logging simple messages.
--- a/xpcom/base/nsIException.idl
+++ b/xpcom/base/nsIException.idl
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Interfaces for representing cross-language exceptions and stack traces.
  */
 
 
 #include "nsISupports.idl"
-#include "nsIProgrammingLanguage.idl"
 
 // XXX - most "string"s in this file should probably move to Unicode
 //       so may as well use AStrings...
 
 
 [scriptable, uuid(91d82105-7c62-4f8b-9779-154277c0ee90)]
 interface nsIStackFrame : nsISupports
 {
--- a/xpcom/base/nsMemoryInfoDumper.cpp
+++ b/xpcom/base/nsMemoryInfoDumper.cpp
@@ -14,16 +14,17 @@
 #include "mozilla/dom/ContentChild.h"
 #include "nsIConsoleService.h"
 #include "nsICycleCollectorListener.h"
 #include "nsIMemoryReporter.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsGZFileWriter.h"
 #include "nsJSEnvironment.h"
 #include "nsPrintfCString.h"
+#include "nsISimpleEnumerator.h"
 #include <errno.h>
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #else
 #include <unistd.h>
 #endif
--- a/xpcom/build/FileLocation.cpp
+++ b/xpcom/build/FileLocation.cpp
@@ -3,16 +3,34 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "FileLocation.h"
 #include "nsZipArchive.h"
 #include "nsURLHelper.h"
 
 namespace mozilla {
 
+FileLocation::FileLocation()
+{
+}
+
+FileLocation::~FileLocation()
+{
+}
+
+FileLocation::FileLocation(nsIFile* file)
+{
+  Init(file);
+}
+
+FileLocation::FileLocation(nsIFile* file, const char *path)
+{
+  Init(file, path);
+}
+
 FileLocation::FileLocation(const FileLocation &file, const char *path)
 {
   if (file.IsZip()) {
     if (file.mBaseFile) {
       Init(file.mBaseFile, file.mPath.get());
     } else {
       Init(file.mBaseZip, file.mPath.get());
     }
@@ -46,16 +64,40 @@ FileLocation::FileLocation(const FileLoc
       Init(cfile);
     } else {
       Init(file.mBaseFile);
     }
   }
 }
 
 void
+FileLocation::Init(nsIFile* file)
+{
+  mBaseZip = NULL;
+  mBaseFile = file;
+  mPath.Truncate();
+}
+
+void
+FileLocation::Init(nsIFile* file, const char* path)
+{
+  mBaseZip = NULL;
+  mBaseFile = file;
+  mPath = path;
+}
+
+void
+FileLocation::Init(nsZipArchive* zip, const char* path)
+{
+  mBaseZip = zip;
+  mBaseFile = NULL;
+  mPath = path;
+}
+
+void
 FileLocation::GetURIString(nsACString &result) const
 {
   if (mBaseFile) {
     net_GetURLSpecFromActualFile(mBaseFile, result);
   } else if (mBaseZip) {
     nsRefPtr<nsZipHandle> handler = mBaseZip->GetFD();
     handler->mFile.GetURIString(result);
   }
--- a/xpcom/build/FileLocation.h
+++ b/xpcom/build/FileLocation.h
@@ -26,68 +26,45 @@ public:
    * - on filesystems
    * - in archives
    * - in archives within archives
    * As such, it stores a path within an archive, as well as the archive
    * path itself, or the complete file path alone when on a filesystem.
    * When the archive is in an archive, an nsZipArchive is stored instead
    * of a file path.
    */
-  FileLocation() { }
+  FileLocation();
+  ~FileLocation();
 
   /**
    * Constructor for plain files
    */
-  FileLocation(nsIFile *file)
-  {
-    Init(file);
-  }
+  FileLocation(nsIFile *file);
 
   /**
    * Constructors for path within an archive. The archive can be given either
    * as nsIFile or nsZipArchive.
    */
-  FileLocation(nsIFile *zip, const char *path)
-  {
-    Init(zip, path);
-  }
+  FileLocation(nsIFile *zip, const char *path);
 
-  FileLocation(nsZipArchive *zip, const char *path)
-  {
-    Init(zip, path);
-  }
+  FileLocation(nsZipArchive *zip, const char *path);
 
   /**
    * Creates a new file location relative to another one.
    */
   FileLocation(const FileLocation &file, const char *path = NULL);
 
   /**
    * Initialization functions corresponding to constructors
    */
-  void Init(nsIFile *file)
-  {
-    mBaseZip = NULL;
-    mBaseFile = file;
-    mPath.Truncate();
-  }
+  void Init(nsIFile *file);
 
-  void Init(nsIFile *zip, const char *path)
-  {
-    mBaseZip = NULL;
-    mBaseFile = zip;
-    mPath = path;
-  }
+  void Init(nsIFile *zip, const char *path);
 
-  void Init(nsZipArchive *zip, const char *path)
-  {
-    mBaseZip = zip;
-    mBaseFile = NULL;
-    mPath = path;
-  }
+  void Init(nsZipArchive *zip, const char *path);
 
   /**
    * Returns an URI string corresponding to the file location
    */
   void GetURIString(nsACString &result) const;
 
   /**
    * Returns the base file of the location, where base file is defined as:
--- a/xpcom/build/perfprobe.h
+++ b/xpcom/build/perfprobe.h
@@ -11,17 +11,17 @@
 #ifndef mozilla_perfprobe_h
 #define mozilla_perfprobe_h
 
 #if !defined(XP_WIN)
 #error "For the moment, perfprobe.h is defined only for Windows platforms"
 #endif
 
 #include "nsError.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "prlog.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include <windows.h>
 #undef GetStartupInfo //Prevent Windows from polluting global namespace
 #include <wmistr.h>
 #include <evntrace.h>
 
--- a/xpcom/components/nsCategoryManager.cpp
+++ b/xpcom/components/nsCategoryManager.cpp
@@ -27,16 +27,17 @@
 #include "nsCRT.h"
 #include "nsQuickSort.h"
 #include "nsEnumeratorUtils.h"
 #include "nsThreadUtils.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Services.h"
 
 #include "ManifestParser.h"
+#include "nsISimpleEnumerator.h"
 
 using namespace mozilla;
 class nsIComponentLoaderManager;
 
 /*
   CategoryDatabase
   contains 0 or more 1-1 mappings of string to Category
   each Category contains 0 or more 1-1 mappings of string keys to string values
--- a/xpcom/components/nsICategoryManager.idl
+++ b/xpcom/components/nsICategoryManager.idl
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsISimpleEnumerator.idl"
+
+interface nsISimpleEnumerator;
 
 /*
  * nsICategoryManager
  */
 
 [scriptable, uuid(3275b2cd-af6d-429a-80d7-f0c5120342ac)]
 interface nsICategoryManager : nsISupports
 {
--- a/xpcom/ds/nsAtomService.cpp
+++ b/xpcom/ds/nsAtomService.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAtomService.h"
+#include "nsIAtom.h"
 
 NS_IMPL_ISUPPORTS1(nsAtomService, nsIAtomService)
 
 nsAtomService::nsAtomService()
 {
 }
 
 nsresult
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -6,17 +6,17 @@
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "nsAtomTable.h"
 #include "nsStaticAtom.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsCRT.h"
 #include "pldhash.h"
 #include "prenv.h"
 #include "nsThreadUtils.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsAutoPtr.h"
 #include "nsUnicharUtils.h"
--- a/xpcom/ds/nsIAtomService.idl
+++ b/xpcom/ds/nsIAtomService.idl
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsIAtom.idl"
+#include "nsISupports.idl"
+
+interface nsIAtom;
 
 %{C++
 #define NS_ATOMSERVICE_CID \
 { /* ed3db3fc-0168-4cab-8818-98f5475a490c */ \
     0xed3db3fc,                              \
     0x0168,                                  \
     0x4cab,                                  \
     {0x88, 0x18, 0x98, 0xf5, 0x47, 0x5a, 0x49, 0x0c} }
--- a/xpcom/ds/nsICollection.idl
+++ b/xpcom/ds/nsICollection.idl
@@ -1,15 +1,16 @@
 /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsISerializable.idl"
-#include "nsIEnumerator.idl"
+
+interface nsIEnumerator;
 
 [scriptable, uuid(83b6019c-cbc4-11d2-8cca-0060b0fc14a3)]
 interface nsICollection : nsISerializable
 {
 
   uint32_t Count();
   nsISupports GetElementAt(in uint32_t index);
   void QueryElementAt(in uint32_t index, in nsIIDRef uuid, 
--- a/xpcom/ds/nsIEnumerator.idl
+++ b/xpcom/ds/nsIEnumerator.idl
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsISimpleEnumerator.idl"
+#include "nsISupports.idl"
 
 %{C++
 #define NS_ENUMERATOR_FALSE 1
 %}
 /*
  * DO NOT USE THIS INTERFACE.  IT IS HORRIBLY BROKEN, USES NS_COMFALSE
  * AND IS BASICALLY IMPOSSIBLE TO USE CORRECTLY THROUGH PROXIES OR
  * XPCONNECT.  IF YOU SEE NEW USES OF THIS INTERFACE IN CODE YOU ARE
--- a/xpcom/ds/nsIPersistentProperties2.idl
+++ b/xpcom/ds/nsIPersistentProperties2.idl
@@ -1,19 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
 #include "nsIProperties.idl"
-#include "nsISimpleEnumerator.idl"
 
 interface nsIInputStream;
 interface nsIOutputStream;
+interface nsISimpleEnumerator;
 
 [scriptable, uuid(283EE646-1AEF-11D4-98B3-00C04fA0CE9A)]
 interface nsIPropertyElement : nsISupports {
   attribute AUTF8String key;
   attribute AString value;
 };
 
 [scriptable, uuid(1A180F60-93B2-11d2-9B8B-00805F8A16D9)]
--- a/xpcom/ds/nsISupportsArray.idl
+++ b/xpcom/ds/nsISupportsArray.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
-#include "nsISupports.idl"
 #include "nsICollection.idl"
 
 /*
  * This entire interface is deprecated and should not be used.
  * See nsIArray and nsIMutableArray for the new implementations.
  *
  * http://groups.google.com/groups?q=nsisupportsarray+group:netscape.public.mozilla.xpcom&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=3D779491.3050506%40netscape.com&rnum=2
  * http://groups.google.com/groups?q=nsisupportsarray+group:netscape.public.mozilla.xpcom&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=al8412%245ab2%40ripley.netscape.com&rnum=8
--- a/xpcom/ds/nsPersistentProperties.h
+++ b/xpcom/ds/nsPersistentProperties.h
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPersistentProperties_h___
 #define nsPersistentProperties_h___
 
 #include "nsIPersistentProperties2.h"
 #include "pldhash.h"
 #include "plarena.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Attributes.h"
 
 class nsIUnicharInputStream;
 
 class nsPersistentProperties MOZ_FINAL : public nsIPersistentProperties
 {
 public:
--- a/xpcom/ds/nsStaticNameTable.h
+++ b/xpcom/ds/nsStaticNameTable.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Classes to manage lookup of static names in a table. */
 
 #ifndef nsStaticNameTable_h___
 #define nsStaticNameTable_h___
 
 #include "pldhash.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 /* This class supports case insensitive lookup.
  *
  * It differs from atom tables:
  * - It supports case insensitive lookup.
  * - It has minimal footprint by not copying the string table.
  * - It does no locking.
  * - It returns zero based indexes and const nsCString& as required by its
--- a/xpcom/ds/nsSupportsPrimitives.h
+++ b/xpcom/ds/nsSupportsPrimitives.h
@@ -5,17 +5,17 @@
 
 #ifndef nsSupportsPrimitives_h__
 #define nsSupportsPrimitives_h__
 
 #include "mozilla/Attributes.h"
 
 #include "nsISupportsPrimitives.h"
 #include "nsCOMPtr.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 class nsSupportsIDImpl MOZ_FINAL : public nsISupportsID
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSISUPPORTSPRIMITIVE
     NS_DECL_NSISUPPORTSID
 
--- a/xpcom/ds/nsVariant.cpp
+++ b/xpcom/ds/nsVariant.cpp
@@ -9,17 +9,17 @@
 #include "nsVariant.h"
 #include "prprf.h"
 #include "prdtoa.h"
 #include <math.h>
 #include "nsCycleCollectionParticipant.h"
 #include "xpt_struct.h"
 #include "nsReadableUtils.h"
 #include "nsMemory.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsCRTGlue.h"
 
 /***************************************************************************/
 // Helpers for static convert functions...
 
 static nsresult String2Double(const char* aString, double* retval)
 {
     char* next;
--- a/xpcom/glue/nsStringGlue.h
+++ b/xpcom/glue/nsStringGlue.h
@@ -1,11 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// IWYU pragma: private, include "nsString.h"
 
 /**
  * @file nsStringGlue.h
  * This header exists solely to #include the proper internal/frozen string
  * headers, depending on whether MOZILLA_INTERNAL_API is defined.
  */
 
 #ifndef nsStringGlue_h__
--- a/xpcom/io/Base64.cpp
+++ b/xpcom/io/Base64.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Base64.h"
 
 #include "nsIInputStream.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 
 #include "plbase64.h"
 
 namespace {
 
 // BEGIN base64 encode code copied and modified from NSPR
 const unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
--- a/xpcom/io/nsIBinaryInputStream.idl
+++ b/xpcom/io/nsIBinaryInputStream.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "nsIInputStream.idl"
-#include "nsrootidl.idl"
 
 /**
  * This interface allows consumption of primitive data types from a "binary
  * stream" containing untagged, big-endian binary data, i.e. as produced by an
  * implementation of nsIBinaryOutputStream.  This might be used, for example,
  * to implement network protocols or to read from architecture-neutral disk
  * files, i.e. ones that can be read and written by both big-endian and
  * little-endian platforms.
--- a/xpcom/io/nsIBinaryOutputStream.idl
+++ b/xpcom/io/nsIBinaryOutputStream.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "nsIOutputStream.idl"
-#include "nsrootidl.idl"
 
 /**
  * This interface allows writing of primitive data types (integers,
  * floating-point values, booleans, etc.) to a stream in a binary, untagged,
  * fixed-endianness format.  This might be used, for example, to implement
  * network protocols or to produce architecture-neutral binary disk files,
  * i.e. ones that can be read and written by both big-endian and little-endian
  * platforms.  Output is written in big-endian order (high-order byte first),
--- a/xpcom/io/nsIDirectoryService.idl
+++ b/xpcom/io/nsIDirectoryService.idl
@@ -1,15 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsIFile.idl"
+
+interface nsIFile;
+interface nsISimpleEnumerator;
 
 /**
  * nsIDirectoryServiceProvider
  *
  * Used by Directory Service to get file locations.
  */
 
 [scriptable, uuid(bbf8cab0-d43a-11d3-8cc2-00609792278c)]
--- a/xpcom/io/nsIFile.idl
+++ b/xpcom/io/nsIFile.idl
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 %{C++
-#include "prio.h"
-#include "prlink.h"
+struct PRFileDesc;
+struct PRLibrary;
 #include <stdio.h>
 %}
 
 [ptr] native PRFileDescStar(PRFileDesc);
 [ptr] native PRLibraryStar(PRLibrary);
 [ptr] native FILE(FILE);
 
 interface nsISimpleEnumerator;
--- a/xpcom/io/nsIObjectInputStream.idl
+++ b/xpcom/io/nsIObjectInputStream.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsIBinaryInputStream.idl"
-#include "nsrootidl.idl"
 
 /**
  * @see nsIObjectOutputStream
  * @see nsIBinaryInputStream
  */
 
 [scriptable, uuid(6c248606-4eae-46fa-9df0-ba58502368eb)]
 interface nsIObjectInputStream : nsIBinaryInputStream
--- a/xpcom/io/nsIObjectOutputStream.idl
+++ b/xpcom/io/nsIObjectOutputStream.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsIBinaryOutputStream.idl"
-#include "nsrootidl.idl"
 
 /**
  * @See nsIObjectInputStream
  * @See nsIBinaryOutputStream
  */
 
 [scriptable, uuid(92c898ac-5fde-4b99-87b3-5d486422094b)]
 interface nsIObjectOutputStream : nsIBinaryOutputStream
--- a/xpcom/io/nsIPipe.idl
+++ b/xpcom/io/nsIPipe.idl
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "nsIAsyncInputStream.idl"
-#include "nsIAsyncOutputStream.idl"
+#include "nsISupports.idl"
 
+interface nsIAsyncInputStream;
+interface nsIAsyncOutputStream;
 interface nsIMemory;
 
 /**
  * nsIPipe represents an in-process buffer that can be read using nsIInputStream
  * and written using nsIOutputStream.  The reader and writer of a pipe do not
  * have to be on the same thread.  As a result, the pipe is an ideal mechanism
  * to bridge data exchange between two threads.  For example, a worker thread
  * might write data to a pipe from which the main thread will read.
@@ -95,16 +96,19 @@ interface nsISearchableInputStream : nsI
     void search(in string forString, 
                 in boolean ignoreCase, 
                 out boolean found,
                 out unsigned long offsetSearchedTo);
 };
 
 %{C++
 
+class nsIInputStream;
+class nsIOutputStream;
+
 /**
  * NS_NewPipe2
  *
  * This function supersedes NS_NewPipe.  It differs from NS_NewPipe in two
  * major ways:
  *  (1) returns nsIAsyncInputStream and nsIAsyncOutputStream, so it is
  *      not necessary to QI in order to access these interfaces.
  *  (2) the size of the pipe is determined by the number of segments
--- a/xpcom/io/nsIStorageStream.idl
+++ b/xpcom/io/nsIStorageStream.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsrootidl.idl"
 
 interface nsIMemory;
 interface nsIInputStream;
 interface nsIOutputStream;
 
 /**
  * The nsIStorageStream interface maintains an internal data buffer that can be
  * filled using a single output stream.  One or more independent input streams
--- a/xpcom/io/nsIStreamBufferAccess.idl
+++ b/xpcom/io/nsIStreamBufferAccess.idl
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsrootidl.idl"
 
 /**
  * An interface for access to a buffering stream implementation's underlying
  * memory buffer.
  *
  * Stream implementations that QueryInterface to nsIStreamBufferAccess must
  * ensure that all buffers are aligned on the most restrictive type size for
  * the current architecture (e.g., sizeof(double) for RISCy CPUs).  malloc(3)
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -38,16 +38,17 @@
 #include "nsReadableUtils.h"
 #include "nsLocalFile.h"
 #include "nsIComponentManager.h"
 #include "nsXPIDLString.h"
 #include "prproces.h"
 #include "nsIDirectoryEnumerator.h"
 #include "nsISimpleEnumerator.h"
 #include "private/pprio.h"
+#include "prlink.h"
 
 #ifdef MOZ_WIDGET_GTK
 #include "nsIGIOService.h"
 #include "nsIGnomeVFSService.h"
 #endif
 
 #ifdef MOZ_WIDGET_COCOA
 #include <Carbon/Carbon.h>
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -35,16 +35,17 @@
 
 #include  <io.h>
 #include  <stdio.h>
 #include  <stdlib.h>
 #include  <mbstring.h>
 
 #include "nsXPIDLString.h"
 #include "prproces.h"
+#include "prlink.h"
 
 #include "mozilla/Mutex.h"
 #include "SpecialSystemDirectory.h"
 
 #include "nsTraceRefcntImpl.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsThreadUtils.h"
 
--- a/xpcom/io/nsLocalFileWin.h
+++ b/xpcom/io/nsLocalFileWin.h
@@ -10,16 +10,17 @@
 #include "nsError.h"
 #include "nsString.h"
 #include "nsCRT.h"
 #include "nsIFile.h"
 #include "nsIFactory.h"
 #include "nsILocalFileWin.h"
 #include "nsIHashable.h"
 #include "nsIClassInfoImpl.h"
+#include "prio.h"
 
 #include "mozilla/Attributes.h"
 
 #include "windows.h"
 #include "shlobj.h"
 
 #include <sys/stat.h>
 
--- a/xpcom/io/nsPipe3.cpp
+++ b/xpcom/io/nsPipe3.cpp
@@ -11,16 +11,18 @@
 #include "nsSegmentedBuffer.h"
 #include "nsStreamUtils.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "prlog.h"
 #include "nsIClassInfoImpl.h"
 #include "nsAlgorithm.h"
 #include "nsMemory.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
 
 using namespace mozilla;
 
 #if defined(PR_LOGGING)
 //
 // set NSPR_LOG_MODULES=nsPipe:5
 //
 static PRLogModuleInfo *
--- a/xpcom/io/nsStreamUtils.cpp
+++ b/xpcom/io/nsStreamUtils.cpp
@@ -8,16 +8,18 @@
 #include "nsStreamUtils.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIPipe.h"
 #include "nsIEventTarget.h"
 #include "nsIRunnable.h"
 #include "nsISafeOutputStream.h"
 #include "nsString.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
 
 using namespace mozilla;
 
 //-----------------------------------------------------------------------------
 
 class nsInputStreamReadyEvent MOZ_FINAL : public nsIRunnable
                                         , public nsIInputStreamCallback
 {
--- a/xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl
+++ b/xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl
@@ -2,19 +2,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* The nsIInterfaceInfoManager public declaration. */
 
 
 #include "nsISupports.idl"
-#include "nsIInterfaceInfo.idl"
-#include "nsIEnumerator.idl"
-#include "nsISimpleEnumerator.idl"
+
+interface nsIInterfaceInfo;
+interface nsIEnumerator;
 
 /* this is NOT intended to be scriptable */
 [uuid(1d53d8d9-1d92-428f-b5cc-198b55e897d7)]
 interface nsIInterfaceInfoManager : nsISupports
 {
     nsIInterfaceInfo getInfoForIID(in nsIIDPtr iid);
     nsIInterfaceInfo getInfoForName(in string name);
 
--- a/xpcom/string/public/nsAString.h
+++ b/xpcom/string/public/nsAString.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
 #ifndef nsAString_h___
 #define nsAString_h___
 
 #ifndef nsStringFwd_h___
 #include "nsStringFwd.h"
 #endif
 
--- a/xpcom/string/public/nsReadableUtils.h
+++ b/xpcom/string/public/nsReadableUtils.h
@@ -1,13 +1,13 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
 #ifndef nsReadableUtils_h___
 #define nsReadableUtils_h___
 
   /**
    * I guess all the routines in this file are all mis-named.
    * According to our conventions, they should be |NS_xxx|.
    */
--- a/xpcom/string/public/nsString.h
+++ b/xpcom/string/public/nsString.h
@@ -1,14 +1,13 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
 
 #ifndef nsString_h___
 #define nsString_h___
 
 #include "mozilla/Attributes.h"
 
 #ifndef nsSubstring_h___
 #include "nsSubstring.h"
--- a/xpcom/string/public/nsTDependentSubstring.h
+++ b/xpcom/string/public/nsTDependentSubstring.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
   /**
    * nsTDependentSubstring_CharT
    *
    * A string class which wraps an external array of string characters. It
    * is the client code's responsibility to ensure that the external buffer
    * remains valid for a long as the string is alive.
    *
--- a/xpcom/string/public/nsTString.h
+++ b/xpcom/string/public/nsTString.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
   /**
    * This is the canonical null-terminated string class.  All subclasses
    * promise null-terminated storage.  Instances of this class allocate
    * strings on the heap.
    *
    * NAMES:
    *   nsString for wide characters
--- a/xpcom/string/public/nsTSubstring.h
+++ b/xpcom/string/public/nsTSubstring.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
 #include "mozilla/MemoryReporting.h"
 
 #ifndef MOZILLA_INTERNAL_API
 #error Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead.
 #endif
 
   /**
--- a/xpcom/string/public/nsTSubstringTuple.h
+++ b/xpcom/string/public/nsTSubstringTuple.h
@@ -1,14 +1,14 @@
 //* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
   /**
    * nsTSubstringTuple_CharT
    *
    * Represents a tuple of string fragments.  Built as a recursive binary tree.
    * It is used to implement the concatenation of two or more string objects.
    *
    * NOTE: This class is a private implementation detail and should never be 
--- a/xpcom/string/public/string-template-def-char.h
+++ b/xpcom/string/public/string-template-def-char.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
 #define CharT                               char
 #define CharT_is_char                       1
 #define nsTAString_IncompatibleCharT        nsAString
 #define nsTString_CharT                     nsCString
 #define nsTFixedString_CharT                nsFixedCString
 #define nsTAutoString_CharT                 nsAutoCString
 #define nsTSubstring_CharT                  nsACString
--- a/xpcom/string/public/string-template-def-unichar.h
+++ b/xpcom/string/public/string-template-def-unichar.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
 #define CharT                               PRUnichar
 #define CharT_is_PRUnichar                  1
 #define nsTAString_IncompatibleCharT        nsACString
 #define nsTString_CharT                     nsString
 #define nsTFixedString_CharT                nsFixedString
 #define nsTAutoString_CharT                 nsAutoString
 #define nsTSubstring_CharT                  nsAString
--- a/xpcom/string/public/string-template-undef.h
+++ b/xpcom/string/public/string-template-undef.h
@@ -1,14 +1,14 @@
 /* -*- 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/. */
-// IWYU pragma: private, include "nsStringGlue.h"
+// IWYU pragma: private, include "nsString.h"
 
 #undef CharT
 #undef CharT_is_PRUnichar
 #undef CharT_is_char
 #undef nsTAString_IncompatibleCharT
 #undef nsTString_CharT
 #undef nsTFixedString_CharT
 #undef nsTAutoString_CharT
--- a/xpcom/system/nsIGConfService.idl
+++ b/xpcom/system/nsIGConfService.idl
@@ -1,15 +1,16 @@
 /* -*- 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/. */
 
 #include "nsISupports.idl"
-#include "nsIArray.idl"
+
+interface nsIArray;
 
 [scriptable, uuid(5009acae-6973-48c3-b6d6-52c692cc5d9d)]
 interface nsIGConfService : nsISupports
 {
   /* Basic registry access */
   boolean       getBool(in AUTF8String key);
   AUTF8String   getString(in AUTF8String key);
   long          getInt(in AUTF8String key);
--- a/xpcom/system/nsIGSettingsService.idl
+++ b/xpcom/system/nsIGSettingsService.idl
@@ -1,15 +1,16 @@
 /* -*- 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/. */
 
 #include "nsISupports.idl"
-#include "nsIArray.idl"
+
+interface nsIArray;
 
 [scriptable, uuid(16d5b0ed-e756-4f1b-a8ce-9132e869acd8)]
 interface nsIGSettingsCollection : nsISupports
 {
   void          setString(in AUTF8String key, in AUTF8String value);
   void          setBoolean(in AUTF8String key, in boolean value);
   void          setInt(in AUTF8String key, in long value);
   AUTF8String   getString(in AUTF8String key);
--- a/xpcom/tests/TestPipe.cpp
+++ b/xpcom/tests/TestPipe.cpp
@@ -3,16 +3,18 @@
  * 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 "TestHarness.h"
 
 #include "nsIPipe.h"
 #include "nsIMemory.h"
 #include "mozilla/Attributes.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
 
 /** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
 nsresult TP_NewPipe2(nsIAsyncInputStream** input,
                      nsIAsyncOutputStream** output,
                      bool nonBlockingInput,
                      bool nonBlockingOutput,
                      uint32_t segmentSize,
                      uint32_t segmentCount,
--- a/xpcom/threads/nsIProcess.idl
+++ b/xpcom/threads/nsIProcess.idl
@@ -1,15 +1,15 @@
 /* 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 "nsIFile.idl"
 #include "nsISupports.idl"
 
+interface nsIFile;
 interface nsIObserver;
 
 [scriptable, uuid(609610de-9954-4a63-8a7c-346350a86403)]
 interface nsIProcess : nsISupports
 {
   /**
    * Initialises the process with an executable to be run. Call the run method
    * to run the executable.