merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 16 Aug 2013 10:35:19 +0200
changeset 143000 7fe36b0bd01a76f0cf58a1d603793b514c7caacd
parent 142999 85b6f4124b7b4155b5c1f12727de48545533905c (current diff)
parent 142860 6f265af4e3d839c20a452c5dfcd6f63a565546d0 (diff)
child 143001 573d656dadcfc346c7d01d4623939b4ae8fd233a
push id32605
push userphilringnalda@gmail.com
push dateMon, 19 Aug 2013 00:51:46 +0000
treeherdermozilla-inbound@7f882e063eaf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-central to fx-team
toolkit/components/osfile/Makefile.in
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Add an WebIDL interface for bug 892978 requires a clobber for Windows.
+touching resources in Android requires a clobber, and I did that in bug 880259
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "9caa3c130cdfe2597d396d7fc4e70a2463d492ed", 
+    "revision": "340f6676fc5dc34f1b9ab0c40169c0c4fd744587", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -345,17 +345,17 @@ nsContextMenu.prototype = {
     this.showItem("context-shareselect", shareEnabled && this.isContentSelected);
     this.showItem("context-sharelink", shareEnabled && (this.onLink || this.onPlainTextLink) && !this.onMailtoLink);
     this.showItem("context-shareimage", shareEnabled && this.onImage);
     this.showItem("context-sharevideo", shareEnabled && this.onVideo);
     this.setItemAttr("context-sharevideo", "disabled", !this.mediaURL);
   },
 
   initSpellingItems: function() {
-    var canSpell = InlineSpellCheckerUI.canSpellCheck;
+    var canSpell = InlineSpellCheckerUI.canSpellCheck && this.canSpellCheck;
     var onMisspelling = InlineSpellCheckerUI.overMisspelling;
     var showUndo = canSpell && InlineSpellCheckerUI.canUndo();
     this.showItem("spell-check-enabled", canSpell);
     this.showItem("spell-separator", canSpell || this.onEditableArea);
     document.getElementById("spell-check-enabled")
             .setAttribute("checked", canSpell && InlineSpellCheckerUI.enabled);
 
     this.showItem("spell-add-to-dictionary", onMisspelling);
@@ -370,17 +370,17 @@ nsContextMenu.prototype = {
         InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
                                                   suggestionsSeparator, 5);
       this.showItem("spell-no-suggestions", numsug == 0);
     }
     else
       this.showItem("spell-no-suggestions", false);
 
     // dictionary list
-    this.showItem("spell-dictionaries", InlineSpellCheckerUI.enabled);
+    this.showItem("spell-dictionaries", canSpell && InlineSpellCheckerUI.enabled);
     if (canSpell) {
       var dictMenu = document.getElementById("spell-dictionaries-menu");
       var dictSep = document.getElementById("spell-language-separator");
       InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep);
       this.showItem("spell-add-dictionaries-main", false);
     }
     else if (this.onEditableArea) {
       // when there is no spellchecker but we might be able to spellcheck
@@ -542,16 +542,17 @@ nsContextMenu.prototype = {
     this.inFrame           = false;
     this.inSrcdocFrame     = false;
     this.inSyntheticDoc    = false;
     this.hasBGImage        = false;
     this.bgImageURL        = "";
     this.onEditableArea    = false;
     this.isDesignMode      = false;
     this.onCTPPlugin       = false;
+    this.canSpellCheck     = false;
 
     // Remember the node that was clicked.
     this.target = aNode;
 
     // If this is a remote context menu event, use the information from
     // gContextMenuContentData instead.
     if (this.isRemote) {
       this.browser = gContextMenuContentData.browser;
@@ -643,16 +644,23 @@ nsContextMenu.prototype = {
         }
       }
       else if ((this.target instanceof HTMLEmbedElement ||
                 this.target instanceof HTMLObjectElement ||
                 this.target instanceof HTMLAppletElement) &&
                this.target.mozMatchesSelector(":-moz-handler-clicktoplay")) {
         this.onCTPPlugin = true;
       }
+
+      this.canSpellCheck = this._isSpellCheckEnabled(this.target);
+    }
+    else if (this.target.nodeType == Node.TEXT_NODE) {
+      // For text nodes, look at the parent node to determine the spellcheck attribute.
+      this.canSpellCheck = this.target.parentNode &&
+                           this._isSpellCheckEnabled(this.target);
     }
 
     // Second, bubble out, looking for items of interest that can have childen.
     // Always pick the innermost link, background image, etc.
     const XMLNS = "http://www.w3.org/XML/1998/namespace";
     var elem = this.target;
     while (elem) {
       if (elem.nodeType == Node.ELEMENT_NODE) {
@@ -744,17 +752,17 @@ nsContextMenu.prototype = {
           this.onCompletedImage  = false;
           this.onMathML          = false;
           this.inFrame           = false;
           this.inSrcdocFrame     = false;
           this.hasBGImage        = false;
           this.isDesignMode      = true;
           this.onEditableArea = true;
           InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
-          var canSpell = InlineSpellCheckerUI.canSpellCheck;
+          var canSpell = InlineSpellCheckerUI.canSpellCheck && this.canSpellCheck;
           InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
           this.showItem("spell-check-enabled", canSpell);
           this.showItem("spell-separator", canSpell);
         }
       }
     }
   },
 
@@ -797,16 +805,33 @@ nsContextMenu.prototype = {
                .getAppCodebasePrincipal(aRemotePrincipal.URI,
                                         aRemotePrincipal.appId,
                                         aRemotePrincipal.isInBrowserElement);
     }
 
     return aRemotePrincipal;
   },
 
+  _isSpellCheckEnabled: function(aNode) {
+    // We can always force-enable spellchecking on textboxes
+    if (this.isTargetATextBox(aNode)) {
+      return true;
+    }
+    // We can never spell check something which is not content editable
+    var editable = aNode.isContentEditable;
+    if (!editable && aNode.ownerDocument) {
+      editable = aNode.ownerDocument.designMode == "on";
+    }
+    if (!editable) {
+      return false;
+    }
+    // Otherwise make sure that nothing in the parent chain disables spellchecking
+    return aNode.spellcheck;
+  },
+
   // Open linked-to URL in a new window.
   openLink : function () {
     var doc = this.target.ownerDocument;
     urlSecurityCheck(this.linkURL, this._unremotePrincipal(doc.nodePrincipal));
     openLinkIn(this.linkURL, "window",
                { charset: doc.characterSet,
                  referrerURI: doc.documentURIObject });
   },
--- a/browser/base/content/test/contextmenu_common.js
+++ b/browser/base/content/test/contextmenu_common.js
@@ -52,17 +52,18 @@ function getVisibleMenuItems(aMenu, aDat
             var label = item.getAttribute("label");
             ok(label.length, "menuitem " + item.id + " has a label");
             if (isSpellSuggestion) {
               is(key, "", "Spell suggestions shouldn't have an access key");
               items.push("*" + label);
             } else if (isGenerated) {
               items.push("+" + label);
             } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
-                       item.id != "spell-no-suggestions") {
+                       item.id != "spell-no-suggestions" &&
+                       item.id != "spell-add-dictionaries-main") {
               ok(key, "menuitem " + item.id + " has an access key");
               if (accessKeys[key])
                   ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
               else
                   accessKeys[key] = item.id;
             }
             if (!isSpellSuggestion && !isGenerated) {
               items.push(item.id);
--- a/browser/base/content/test/subtst_contextmenu.html
+++ b/browser/base/content/test/subtst_contextmenu.html
@@ -18,16 +18,17 @@ Browser context menu subtest.
 <video controls id="test-video-bad2" width="100" height="100" style="background-color: yellow">
   <source src="bogus.duh" type="video/durrrr;">
 </video>
 <iframe id="test-iframe" width="98"  height="98" style="border: 1px solid black"></iframe>
 <iframe id="test-video-in-iframe" src="video.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
 <iframe id="test-image-in-iframe" src="ctxmenu-image.png" width="98" height="98" style="border: 1px solid black"></iframe>
 <textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
 <div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
+<div id="test-contenteditable-spellcheck-false" contenteditable="true" spellcheck="false">test</div> <!-- No Check Spelling menu item -->
 <div id="test-dom-full-screen">DOM full screen FTW</div>
 <div contextmenu="myMenu">
   <p id="test-pagemenu" hopeless="true">I've got a context menu!</p>
   <menu id="myMenu" type="context">
     <menuitem label="Plain item" onclick="document.getElementById('test-pagemenu').removeAttribute('hopeless');"></menuitem>
     <menuitem label="Disabled item" disabled></menuitem>
     <menuitem> Item w/ textContent</menuitem>
     <menu>
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -749,16 +749,33 @@ function runTest(testNum) {
                                "context-printframe",        true,
                                "---",                       null,
                                "context-viewframesource",   true,
                                "context-viewframeinfo",     true], null,
                           "---",                  null,
                           "context-viewsource",   true,
                           "context-viewinfo",     true
         ].concat(inspectItems));
+        closeContextMenu();
+        openContextMenuFor(inputspellfalse, false, true); // Invoke context menu for next test.
+        break;
+
+    case 30:
+        // Context menu for text input field with spellcheck=false
+        checkContextMenu(["context-undo",        false,
+                          "---",                 null,
+                          "context-cut",         false,
+                          "context-copy",        false,
+                          "context-paste",       null, // ignore clipboard state
+                          "context-delete",      false,
+                          "---",                 null,
+                          "context-selectall",   true,
+                          "---",                 null,
+                          "spell-add-dictionaries-main",  true,
+                         ].concat(inspectItems));
 
         // finish test
         subwindow.close();
         SimpleTest.finish();
         return;
 
     /*
      * Other things that would be nice to test:
@@ -777,17 +794,17 @@ function runTest(testNum) {
 
 
 var testNum = 1;
 var subwindow, chromeWin, contextMenu;
 var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2,
     iframe, video_in_iframe, image_in_iframe, textarea, contenteditable,
     pagemenu, dom_full_screen, plainTextItems, audio_in_video,
     selecttext, selecttextlink, imagelink, select_inputtext, select_inputtext_password,
-    plugin, longdesc, iframe;
+    plugin, longdesc, iframe, inputspellfalse;
 
 function startTest() {
     chromeWin = SpecialPowers.wrap(subwindow)
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
                     .QueryInterface(Ci.nsIInterfaceRequestor)
@@ -818,16 +835,18 @@ function startTest() {
     video_bad2 = subwindow.document.getElementById("test-video-bad2");
     iframe = subwindow.document.getElementById("test-iframe");
     video_in_iframe = subwindow.document.getElementById("test-video-in-iframe").contentDocument.getElementsByTagName("video")[0];
     video_in_iframe.pause();
     image_in_iframe = subwindow.document.getElementById("test-image-in-iframe").contentDocument.getElementsByTagName("img")[0];
     textarea = subwindow.document.getElementById("test-textarea");
     contenteditable = subwindow.document.getElementById("test-contenteditable");
     contenteditable.focus(); // content editable needs to be focused to enable spellcheck
+    inputspellfalse = subwindow.document.getElementById("test-contenteditable-spellcheck-false");
+    inputspellfalse.focus(); // content editable needs to be focused to enable spellcheck
     pagemenu = subwindow.document.getElementById("test-pagemenu");
     dom_full_screen = subwindow.document.getElementById("test-dom-full-screen");
     selecttext = subwindow.document.getElementById("test-select-text");
     selecttextlink = subwindow.document.getElementById("test-select-text-link");
     select_inputtext = subwindow.document.getElementById("test-select-input-text");
     select_inputtext_password = subwindow.document.getElementById("test-select-input-text-type-password");
     plugin = subwindow.document.getElementById("test-plugin");
     longdesc = subwindow.document.getElementById("test-longdesc");
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -76,16 +76,28 @@ if test -z "$_MOZ_USE_RTTI"; then
         esac
     fi
 fi
 ])
 
 dnl A high level macro for selecting compiler options.
 AC_DEFUN([MOZ_COMPILER_OPTS],
 [
+  DEVELOPER_OPTIONS=1
+  MOZ_ARG_ENABLE_BOOL(release,
+  [  --enable-release        Build with more conservative, release engineering-oriented options.
+                          This may slow down builds.],
+      DEVELOPER_OPTIONS=)
+
+  if test -n "$MOZILLA_OFFICIAL" -a -n "$DEVELOPER_OPTIONS"; then
+    AC_MSG_ERROR([You cannot set MOZILLA_OFFICIAL without --enable-release])
+  fi
+  AC_SUBST(DEVELOPER_OPTIONS)
+
+  MOZ_DEBUGGING_OPTS
   MOZ_RTTI
 if test "$CLANG_CXX"; then
     ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
     ## returned by C functions. This is possible because we use knowledge about the ABI
     ## to typedef it to a C type with the same layout when the headers are included
     ## from C.
     ##
     ## mismatched-tags is disabled (bug 780474) mostly because it's useless.
@@ -98,31 +110,58 @@ if test -z "$GNU_CC"; then
     case "$target" in
     *-mingw*)
         ## Warning 4099 (equivalent of mismatched-tags) is disabled (bug 780474)
         ## for the same reasons as above.
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -wd4099"
     esac
 fi
 
+if test "$GNU_CC" -a -n "$DEVELOPER_OPTIONS"; then
+    dnl if the default linker is BFD ld, check if gold is available and try to use it
+    dnl for local builds only.
+    if $CC -Wl,--version 2>&1 | grep -q "GNU ld"; then
+        GOLD=$($CC -print-prog-name=ld.gold)
+        case "$GOLD" in
+        /*)
+            ;;
+        *)
+            GOLD=$(which $GOLD)
+            ;;
+        esac
+        if test -n "$GOLD"; then
+            mkdir -p $_objdir/build/unix/gold
+            ln -s "$GOLD" $_objdir/build/unix/gold/ld
+            if $CC -B $_objdir/build/unix/gold -Wl,--version 2>&1 | grep -q "GNU gold"; then
+                LDFLAGS="$LDFLAGS -B $_objdir/build/unix/gold"
+            else
+                rm -rf $_objdir/build/unix/gold
+            fi
+        fi
+    fi
+fi
+
 if test "$GNU_CC"; then
-    CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
-    CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
+    if test -z "$DEVELOPER_OPTIONS"; then
+        CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
+        CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
+    fi
+    CXXFLAGS="$CXXFLAGS -fno-exceptions"
 fi
 
 dnl ========================================================
 dnl = Identical Code Folding
 dnl ========================================================
 
 MOZ_ARG_DISABLE_BOOL(icf,
 [  --disable-icf          Disable Identical Code Folding],
     MOZ_DISABLE_ICF=1,
     MOZ_DISABLE_ICF= )
 
-if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$MOZ_DISABLE_ICF"; then
+if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$MOZ_DISABLE_ICF" -a -z "$DEVELOPER_OPTIONS"; then
     AC_CACHE_CHECK([whether the linker supports Identical Code Folding],
         LD_SUPPORTS_ICF,
         [echo 'int foo() {return 42;}' \
               'int bar() {return 42;}' \
               'int main() {return foo() - bar();}' > conftest.${ac_ext}
         # If the linker supports ICF, foo and bar symbols will have
         # the same address
         if AC_TRY_COMMAND([${CC-cc} -o conftest${ac_exeext} $LDFLAGS -Wl,--icf=safe -ffunction-sections conftest.${ac_ext} $LIBS 1>&2]) &&
@@ -143,17 +182,17 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
         LDFLAGS="$_SAVE_LDFLAGS"
     fi
 fi
 
 dnl ========================================================
 dnl = Automatically remove dead symbols
 dnl ========================================================
 
-if test "$GNU_CC" -a "$GCC_USE_GNU_LD"; then
+if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS"; then
     if test -n "$MOZ_DEBUG_FLAGS"; then
         dnl See bug 670659
         AC_CACHE_CHECK([whether removing dead symbols breaks debugging],
             GC_SECTIONS_BREAKS_DEBUG_RANGES,
             [echo 'int foo() {return 42;}' \
                   'int bar() {return 1;}' \
                   'int main() {return foo();}' > conftest.${ac_ext}
             if AC_TRY_COMMAND([${CC-cc} -o conftest.${ac_objext} $CFLAGS $MOZ_DEBUG_FLAGS -c conftest.${ac_ext} 1>&2]) &&
--- a/build/autoconf/config.status.m4
+++ b/build/autoconf/config.status.m4
@@ -62,17 +62,16 @@ dnl Picked from autoconf 2.13
 trap '' 1 2 15
 AC_CACHE_SAVE
 
 test "x$prefix" = xNONE && prefix=$ac_default_prefix
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
 trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
 : ${CONFIG_STATUS=./config.status}
 
 dnl We're going to need [ ] for python syntax.
 changequote(<<<, >>>)dnl
 echo creating $CONFIG_STATUS
 
 extra_python_path=${COMM_BUILD:+"'mozilla', "}
 
@@ -172,10 +171,13 @@ dnl Don't rely on virtualenv here. Stand
     sys.path.append(os.path.join(topsrcdir, ${extra_python_path}'build'))
     from ConfigStatus import config_status
     config_status(**args)
 EOF
 changequote([, ])
 chmod +x $CONFIG_STATUS
 rm -fr confdefs* $ac_clean_files
 dnl Execute config.status, unless --no-create was passed to configure.
-test "$no_create" = yes || ${PYTHON} $CONFIG_STATUS || exit 1
+if test "$no_create" != yes && ! ${PYTHON} $CONFIG_STATUS; then
+    trap '' EXIT
+    exit 1
+fi
 ])
--- a/build/autoconf/hooks.m4
+++ b/build/autoconf/hooks.m4
@@ -19,8 +19,12 @@ MOZ_CONFIG_LOG_TRAP
 
 dnl Disable the trap when running sub-configures.
 define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS]))
 define([AC_OUTPUT_SUBDIRS],
 [trap '' EXIT
 _MOZ_AC_OUTPUT_SUBDIRS($1)
 MOZ_CONFIG_LOG_TRAP
 ])
+
+dnl Print error messages in config.log as well as stderr
+define([AC_MSG_ERROR],
+[{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
--- a/build/dumbmake-dependencies
+++ b/build/dumbmake-dependencies
@@ -1,9 +1,12 @@
 toolkit/library
+  dom
+    ipc
+    security/sandbox
   ipc
   netwerk/build
     netwerk
   storage/build
     storage
   xpcom
     chrome
   extensions
--- a/build/mozconfig.common
+++ b/build/mozconfig.common
@@ -1,15 +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/.
 
-# Common mozconfig for all users
+# Common mozconfig for official builds.
 #
 # Add options to this file that will be inherited by all in-tree mozconfigs.
 # This is useful for eg try builds with nondefault options that apply to all
 # architectures, though note that if you want to override options set in
 # another mozconfig file, you'll need to use mozconfig.common.override instead
 # of this file.
 
 mk_add_options AUTOCLOBBER=1
 
 ac_add_options --enable-crashreporter
+
+ac_add_options --enable-release
--- a/config/makefiles/precompile/Makefile.in
+++ b/config/makefiles/precompile/Makefile.in
@@ -13,24 +13,24 @@ include $(DEPTH)/config/autoconf.mk
 
 SUPPRESS_DEFAULT_RULES := 1
 
 include $(topsrcdir)/config/rules.mk
 
 # We don't print the build status messages unless we're in a top level build
 # otherwise the output is unexpected and it confuses downstream parsers.
 define make_subtier_dir
-@echo "BUILDSTATUS SUBTIER_START precompile $(1)"
+$(call BUILDSTATUS,SUBTIER_START precompile $(1))
 +$(MAKE) -C $(2) $(3)
-@echo "BUILDSTATUS SUBTIER_FINISH precompile $(1)"
+$(call BUILDSTATUS,SUBTIER_FINISH precompile $(1))
 
 endef
 
 export::
-	@echo "BUILDSTATUS SUBTIERS IPDL WebIDL XPIDL"
+	$(call BUILDSTATUS,SUBTIERS IPDL WebIDL XPIDL)
 
 export:: ipdl webidl xpidl-parser xpidl
 
 ipdl:
 	$(call make_subtier_dir,IPDL,$(DEPTH)/ipc/ipdl,ipdl)
 
 webidl:
 	$(call make_subtier_dir,WebIDL,$(DEPTH)/dom/bindings,webidl)
--- a/config/rebuild_check.py
+++ b/config/rebuild_check.py
@@ -1,30 +1,44 @@
 # 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/.
 
 import os
+import errno
 
 def mtime(path):
-    return os.stat(path).st_mtime
+    try:
+        return os.stat(path).st_mtime
+    except OSError as e:
+        if e.errno == errno.ENOENT:
+            return -1
+        raise
 
 def rebuild_check(args):
     target = args[0]
     deps = args[1:]
-    if not os.path.exists(target):
+    t = mtime(target)
+    if t < 0:
         print target
         return
-    t = mtime(target)
 
     newer = []
+    removed = []
     for dep in deps:
-        if mtime(dep) > t:
+        deptime = mtime(dep)
+        if deptime < 0:
+            removed.append(dep)
+        elif mtime(dep) > t:
             newer.append(dep)
 
-    if newer:
+    if newer and removed:
+        print 'Rebuilding %s because %s changed and %s was removed' % (target, ', '.join(newer), ', '.join(removed))
+    elif newer:
         print 'Rebuilding %s because %s changed' % (target, ', '.join(newer))
+    elif removed:
+        print 'Rebuilding %s because %s was removed' % (target, ', '.join(removed))
     else:
         print 'Rebuilding %s for an unknown reason' % target
 
 if __name__ == '__main__':
     import sys
     rebuild_check(sys.argv[1:])
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -427,31 +427,34 @@ endif
 
 ifdef MOZ_UPDATE_XTERM
 # Its good not to have a newline at the end of the titlebar string because it
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick printf into doing it.
 UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ;
 endif
 
+ifdef MACH
+BUILDSTATUS=@echo BUILDSTATUS $1
+endif
 # Static directories are largely independent of our build system. But, they
 # could share the same build mechanism (like moz.build files). We need to
 # prevent leaking of our backend state to these independent build systems. This
 # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static
 # directories.
 define SUBMAKE # $(call SUBMAKE,target,directory,static)
 +@$(UPDATE_TITLE)
 +$(if $(3), MOZBUILD_BACKEND_CHECKED=,) $(MAKE) $(if $(2),-C $(2)) $(1)
 
 endef # The extra line is important here! don't delete it
 
 define TIER_DIR_SUBMAKE
-@echo "BUILDSTATUS TIERDIR_START  $(2)"
+$(call BUILDSTATUS,TIERDIR_START  $(2))
 $(call SUBMAKE,$(1),$(2),$(3))
-@echo "BUILDSTATUS TIERDIR_FINISH $(2)"
+$(call BUILDSTATUS,TIERDIR_FINISH $(2))
 
 endef # Ths empty line is important.
 
 
 ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
   $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
@@ -677,17 +680,17 @@ SUBMAKEFILES += $(addsuffix /Makefile, $
 
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
 ifdef TIERS
 default all alldep::
-	@echo "BUILDSTATUS TIERS $(TIERS)"
+	$(call BUILDSTATUS,TIERS $(TIERS))
 	$(foreach tier,$(TIERS),$(call SUBMAKE,tier_$(tier)))
 else
 
 default all::
 ifneq (,$(strip $(STATIC_DIRS)))
 	$(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,,$(dir),1))
 endif
 	$(MAKE) export
@@ -714,43 +717,36 @@ endif
 
 # This function is called and evaluated to produce the rule to build the
 # specified tier. Each tier begins by building the "static" directories.
 # The BUILDSTATUS echo commands are used to faciliate easier parsing
 # of build output. Build drivers are encouraged to filter these lines
 # from the user.
 define CREATE_TIER_RULE
 tier_$(1)::
-	@echo "BUILDSTATUS TIER_START $(1)"
-	@printf "BUILDSTATUS SUBTIERS"
+	$(call BUILDSTATUS,TIER_START $(1))
+	$(call BUILDSTATUS,SUBTIERS $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
+	$(call BUILDSTATUS,STATICDIRS $$($$@_staticdirs))
+	$(call BUILDSTATUS,DIRS $$($$@_dirs))
 ifneq (,$(tier_$(1)_staticdirs))
-	@printf " static"
+	$(call BUILDSTATUS,SUBTIER_START $(1) static)
+	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1))
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) static)
 endif
 ifneq (,$(tier_$(1)_dirs))
-	@printf " export libs tools"
-endif
-	@printf "\n"
-	@echo "BUILDSTATUS STATICDIRS $$($$@_staticdirs)"
-	@echo "BUILDSTATUS DIRS $$($$@_dirs)"
-ifneq (,$(tier_$(1)_staticdirs))
-	@echo "BUILDSTATUS SUBTIER_START $(1) static"
-	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1))
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) static"
-endif
-ifneq (,$(tier_$(1)_dirs))
-	@echo "BUILDSTATUS SUBTIER_START $(1) export"
+	$(call BUILDSTATUS,SUBTIER_START $(1) export)
 	$$(MAKE) export_$$@
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) export"
-	@echo "BUILDSTATUS SUBTIER_START $(1) libs"
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) export)
+	$(call BUILDSTATUS,SUBTIER_START $(1) libs)
 	$$(MAKE) libs_$$@
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) libs"
-	@echo "BUILDSTATUS SUBTIER_START $(1) tools"
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) libs)
+	$(call BUILDSTATUS,SUBTIER_START $(1) tools)
 	$$(MAKE) tools_$$@
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) tools"
-	@echo "BUILDSTATUS TIER_FINISH $(1)"
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) tools)
+	$(call BUILDSTATUS TIER_FINISH $(1))
 endif
 endef
 
 $(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier))))
 
 # Do everything from scratch
 everything::
 	$(MAKE) clean
--- a/configure.in
+++ b/configure.in
@@ -4203,16 +4203,18 @@ MOZ_USE_NATIVE_POPUP_WINDOWS=
 MOZ_ANDROID_HISTORY=
 MOZ_WEBSMS_BACKEND=
 MOZ_ANDROID_BEAM=
 ACCESSIBILITY=1
 MOZ_TIME_MANAGER=
 MOZ_PAY=
 MOZ_AUDIO_CHANNEL_MANAGER=
 NSS_NO_LIBPKIX=
+MOZ_CONTENT_SANDBOX=
+MOZ_CONTENT_SANDBOX_REPORTER=
 
 case "$target_os" in
     mingw*)
         NS_ENABLE_TSF=1
         AC_DEFINE(NS_ENABLE_TSF)
         ;;
 esac
 
@@ -6486,16 +6488,42 @@ AC_SUBST(MOZ_DISABLE_CRYPTOLEGACY)
 dnl ========================================================
 dnl = Disable libpkix
 dnl ========================================================
 if test -n "$NSS_NO_LIBPKIX"; then
     AC_DEFINE(NSS_NO_LIBPKIX)
 fi
 AC_SUBST(NSS_NO_LIBPKIX)
 
+dnl ========================================================
+dnl = Content process sandboxing
+dnl ========================================================
+if test -n "$gonkdir"; then
+    MOZ_CONTENT_SANDBOX=1
+fi
+
+MOZ_ARG_ENABLE_BOOL(content-sandbox,
+[  --enable-content-sandbox        Enable sandboxing support for content-processes],
+    MOZ_CONTENT_SANDBOX=1)
+
+if test -n "$MOZ_CONTENT_SANDBOX"; then
+    AC_DEFINE(MOZ_CONTENT_SANDBOX)
+fi
+
+AC_SUBST(MOZ_CONTENT_SANDBOX)
+
+MOZ_ARG_ENABLE_BOOL(content-sandbox-reporter,
+[ --enable-content-sandbox-reporter        Enable syscall reporter to troubleshoot syscalls denied by the content-processes sandbox],
+    MOZ_CONTENT_SANDBOX_REPORTER=1)
+
+if test -n "$MOZ_CONTENT_SANDBOX_REPORTER"; then
+    AC_DEFINE(MOZ_CONTENT_SANDBOX_REPORTER)
+fi
+
+AC_SUBST(MOZ_CONTENT_SANDBOX_REPORTER)
 
 dnl ========================================================
 dnl =
 dnl = Module specific options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Individual module options)
 
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -111,18 +111,18 @@ template<typename> class OwningNonNull;
 template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x62cca591, 0xa030, 0x4117, \
- { 0x9b, 0x80, 0xdc, 0xd3, 0x66, 0xbb, 0xb5, 0x9 } }
+{ 0x56a350f4, 0xc286, 0x440c, \
+  { 0x85, 0xb1, 0xb6, 0x55, 0x77, 0xeb, 0x63, 0xfd } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
@@ -650,16 +650,19 @@ public:
 
   /*
    * Gets the srcdoc string from within the channel (assuming both exist).
    * Returns a void string if this isn't a srcdoc document or if
    * the channel has not been set.
    */
   nsresult GetSrcdocData(nsAString& aSrcdocData);
 
+  bool DidDocumentOpen() {
+    return mDidDocumentOpen;
+  }
 
 protected:
   virtual Element *GetRootElementInternal() const = 0;
 
 public:
   // Get the root <html> element, or return null if there isn't one (e.g.
   // if the root isn't <html>)
   Element* GetHtmlElement() const;
@@ -2333,16 +2336,21 @@ protected:
   bool mHasHadDefaultView;
 
   // Whether style sheet change events will be dispatched for this document
   bool mStyleSheetChangeEventsEnabled;
 
   // Whether the document was created by a srcdoc iframe.
   bool mIsSrcdocDocument;
 
+  // Records whether we've done a document.open. If this is true, it's possible
+  // for nodes from this document to have outdated wrappers in their wrapper
+  // caches.
+  bool mDidDocumentOpen;
+
   // The document's script global object, the object from which the
   // document can get its script context and scope. This is the
   // *inner* window object.
   nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
 
   // If mIsStaticDocument is true, mOriginalDocument points to the original
   // document.
   nsCOMPtr<nsIDocument> mOriginalDocument;
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -1319,16 +1319,35 @@ AdoptNodeIntoOwnerDoc(nsINode *aParent, 
                "ownerDoc chainged while adopting");
   NS_ASSERTION(adoptedNode == node, "Uh, adopt node changed nodes?");
   NS_ASSERTION(aParent->OwnerDoc() == aNode->OwnerDoc(),
                "ownerDocument changed again after adopting!");
 
   return NS_OK;
 }
 
+static nsresult
+CheckForOutdatedParent(nsINode* aParent, nsINode* aNode)
+{
+  if (JSObject* existingObj = aNode->GetWrapper()) {
+    nsIGlobalObject* global = aParent->OwnerDoc()->GetScopeObject();
+    MOZ_ASSERT(global);
+
+    if (js::GetGlobalForObjectCrossCompartment(existingObj) !=
+        global->GetGlobalJSObject()) {
+      AutoJSContext cx;
+      JS::Rooted<JSObject*> rooted(cx, existingObj);
+      nsresult rv = ReparentWrapper(cx, rooted);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+
+  return NS_OK;
+}
+
 nsresult
 nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
                          bool aNotify, nsAttrAndChildArray& aChildArray)
 {
   NS_PRECONDITION(!aKid->GetParentNode(),
                   "Inserting node that already has parent");
   nsresult rv;
 
@@ -1338,16 +1357,19 @@ nsINode::doInsertChildAt(nsIContent* aKi
 
   // Do this before checking the child-count since this could cause mutations
   nsIDocument* doc = GetCurrentDoc();
   mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
 
   if (OwnerDoc() != aKid->OwnerDoc()) {
     rv = AdoptNodeIntoOwnerDoc(this, aKid);
     NS_ENSURE_SUCCESS(rv, rv);
+  } else if (OwnerDoc()->DidDocumentOpen()) {
+    rv = CheckForOutdatedParent(this, aKid);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   uint32_t childCount = aChildArray.ChildCount();
   NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
   bool isAppend = (aIndex == childCount);
 
   rv = aChildArray.InsertChildAt(aKid, aIndex);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1948,21 +1970,26 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     --insPos;
   }
 
   // Move new child over to our document if needed. Do this after removing
   // it from its parent so that AdoptNode doesn't fire DOMNodeRemoved
   // DocumentType nodes are the only nodes that can have a null
   // ownerDocument according to the DOM spec, and we need to allow
   // inserting them w/o calling AdoptNode().
-  if (OwnerDoc() != newContent->OwnerDoc()) {
+  if (doc != newContent->OwnerDoc()) {
     aError = AdoptNodeIntoOwnerDoc(this, aNewChild);
     if (aError.Failed()) {
       return nullptr;
     }
+  } else if (doc->DidDocumentOpen()) {
+    aError = CheckForOutdatedParent(this, aNewChild);
+    if (aError.Failed()) {
+      return nullptr;
+    }
   }
 
   /*
    * Check if we're inserting a document fragment. If we are, we need
    * to actually add its children individually (i.e. we don't add the
    * actual document fragment).
    */
   nsINode* result = aReplace ? aRefChild : aNewChild;
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -70,16 +70,17 @@
 #include "nsIContentSecurityPolicy.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "mozilla/dom/Element.h"
 #include "GeckoProfiler.h"
 #include "nsObjectFrame.h"
 #include "nsDOMClassInfo.h"
 #include "nsWrapperCacheInlines.h"
+#include "nsDOMJSUtils.h"
 
 #include "nsWidgetsCID.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Telemetry.h"
 
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -646,16 +646,27 @@ MOCHITEST_FILES_C= \
 		file_CSP_bug885433_blocks.html^headers^ \
 		test_bug890580.html \
 		test_declare_stylesheet_obsolete.html \
 		variable_style_sheet.sjs \
 		test_processing_instruction_update_stylesheet.xhtml \
 		test_CSP_bug888172.html \
 		file_CSP_bug888172.html \
 		file_CSP_bug888172.sjs \
+		test_CSP_bug663567.html \
+		file_CSP_bug663567_allows.xml \
+		file_CSP_bug663567_allows.xml^headers^ \
+		file_CSP_bug663567_allows.xsl \
+		file_CSP_bug663567_blocks.xml \
+		file_CSP_bug663567_blocks.xml^headers^ \
+		test_CSP_bug802872.html \
+		file_CSP_bug802872.html \
+		file_CSP_bug802872.html^headers^ \
+		file_CSP_bug802872.js \
+		file_CSP_bug802872.sjs \
 		$(NULL)
 
 # OOP tests don't work on Windows (bug 763081) or native-fennec
 # (see Bug 774939)
 ifneq ($(OS_ARCH),WINNT)
 ifndef MOZ_ANDROID_OMTC
 MOCHITEST_FILES_B += \
 		test_messagemanager_assertpermission.html \
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug663567_allows.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type="text/xsl" href="file_CSP_bug663567_allows.xsl"?>
+<catalog>
+	<cd>
+		<title>Empire Burlesque</title>
+		<artist>Bob Dylan</artist>
+		<country>USA</country>
+		<company>Columbia</company>
+		<price>10.90</price>
+		<year>1985</year>
+	</cd>
+	<cd>
+		<title>Hide your heart</title>
+		<artist>Bonnie Tyler</artist>
+		<country>UK</country>
+		<company>CBS Records</company>
+		<price>9.90</price>
+		<year>1988</year>
+	</cd>
+	<cd>
+		<title>Greatest Hits</title>
+		<artist>Dolly Parton</artist>
+		<country>USA</country>
+		<company>RCA</company>
+		<price>9.90</price>
+		<year>1982</year>
+	</cd>
+</catalog>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug663567_allows.xml^headers^
@@ -0,0 +1,1 @@
+Content-Security-Policy: default-src 'self'
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug663567_allows.xsl
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- Edited by XMLSpy® -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="/">
+  <html>
+  <body>
+  <h2 id="xsltheader">this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!</h2>
+    <table border="1">
+      <tr bgcolor="#990099">
+        <th>Title</th>
+        <th>Artist</th>
+        <th>Price</th>
+      </tr>
+      <xsl:for-each select="catalog/cd">
+      <tr>
+        <td><xsl:value-of select="title"/></td>
+        <td><xsl:value-of select="artist"/></td>
+        <td><xsl:value-of select="price"/></td>
+      </tr>
+      </xsl:for-each>
+    </table>
+  </body>
+  </html>
+</xsl:template>
+</xsl:stylesheet>
+
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug663567_blocks.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml-stylesheet type="text/xsl" href="http://example.org/tests/content/base/test/file_CSP_bug663567_blocks.xsl"?>
+<catalog>
+	<cd>
+		<title>Empire Burlesque</title>
+		<artist>Bob Dylan</artist>
+		<country>USA</country>
+		<company>Columbia</company>
+		<price>10.90</price>
+		<year>1985</year>
+	</cd>
+	<cd>
+		<title>Hide your heart</title>
+		<artist>Bonnie Tyler</artist>
+		<country>UK</country>
+		<company>CBS Records</company>
+		<price>9.90</price>
+		<year>1988</year>
+	</cd>
+	<cd>
+		<title>Greatest Hits</title>
+		<artist>Dolly Parton</artist>
+		<country>USA</country>
+		<company>RCA</company>
+		<price>9.90</price>
+		<year>1982</year>
+	</cd>
+</catalog>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug663567_blocks.xml^headers^
@@ -0,0 +1,1 @@
+Content-Security-Policy: default-src 'self'
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug802872.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 802872</title>
+  <!-- Including SimpleTest.js so we can use AddLoadEvent !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <script src='file_CSP_bug802872.js'></script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug802872.html^headers^
@@ -0,0 +1,1 @@
+Content-Security-Policy: default-src 'self'
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug802872.js
@@ -0,0 +1,43 @@
+/*
+ *   The policy for this test is:
+ *   Content-Security-Policy: default-src 'self'
+ */
+
+function createAllowedEvent() {
+  /*
+   * Creates a new EventSource using 'http://mochi.test:8888'. Since all mochitests run on
+   * 'http://mochi.test', a default-src of 'self' allows this request.
+   */
+  var src_event = new EventSource("http://mochi.test:8888/tests/content/base/test/file_CSP_bug802872.sjs");
+
+  src_event.onmessage = function(e) {
+    src_event.close();
+    parent.dispatchEvent(new Event('allowedEventSrcCallbackOK'));
+  }
+
+  src_event.onerror = function(e) {
+    src_event.close();
+    parent.dispatchEvent(new Event('allowedEventSrcCallbackFailed'));
+  }
+}
+
+function createBlockedEvent() {
+  /*
+   * creates a new EventSource using 'http://example.com'. This domain is not whitelisted by the 
+   * CSP of this page, therefore the CSP blocks this request.
+   */
+  var src_event = new EventSource("http://example.com/tests/content/base/test/file_CSP_bug802872.sjs");
+
+  src_event.onmessage = function(e) {
+    src_event.close();
+    parent.dispatchEvent(new Event('blockedEventSrcCallbackOK'));
+  }
+
+  src_event.onerror = function(e) {
+    src_event.close();
+    parent.dispatchEvent(new Event('blockedEventSrcCallbackFailed'));
+  }
+}
+
+addLoadEvent(createAllowedEvent);
+addLoadEvent(createBlockedEvent);
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_bug802872.sjs
@@ -0,0 +1,7 @@
+function handleRequest(request, response)
+{
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "text/event-stream", false);
+  response.write("data: eventsource response from server!");
+  response.write("\n\n");
+}
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_CSP_bug663567.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test if XSLT stylesheet is subject to document's CSP</title>
+  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <iframe style="width:100%;" id='xsltframe'></iframe>
+  <iframe style="width:100%;" id='xsltframe2'></iframe>
+
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+// define the expected output of this test
+var header = "this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!";
+
+var finishedTests = 0;
+var numberOfTests = 2;
+
+var checkExplicitFinish = function() {
+  finishedTests++;
+  if (finishedTests == numberOfTests) {
+     SimpleTest.finish();
+  }
+}
+
+function checkAllowed () {
+  /*   The policy for this test is:
+   *   Content-Security-Policy: default-src 'self'
+   *
+   *   we load the xsl file using:
+   *   <?xml-stylesheet type="text/xsl" href="file_CSP_bug663467_allows.xsl"?>
+   */
+  try {
+    var cspframe = document.getElementById('xsltframe');
+    var xsltAllowedHeader = cspframe.contentWindow.document.getElementById('xsltheader').innerHTML;
+    is(xsltAllowedHeader, header, "XSLT loaded from 'self' should be allowed!");
+  }
+  catch (e) {
+    ok(false, "Error: could not access content in xsltframe!")
+  }
+  checkExplicitFinish();
+}
+
+function checkBlocked () {
+  /*   The policy for this test is:
+   *   Content-Security-Policy: default-src 'self'
+   *
+   *   we load the xsl file using:
+   *   <?xml-stylesheet type="text/xsl"
+   *    href="http://example.org/tests/content/base/test/file_CSP_bug663467_blocks.xsl"?>
+   */
+  try {
+    var cspframe = document.getElementById('xsltframe2');
+    var xsltBlockedHeader = cspframe.contentWindow.document.getElementById('xsltheader');
+    is(xsltBlockedHeader, null, "XSLT loaded from different host should be blocked!");
+  }
+  catch (e) {
+    ok(false, "Error: could not access content in xsltframe2!")
+  }
+  checkExplicitFinish();
+}
+
+SpecialPowers.pushPrefEnv(
+  {'set':[["security.csp.speccompliant", true]]},
+  function () {
+    document.getElementById('xsltframe').addEventListener('load', checkAllowed, false);
+    document.getElementById('xsltframe').src = 'file_CSP_bug663567_allows.xml';
+
+    document.getElementById('xsltframe2').addEventListener('load', checkBlocked, false);
+    document.getElementById('xsltframe2').src = 'file_CSP_bug663567_blocks.xml';
+  }
+);
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_CSP_bug802872.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 802872</title>
+  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <iframe style="width:100%;" id='eventframe'></iframe>
+
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var finishedTests = 0;
+var numberOfTests = 2;
+
+var checkExplicitFinish = function () {
+  finishedTests++;
+  if (finishedTests == numberOfTests) {
+     SimpleTest.finish();
+  }
+}
+
+SpecialPowers.pushPrefEnv(
+  {'set':[["security.csp.speccompliant", true]]},
+  function () {
+    // add event listeners for CSP-permitted EventSrc callbacks
+    addEventListener('allowedEventSrcCallbackOK', function (e) {
+      ok(true, "OK: CSP allows EventSource for whitelisted domain!");
+      checkExplicitFinish();
+    }, false);
+    addEventListener('allowedEventSrcCallbackFailed', function (e) {
+      ok(false, "Error: CSP blocks EventSource for whitelisted domain!");
+      checkExplicitFinish();
+    }, false);
+
+    // add event listeners for CSP-blocked EventSrc callbacks
+    addEventListener('blockedEventSrcCallbackOK', function (e) {
+      ok(false, "Error: CSP allows EventSource to not whitelisted domain!");
+      checkExplicitFinish();
+    }, false);
+    addEventListener('blockedEventSrcCallbackFailed', function (e) {
+      ok(true, "OK: CSP blocks EventSource for not whitelisted domain!");
+      checkExplicitFinish();
+    }, false);
+
+    // load it
+    document.getElementById('eventframe').src = 'file_CSP_bug802872.html';
+  }
+);
+
+</script>
+</body>
+</html>
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -964,32 +964,26 @@ bool WebGLContext::IsExtensionSupported(
 bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
 {
     if (mDisableExtensions) {
         return false;
     }
 
     switch (ext) {
         case OES_element_index_uint:
-            if (!gl->IsGLES2())
-                return true;
-            return gl->IsExtensionSupported(GLContext::OES_element_index_uint);
+            return gl->IsExtensionSupported(GLContext::XXX_element_index_uint);
         case OES_standard_derivatives:
-            if (!gl->IsGLES2())
-                return true;
-            return gl->IsExtensionSupported(GLContext::OES_standard_derivatives);
+            return gl->IsExtensionSupported(GLContext::XXX_standard_derivatives);
         case WEBGL_lose_context:
             // We always support this extension.
             return true;
         case OES_texture_float:
-            return gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float
-                                                          : GLContext::ARB_texture_float);
+            return gl->IsExtensionSupported(GLContext::XXX_texture_float);
         case OES_texture_float_linear:
-            return gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float_linear
-                                                          : GLContext::ARB_texture_float);
+            return gl->IsExtensionSupported(GLContext::XXX_texture_float_linear);
         case OES_vertex_array_object:
             return WebGLExtensionVertexArray::IsSupported(this);
         case EXT_texture_filter_anisotropic:
             return gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
         case WEBGL_compressed_texture_s3tc:
             if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_s3tc)) {
                 return true;
             }
@@ -1000,28 +994,18 @@ bool WebGLContext::IsExtensionSupported(
                 return true;
             }
             return false;
         case WEBGL_compressed_texture_atc:
             return gl->IsExtensionSupported(GLContext::AMD_compressed_ATC_texture);
         case WEBGL_compressed_texture_pvrtc:
             return gl->IsExtensionSupported(GLContext::IMG_texture_compression_pvrtc);
         case WEBGL_depth_texture:
-            if (gl->IsGLES2() &&
-                gl->IsExtensionSupported(GLContext::OES_packed_depth_stencil) &&
-                gl->IsExtensionSupported(GLContext::OES_depth_texture))
-            {
-                return true;
-            }
-            else if (!gl->IsGLES2() &&
-                     gl->IsExtensionSupported(GLContext::EXT_packed_depth_stencil))
-            {
-                return true;
-            }
-            return false;
+            return gl->IsExtensionSupported(GLContext::XXX_packed_depth_stencil) &&
+                   gl->IsExtensionSupported(GLContext::XXX_depth_texture);
         case ANGLE_instanced_arrays:
             return WebGLExtensionInstancedArrays::IsSupported(this);
         default:
             // For warnings-as-errors.
             break;
     }
 
     if (Preferences::GetBool("webgl.enable-draft-extensions", false) || IsWebGL2()) {
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -384,19 +384,17 @@ public:
     void DeleteRenderbuffer(WebGLRenderbuffer *rbuf);
     void DeleteShader(WebGLShader *shader);
     void DeleteVertexArray(WebGLVertexArray *vao);
     void DeleteTexture(WebGLTexture *tex);
     void DepthFunc(WebGLenum func);
     void DepthMask(WebGLboolean b);
     void DepthRange(WebGLclampf zNear, WebGLclampf zFar);
     void DetachShader(WebGLProgram *program, WebGLShader *shader);
-    void Disable(WebGLenum cap);
     void DrawBuffers(const dom::Sequence<GLenum>& buffers);
-    void Enable(WebGLenum cap);
     void Flush() {
         if (!IsContextStable())
             return;
         MakeContextCurrent();
         gl->fFlush();
     }
     void Finish() {
         if (!IsContextStable())
@@ -418,17 +416,16 @@ public:
     void GetAttachedShaders(WebGLProgram* prog,
                             dom::Nullable< nsTArray<WebGLShader*> > &retval);
     WebGLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
     JS::Value GetBufferParameter(WebGLenum target, WebGLenum pname);
     JS::Value GetBufferParameter(JSContext* /* unused */, WebGLenum target,
                                  WebGLenum pname) {
         return GetBufferParameter(target, pname);
     }
-    JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv);
     WebGLenum GetError();
     JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
                                                 WebGLenum target,
                                                 WebGLenum attachment,
                                                 WebGLenum pname,
                                                 ErrorResult& rv);
     JS::Value GetProgramParameter(WebGLProgram *prog, WebGLenum pname);
     JS::Value GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
@@ -458,17 +455,16 @@ public:
         return GetTexParameter(target, pname);
     }
     JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
                          WebGLUniformLocation *location, ErrorResult& rv);
     already_AddRefed<WebGLUniformLocation>
       GetUniformLocation(WebGLProgram *prog, const nsAString& name);
     void Hint(WebGLenum target, WebGLenum mode);
     bool IsBuffer(WebGLBuffer *buffer);
-    bool IsEnabled(WebGLenum cap);
     bool IsFramebuffer(WebGLFramebuffer *fb);
     bool IsProgram(WebGLProgram *prog);
     bool IsRenderbuffer(WebGLRenderbuffer *rb);
     bool IsShader(WebGLShader *shader);
     bool IsTexture(WebGLTexture *tex);
     bool IsVertexArray(WebGLVertexArray *vao);
     void LineWidth(WebGLfloat width) {
         if (!IsContextStable())
@@ -754,16 +750,27 @@ public:
     already_AddRefed<WebGLQuery> GetQuery(WebGLenum target, WebGLenum pname);
     JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname);
 
 private:
     bool ValidateTargetParameter(WebGLenum target, const char* infos);
     WebGLRefPtr<WebGLQuery>& GetActiveQueryByTarget(WebGLenum target);
 
 // -----------------------------------------------------------------------------
+// State and State Requests (WebGLContextState.cpp)
+public:
+    void Disable(WebGLenum cap);
+    void Enable(WebGLenum cap);
+    JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv);
+    bool IsEnabled(WebGLenum cap);
+
+private:
+    bool ValidateCapabilityEnum(WebGLenum cap, const char* info);
+
+// -----------------------------------------------------------------------------
 // Vertices Feature (WebGLContextVertices.cpp)
 public:
     void DrawArrays(GLenum mode, WebGLint first, WebGLsizei count);
     void DrawArraysInstanced(GLenum mode, WebGLint first, WebGLsizei count, WebGLsizei primcount);
     void DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, WebGLintptr byteOffset);
     void DrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type,
                                WebGLintptr byteOffset, WebGLsizei primcount);
 
@@ -959,17 +966,16 @@ protected:
     bool IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const;
     bool IsExtensionSupported(WebGLExtensionID ext) const;
 
     nsTArray<WebGLenum> mCompressedTextureFormats;
 
     // -------------------------------------------------------------------------
     // Validation functions (implemented in WebGLContextValidate.cpp)
     bool InitAndValidateGL();
-    bool ValidateCapabilityEnum(WebGLenum cap, const char *info);
     bool ValidateBlendEquationEnum(WebGLenum cap, const char *info);
     bool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info);
     bool ValidateBlendFuncSrcEnum(WebGLenum mode, const char *info);
     bool ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info);
     bool ValidateTextureTargetEnum(WebGLenum target, const char *info);
     bool ValidateComparisonEnum(WebGLenum target, const char *info);
     bool ValidateStencilOpEnum(WebGLenum action, const char *info);
     bool ValidateFaceEnum(WebGLenum face, const char *info);
--- a/content/canvas/src/WebGLContextAsyncQueries.cpp
+++ b/content/canvas/src/WebGLContextAsyncQueries.cpp
@@ -25,21 +25,37 @@ GetQueryTargetEnumString(WebGLenum targe
     {
         case LOCAL_GL_ANY_SAMPLES_PASSED:
             return "ANY_SAMPLES_PASSED";
         case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
             return "ANY_SAMPLES_PASSED_CONSERVATIVE";
         default:
             break;
     }
-    
+
     MOZ_ASSERT(false, "Unknown query `target`.");
     return "UNKNOWN_QUERY_TARGET";
 }
 
+static inline GLenum
+SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target)
+{
+    MOZ_ASSERT(target == LOCAL_GL_ANY_SAMPLES_PASSED ||
+               target == LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
+               "unknown occlusion query target");
+
+    if (gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query_boolean)) {
+        return target;
+    } else if (gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query2)) {
+        return LOCAL_GL_ANY_SAMPLES_PASSED;
+    }
+
+    return LOCAL_GL_SAMPLES_PASSED;
+}
+
 already_AddRefed<WebGLQuery>
 WebGLContext::CreateQuery()
 {
     if (!IsContextStable())
         return nullptr;
 
     if (mActiveOcclusionQuery && !gl->IsGLES2()) {
         /* http://www.opengl.org/registry/specs/ARB/occlusion_query.txt
@@ -144,21 +160,17 @@ WebGLContext::BeginQuery(WebGLenum targe
     }
 
     if (!query->HasEverBeenActive()) {
         query->mType = target;
     }
 
     MakeContextCurrent();
 
-    if (!gl->IsGLES2()) {
-        gl->fBeginQuery(LOCAL_GL_SAMPLES_PASSED, query->mGLName);
-    } else {
-        gl->fBeginQuery(target, query->mGLName);
-    }
+    gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target), query->mGLName);
 
     GetActiveQueryByTarget(target) = query;
 }
 
 void
 WebGLContext::EndQuery(WebGLenum target)
 {
     if (!IsContextStable())
@@ -185,21 +197,17 @@ WebGLContext::EndQuery(WebGLenum target)
          */
         ErrorInvalidOperation("endQuery: There is no active query of type %s.",
                               GetQueryTargetEnumString(target));
         return;
     }
 
     MakeContextCurrent();
 
-    if (!gl->IsGLES2()) {
-        gl->fEndQuery(LOCAL_GL_SAMPLES_PASSED);
-    } else {
-        gl->fEndQuery(target);
-    }
+    gl->fEndQuery(SimulateOcclusionQueryTarget(gl, target));
 
     GetActiveQueryByTarget(target) = nullptr;
 }
 
 bool
 WebGLContext::IsQuery(WebGLQuery *query)
 {
     if (!IsContextStable())
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1328,60 +1328,16 @@ WebGLContext::UnbindFakeBlackTextures()
             gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->GLName());
         }
     }
 
     gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
 }
 
 void
-WebGLContext::Enable(WebGLenum cap)
-{
-    if (!IsContextStable())
-        return;
-
-    if (!ValidateCapabilityEnum(cap, "enable"))
-        return;
-
-    switch(cap) {
-        case LOCAL_GL_SCISSOR_TEST:
-            mScissorTestEnabled = 1;
-            break;
-        case LOCAL_GL_DITHER:
-            mDitherEnabled = 1;
-            break;
-    }
-
-    MakeContextCurrent();
-    gl->fEnable(cap);
-}
-
-void
-WebGLContext::Disable(WebGLenum cap)
-{
-    if (!IsContextStable())
-        return;
-
-    if (!ValidateCapabilityEnum(cap, "disable"))
-        return;
-
-    switch(cap) {
-        case LOCAL_GL_SCISSOR_TEST:
-            mScissorTestEnabled = 0;
-            break;
-        case LOCAL_GL_DITHER:
-            mDitherEnabled = 0;
-            break;
-    }
-
-    MakeContextCurrent();
-    gl->fDisable(cap);
-}
-
-void
 WebGLContext::FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum rbtarget, WebGLRenderbuffer *wrb)
 {
     if (!IsContextStable())
         return;
 
     if (!mBoundFramebuffer)
         return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
 
@@ -1598,428 +1554,16 @@ WebGLContext::GetAttribLocation(WebGLPro
     prog->MapIdentifier(cname, &mappedName);
 
     WebGLuint progname = prog->GLName();
 
     MakeContextCurrent();
     return gl->fGetAttribLocation(progname, mappedName.get());
 }
 
-static JS::Value
-StringValue(JSContext* cx, const char* chars, ErrorResult& rv)
-{
-    JSString* str = JS_NewStringCopyZ(cx, chars);
-    if (!str) {
-        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
-        return JS::NullValue();
-    }
-
-    return JS::StringValue(str);
-}
-
-JS::Value
-WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
-{
-    if (!IsContextStable())
-        return JS::NullValue();
-
-    MakeContextCurrent();
-    
-    if (MinCapabilityMode()) {
-        switch(pname) {
-            //
-            // Single-value params
-            //
-                
-// int
-            case LOCAL_GL_MAX_VERTEX_ATTRIBS:
-                return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_ATTRIBS);
-            
-            case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
-                return JS::Int32Value(MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS);
-            
-            case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
-                return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS);
-            
-            case LOCAL_GL_MAX_VARYING_VECTORS:
-                return JS::Int32Value(MINVALUE_GL_MAX_VARYING_VECTORS);
-            
-            case LOCAL_GL_MAX_TEXTURE_SIZE:
-                return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_SIZE);
-            
-            case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
-                return JS::Int32Value(MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE);
-            
-            case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
-                return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS);
-            
-            case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-                return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
-                
-            case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
-                return JS::Int32Value(MINVALUE_GL_MAX_RENDERBUFFER_SIZE);
-            
-            default:
-                // Return the real value; we're not overriding this one
-                break;
-        }
-    }
-
-    if (IsExtensionEnabled(WEBGL_draw_buffers))
-    {
-        if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS)
-        {
-            return JS::Int32Value(mGLMaxColorAttachments);
-        }
-        else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS)
-        {
-            return JS::Int32Value(mGLMaxDrawBuffers);
-        }
-        else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
-                 pname < WebGLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
-        {
-            if (mBoundFramebuffer) {
-                GLint iv = 0;
-                gl->fGetIntegerv(pname, &iv);
-                return JS::Int32Value(iv);
-            }
-            
-            GLint iv = 0;
-            gl->fGetIntegerv(pname, &iv);
-            
-            if (iv == GLint(LOCAL_GL_COLOR_ATTACHMENT0 + pname - LOCAL_GL_DRAW_BUFFER0)) {
-                return JS::Int32Value(LOCAL_GL_BACK);
-            }
-            
-            return JS::Int32Value(LOCAL_GL_NONE);
-        }
-    }
-
-    if (IsExtensionEnabled(OES_vertex_array_object)) {
-        switch (pname) {
-
-             case LOCAL_GL_VERTEX_ARRAY_BINDING:
-             {
-                 if (mBoundVertexArray == mDefaultVertexArray){
-                     return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
-                 }
-
-                 return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
-             }
-
-        }
-    }
-
-    switch (pname) {
-        //
-        // String params
-        //
-        case LOCAL_GL_VENDOR:
-            return StringValue(cx, "Mozilla", rv);
-        case LOCAL_GL_RENDERER:
-            return StringValue(cx, "Mozilla", rv);
-        case LOCAL_GL_VERSION:
-        {
-            const char* version = 0;
-
-            if (IsWebGL2()) {
-                version = "WebGL 2.0";
-            } else {
-                version = "WebGL 1.0";
-            }
-
-            MOZ_ASSERT(version != 0);
-            return StringValue(cx, version, rv);
-        }
-        case LOCAL_GL_SHADING_LANGUAGE_VERSION:
-            return StringValue(cx, "WebGL GLSL ES 1.0", rv);
-
-        // Privileged string params exposed by WEBGL_debug_renderer_info:
-        case UNMASKED_VENDOR_WEBGL:
-        case UNMASKED_RENDERER_WEBGL:
-        {
-            // The privilege check is done in WebGLContext::IsExtensionSupported.
-            // So here we just have to check that the extension is enabled.
-            if (!IsExtensionEnabled(WEBGL_debug_renderer_info)) {
-                ErrorInvalidEnumInfo("getParameter: parameter", pname);
-                return JS::NullValue();
-            }
-            GLenum glstringname = LOCAL_GL_NONE;
-            if (pname == UNMASKED_VENDOR_WEBGL) {
-                glstringname = LOCAL_GL_VENDOR;
-            } else if (pname == UNMASKED_RENDERER_WEBGL) {
-                glstringname = LOCAL_GL_RENDERER;
-            }
-            const char* string = reinterpret_cast<const char*>(gl->fGetString(glstringname));
-            return StringValue(cx, string, rv);
-        }
-
-        //
-        // Single-value params
-        //
-
-        // unsigned int
-        case LOCAL_GL_CULL_FACE_MODE:
-        case LOCAL_GL_FRONT_FACE:
-        case LOCAL_GL_ACTIVE_TEXTURE:
-        case LOCAL_GL_STENCIL_FUNC:
-        case LOCAL_GL_STENCIL_FAIL:
-        case LOCAL_GL_STENCIL_PASS_DEPTH_FAIL:
-        case LOCAL_GL_STENCIL_PASS_DEPTH_PASS:
-        case LOCAL_GL_STENCIL_BACK_FUNC:
-        case LOCAL_GL_STENCIL_BACK_FAIL:
-        case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL:
-        case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS:
-        case LOCAL_GL_DEPTH_FUNC:
-        case LOCAL_GL_BLEND_SRC_RGB:
-        case LOCAL_GL_BLEND_SRC_ALPHA:
-        case LOCAL_GL_BLEND_DST_RGB:
-        case LOCAL_GL_BLEND_DST_ALPHA:
-        case LOCAL_GL_BLEND_EQUATION_RGB:
-        case LOCAL_GL_BLEND_EQUATION_ALPHA:
-        case LOCAL_GL_GENERATE_MIPMAP_HINT:
-        {
-            GLint i = 0;
-            gl->fGetIntegerv(pname, &i);
-            return JS::NumberValue(uint32_t(i));
-        }
-        // int
-        case LOCAL_GL_STENCIL_CLEAR_VALUE:
-        case LOCAL_GL_STENCIL_REF:
-        case LOCAL_GL_STENCIL_BACK_REF:
-        case LOCAL_GL_UNPACK_ALIGNMENT:
-        case LOCAL_GL_PACK_ALIGNMENT:
-        case LOCAL_GL_SUBPIXEL_BITS:
-        case LOCAL_GL_SAMPLE_BUFFERS:
-        case LOCAL_GL_SAMPLES:
-        case LOCAL_GL_MAX_VERTEX_ATTRIBS:
-        case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
-        case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-        case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
-        case LOCAL_GL_RED_BITS:
-        case LOCAL_GL_GREEN_BITS:
-        case LOCAL_GL_BLUE_BITS:
-        case LOCAL_GL_ALPHA_BITS:
-        case LOCAL_GL_DEPTH_BITS:
-        case LOCAL_GL_STENCIL_BITS:
-        {
-            GLint i = 0;
-            gl->fGetIntegerv(pname, &i);
-            return JS::Int32Value(i);
-        }
-        case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
-            if (IsExtensionEnabled(OES_standard_derivatives)) {
-                GLint i = 0;
-                gl->fGetIntegerv(pname, &i);
-                return JS::Int32Value(i);
-            }
-            else {
-                ErrorInvalidEnum("getParameter: parameter", pname);
-                return JS::NullValue();
-            }
-
-        case LOCAL_GL_MAX_TEXTURE_SIZE:
-            return JS::Int32Value(mGLMaxTextureSize);
-
-        case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
-            return JS::Int32Value(mGLMaxCubeMapTextureSize);
-
-        case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
-            return JS::Int32Value(mGLMaxRenderbufferSize);
-
-        case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
-            return JS::Int32Value(mGLMaxVertexUniformVectors);
-
-        case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
-            return JS::Int32Value(mGLMaxFragmentUniformVectors);
-
-        case LOCAL_GL_MAX_VARYING_VECTORS:
-            return JS::Int32Value(mGLMaxVaryingVectors);
-
-        case LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
-            return JS::Int32Value(0);
-        case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS:
-        {
-            uint32_t length = mCompressedTextureFormats.Length();
-            JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements());
-            if (!obj) {
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            }
-            return JS::ObjectOrNullValue(obj);
-        }
-
-// unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as
-// javascript integer values. We just return them as doubles and javascript doesn't care.
-        case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
-        case LOCAL_GL_STENCIL_BACK_WRITEMASK:
-        case LOCAL_GL_STENCIL_VALUE_MASK:
-        case LOCAL_GL_STENCIL_WRITEMASK:
-        {
-            GLint i = 0; // the GL api (glGetIntegerv) only does signed ints
-            gl->fGetIntegerv(pname, &i);
-            GLuint i_unsigned(i); // this is where -1 becomes 2^32-1
-            double i_double(i_unsigned); // pass as FP value to allow large values such as 2^32-1.
-            return JS::DoubleValue(i_double);
-        }
-
-// float
-        case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
-            if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
-                GLfloat f = 0.f;
-                gl->fGetFloatv(pname, &f);
-                return JS::DoubleValue(f);
-            } else {
-                ErrorInvalidEnumInfo("getParameter: parameter", pname);
-                return JS::NullValue();
-            }
-        case LOCAL_GL_DEPTH_CLEAR_VALUE:
-        case LOCAL_GL_LINE_WIDTH:
-        case LOCAL_GL_POLYGON_OFFSET_FACTOR:
-        case LOCAL_GL_POLYGON_OFFSET_UNITS:
-        case LOCAL_GL_SAMPLE_COVERAGE_VALUE:
-        {
-            GLfloat f = 0.f;
-            gl->fGetFloatv(pname, &f);
-            return JS::DoubleValue(f);
-        }
-
-// bool
-        case LOCAL_GL_BLEND:
-        case LOCAL_GL_DEPTH_TEST:
-        case LOCAL_GL_STENCIL_TEST:
-        case LOCAL_GL_CULL_FACE:
-        case LOCAL_GL_DITHER:
-        case LOCAL_GL_POLYGON_OFFSET_FILL:
-        case LOCAL_GL_SCISSOR_TEST:
-        case LOCAL_GL_SAMPLE_COVERAGE_INVERT:
-        case LOCAL_GL_DEPTH_WRITEMASK:
-        {
-            realGLboolean b = 0;
-            gl->fGetBooleanv(pname, &b);
-            return JS::BooleanValue(bool(b));
-        }
-
-// bool, WebGL-specific
-        case UNPACK_FLIP_Y_WEBGL:
-            return JS::BooleanValue(mPixelStoreFlipY);
-        case UNPACK_PREMULTIPLY_ALPHA_WEBGL:
-            return JS::BooleanValue(mPixelStorePremultiplyAlpha);
-
-// uint, WebGL-specific
-        case UNPACK_COLORSPACE_CONVERSION_WEBGL:
-            return JS::NumberValue(uint32_t(mPixelStoreColorspaceConversion));
-
-        //
-        // Complex values
-        //
-        case LOCAL_GL_DEPTH_RANGE: // 2 floats
-        case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: // 2 floats
-        case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: // 2 floats
-        {
-            GLfloat fv[2] = { 0 };
-            gl->fGetFloatv(pname, fv);
-            JSObject* obj = Float32Array::Create(cx, this, 2, fv);
-            if (!obj) {
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            }
-            return JS::ObjectOrNullValue(obj);
-        }
-        
-        case LOCAL_GL_COLOR_CLEAR_VALUE: // 4 floats
-        case LOCAL_GL_BLEND_COLOR: // 4 floats
-        {
-            GLfloat fv[4] = { 0 };
-            gl->fGetFloatv(pname, fv);
-            JSObject* obj = Float32Array::Create(cx, this, 4, fv);
-            if (!obj) {
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            }
-            return JS::ObjectOrNullValue(obj);
-        }
-
-        case LOCAL_GL_MAX_VIEWPORT_DIMS: // 2 ints
-        {
-            GLint iv[2] = { 0 };
-            gl->fGetIntegerv(pname, iv);
-            JSObject* obj = Int32Array::Create(cx, this, 2, iv);
-            if (!obj) {
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            }
-            return JS::ObjectOrNullValue(obj);
-        }
-
-        case LOCAL_GL_SCISSOR_BOX: // 4 ints
-        case LOCAL_GL_VIEWPORT: // 4 ints
-        {
-            GLint iv[4] = { 0 };
-            gl->fGetIntegerv(pname, iv);
-            JSObject* obj = Int32Array::Create(cx, this, 4, iv);
-            if (!obj) {
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            }
-            return JS::ObjectOrNullValue(obj);
-        }
-
-        case LOCAL_GL_COLOR_WRITEMASK: // 4 bools
-        {
-            realGLboolean gl_bv[4] = { 0 };
-            gl->fGetBooleanv(pname, gl_bv);
-            JS::Value vals[4] = { JS::BooleanValue(bool(gl_bv[0])),
-                                  JS::BooleanValue(bool(gl_bv[1])),
-                                  JS::BooleanValue(bool(gl_bv[2])),
-                                  JS::BooleanValue(bool(gl_bv[3])) };
-            JSObject* obj = JS_NewArrayObject(cx, 4, vals);
-            if (!obj) {
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            }
-            return JS::ObjectOrNullValue(obj);
-        }
-
-        case LOCAL_GL_ARRAY_BUFFER_BINDING:
-        {
-            return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
-        }
-
-        case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING:
-        {
-            return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv);
-        }
-
-        case LOCAL_GL_RENDERBUFFER_BINDING:
-        {
-            return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
-        }
-
-        case LOCAL_GL_FRAMEBUFFER_BINDING:
-        {
-            return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv);
-        }
-
-        case LOCAL_GL_CURRENT_PROGRAM:
-        {
-            return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv);
-        }
-
-        case LOCAL_GL_TEXTURE_BINDING_2D:
-        {
-            return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv);
-        }
-
-        case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP:
-        {
-            return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv);
-        }
-
-        default:
-            ErrorInvalidEnumInfo("getParameter: parameter", pname);
-    }
-
-    return JS::NullValue();
-}
-
 JS::Value
 WebGLContext::GetBufferParameter(WebGLenum target, WebGLenum pname)
 {
     if (!IsContextStable())
         return JS::NullValue();
 
     if (target != LOCAL_GL_ARRAY_BUFFER && target != LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
         ErrorInvalidEnumInfo("getBufferParameter: target", target);
@@ -2719,29 +2263,16 @@ WebGLContext::IsTexture(WebGLTexture *te
     if (!IsContextStable())
         return false;
 
     return ValidateObjectAllowDeleted("isTexture", tex) &&
         !tex->IsDeleted() &&
         tex->HasEverBeenBound();
 }
 
-bool
-WebGLContext::IsEnabled(WebGLenum cap)
-{
-    if (!IsContextStable())
-        return false;
-
-    if (!ValidateCapabilityEnum(cap, "isEnabled"))
-        return false;
-
-    MakeContextCurrent();
-    return gl->fIsEnabled(cap);
-}
-
 void
 WebGLContext::LinkProgram(WebGLProgram *program)
 {
     if (!IsContextStable())
         return;
 
     if (!ValidateObject("linkProgram", program))
         return;
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLContextState.cpp
@@ -0,0 +1,508 @@
+/* -*- 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 "WebGLContext.h"
+#include "WebGLContextUtils.h"
+#include "WebGLBuffer.h"
+#include "WebGLShader.h"
+#include "WebGLProgram.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLRenderbuffer.h"
+#include "WebGLTexture.h"
+#include "WebGLVertexArray.h"
+
+using namespace mozilla;
+using namespace dom;
+
+void
+WebGLContext::Disable(WebGLenum cap)
+{
+    if (!IsContextStable())
+        return;
+
+    if (!ValidateCapabilityEnum(cap, "disable"))
+        return;
+
+    switch(cap) {
+        case LOCAL_GL_SCISSOR_TEST:
+            mScissorTestEnabled = 0;
+            break;
+        case LOCAL_GL_DITHER:
+            mDitherEnabled = 0;
+            break;
+    }
+
+    MakeContextCurrent();
+    gl->fDisable(cap);
+}
+
+void
+WebGLContext::Enable(WebGLenum cap)
+{
+    if (!IsContextStable())
+        return;
+
+    if (!ValidateCapabilityEnum(cap, "enable"))
+        return;
+
+    switch(cap) {
+        case LOCAL_GL_SCISSOR_TEST:
+            mScissorTestEnabled = 1;
+            break;
+        case LOCAL_GL_DITHER:
+            mDitherEnabled = 1;
+            break;
+    }
+
+    MakeContextCurrent();
+    gl->fEnable(cap);
+}
+
+static JS::Value
+StringValue(JSContext* cx, const char* chars, ErrorResult& rv)
+{
+    JSString* str = JS_NewStringCopyZ(cx, chars);
+    if (!str) {
+        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
+        return JS::NullValue();
+    }
+
+    return JS::StringValue(str);
+}
+
+JS::Value
+WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
+{
+    if (!IsContextStable())
+        return JS::NullValue();
+
+    MakeContextCurrent();
+
+    if (MinCapabilityMode()) {
+        switch(pname) {
+            //
+            // Single-value params
+            //
+
+            // int
+            case LOCAL_GL_MAX_VERTEX_ATTRIBS:
+                return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_ATTRIBS);
+
+            case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+                return JS::Int32Value(MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS);
+
+            case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
+                return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS);
+
+            case LOCAL_GL_MAX_VARYING_VECTORS:
+                return JS::Int32Value(MINVALUE_GL_MAX_VARYING_VECTORS);
+
+            case LOCAL_GL_MAX_TEXTURE_SIZE:
+                return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_SIZE);
+
+            case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+                return JS::Int32Value(MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE);
+
+            case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
+                return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS);
+
+            case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+                return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+
+            case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
+                return JS::Int32Value(MINVALUE_GL_MAX_RENDERBUFFER_SIZE);
+
+            default:
+                // Return the real value; we're not overriding this one
+                break;
+        }
+    }
+
+    if (IsExtensionEnabled(WEBGL_draw_buffers))
+    {
+        if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS)
+        {
+            return JS::Int32Value(mGLMaxColorAttachments);
+        }
+        else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS)
+        {
+            return JS::Int32Value(mGLMaxDrawBuffers);
+        }
+        else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
+                 pname < WebGLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
+        {
+            if (mBoundFramebuffer) {
+                GLint iv = 0;
+                gl->fGetIntegerv(pname, &iv);
+                return JS::Int32Value(iv);
+            }
+
+            GLint iv = 0;
+            gl->fGetIntegerv(pname, &iv);
+
+            if (iv == GLint(LOCAL_GL_COLOR_ATTACHMENT0 + pname - LOCAL_GL_DRAW_BUFFER0)) {
+                return JS::Int32Value(LOCAL_GL_BACK);
+            }
+
+            return JS::Int32Value(LOCAL_GL_NONE);
+        }
+    }
+
+    if (IsExtensionEnabled(OES_vertex_array_object)) {
+        switch (pname) {
+
+            case LOCAL_GL_VERTEX_ARRAY_BINDING:
+            {
+                if (mBoundVertexArray == mDefaultVertexArray){
+                    return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
+                }
+
+                return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
+            }
+
+        }
+    }
+
+    switch (pname) {
+        //
+        // String params
+        //
+        case LOCAL_GL_VENDOR:
+            return StringValue(cx, "Mozilla", rv);
+        case LOCAL_GL_RENDERER:
+            return StringValue(cx, "Mozilla", rv);
+        case LOCAL_GL_VERSION:
+        {
+            const char* version = 0;
+
+            if (IsWebGL2()) {
+                version = "WebGL 2.0";
+            } else {
+                version = "WebGL 1.0";
+            }
+
+            MOZ_ASSERT(version != 0);
+            return StringValue(cx, version, rv);
+        }
+        case LOCAL_GL_SHADING_LANGUAGE_VERSION:
+            return StringValue(cx, "WebGL GLSL ES 1.0", rv);
+
+            // Privileged string params exposed by WEBGL_debug_renderer_info:
+        case UNMASKED_VENDOR_WEBGL:
+        case UNMASKED_RENDERER_WEBGL:
+        {
+            // The privilege check is done in WebGLContext::IsExtensionSupported.
+            // So here we just have to check that the extension is enabled.
+            if (!IsExtensionEnabled(WEBGL_debug_renderer_info)) {
+                ErrorInvalidEnumInfo("getParameter: parameter", pname);
+                return JS::NullValue();
+            }
+            GLenum glstringname = LOCAL_GL_NONE;
+            if (pname == UNMASKED_VENDOR_WEBGL) {
+                glstringname = LOCAL_GL_VENDOR;
+            } else if (pname == UNMASKED_RENDERER_WEBGL) {
+                glstringname = LOCAL_GL_RENDERER;
+            }
+            const char* string = reinterpret_cast<const char*>(gl->fGetString(glstringname));
+            return StringValue(cx, string, rv);
+        }
+
+        //
+        // Single-value params
+        //
+
+        // unsigned int
+        case LOCAL_GL_CULL_FACE_MODE:
+        case LOCAL_GL_FRONT_FACE:
+        case LOCAL_GL_ACTIVE_TEXTURE:
+        case LOCAL_GL_STENCIL_FUNC:
+        case LOCAL_GL_STENCIL_FAIL:
+        case LOCAL_GL_STENCIL_PASS_DEPTH_FAIL:
+        case LOCAL_GL_STENCIL_PASS_DEPTH_PASS:
+        case LOCAL_GL_STENCIL_BACK_FUNC:
+        case LOCAL_GL_STENCIL_BACK_FAIL:
+        case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+        case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS:
+        case LOCAL_GL_DEPTH_FUNC:
+        case LOCAL_GL_BLEND_SRC_RGB:
+        case LOCAL_GL_BLEND_SRC_ALPHA:
+        case LOCAL_GL_BLEND_DST_RGB:
+        case LOCAL_GL_BLEND_DST_ALPHA:
+        case LOCAL_GL_BLEND_EQUATION_RGB:
+        case LOCAL_GL_BLEND_EQUATION_ALPHA:
+        case LOCAL_GL_GENERATE_MIPMAP_HINT:
+        {
+            GLint i = 0;
+            gl->fGetIntegerv(pname, &i);
+            return JS::NumberValue(uint32_t(i));
+        }
+        // int
+        case LOCAL_GL_STENCIL_CLEAR_VALUE:
+        case LOCAL_GL_STENCIL_REF:
+        case LOCAL_GL_STENCIL_BACK_REF:
+        case LOCAL_GL_UNPACK_ALIGNMENT:
+        case LOCAL_GL_PACK_ALIGNMENT:
+        case LOCAL_GL_SUBPIXEL_BITS:
+        case LOCAL_GL_SAMPLE_BUFFERS:
+        case LOCAL_GL_SAMPLES:
+        case LOCAL_GL_MAX_VERTEX_ATTRIBS:
+        case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+        case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+        case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
+        case LOCAL_GL_RED_BITS:
+        case LOCAL_GL_GREEN_BITS:
+        case LOCAL_GL_BLUE_BITS:
+        case LOCAL_GL_ALPHA_BITS:
+        case LOCAL_GL_DEPTH_BITS:
+        case LOCAL_GL_STENCIL_BITS:
+        {
+            GLint i = 0;
+            gl->fGetIntegerv(pname, &i);
+            return JS::Int32Value(i);
+        }
+        case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+            if (IsExtensionEnabled(OES_standard_derivatives)) {
+                GLint i = 0;
+                gl->fGetIntegerv(pname, &i);
+                return JS::Int32Value(i);
+            }
+            else {
+                ErrorInvalidEnum("getParameter: parameter", pname);
+                return JS::NullValue();
+            }
+
+        case LOCAL_GL_MAX_TEXTURE_SIZE:
+            return JS::Int32Value(mGLMaxTextureSize);
+
+        case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+            return JS::Int32Value(mGLMaxCubeMapTextureSize);
+
+        case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
+            return JS::Int32Value(mGLMaxRenderbufferSize);
+
+        case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
+            return JS::Int32Value(mGLMaxVertexUniformVectors);
+
+        case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+            return JS::Int32Value(mGLMaxFragmentUniformVectors);
+
+        case LOCAL_GL_MAX_VARYING_VECTORS:
+            return JS::Int32Value(mGLMaxVaryingVectors);
+
+        case LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+            return JS::Int32Value(0);
+        case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS:
+        {
+            uint32_t length = mCompressedTextureFormats.Length();
+            JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements());
+            if (!obj) {
+                rv = NS_ERROR_OUT_OF_MEMORY;
+            }
+            return JS::ObjectOrNullValue(obj);
+        }
+
+        // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as
+        // javascript integer values. We just return them as doubles and javascript doesn't care.
+        case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
+        case LOCAL_GL_STENCIL_BACK_WRITEMASK:
+        case LOCAL_GL_STENCIL_VALUE_MASK:
+        case LOCAL_GL_STENCIL_WRITEMASK:
+        {
+            GLint i = 0; // the GL api (glGetIntegerv) only does signed ints
+            gl->fGetIntegerv(pname, &i);
+            GLuint i_unsigned(i); // this is where -1 becomes 2^32-1
+            double i_double(i_unsigned); // pass as FP value to allow large values such as 2^32-1.
+            return JS::DoubleValue(i_double);
+        }
+
+        // float
+        case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+            if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
+                GLfloat f = 0.f;
+                gl->fGetFloatv(pname, &f);
+                return JS::DoubleValue(f);
+            } else {
+                ErrorInvalidEnumInfo("getParameter: parameter", pname);
+                return JS::NullValue();
+            }
+        case LOCAL_GL_DEPTH_CLEAR_VALUE:
+        case LOCAL_GL_LINE_WIDTH:
+        case LOCAL_GL_POLYGON_OFFSET_FACTOR:
+        case LOCAL_GL_POLYGON_OFFSET_UNITS:
+        case LOCAL_GL_SAMPLE_COVERAGE_VALUE:
+        {
+            GLfloat f = 0.f;
+            gl->fGetFloatv(pname, &f);
+            return JS::DoubleValue(f);
+        }
+
+        // bool
+        case LOCAL_GL_BLEND:
+        case LOCAL_GL_DEPTH_TEST:
+        case LOCAL_GL_STENCIL_TEST:
+        case LOCAL_GL_CULL_FACE:
+        case LOCAL_GL_DITHER:
+        case LOCAL_GL_POLYGON_OFFSET_FILL:
+        case LOCAL_GL_SCISSOR_TEST:
+        case LOCAL_GL_SAMPLE_COVERAGE_INVERT:
+        case LOCAL_GL_DEPTH_WRITEMASK:
+        {
+            realGLboolean b = 0;
+            gl->fGetBooleanv(pname, &b);
+            return JS::BooleanValue(bool(b));
+        }
+
+        // bool, WebGL-specific
+        case UNPACK_FLIP_Y_WEBGL:
+            return JS::BooleanValue(mPixelStoreFlipY);
+        case UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+            return JS::BooleanValue(mPixelStorePremultiplyAlpha);
+
+        // uint, WebGL-specific
+        case UNPACK_COLORSPACE_CONVERSION_WEBGL:
+            return JS::NumberValue(uint32_t(mPixelStoreColorspaceConversion));
+
+        //
+        // Complex values
+        //
+        case LOCAL_GL_DEPTH_RANGE: // 2 floats
+        case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: // 2 floats
+        case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: // 2 floats
+        {
+            GLfloat fv[2] = { 0 };
+            gl->fGetFloatv(pname, fv);
+            JSObject* obj = Float32Array::Create(cx, this, 2, fv);
+            if (!obj) {
+                rv = NS_ERROR_OUT_OF_MEMORY;
+            }
+            return JS::ObjectOrNullValue(obj);
+        }
+
+        case LOCAL_GL_COLOR_CLEAR_VALUE: // 4 floats
+        case LOCAL_GL_BLEND_COLOR: // 4 floats
+        {
+            GLfloat fv[4] = { 0 };
+            gl->fGetFloatv(pname, fv);
+            JSObject* obj = Float32Array::Create(cx, this, 4, fv);
+            if (!obj) {
+                rv = NS_ERROR_OUT_OF_MEMORY;
+            }
+            return JS::ObjectOrNullValue(obj);
+        }
+
+        case LOCAL_GL_MAX_VIEWPORT_DIMS: // 2 ints
+        {
+            GLint iv[2] = { 0 };
+            gl->fGetIntegerv(pname, iv);
+            JSObject* obj = Int32Array::Create(cx, this, 2, iv);
+            if (!obj) {
+                rv = NS_ERROR_OUT_OF_MEMORY;
+            }
+            return JS::ObjectOrNullValue(obj);
+        }
+
+        case LOCAL_GL_SCISSOR_BOX: // 4 ints
+        case LOCAL_GL_VIEWPORT: // 4 ints
+        {
+            GLint iv[4] = { 0 };
+            gl->fGetIntegerv(pname, iv);
+            JSObject* obj = Int32Array::Create(cx, this, 4, iv);
+            if (!obj) {
+                rv = NS_ERROR_OUT_OF_MEMORY;
+            }
+            return JS::ObjectOrNullValue(obj);
+        }
+
+        case LOCAL_GL_COLOR_WRITEMASK: // 4 bools
+        {
+            realGLboolean gl_bv[4] = { 0 };
+            gl->fGetBooleanv(pname, gl_bv);
+            JS::Value vals[4] = { JS::BooleanValue(bool(gl_bv[0])),
+                JS::BooleanValue(bool(gl_bv[1])),
+                JS::BooleanValue(bool(gl_bv[2])),
+                JS::BooleanValue(bool(gl_bv[3])) };
+            JSObject* obj = JS_NewArrayObject(cx, 4, vals);
+            if (!obj) {
+                rv = NS_ERROR_OUT_OF_MEMORY;
+            }
+            return JS::ObjectOrNullValue(obj);
+        }
+
+        case LOCAL_GL_ARRAY_BUFFER_BINDING:
+        {
+            return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
+        }
+
+        case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING:
+        {
+            return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv);
+        }
+
+        case LOCAL_GL_RENDERBUFFER_BINDING:
+        {
+            return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
+        }
+
+        case LOCAL_GL_FRAMEBUFFER_BINDING:
+        {
+            return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv);
+        }
+
+        case LOCAL_GL_CURRENT_PROGRAM:
+        {
+            return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv);
+        }
+
+        case LOCAL_GL_TEXTURE_BINDING_2D:
+        {
+            return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv);
+        }
+
+        case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP:
+        {
+            return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv);
+        }
+
+        default:
+            ErrorInvalidEnumInfo("getParameter: parameter", pname);
+    }
+
+    return JS::NullValue();
+}
+
+bool
+WebGLContext::IsEnabled(WebGLenum cap)
+{
+    if (!IsContextStable())
+        return false;
+
+    if (!ValidateCapabilityEnum(cap, "isEnabled"))
+        return false;
+
+    MakeContextCurrent();
+    return gl->fIsEnabled(cap);
+}
+
+bool
+WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char* info)
+{
+    switch (cap) {
+        case LOCAL_GL_BLEND:
+        case LOCAL_GL_CULL_FACE:
+        case LOCAL_GL_DEPTH_TEST:
+        case LOCAL_GL_DITHER:
+        case LOCAL_GL_POLYGON_OFFSET_FILL:
+        case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
+        case LOCAL_GL_SAMPLE_COVERAGE:
+        case LOCAL_GL_SCISSOR_TEST:
+        case LOCAL_GL_STENCIL_TEST:
+            return true;
+        case LOCAL_GL_RASTERIZER_DISCARD:
+            return IsWebGL2();
+        default:
+            ErrorInvalidEnumInfo(info, cap);
+            return false;
+    }
+}
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -84,35 +84,16 @@ WebGLProgram::UpdateInfo()
 	        mUniformInfoMap->Put(uniform.mapped, info);
             }
         }
     }
 
     return true;
 }
 
-bool WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char *info)
-{
-    switch (cap) {
-        case LOCAL_GL_BLEND:
-        case LOCAL_GL_CULL_FACE:
-        case LOCAL_GL_DEPTH_TEST:
-        case LOCAL_GL_DITHER:
-        case LOCAL_GL_POLYGON_OFFSET_FILL:
-        case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
-        case LOCAL_GL_SAMPLE_COVERAGE:
-        case LOCAL_GL_SCISSOR_TEST:
-        case LOCAL_GL_STENCIL_TEST:
-            return true;
-        default:
-            ErrorInvalidEnumInfo(info, cap);
-            return false;
-    }
-}
-
 bool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode, const char *info)
 {
     switch (mode) {
         case LOCAL_GL_FUNC_ADD:
         case LOCAL_GL_FUNC_SUBTRACT:
         case LOCAL_GL_FUNC_REVERSE_SUBTRACT:
             return true;
         case LOCAL_GL_MIN:
@@ -894,17 +875,17 @@ WebGLContext::InitAndValidateGL()
     mGLMaxTextureSize = floorPOT(mGLMaxTextureSize);
     mGLMaxRenderbufferSize = floorPOT(mGLMaxRenderbufferSize);
 
     if (MinCapabilityMode()) {
         mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
         mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
         mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
     } else {
-        if (gl->HasES2Compatibility()) {
+        if (gl->IsExtensionSupported(gl::GLContext::XXX_ES2_compatibility)) {
             gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
             gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
             gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &mGLMaxVaryingVectors);
         } else {
             gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
             mGLMaxFragmentUniformVectors /= 4;
             gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
             mGLMaxVertexUniformVectors /= 4;
@@ -993,17 +974,18 @@ WebGLContext::InitAndValidateGL()
     }
 
     if (IsWebGL2() &&
         (!IsExtensionSupported(OES_vertex_array_object) ||
          !IsExtensionSupported(WEBGL_draw_buffers) ||
          !IsExtensionSupported(ANGLE_instanced_arrays) ||
          !gl->IsExtensionSupported(gl::GLContext::EXT_gpu_shader4) ||
          !gl->IsExtensionSupported(gl::GLContext::EXT_blend_minmax) ||
-         (gl->IsGLES2() && !gl->IsExtensionSupported(gl::GLContext::EXT_occlusion_query_boolean))
+         (!gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query) &&
+          !gl->IsExtensionSupported(gl::GLContext::XXX_occlusion_query_boolean))
         ))
     {
         // Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL.
         return false;
     }
 
     mMemoryPressureObserver
         = new WebGLMemoryPressureObserver(this);
--- a/content/canvas/src/moz.build
+++ b/content/canvas/src/moz.build
@@ -30,16 +30,17 @@ if CONFIG['MOZ_WEBGL']:
         'WebGLBuffer.cpp',
         'WebGL1Context.cpp',
         'WebGL2Context.cpp',
         'WebGLContext.cpp',
         'WebGLContextAsyncQueries.cpp',
         'WebGLContextGL.cpp',
         'WebGLContextUtils.cpp',
         'WebGLContextReporter.cpp',
+        'WebGLContextState.cpp',
         'WebGLContextValidate.cpp',
         'WebGLContextFramebufferOperations.cpp',
         'WebGLContextVertexArray.cpp',
         'WebGLContextVertices.cpp',
         'WebGLElementArrayCache.cpp',
         'WebGLExtensionBase.cpp',
         'WebGLExtensionCompressedTextureATC.cpp',
         'WebGLExtensionCompressedTexturePVRTC.cpp',
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -92,16 +92,17 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include "nsIIDNService.h"
 
 #include <limits>
 
 #include "nsIColorPicker.h"
+#include "nsIStringEnumerator.h"
 
 // input type=date
 #include "js/Date.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
 
 // XXX align=left, hspace, vspace, border? other nav4 attrs
 
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1676,16 +1676,18 @@ nsHTMLDocument::Open(JSContext* cx,
       nsIXPConnect *xpc = nsContentUtils::XPConnect();
       rv = xpc->RescueOrphansInScope(cx, oldScope->GetGlobalJSObject());
       if (rv.Failed()) {
         return nullptr;
       }
     }
   }
 
+  mDidDocumentOpen = true;
+
   // Call Reset(), this will now do the full reset
   Reset(channel, group);
   if (baseURI) {
     mDocumentBaseURI = baseURI;
   }
 
   // Store the security info of the caller now that we're done
   // resetting the document.
--- a/content/media/webaudio/AudioBuffer.cpp
+++ b/content/media/webaudio/AudioBuffer.cpp
@@ -2,24 +2,22 @@
 /* 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/. */
 
 #include "AudioBuffer.h"
 #include "mozilla/dom/AudioBufferBinding.h"
 #include "nsContentUtils.h"
-#include "AudioContext.h"
 #include "jsfriendapi.h"
 #include "mozilla/ErrorResult.h"
 #include "AudioSegment.h"
-#include "nsIScriptError.h"
-#include "nsPIDOMWindow.h"
 #include "AudioChannelFormat.h"
 #include "mozilla/PodOperations.h"
+#include "AudioNodeEngine.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioBuffer)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioBuffer)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
--- a/content/media/webaudio/AudioBuffer.h
+++ b/content/media/webaudio/AudioBuffer.h
@@ -9,28 +9,29 @@
 
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 #include "EnableWebAudioCheck.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "AudioContext.h"
-#include "AudioSegment.h"
-#include "AudioNodeEngine.h"
 
 struct JSContext;
 class JSObject;
 
 namespace mozilla {
 
 class ErrorResult;
+class ThreadSharedFloatArrayBufferList;
 
 namespace dom {
 
+class AudioContext;
+
 /**
  * An AudioBuffer keeps its data either in the mJSChannels objects, which
  * are Float32Arrays, or in mSharedChannels if the mJSChannels objects have
  * been neutered.
  */
 class AudioBuffer MOZ_FINAL : public nsWrapperCache,
                               public EnableWebAudioCheck
 {
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AudioBufferSourceNode.h"
 #include "mozilla/dom/AudioBufferSourceNodeBinding.h"
 #include "nsMathUtils.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioDestinationNode.h"
-#include "PannerNode.h"
+#include "AudioParamTimeline.h"
 #include "speex/speex_resampler.h"
 #include <limits>
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioBufferSourceNode)
 
--- a/content/media/webaudio/AudioBufferSourceNode.h
+++ b/content/media/webaudio/AudioBufferSourceNode.h
@@ -4,22 +4,22 @@
  * 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 AudioBufferSourceNode_h_
 #define AudioBufferSourceNode_h_
 
 #include "AudioNode.h"
 #include "AudioBuffer.h"
-#include "AudioParam.h"
-#include "mozilla/dom/BindingUtils.h"
 
 namespace mozilla {
 namespace dom {
 
+class AudioParam;
+
 class AudioBufferSourceNode : public AudioNode,
                               public MainThreadMediaStreamListener
 {
 public:
   explicit AudioBufferSourceNode(AudioContext* aContext);
   virtual ~AudioBufferSourceNode();
 
   virtual void DestroyMediaStream() MOZ_OVERRIDE
--- a/content/media/webaudio/AudioContext.h
+++ b/content/media/webaudio/AudioContext.h
@@ -4,42 +4,41 @@
  * 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 AudioContext_h_
 #define AudioContext_h_
 
 #include "EnableWebAudioCheck.h"
 #include "MediaBufferDecoder.h"
-#include "MediaStreamGraph.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/AudioContextBinding.h"
 #include "mozilla/dom/TypedArray.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsHashKeys.h"
 #include "nsTHashtable.h"
-#include "StreamBuffer.h"
 
 // X11 has a #define for CurrentTime. Unbelievable :-(.
 // See content/media/DOMMediaStream.h for more fun!
 #ifdef CurrentTime
 #undef CurrentTime
 #endif
 
 struct JSContext;
 class JSObject;
 class nsPIDOMWindow;
 
 namespace mozilla {
 
+class DOMMediaStream;
 class ErrorResult;
-struct WebAudioDecodeJob;
+class MediaStream;
+class MediaStreamGraph;
 
 namespace dom {
 
 class AnalyserNode;
 class AudioBuffer;
 class AudioBufferSourceNode;
 class AudioDestinationNode;
 class AudioListener;
@@ -50,17 +49,16 @@ class ConvolverNode;
 class DelayNode;
 class DynamicsCompressorNode;
 class GainNode;
 class GlobalObject;
 class HTMLMediaElement;
 class MediaElementAudioSourceNode;
 class MediaStreamAudioDestinationNode;
 class MediaStreamAudioSourceNode;
-class OfflineRenderSuccessCallback;
 class PannerNode;
 class ScriptProcessorNode;
 class WaveShaperNode;
 class PeriodicWave;
 
 class AudioContext MOZ_FINAL : public nsDOMEventTargetHelper,
                                public EnableWebAudioCheck
 {
--- a/content/media/webaudio/AudioListener.cpp
+++ b/content/media/webaudio/AudioListener.cpp
@@ -1,17 +1,16 @@
 /* -*- 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/. */
 
 #include "AudioListener.h"
 #include "AudioContext.h"
-#include "mozilla/ErrorResult.h"
 #include "mozilla/dom/AudioListenerBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(AudioListener, mContext)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioListener, AddRef)
--- a/content/media/webaudio/AudioListener.h
+++ b/content/media/webaudio/AudioListener.h
@@ -18,18 +18,16 @@
 #include "WebAudioUtils.h"
 
 struct JSContext;
 
 namespace mozilla {
 
 namespace dom {
 
-class AudioContext;
-
 class AudioListener MOZ_FINAL : public nsWrapperCache,
                                 public EnableWebAudioCheck
 {
 public:
   explicit AudioListener(AudioContext* aContext);
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioListener)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioListener)
--- a/content/media/webaudio/AudioNode.cpp
+++ b/content/media/webaudio/AudioNode.cpp
@@ -1,16 +1,15 @@
 /* -*- 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/. */
 
 #include "AudioNode.h"
-#include "AudioContext.h"
 #include "mozilla/ErrorResult.h"
 #include "AudioNodeStream.h"
 
 namespace mozilla {
 namespace dom {
 
 static const uint32_t INVALID_PORT = 0xffffffff;
 
--- a/content/media/webaudio/AudioNode.h
+++ b/content/media/webaudio/AudioNode.h
@@ -5,34 +5,31 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AudioNode_h_
 #define AudioNode_h_
 
 #include "nsDOMEventTargetHelper.h"
 #include "mozilla/dom/AudioNodeBinding.h"
 #include "nsCycleCollectionParticipant.h"
-#include "mozilla/Attributes.h"
 #include "EnableWebAudioCheck.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "AudioContext.h"
-#include "AudioParamTimeline.h"
 #include "MediaStreamGraph.h"
 #include "WebAudioUtils.h"
 
-struct JSContext;
-
 namespace mozilla {
 
-class ErrorResult;
-
 namespace dom {
 
+class AudioContext;
+class AudioBufferSourceNode;
 class AudioParam;
+class AudioParamTimeline;
 struct ThreeDPoint;
 
 template<class T>
 class SelfReference {
 public:
   SelfReference() : mHeld(false) {}
   ~SelfReference()
   {
--- a/content/media/webaudio/AudioParam.cpp
+++ b/content/media/webaudio/AudioParam.cpp
@@ -1,20 +1,19 @@
 /* -*- 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/. */
 
 #include "AudioParam.h"
-#include "nsIDOMWindow.h"
-#include "mozilla/ErrorResult.h"
 #include "mozilla/dom/AudioParamBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
+#include "AudioContext.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioParam)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioParam)
   tmp->DisconnectFromGraphAndDestroyStream();
--- a/content/media/webaudio/AudioParam.h
+++ b/content/media/webaudio/AudioParam.h
@@ -5,26 +5,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AudioParam_h_
 #define AudioParam_h_
 
 #include "AudioParamTimeline.h"
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsCOMPtr.h"
 #include "EnableWebAudioCheck.h"
 #include "nsAutoPtr.h"
 #include "AudioNode.h"
 #include "mozilla/dom/TypedArray.h"
-#include "mozilla/Util.h"
 #include "WebAudioUtils.h"
 
 struct JSContext;
-class nsIDOMWindow;
 
 namespace mozilla {
 
 namespace dom {
 
 class AudioParam MOZ_FINAL : public nsWrapperCache,
                              public EnableWebAudioCheck,
                              public AudioParamTimeline
--- a/content/media/webaudio/AudioProcessingEvent.cpp
+++ b/content/media/webaudio/AudioProcessingEvent.cpp
@@ -1,16 +1,17 @@
 /* -*- 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/. */
 
 #include "AudioProcessingEvent.h"
 #include "mozilla/dom/AudioProcessingEventBinding.h"
+#include "AudioContext.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_3(AudioProcessingEvent, nsDOMEvent,
                                      mInputBuffer, mOutputBuffer, mNode)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioProcessingEvent)
--- a/content/media/webaudio/BiquadFilterNode.cpp
+++ b/content/media/webaudio/BiquadFilterNode.cpp
@@ -6,16 +6,17 @@
 
 #include "BiquadFilterNode.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioDestinationNode.h"
 #include "WebAudioUtils.h"
 #include "blink/Biquad.h"
 #include "mozilla/Preferences.h"
+#include "AudioParamTimeline.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_4(BiquadFilterNode, AudioNode,
                                      mFrequency, mDetune, mQ, mGain)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BiquadFilterNode)
--- a/content/media/webaudio/ChannelMergerNode.cpp
+++ b/content/media/webaudio/ChannelMergerNode.cpp
@@ -3,17 +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/. */
 
 #include "mozilla/dom/ChannelMergerNode.h"
 #include "mozilla/dom/ChannelMergerNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
-#include "mozilla/PodOperations.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS_INHERITED0(ChannelMergerNode, AudioNode)
 
 class ChannelMergerNodeEngine : public AudioNodeEngine
 {
--- a/content/media/webaudio/ChannelSplitterNode.cpp
+++ b/content/media/webaudio/ChannelSplitterNode.cpp
@@ -3,17 +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/. */
 
 #include "mozilla/dom/ChannelSplitterNode.h"
 #include "mozilla/dom/ChannelSplitterNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
-#include "mozilla/PodOperations.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS_INHERITED0(ChannelSplitterNode, AudioNode)
 
 class ChannelSplitterNodeEngine : public AudioNodeEngine
 {
--- a/content/media/webaudio/ConvolverNode.cpp
+++ b/content/media/webaudio/ConvolverNode.cpp
@@ -4,19 +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 "ConvolverNode.h"
 #include "mozilla/dom/ConvolverNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "blink/Reverb.h"
-
-#include <cmath>
-#include "nsMathUtils.h"
+#include "PlayingRefChangeHandler.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ConvolverNode, AudioNode, mBuffer)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ConvolverNode)
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
--- a/content/media/webaudio/ConvolverNode.h
+++ b/content/media/webaudio/ConvolverNode.h
@@ -4,21 +4,22 @@
  * 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 ConvolverNode_h_
 #define ConvolverNode_h_
 
 #include "AudioNode.h"
 #include "AudioBuffer.h"
-#include "PlayingRefChangeHandler.h"
 
 namespace mozilla {
 namespace dom {
 
+template <class T> class PlayingRefChangeHandler;
+
 class ConvolverNode : public AudioNode
 {
 public:
   explicit ConvolverNode(AudioContext* aContext);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConvolverNode, AudioNode);
 
--- a/content/media/webaudio/DelayNode.cpp
+++ b/content/media/webaudio/DelayNode.cpp
@@ -6,16 +6,17 @@
 
 #include "DelayNode.h"
 #include "mozilla/dom/DelayNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioDestinationNode.h"
 #include "WebAudioUtils.h"
 #include "DelayProcessor.h"
+#include "PlayingRefChangeHandler.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DelayNode, AudioNode,
                                      mDelay)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DelayNode)
--- a/content/media/webaudio/DelayNode.h
+++ b/content/media/webaudio/DelayNode.h
@@ -4,22 +4,22 @@
  * 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 DelayNode_h_
 #define DelayNode_h_
 
 #include "AudioNode.h"
 #include "AudioParam.h"
-#include "PlayingRefChangeHandler.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
+template <class T> class PlayingRefChangeHandler;
 
 class DelayNode : public AudioNode
 {
 public:
   DelayNode(AudioContext* aContext, double aMaxDelay);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DelayNode, AudioNode)
--- a/content/media/webaudio/FFTBlock.cpp
+++ b/content/media/webaudio/FFTBlock.cpp
@@ -25,18 +25,16 @@
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "FFTBlock.h"
 
-#include "AudioNodeEngine.h"
-
 #include <complex>
 
 namespace mozilla {
 
 typedef std::complex<double> Complex;
 
 FFTBlock* FFTBlock::CreateInterpolatedBlock(const FFTBlock& block0, const FFTBlock& block1, double interp)
 {
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -3,26 +3,25 @@
 /* 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 "MediaBufferDecoder.h"
 #include "AbstractMediaDecoder.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
+#include "mozilla/dom/AudioContextBinding.h"
 #include <speex/speex_resampler.h>
 #include "nsXPCOMCIDInternal.h"
 #include "nsComponentManagerUtils.h"
 #include "MediaDecoderReader.h"
 #include "BufferMediaResource.h"
 #include "DecoderTraits.h"
 #include "AudioContext.h"
 #include "AudioBuffer.h"
-#include "nsIScriptGlobalObject.h"
-#include "nsIScriptContext.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptError.h"
 #include "nsMimeTypes.h"
 #include "nsCxPusher.h"
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(WebAudioDecodeJob)
--- a/content/media/webaudio/MediaBufferDecoder.h
+++ b/content/media/webaudio/MediaBufferDecoder.h
@@ -9,21 +9,19 @@
 
 #include "nsWrapperCache.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIThreadPool.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/dom/TypedArray.h"
-#include <utility>
 
 namespace mozilla {
 
-class MediaDecoderReader;
 namespace dom {
 class AudioBuffer;
 class AudioContext;
 class DecodeErrorCallback;
 class DecodeSuccessCallback;
 }
 
 struct WebAudioDecodeJob MOZ_FINAL
--- a/content/media/webaudio/MediaElementAudioSourceNode.cpp
+++ b/content/media/webaudio/MediaElementAudioSourceNode.cpp
@@ -1,17 +1,16 @@
 /* -*- 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/. */
 
 #include "MediaElementAudioSourceNode.h"
 #include "mozilla/dom/MediaElementAudioSourceNodeBinding.h"
-#include "mozilla/dom/HTMLMediaElement.h"
 
 namespace mozilla {
 namespace dom {
 
 MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext,
                                                          DOMMediaStream* aStream)
   : MediaStreamAudioSourceNode(aContext, aStream)
 {
--- a/content/media/webaudio/MediaElementAudioSourceNode.h
+++ b/content/media/webaudio/MediaElementAudioSourceNode.h
@@ -7,18 +7,16 @@
 #ifndef MediaElementAudioSourceNode_h_
 #define MediaElementAudioSourceNode_h_
 
 #include "MediaStreamAudioSourceNode.h"
 
 namespace mozilla {
 namespace dom {
 
-class HTMLMediaElement;
-
 class MediaElementAudioSourceNode : public MediaStreamAudioSourceNode
 {
 public:
   MediaElementAudioSourceNode(AudioContext* aContext,
                               DOMMediaStream* aStream);
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
--- a/content/media/webaudio/MediaStreamAudioDestinationNode.cpp
+++ b/content/media/webaudio/MediaStreamAudioDestinationNode.cpp
@@ -1,17 +1,16 @@
 /* -*- 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/. */
 
 #include "MediaStreamAudioDestinationNode.h"
 #include "nsIDocument.h"
-#include "mozilla/dom/AudioStreamTrack.h"
 #include "mozilla/dom/MediaStreamAudioDestinationNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "DOMMediaStream.h"
 #include "TrackUnionStream.h"
 
 namespace mozilla {
 namespace dom {
--- a/content/media/webaudio/MediaStreamAudioDestinationNode.h
+++ b/content/media/webaudio/MediaStreamAudioDestinationNode.h
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MediaStreamAudioDestinationNode_h_
 #define MediaStreamAudioDestinationNode_h_
 
 #include "AudioNode.h"
 
 namespace mozilla {
-class DOMMediaStream;
-
 namespace dom {
 
 class MediaStreamAudioDestinationNode : public AudioNode
 {
 public:
   explicit MediaStreamAudioDestinationNode(AudioContext* aContext);
 
   NS_DECL_ISUPPORTS_INHERITED
--- a/content/media/webaudio/OfflineAudioCompletionEvent.cpp
+++ b/content/media/webaudio/OfflineAudioCompletionEvent.cpp
@@ -1,16 +1,17 @@
 /* -*- 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/. */
 
 #include "OfflineAudioCompletionEvent.h"
 #include "mozilla/dom/OfflineAudioCompletionEventBinding.h"
+#include "AudioContext.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(OfflineAudioCompletionEvent, nsDOMEvent,
                                      mRenderedBuffer)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(OfflineAudioCompletionEvent)
--- a/content/media/webaudio/OfflineAudioCompletionEvent.h
+++ b/content/media/webaudio/OfflineAudioCompletionEvent.h
@@ -4,21 +4,22 @@
  * 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 OfflineAudioCompletionEvent_h_
 #define OfflineAudioCompletionEvent_h_
 
 #include "nsDOMEvent.h"
 #include "AudioBuffer.h"
-#include "AudioContext.h"
 
 namespace mozilla {
 namespace dom {
 
+class AudioContext;
+
 class OfflineAudioCompletionEvent : public nsDOMEvent,
                                     public EnableWebAudioCheck
 {
 public:
   OfflineAudioCompletionEvent(AudioContext* aOwner,
                               nsPresContext *aPresContext,
                               nsEvent *aEvent);
 
--- a/content/media/webaudio/PannerNode.cpp
+++ b/content/media/webaudio/PannerNode.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PannerNode.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioListener.h"
 #include "AudioBufferSourceNode.h"
 #include "blink/HRTFPanner.h"
+#include "blink/HRTFDatabaseLoader.h"
 
 using WebCore::HRTFDatabaseLoader;
 using WebCore::HRTFPanner;
 
 namespace mozilla {
 namespace dom {
 
 using namespace std;
--- a/content/media/webaudio/PannerNode.h
+++ b/content/media/webaudio/PannerNode.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 PannerNode_h_
 #define PannerNode_h_
 
 #include "AudioNode.h"
-#include "AudioParam.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/TypedEnum.h"
 #include "mozilla/dom/PannerNodeBinding.h"
 #include "ThreeDPoint.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/Preferences.h"
 #include "WebAudioUtils.h"
 #include <set>
 
 namespace mozilla {
--- a/content/media/webaudio/ScriptProcessorNode.h
+++ b/content/media/webaudio/ScriptProcessorNode.h
@@ -6,23 +6,19 @@
 
 #ifndef ScriptProcessorNode_h_
 #define ScriptProcessorNode_h_
 
 #include "AudioNode.h"
 #include "nsAutoPtr.h"
 
 namespace mozilla {
-
-class AudioNodeStream;
-
 namespace dom {
 
 class AudioContext;
-class ScriptProcessorNodeEngine;
 class SharedBuffers;
 
 class ScriptProcessorNode : public AudioNode
 {
 public:
   ScriptProcessorNode(AudioContext* aContext,
                       uint32_t aBufferSize,
                       uint32_t aNumberOfInputChannels,
--- a/content/media/webaudio/WaveShaperNode.h
+++ b/content/media/webaudio/WaveShaperNode.h
@@ -3,18 +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 WaveShaperNode_h_
 #define WaveShaperNode_h_
 
 #include "AudioNode.h"
-#include "AudioParam.h"
 #include "mozilla/dom/WaveShaperNodeBinding.h"
+#include "mozilla/dom/TypedArray.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 
 class WaveShaperNode : public AudioNode
 {
--- a/content/media/webaudio/WebAudioUtils.cpp
+++ b/content/media/webaudio/WebAudioUtils.cpp
@@ -1,16 +1,17 @@
 /* -*- 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/. */
 
 #include "WebAudioUtils.h"
 #include "AudioNodeStream.h"
+#include "AudioParamTimeline.h"
 #include "blink/HRTFDatabaseLoader.h"
 
 namespace mozilla {
 
 namespace dom {
 
 struct ConvertTimeToTickHelper
 {
--- a/content/media/webaudio/WebAudioUtils.h
+++ b/content/media/webaudio/WebAudioUtils.h
@@ -5,26 +5,28 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WebAudioUtils_h_
 #define WebAudioUtils_h_
 
 #include <cmath>
 #include <limits>
 #include "mozilla/TypeTraits.h"
-#include "mozilla/Assertions.h"
-#include "AudioParamTimeline.h"
+#include "mozilla/FloatingPoint.h"
 #include "MediaSegment.h"
 
 namespace mozilla {
 
 class AudioNodeStream;
+class MediaStream;
 
 namespace dom {
 
+class AudioParamTimeline;
+
 struct WebAudioUtils {
   // This is an arbitrary large number used to protect against OOMs.
   // We can adjust it later if needed.
   static const uint32_t MaxChannelCount = 32;
 
   static bool FuzzyEqual(float v1, float v2)
   {
     using namespace std;
--- a/content/media/webaudio/blink/Biquad.cpp
+++ b/content/media/webaudio/blink/Biquad.cpp
@@ -25,17 +25,16 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "DenormalDisabler.h"
 #include "Biquad.h"
 
 #include <algorithm>
-#include <stdio.h>
 
 namespace WebCore {
 
 const int kBufferSize = 1024;
 
 Biquad::Biquad()
 {
     // Initialize as pass-thru (straight-wire, no filter effect)
--- a/content/media/webaudio/blink/DynamicsCompressorKernel.cpp
+++ b/content/media/webaudio/blink/DynamicsCompressorKernel.cpp
@@ -27,16 +27,17 @@
  */
 
 #include "DynamicsCompressorKernel.h"
 
 #include "DenormalDisabler.h"
 #include <algorithm>
 
 #include "mozilla/FloatingPoint.h"
+#include "mozilla/Constants.h"
 #include "WebAudioUtils.h"
 
 using namespace std;
 
 using mozilla::dom::WebAudioUtils;
 using mozilla::IsInfinite;
 using mozilla::IsNaN;
 
--- a/content/media/webaudio/blink/HRTFDatabaseLoader.cpp
+++ b/content/media/webaudio/blink/HRTFDatabaseLoader.cpp
@@ -22,17 +22,16 @@
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "HRTFDatabaseLoader.h"
-
 #include "HRTFDatabase.h"
 
 using namespace mozilla;
 
 namespace WebCore {
 
 // Singleton
 nsTHashtable<HRTFDatabaseLoader::LoaderByRateEntry>*
--- a/content/media/webaudio/blink/HRTFDatabaseLoader.h
+++ b/content/media/webaudio/blink/HRTFDatabaseLoader.h
@@ -24,21 +24,23 @@
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef HRTFDatabaseLoader_h
 #define HRTFDatabaseLoader_h
 
-#include "HRTFDatabase.h"
-#include "nsTHashtable.h"
+#include "nsHashKeys.h"
 #include "mozilla/RefPtr.h"
-#include "nsIThread.h"
 #include "mozilla/Mutex.h"
+#include "HRTFDatabase.h"
+
+template <class EntryType> class nsTHashtable;
+template <class T> class nsAutoRef;
 
 namespace WebCore {
 
 // HRTFDatabaseLoader will asynchronously load the default HRTFDatabase in a new thread.
 
 class HRTFDatabaseLoader {
 public:
     // Lazily creates a HRTFDatabaseLoader (if not already created) for the given sample-rate
--- a/content/media/webaudio/blink/HRTFPanner.cpp
+++ b/content/media/webaudio/blink/HRTFPanner.cpp
@@ -18,16 +18,17 @@
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "HRTFPanner.h"
+#include "HRTFDatabaseLoader.h"
 
 #include "FFTConvolver.h"
 #include "HRTFDatabase.h"
 #include "WebAudioUtils.h"
 
 using namespace std;
 using namespace mozilla;
 using mozilla::dom::WebAudioUtils;
--- a/content/media/webaudio/blink/HRTFPanner.h
+++ b/content/media/webaudio/blink/HRTFPanner.h
@@ -21,25 +21,26 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef HRTFPanner_h
 #define HRTFPanner_h
 
 #include "FFTConvolver.h"
-#include "HRTFDatabaseLoader.h"
 #include "DelayProcessor.h"
 
 namespace mozilla {
 struct AudioChunk;
 }
 
 namespace WebCore {
 
+class HRTFDatabaseLoader;
+
 using mozilla::AudioChunk;
 
 class HRTFPanner {
 public:
     HRTFPanner(float sampleRate, mozilla::TemporaryRef<HRTFDatabaseLoader> databaseLoader);
     ~HRTFPanner();
 
     // framesToProcess must be a power of 2 and greater than 128
--- a/content/media/webaudio/blink/Reverb.cpp
+++ b/content/media/webaudio/blink/Reverb.cpp
@@ -22,16 +22,17 @@
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "Reverb.h"
+#include "ReverbConvolverStage.h"
 
 #include <math.h>
 #include "ReverbConvolver.h"
 #include "mozilla/FloatingPoint.h"
 
 using namespace mozilla;
 
 namespace WebCore {
--- a/content/media/webaudio/blink/Reverb.h
+++ b/content/media/webaudio/blink/Reverb.h
@@ -27,23 +27,27 @@
  */
 
 #ifndef Reverb_h
 #define Reverb_h
 
 #include "ReverbConvolver.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
+#include "AudioSegment.h"
 
 namespace mozilla {
 class ThreadSharedFloatArrayBufferList;
 }
 
 namespace WebCore {
 
+class DirectConvolver;
+class FFTConvolver;
+
 // Multi-channel convolution reverb with channel matrixing - one or more ReverbConvolver objects are used internally.
 
 class Reverb {
 public:
     enum { MaxFrameSize = 256 };
 
     // renderSliceSize is a rendering hint, so the FFTs can be optimized to not all occur at the same time (very bad when rendering on a real-time thread).
     Reverb(mozilla::ThreadSharedFloatArrayBufferList* impulseResponseBuffer, size_t impulseResponseBufferLength, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize, float sampleRate);
--- a/content/media/webaudio/blink/ReverbConvolver.cpp
+++ b/content/media/webaudio/blink/ReverbConvolver.cpp
@@ -22,16 +22,17 @@
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "ReverbConvolver.h"
+#include "ReverbConvolverStage.h"
 
 using namespace mozilla;
 
 template<>
 struct RunnableMethodTraits<WebCore::ReverbConvolver>
 {
   static void RetainCallee(WebCore::ReverbConvolver* obj) {}
   static void ReleaseCallee(WebCore::ReverbConvolver* obj) {}
--- a/content/media/webaudio/blink/ReverbConvolver.h
+++ b/content/media/webaudio/blink/ReverbConvolver.h
@@ -24,34 +24,29 @@
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef ReverbConvolver_h
 #define ReverbConvolver_h
 
-#include "DirectConvolver.h"
-#include "FFTConvolver.h"
 #include "ReverbAccumulationBuffer.h"
-#include "ReverbConvolverStage.h"
 #include "ReverbInputBuffer.h"
 #include "nsAutoPtr.h"
-#include "nsTArray.h"
-#include "nsCOMPtr.h"
 #ifdef LOG
 #undef LOG
 #endif
 #include "base/condition_variable.h"
 #include "base/lock.h"
 #include "base/thread.h"
 
 namespace WebCore {
 
-class AudioChannel;
+class ReverbConvolverStage;
 
 class ReverbConvolver {
 public:
     // maxFFTSize can be adjusted (from say 2048 to 32768) depending on how much precision is necessary.
     // For certain tweaky de-convolving applications the phase errors add up quickly and lead to non-sensical results with
     // larger FFT sizes and single-precision floats.  In these cases 2048 is a good size.
     // If not doing multi-threaded convolution, then should not go > 8192.
     ReverbConvolver(const float* impulseResponseData, size_t impulseResponseLength, size_t renderSliceSize, size_t maxFFTSize, size_t convolverRenderPhase, bool useBackgroundThreads);
--- a/content/media/webaudio/blink/ReverbConvolverStage.h
+++ b/content/media/webaudio/blink/ReverbConvolverStage.h
@@ -24,27 +24,28 @@
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef ReverbConvolverStage_h
 #define ReverbConvolverStage_h
 
+#include "DirectConvolver.h"
+#include "FFTConvolver.h"
+
 #include "nsTArray.h"
 #include "mozilla/FFTBlock.h"
 
 namespace WebCore {
 
 using mozilla::FFTBlock;
 
 class ReverbAccumulationBuffer;
 class ReverbConvolver;
-class FFTConvolver;
-class DirectConvolver;
 
 // A ReverbConvolverStage represents the convolution associated with a sub-section of a large impulse response.
 // It incorporates a delay line to account for the offset of the sub-section within the larger impulse response.
 class ReverbConvolverStage {
 public:
     // renderPhase is useful to know so that we can manipulate the pre versus post delay so that stages will perform
     // their heavy work (FFT processing) on different slices to balance the load in a real-time thread.
     ReverbConvolverStage(const float* impulseResponse, size_t responseLength, size_t reverbTotalLatency, size_t stageOffset, size_t stageLength, size_t fftSize, size_t renderPhase, size_t renderSliceSize, ReverbAccumulationBuffer*, bool directMode = false);
--- a/content/media/webspeech/recognition/SpeechStreamListener.cpp
+++ b/content/media/webspeech/recognition/SpeechStreamListener.cpp
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #include "SpeechStreamListener.h"
 
 #include "SpeechRecognition.h"
+#include "nsProxyRelease.h"
 
 namespace mozilla {
 namespace dom {
 
 SpeechStreamListener::SpeechStreamListener(SpeechRecognition* aRecognition)
   : mRecognition(aRecognition)
 {
 }
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -2543,23 +2543,66 @@ nsXULPrototypeScript::DeserializeOutOfLi
                 if (rv != NS_ERROR_NOT_AVAILABLE)
                     cache->AbortCaching();
             }
         }
     }
     return rv;
 }
 
+class NotifyOffThreadScriptCompletedRunnable : public nsRunnable
+{
+    nsRefPtr<nsIOffThreadScriptReceiver> mReceiver;
+
+    // Note: there is no need to root the script, it is protected against GC
+    // until FinishOffThreadScript is called on it.
+    JSScript *mScript;
+
+public:
+    NotifyOffThreadScriptCompletedRunnable(already_AddRefed<nsIOffThreadScriptReceiver> aReceiver,
+                                           JSScript *aScript)
+      : mReceiver(aReceiver), mScript(aScript)
+    {}
+
+    NS_DECL_NSIRUNNABLE
+};
+
+NS_IMETHODIMP
+NotifyOffThreadScriptCompletedRunnable::Run()
+{
+    MOZ_ASSERT(NS_IsMainThread());
+
+    // Note: this unroots mScript so that it is available to be collected by the
+    // JS GC. The receiver needs to root the script before performing a call that
+    // could GC.
+    JS::FinishOffThreadScript(nsJSRuntime::sRuntime, mScript);
+
+    return mReceiver->OnScriptCompileComplete(mScript, mScript ? NS_OK : NS_ERROR_FAILURE);
+}
+
+static void
+OffThreadScriptReceiverCallback(JSScript *script, void *ptr)
+{
+    // Be careful not to adjust the refcount on the receiver, as this callback
+    // may be invoked off the main thread.
+    nsIOffThreadScriptReceiver* aReceiver = static_cast<nsIOffThreadScriptReceiver*>(ptr);
+    nsRefPtr<NotifyOffThreadScriptCompletedRunnable> notify =
+        new NotifyOffThreadScriptCompletedRunnable(
+            already_AddRefed<nsIOffThreadScriptReceiver>(aReceiver), script);
+    NS_DispatchToMainThread(notify);
+}
+
 nsresult
 nsXULPrototypeScript::Compile(const PRUnichar* aText,
                               int32_t aTextLength,
                               nsIURI* aURI,
                               uint32_t aLineNo,
                               nsIDocument* aDocument,
-                              nsIScriptGlobalObject* aGlobal)
+                              nsIScriptGlobalObject* aGlobal,
+                              nsIOffThreadScriptReceiver *aOffThreadReceiver /* = nullptr */)
 {
     // We'll compile the script using the prototype document's special
     // script object as the parent. This ensures that we won't end up
     // with an uncollectable reference.
     //
     // Compiling it using (for example) the first document's global
     // object would cause JS to keep a reference via the __proto__ or
     // parent pointer to the first document's global. If that happened,
@@ -2599,21 +2642,33 @@ nsXULPrototypeScript::Compile(const PRUn
            .setVersion(JSVersion(mLangVersion));
     // If the script was inline, tell the JS parser to save source for
     // Function.prototype.toSource(). If it's out of line, we retrieve the
     // source from the files on demand.
     options.setSourcePolicy(mOutOfLine ? JS::CompileOptions::LAZY_SOURCE
                                        : JS::CompileOptions::SAVE_SOURCE);
     JS::RootedObject scope(cx, JS::CurrentGlobalOrNull(cx));
     xpc_UnmarkGrayObject(scope);
-    JSScript* script = JS::Compile(cx, scope, options,
+
+    if (aOffThreadReceiver && JS::CanCompileOffThread(cx, options)) {
+        if (!JS::CompileOffThread(cx, scope, options,
+                                  static_cast<const jschar*>(aText), aTextLength,
+                                  OffThreadScriptReceiverCallback,
+                                  static_cast<void*>(aOffThreadReceiver))) {
+            return NS_ERROR_OUT_OF_MEMORY;
+        }
+        // This reference will be consumed by the NotifyOffThreadScriptCompletedRunnable.
+        NS_ADDREF(aOffThreadReceiver);
+    } else {
+        JSScript* script = JS::Compile(cx, scope, options,
                                    static_cast<const jschar*>(aText), aTextLength);
-    if (!script)
-        return NS_ERROR_OUT_OF_MEMORY;
-    Set(script);
+        if (!script)
+            return NS_ERROR_OUT_OF_MEMORY;
+        Set(script);
+    }
     return NS_OK;
 }
 
 void
 nsXULPrototypeScript::UnlinkJSObjects()
 {
     if (mScriptObject) {
         mScriptObject = nullptr;
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -226,17 +226,18 @@ public:
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     nsresult DeserializeOutOfLine(nsIObjectInputStream* aInput,
                                   nsIScriptGlobalObject* aGlobal);
 
     nsresult Compile(const PRUnichar* aText, int32_t aTextLength,
                      nsIURI* aURI, uint32_t aLineNo,
                      nsIDocument* aDocument,
-                     nsIScriptGlobalObject* aGlobal);
+                     nsIScriptGlobalObject* aGlobal,
+                     nsIOffThreadScriptReceiver *aOffThreadReceiver = nullptr);
 
     void UnlinkJSObjects();
 
     void Set(JSScript* aObject);
 
     // It's safe to return a handle because we trace mScriptObject, no one ever
     // uses the handle (or the script object) past the point at which the
     // nsXULPrototypeScript dies, and we can't get memmoved so the
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -349,19 +349,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(XULDocument, XMLDocument)
 NS_IMPL_RELEASE_INHERITED(XULDocument, XMLDocument)
 
 
 // QueryInterface implementation for XULDocument
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(XULDocument)
-    NS_INTERFACE_TABLE_INHERITED4(XULDocument, nsIXULDocument,
+    NS_INTERFACE_TABLE_INHERITED5(XULDocument, nsIXULDocument,
                                   nsIDOMXULDocument, nsIStreamLoaderObserver,
-                                  nsICSSLoaderObserver)
+                                  nsICSSLoaderObserver, nsIOffThreadScriptReceiver)
 NS_INTERFACE_TABLE_TAIL_INHERITING(XMLDocument)
 
 
 //----------------------------------------------------------------------
 //
 // nsIDocument interface
 //
 
@@ -3460,17 +3460,16 @@ XULDocument::LoadScript(nsXULPrototypeSc
         aScriptProto->mSrcLoading = true;
     }
 
     // Block until OnStreamComplete resumes us.
     *aBlock = true;
     return NS_OK;
 }
 
-
 NS_IMETHODIMP
 XULDocument::OnStreamComplete(nsIStreamLoader* aLoader,
                               nsISupports* context,
                               nsresult aStatus,
                               uint32_t stringLen,
                               const uint8_t* string)
 {
     nsCOMPtr<nsIRequest> request;
@@ -3500,107 +3499,141 @@ XULDocument::OnStreamComplete(nsIStreamL
 
     NS_ASSERTION(mCurrentScriptProto && mCurrentScriptProto->mSrcLoading,
                  "script source not loading on unichar stream complete?");
     if (!mCurrentScriptProto) {
         // XXX Wallpaper for bug 270042
         return NS_OK;
     }
 
-    // Clear mCurrentScriptProto now, but save it first for use below in
-    // the compile/execute code, and in the while loop that resumes walks
-    // of other documents that raced to load this script
-    nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
-    mCurrentScriptProto = nullptr;
-
-    // Clear the prototype's loading flag before executing the script or
-    // resuming document walks, in case any of those control flows starts a
-    // new script load.
-    scriptProto->mSrcLoading = false;
-
     if (NS_SUCCEEDED(aStatus)) {
         // If the including XUL document is a FastLoad document, and we're
         // compiling an out-of-line script (one with src=...), then we must
         // be writing a new FastLoad file.  If we were reading this script
         // from the FastLoad file, XULContentSinkImpl::OpenScript (over in
         // nsXULContentSink.cpp) would have already deserialized a non-null
         // script->mScriptObject, causing control flow at the top of LoadScript
         // not to reach here.
-        nsCOMPtr<nsIURI> uri = scriptProto->mSrcURI;
+        nsCOMPtr<nsIURI> uri = mCurrentScriptProto->mSrcURI;
 
         // XXX should also check nsIHttpChannel::requestSucceeded
 
-        nsString stringStr;
+        MOZ_ASSERT(!mOffThreadCompiling && mOffThreadCompileString.Length() == 0,
+                   "XULDocument can't load multiple scripts at once");
+
         rv = nsScriptLoader::ConvertToUTF16(channel, string, stringLen,
-                                            EmptyString(), this, stringStr);
-        if (NS_SUCCEEDED(rv)) {
-            rv = scriptProto->Compile(stringStr.get(), stringStr.Length(),
-                                      uri, 1, this,
-                                      mCurrentPrototype->GetScriptGlobalObject());
-        }
-
-        aStatus = rv;
+                                            EmptyString(), this, mOffThreadCompileString);
         if (NS_SUCCEEDED(rv)) {
-            rv = ExecuteScript(scriptProto);
-
-            // If the XUL cache is enabled, save the script object there in
-            // case different XUL documents source the same script.
-            //
-            // But don't save the script in the cache unless the master XUL
-            // document URL is a chrome: URL.  It is valid for a URL such as
-            // about:config to translate into a master document URL, whose
-            // prototype document nodes -- including prototype scripts that
-            // hold GC roots protecting their mJSObject pointers -- are not
-            // cached in the XUL prototype cache.  See StartDocumentLoad,
-            // the fillXULCache logic.
-            //
-            // A document such as about:config is free to load a script via
-            // a URL such as chrome://global/content/config.js, and we must
-            // not cache that script object without a prototype cache entry
-            // containing a companion nsXULPrototypeScript node that owns a
-            // GC root protecting the script object.  Otherwise, the script
-            // cache entry will dangle once the uncached prototype document
-            // is released when its owning XULDocument is unloaded.
+            rv = mCurrentScriptProto->Compile(mOffThreadCompileString.get(),
+                                              mOffThreadCompileString.Length(),
+                                              uri, 1, this,
+                                              mCurrentPrototype->GetScriptGlobalObject(),
+                                              this);
+            if (NS_SUCCEEDED(rv) && !mCurrentScriptProto->GetScriptObject()) {
+                // We will be notified via OnOffThreadCompileComplete when the
+                // compile finishes. Keep the contents of the compiled script
+                // alive until the compilation finishes.
+                mOffThreadCompiling = true;
+                BlockOnload();
+                return NS_OK;
+            }
+            mOffThreadCompileString.Truncate();
+        }
+    }
+
+    return OnScriptCompileComplete(mCurrentScriptProto->GetScriptObject(), rv);
+}
+
+NS_IMETHODIMP
+XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus)
+{
+    // Allow load events to be fired once off thread compilation finishes.
+    if (mOffThreadCompiling) {
+        mOffThreadCompiling = false;
+        UnblockOnload(false);
+    }
+
+    // After compilation finishes the script's characters are no longer needed.
+    mOffThreadCompileString.Truncate();
+
+    // When compiling off thread the script will not have been attached to the
+    // script proto yet.
+    if (aScript && !mCurrentScriptProto->GetScriptObject())
+        mCurrentScriptProto->Set(aScript);
+
+    // Clear mCurrentScriptProto now, but save it first for use below in
+    // the execute code, and in the while loop that resumes walks of other
+    // documents that raced to load this script.
+    nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
+    mCurrentScriptProto = nullptr;
+
+    // Clear the prototype's loading flag before executing the script or
+    // resuming document walks, in case any of those control flows starts a
+    // new script load.
+    scriptProto->mSrcLoading = false;
+
+    nsresult rv = aStatus;
+    if (NS_SUCCEEDED(rv)) {
+        rv = ExecuteScript(scriptProto);
+
+        // If the XUL cache is enabled, save the script object there in
+        // case different XUL documents source the same script.
+        //
+        // But don't save the script in the cache unless the master XUL
+        // document URL is a chrome: URL.  It is valid for a URL such as
+        // about:config to translate into a master document URL, whose
+        // prototype document nodes -- including prototype scripts that
+        // hold GC roots protecting their mJSObject pointers -- are not
+        // cached in the XUL prototype cache.  See StartDocumentLoad,
+        // the fillXULCache logic.
+        //
+        // A document such as about:config is free to load a script via
+        // a URL such as chrome://global/content/config.js, and we must
+        // not cache that script object without a prototype cache entry
+        // containing a companion nsXULPrototypeScript node that owns a
+        // GC root protecting the script object.  Otherwise, the script
+        // cache entry will dangle once the uncached prototype document
+        // is released when its owning XULDocument is unloaded.
+        //
+        // (See http://bugzilla.mozilla.org/show_bug.cgi?id=98207 for
+        // the true crime story.)
+        bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
+  
+        if (useXULCache && IsChromeURI(mDocumentURI) && scriptProto->GetScriptObject()) {
+            nsXULPrototypeCache::GetInstance()->PutScript(
+                               scriptProto->mSrcURI,
+                               scriptProto->GetScriptObject());
+        }
+
+        if (mIsWritingFastLoad && mCurrentPrototype != mMasterPrototype) {
+            // If we are loading an overlay script, try to serialize
+            // it to the FastLoad file here.  Master scripts will be
+            // serialized when the master prototype document gets
+            // written, at the bottom of ResumeWalk.  That way, master
+            // out-of-line scripts are serialized in the same order that
+            // they'll be read, in the FastLoad file, which reduces the
+            // number of seeks that dump the underlying stream's buffer.
             //
-            // (See http://bugzilla.mozilla.org/show_bug.cgi?id=98207 for
-            // the true crime story.)
-            bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
-  
-            if (useXULCache && IsChromeURI(mDocumentURI)) {
-                nsXULPrototypeCache::GetInstance()->PutScript(
-                                   scriptProto->mSrcURI,
-                                   scriptProto->GetScriptObject());
-            }
-
-            if (mIsWritingFastLoad && mCurrentPrototype != mMasterPrototype) {
-                // If we are loading an overlay script, try to serialize
-                // it to the FastLoad file here.  Master scripts will be
-                // serialized when the master prototype document gets
-                // written, at the bottom of ResumeWalk.  That way, master
-                // out-of-line scripts are serialized in the same order that
-                // they'll be read, in the FastLoad file, which reduces the
-                // number of seeks that dump the underlying stream's buffer.
-                //
-                // Ignore the return value, as we don't need to propagate
-                // a failure to write to the FastLoad file, because this
-                // method aborts that whole process on error.
-                nsIScriptGlobalObject* global =
-                    mCurrentPrototype->GetScriptGlobalObject();
-
-                NS_ASSERTION(global != nullptr, "master prototype w/o global?!");
-                if (global) {
-                    nsIScriptContext *scriptContext = \
-                          global->GetScriptContext();
-                    NS_ASSERTION(scriptContext != nullptr,
-                                 "Failed to get script context for language");
-                    if (scriptContext)
-                        scriptProto->SerializeOutOfLine(nullptr, global);
-                }
+            // Ignore the return value, as we don't need to propagate
+            // a failure to write to the FastLoad file, because this
+            // method aborts that whole process on error.
+            nsIScriptGlobalObject* global =
+                mCurrentPrototype->GetScriptGlobalObject();
+
+            NS_ASSERTION(global != nullptr, "master prototype w/o global?!");
+            if (global) {
+                nsIScriptContext *scriptContext =
+                    global->GetScriptContext();
+                NS_ASSERTION(scriptContext != nullptr,
+                             "Failed to get script context for language");
+                if (scriptContext)
+                    scriptProto->SerializeOutOfLine(nullptr, global);
             }
         }
+
         // ignore any evaluation errors
     }
 
     rv = ResumeWalk();
 
     // Load a pointer to the prototype-script's list of XULDocuments who
     // raced to load the same script
     XULDocument** docp = &scriptProto->mSrcLoadWaiters;
@@ -3623,17 +3656,16 @@ XULDocument::OnStreamComplete(nsIStreamL
         }
         doc->ResumeWalk();
         NS_RELEASE(doc);
     }
 
     return rv;
 }
 
-
 nsresult
 XULDocument::ExecuteScript(nsIScriptContext * aContext,
                            JS::Handle<JSScript*> aScriptObject)
 {
     NS_PRECONDITION(aScriptObject != nullptr && aContext != nullptr, "null ptr");
     if (! aScriptObject || ! aContext)
         return NS_ERROR_NULL_POINTER;
 
--- a/content/xul/document/src/XULDocument.h
+++ b/content/xul/document/src/XULDocument.h
@@ -83,17 +83,18 @@ private:
 
 namespace mozilla {
 namespace dom {
 
 class XULDocument MOZ_FINAL : public XMLDocument,
                               public nsIXULDocument,
                               public nsIDOMXULDocument,
                               public nsIStreamLoaderObserver,
-                              public nsICSSLoaderObserver
+                              public nsICSSLoaderObserver,
+                              public nsIOffThreadScriptReceiver
 {
 public:
     XULDocument();
     virtual ~XULDocument();
 
     // nsISupports interface
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSISTREAMLOADEROBSERVER
@@ -168,16 +169,18 @@ public:
     virtual bool IsDocumentRightToLeft() MOZ_OVERRIDE;
 
     virtual void ResetDocumentDirection() MOZ_OVERRIDE;
 
     virtual int GetDocumentLWTheme() MOZ_OVERRIDE;
 
     virtual void ResetDocumentLWTheme() MOZ_OVERRIDE { mDocLWTheme = Doc_Theme_Uninitialized; }
 
+    NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) MOZ_OVERRIDE;
+
     static bool
     MatchAttribute(nsIContent* aContent,
                    int32_t aNameSpaceID,
                    nsIAtom* aAttrName,
                    void* aData);
 
     NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULDocument, XMLDocument)
 
@@ -435,16 +438,28 @@ protected:
      * The prototype-script of the current transcluded script that is being
      * loaded.  For document.write('<script src="nestedwrite.js"><\/script>')
      * to work, these need to be in a stack element type, and we need to hold
      * the top of stack here.
      */
     nsXULPrototypeScript* mCurrentScriptProto;
 
     /**
+     * Whether the current transcluded script is being compiled off thread.
+     * The load event is blocked while this is in progress.
+     */
+    bool mOffThreadCompiling;
+
+    /**
+     * If the current transcluded script is being compiled off thread, the
+     * source for that script.
+     */
+    nsString mOffThreadCompileString;
+
+    /**
      * Check if a XUL template builder has already been hooked up.
      */
     static nsresult
     CheckTemplateBuilderHookup(nsIContent* aElement, bool* aNeedsHookup);
 
     /**
      * Create a XUL template builder on the specified node.
      */
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -199,16 +199,18 @@ nsXULPrototypeCache::GetScript(nsIURI* a
 {
     return mScriptTable.Get(aURI);
 }
 
 nsresult
 nsXULPrototypeCache::PutScript(nsIURI* aURI,
                                JS::Handle<JSScript*> aScriptObject)
 {
+    MOZ_ASSERT(aScriptObject, "Need a non-NULL script");
+
 #ifdef DEBUG
     if (mScriptTable.Get(aURI)) {
         nsAutoCString scriptName;
         aURI->GetSpec(scriptName);
         nsAutoCString message("Loaded script ");
         message += scriptName;
         message += " twice (bug 392650)";
         NS_WARNING(message.get());
--- a/dom/base/BarProps.cpp
+++ b/dom/base/BarProps.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/BarProps.h"
 #include "mozilla/dom/BarPropBinding.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocShell.h"
 #include "nsIScrollable.h"
+#include "nsIWebBrowserChrome.h"
 
 namespace mozilla {
 namespace dom {
 
 //
 //  Basic (virtual) BarProp class implementation
 //
 BarProp::BarProp(nsGlobalWindow *aWindow)
--- a/dom/base/BarProps.h
+++ b/dom/base/BarProps.h
@@ -8,27 +8,28 @@
    chrome which can be made visible or not through JavaScript by setting
    the appropriate property (window.menubar.visible)
 */
 
 #ifndef mozilla_dom_BarProps_h
 #define mozilla_dom_BarProps_h
 
 #include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsIWeakReference.h"
 #include "nsWrapperCache.h"
 #include "nsAutoPtr.h"
 
 class nsGlobalWindow;
 class nsIWebBrowserChrome;
 class nsPIDOMWindow;
 
 namespace mozilla {
+
+class ErrorResult;
+
 namespace dom {
 
 // Script "BarProp" object
 class BarProp : public nsISupports,
                 public nsWrapperCache
 {
 public:
   explicit BarProp(nsGlobalWindow *aWindow);
--- a/dom/base/Crypto.cpp
+++ b/dom/base/Crypto.cpp
@@ -1,18 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "Crypto.h"
-#include "DOMError.h"
-#include "nsString.h"
 #include "jsfriendapi.h"
-#include "nsIServiceManager.h"
 #include "nsCOMPtr.h"
 #include "nsIRandomGenerator.h"
+#include "nsPIDOMWindow.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/CryptoBinding.h"
 
 using mozilla::dom::ContentChild;
 
 using namespace js::ArrayBufferView;
 
--- a/dom/base/Crypto.h
+++ b/dom/base/Crypto.h
@@ -3,27 +3,30 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef mozilla_dom_Crypto_h
 #define mozilla_dom_Crypto_h
 
 #ifdef MOZ_DISABLE_CRYPTOLEGACY
 #include "nsIDOMCrypto.h"
 #else
 #include "nsIDOMCryptoLegacy.h"
-#include "nsIDOMCRMFObject.h"
+class nsIDOMCRMFObject;
 #endif
 
-#include "nsPIDOMWindow.h"
 #include "nsWrapperCache.h"
-#include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/TypedArray.h"
 #define NS_DOMCRYPTO_CID \
   {0x929d9320, 0x251e, 0x11d4, { 0x8a, 0x7c, 0x00, 0x60, 0x08, 0xc8, 0x44, 0xc3} }
 
+class nsPIDOMWindow;
+
 namespace mozilla {
+
+class ErrorResult;
+
 namespace dom {
 
 class Crypto : public nsIDOMCrypto,
                public nsWrapperCache
 {
 public:
   Crypto();
   virtual ~Crypto();
--- a/dom/base/DOMCursor.cpp
+++ b/dom/base/DOMCursor.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "DOMCursor.h"
-#include "nsError.h"
 #include "mozilla/dom/DOMCursorBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DOMCursor, DOMRequest,
                                      mCallback)
 
--- a/dom/base/DOMError.h
+++ b/dom/base/DOMError.h
@@ -3,18 +3,21 @@
 /* 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_domerror_h__
 #define mozilla_dom_domerror_h__
 
 #include "mozilla/Attributes.h"
-#include "nsPIDOMWindow.h"
 #include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+class nsPIDOMWindow;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
 class GlobalObject;
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -1,20 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "DOMRequest.h"
 
-#include "mozilla/Util.h"
 #include "DOMError.h"
-#include "nsEventDispatcher.h"
-#include "nsDOMEvent.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsThreadUtils.h"
 #include "DOMCursor.h"
 
 using mozilla::dom::DOMRequest;
 using mozilla::dom::DOMRequestService;
 using mozilla::dom::DOMCursor;
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -5,17 +5,16 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_domrequest_h__
 #define mozilla_dom_domrequest_h__
 
 #include "nsIDOMDOMRequest.h"
 #include "nsDOMEventTargetHelper.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/DOMRequestBinding.h"
 
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class DOMRequest : public nsDOMEventTargetHelper,
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -11,34 +11,30 @@
 #include "nsIXULAppInfo.h"
 #include "nsPluginArray.h"
 #include "nsMimeTypeArray.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/DesktopNotification.h"
 #include "nsGeolocation.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsICachingChannel.h"
-#include "nsIDocShell.h"
 #include "nsIWebContentHandlerRegistrar.h"
 #include "nsICookiePermission.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
-#include "nsVariant.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "BatteryManager.h"
 #include "PowerManager.h"
 #include "nsIDOMWakeLock.h"
 #include "nsIPowerManagerService.h"
 #include "mozilla/dom/MobileMessageManager.h"
-#include "nsISmsService.h"
 #include "mozilla/Hal.h"
-#include "nsIWebNavigation.h"
 #include "nsISiteSpecificUserAgent.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "Connection.h"
 #include "nsDOMEvent.h"
 #include "nsGlobalWindow.h"
 #ifdef MOZ_B2G_RIL
 #include "IccManager.h"
@@ -46,27 +42,28 @@
 #include "mozilla/dom/CellBroadcast.h"
 #include "mozilla/dom/Voicemail.h"
 #endif
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
 #include "TimeManager.h"
+#include "DeviceStorage.h"
+#include "nsIDOMNavigatorSystemMessages.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "MediaManager.h"
 #endif
 #ifdef MOZ_B2G_RIL
 #include "Telephony.h"
 #endif
 #ifdef MOZ_B2G_BT
 #include "BluetoothManager.h"
 #endif
-#include "nsIDOMCameraManager.h"
 #include "DOMCameraManager.h"
 
 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
 #include "AudioChannelManager.h"
 #endif
 
 #include "nsIDOMGlobalPropertyInitializer.h"
 #include "nsJSUtils.h"
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -3,51 +3,48 @@
 /* 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_Navigator_h
 #define mozilla_dom_Navigator_h
 
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/ErrorResult.h"
 #include "nsIDOMNavigator.h"
-#include "nsIDOMMobileMessageManager.h"
 #include "nsIMozNavigatorNetwork.h"
 #include "nsAutoPtr.h"
-#include "nsWeakReference.h"
-#include "DeviceStorage.h"
 #include "nsWrapperCache.h"
+#include "nsString.h"
+#include "nsTArray.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsPIDOMWindow;
 class nsIDOMMozConnection;
+class nsIDOMMozMobileMessageManager;
+class nsIDOMNavigatorSystemMessages;
+class nsIMediaStreamOptions;
+class nsDOMCameraManager;
+class nsDOMDeviceStorage;
 
 namespace mozilla {
 namespace dom {
 class Geolocation;
 class systemMessageCallback;
 }
 }
 
-#ifdef MOZ_MEDIA_NAVIGATOR
-#include "nsIDOMNavigatorUserMedia.h"
-#endif
-
 #ifdef MOZ_B2G_RIL
 class nsIDOMMozMobileConnection;
 class nsIDOMMozCellBroadcast;
 class nsIDOMMozVoicemail;
 class nsIDOMMozIccManager;
 #endif // MOZ_B2G_RIL
 
-#include "nsIDOMNavigatorSystemMessages.h"
-
-#include "DOMCameraManager.h"
-
 //*****************************************************************************
 // Navigator: Script "navigator" object
 //*****************************************************************************
 
 void NS_GetNavigatorAppName(nsAString& aAppName);
 
 namespace mozilla {
 namespace dom {
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -1,27 +1,31 @@
 /* -*- 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 URL_h___
 #define URL_h___
 
 #include "nscore.h"
-#include "mozilla/dom/URLBinding.h"
+#include "nsString.h"
 
 class nsIDOMBlob;
+class nsISupports;
 
 namespace mozilla {
 
+class ErrorResult;
 class DOMMediaStream;
 
 namespace dom {
 
 class MediaSource;
+class GlobalObject;
+struct objectURLOptions;
 
 class URL MOZ_FINAL
 {
 public:
   // WebIDL methods
   static void CreateObjectURL(const GlobalObject& aGlobal, nsIDOMBlob* aBlob,
                               const objectURLOptions& aOptions,
                               nsString& aResult,
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -1,16 +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 "nsContentPermissionHelper.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsCOMPtr.h"
-#include "nsIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/unused.h"
 
 using mozilla::unused;          // <snicker>
 using namespace mozilla::dom;
 
--- a/dom/base/nsContentPermissionHelper.h
+++ b/dom/base/nsContentPermissionHelper.h
@@ -1,17 +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/. */
 
 #ifndef nsContentPermissionHelper_h
 #define nsContentPermissionHelper_h
 
-#include "base/basictypes.h"
-
 #include "nsIContentPermissionPrompt.h"
 #include "nsString.h"
 
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/PContentPermissionRequestParent.h"
 
 class nsContentPermissionRequestProxy;
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -10,142 +10,104 @@
 
 #ifdef XP_WIN
 #undef GetClassName
 #endif
 
 // JavaScript includes
 #include "jsapi.h"
 #include "jsfriendapi.h"
-#include "jsdbgapi.h"
 #include "WrapperFactory.h"
 #include "AccessCheck.h"
 #include "XrayWrapper.h"
 
 #include "xpcpublic.h"
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
-#include "XPCQuickStubs.h"
-#include "nsDOMQS.h"
 
 #include "mozilla/dom/RegisterBindings.h"
 
 #include "nscore.h"
 #include "nsDOMClassInfo.h"
 #include "nsCRT.h"
 #include "nsCRTGlue.h"
-#include "nsIServiceManager.h"
 #include "nsICategoryManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIXPConnect.h"
 #include "nsIXPCSecurityManager.h"
-#include "nsIStringBundle.h"
-#include "nsIConsoleService.h"
-#include "nsIScriptError.h"
-#include "nsXPIDLString.h"
-#include "nsReadableUtils.h"
-#include "nsUnicharUtils.h"
 #include "xptcall.h"
-#include "prprf.h"
 #include "nsTArray.h"
-#include "nsCSSValue.h"
-#include "nsThreadUtils.h"
 #include "nsDOMEventTargetHelper.h"
+#include "nsIDOMHTMLCanvasElement.h"
+#include "nsContentList.h"
+#include "nsHTMLDocument.h"
+#include "nsDOMBlobBuilder.h"
 
 // General helper includes
 #include "nsGlobalWindow.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventListener.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
-#include "nsDOMWindowUtils.h"
+#include "nsIDOMWindowUtils.h"
 #include "nsIDOMGlobalPropertyInitializer.h"
-#include "mozilla/Preferences.h"
 #include "nsLocation.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Telemetry.h"
 
 // Window scriptable helper includes
 #include "nsIDocShell.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsIDocShellTreeNode.h"
 #include "nsIScriptExternalNameSet.h"
 #include "nsJSUtils.h"
-#include "nsIInterfaceRequestor.h"
-#include "nsIInterfaceRequestorUtils.h"
 #include "nsScriptNameSpaceManager.h"
 #include "nsIJSNativeInitializer.h"
 #include "nsJSEnvironment.h"
 
 // DOM base includes
 #include "nsIDOMLocation.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMJSWindow.h"
-#include "nsIDOMWindowCollection.h"
 #include "nsIDOMMediaList.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIDOMConstructor.h"
 
 // DOM core includes
 #include "nsError.h"
 #include "nsIDOMDOMException.h"
-#include "nsIDOMNode.h"
 #include "nsIDOMDOMStringList.h"
 #include "nsIDOMUserDataHandler.h"
 #include "nsIDOMGeoPositionError.h"
 #include "nsIDOMLoadStatus.h"
 #include "nsIDOMXPathNamespace.h"
 #include "nsIDOMXULButtonElement.h"
 #include "nsIDOMXULCheckboxElement.h"
 #include "nsIDOMXULPopupElement.h"
 
 // Event related includes
-#include "nsEventListenerManager.h"
 #include "nsIDOMEventTarget.h"
 
 // CSS related includes
 #include "nsCSSRules.h"
-#include "nsIDOMStyleSheet.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIDOMCSSRule.h"
 #include "nsICSSRuleList.h"
-#include "nsIDOMRect.h"
-#include "nsDOMCSSAttrDeclaration.h"
-
-// XBL related includes.
-#include "nsXBLService.h"
-#include "nsXBLBinding.h"
-#include "nsBindingManager.h"
-#include "nsIFrame.h"
-#include "nsIPresShell.h"
-#include "nsIDOMElement.h"
-#include "nsStyleContext.h"
 #include "nsAutoPtr.h"
 #include "nsMemory.h"
 
 // Tranformiix
-#include "nsIDOMXPathEvaluator.h"
 #include "nsIXSLTProcessor.h"
 #include "nsIXSLTProcessorPrivate.h"
 
-#include "nsXMLHttpRequest.h"
-#include "nsIDOMContactManager.h"
-#include "nsIDOMPermissionSettings.h"
-#include "nsIDOMApplicationRegistry.h"
-
 // includes needed for the prototype chain interfaces
-#include "nsIDOMDocumentXBL.h"
-#include "nsIDOMElementCSSInlineStyle.h"
-#include "nsIDOMHTMLDocument.h"
 #include "nsIDOMCSSCharsetRule.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIDOMCSSFontFaceRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSSupportsRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
@@ -160,55 +122,48 @@
 #include "nsIControllers.h"
 #include "nsISelection.h"
 #include "nsIBoxObject.h"
 #ifdef MOZ_XUL
 #include "nsITreeSelection.h"
 #include "nsITreeContentView.h"
 #include "nsITreeView.h"
 #include "nsIXULTemplateBuilder.h"
-#include "nsTreeColumns.h"
+#include "nsITreeColumns.h"
 #endif
 #include "nsIDOMXPathExpression.h"
 #include "nsIDOMNSXPathExpression.h"
 #include "nsIDOMXPathNSResolver.h"
 #include "nsIDOMXPathResult.h"
-#include "nsIDOMMozBrowserFrame.h"
 
 #include "nsIDOMSVGLength.h"
 #include "nsIDOMSVGNumber.h"
 
 // Storage includes
-#include "DOMStorage.h"
+#include "nsIDOMStorage.h"
+#include "nsPIDOMStorage.h"
 
 // Drag and drop
 #include "nsIDOMDataTransfer.h"
 
-// Geolocation
-#include "nsIDOMGeoPositionCoords.h"
-
 // Workers
 #include "mozilla/dom/workers/Workers.h"
 
-#include "nsDOMFile.h"
+#include "nsIDOMFile.h"
 
 #include "nsIEventListenerService.h"
 #include "nsIMessageManager.h"
-#include "mozilla/dom/Element.h"
 #include "mozilla/dom/indexedDB/IDBKeyRange.h"
 #include "nsIDOMMediaQueryList.h"
 
-#include "mozilla/dom/Activity.h"
-
 #include "nsDOMTouchEvent.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/dom/HTMLCollectionBinding.h"
 
-#include "BatteryManager.h"
 #include "nsIDOMPowerManager.h"
 #include "nsIDOMWakeLock.h"
 #include "nsIDOMMobileMessageManager.h"
 #include "nsIDOMMozSmsMessage.h"
 #include "nsIDOMMozMmsMessage.h"
 #include "nsIDOMSmsFilter.h"
 #include "nsIDOMSmsSegmentInfo.h"
 #include "nsIDOMMozMobileMessageThread.h"
@@ -224,24 +179,21 @@
 #ifdef MOZ_B2G_FM
 #include "FMRadio.h"
 #endif
 
 #ifdef MOZ_B2G_BT
 #include "BluetoothDevice.h"
 #endif
 
-#include "DOMCameraManager.h"
-#include "DOMCameraControl.h"
-#include "DOMCameraCapabilities.h"
+#include "nsIDOMCameraManager.h"
 #include "nsIOpenWindowEventDetail.h"
 #include "nsIAsyncScrollEventDetail.h"
 #include "nsIDOMGlobalObjectConstructor.h"
-#include "nsIDOMCanvasRenderingContext2D.h"
-#include "LockedFile.h"
+#include "nsIDOMLockedFile.h"
 #include "nsDebug.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Likely.h"
 #include "WindowNamedPropertiesHandler.h"
 
 #ifdef MOZ_TIME_MANAGER
 #include "TimeManager.h"
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -3,43 +3,28 @@
 /* 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 nsDOMClassInfo_h___
 #define nsDOMClassInfo_h___
 
 #include "mozilla/Attributes.h"
-#include "nsIDOMClassInfo.h"
 #include "nsIXPCScriptable.h"
-#include "jsapi.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsIScriptContext.h"
-#include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
 #include "nsIScriptGlobalObject.h"
-#include "xpcpublic.h"
-#include "nsIRunnable.h"
+#include "nsIDOMScriptObjectFactory.h"
 
 #ifdef XP_WIN
 #undef GetClassName
 #endif
 
 class nsContentList;
 class nsDocument;
 class nsGlobalWindow;
-class nsIDOMWindow;
-class nsIForm;
-class nsNPAPIPluginInstance;
-class nsObjectLoadingContent;
-class nsIObjectLoadingContent;
-
-class nsIDOMCrypto;
-#ifndef MOZ_DISABLE_CRYPTOLEGACY
-class nsIDOMCRMFObject;
-#endif
+class nsIScriptSecurityManager;
 
 struct nsDOMClassInfoData;
 
 typedef nsIClassInfo* (*nsDOMClassInfoConstructorFnc)
   (nsDOMClassInfoData* aData);
 
 typedef nsresult (*nsDOMConstructorFunc)(nsISupports** aNewObject);
 
--- a/dom/base/nsDOMException.h
+++ b/dom/base/nsDOMException.h
@@ -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 "nsCOMPtr.h"
-#include "nsIException.h"
+#include "mozilla/NullPtr.h"
+#include "nsError.h"
+class nsIException;
 
 nsresult
 NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
                                    const char** aMessage,
                                    uint16_t* aCode = nullptr);
 
 nsresult
 NS_NewDOMException(nsresult aNSResult, nsIException* aDefaultException,
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -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/. */
 
 #include "nsDOMNavigationTiming.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
-#include "nscore.h"
 #include "prtime.h"
 #include "TimeStamp.h"
+#include "nsIURI.h"
 
 nsDOMNavigationTiming::nsDOMNavigationTiming()
 {
   Clear();
 }
 
 nsDOMNavigationTiming::~nsDOMNavigationTiming()
 {
--- a/dom/base/nsDOMNavigationTiming.h
+++ b/dom/base/nsDOMNavigationTiming.h
@@ -1,23 +1,21 @@
 /* -*- 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 nsDOMNavigationTiming_h___
 #define nsDOMNavigationTiming_h___
 
-#include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "mozilla/TimeStamp.h"
-#include "nsIURI.h"
 
-class nsDOMNavigationTimingClock;
+class nsIURI;
 
 typedef unsigned long long DOMTimeMilliSec;
 typedef double DOMHighResTimeStamp;
 typedef unsigned short nsDOMPerformanceNavigationType;
 
 namespace mozilla {
 namespace dom {
 namespace PerformanceNavigation {
--- a/dom/base/nsDOMScriptObjectFactory.cpp
+++ b/dom/base/nsDOMScriptObjectFactory.cpp
@@ -15,23 +15,20 @@
  * identified per MPL Section 3.3
  *
  * Date         Modified by     Description of modification
  * 03/27/2000   IBM Corp.       Added PR_CALLBACK for Optlink
  *                               use in OS2
  */
 
 #include "nsDOMScriptObjectFactory.h"
-#include "xpcexception.h"
 #include "nsScriptNameSpaceManager.h"
 #include "nsIObserverService.h"
 #include "nsJSEnvironment.h"
-#include "nsJSEventListener.h"
 #include "nsGlobalWindow.h"
-#include "nsISupportsPrimitives.h"
 #include "nsDOMException.h"
 #include "nsCRT.h"
 #ifdef MOZ_XUL
 #include "nsXULPrototypeCache.h"
 #endif
 #include "nsThreadUtils.h"
 
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
--- a/dom/base/nsDOMScriptObjectFactory.h
+++ b/dom/base/nsDOMScriptObjectFactory.h
@@ -16,17 +16,16 @@
  * Date         Modified by     Description of modification
  * 03/27/2000   IBM Corp.       Added PR_CALLBACK for Optlink
  *                               use in OS2
  */
 
 #include "nsIDOMScriptObjectFactory.h"
 #include "nsIObserver.h"
 #include "nsIExceptionService.h"
-#include "nsIScriptRuntime.h"
 #include "mozilla/Attributes.h"
 
 class nsDOMScriptObjectFactory MOZ_FINAL : public nsIDOMScriptObjectFactory,
                                            public nsIObserver
 {
 public:
   nsDOMScriptObjectFactory();
 
--- a/dom/base/nsDOMWindowList.cpp
+++ b/dom/base/nsDOMWindowList.cpp
@@ -9,17 +9,16 @@
 // Helper classes
 #include "nsCOMPtr.h"
 
 // Interfaces needed
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIDocShell.h"
-#include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIWebNavigation.h"
 
 nsDOMWindowList::nsDOMWindowList(nsIDocShell *aDocShell)
 {
   SetDocShell(aDocShell);
 }
--- a/dom/base/nsDOMWindowList.h
+++ b/dom/base/nsDOMWindowList.h
@@ -1,23 +1,20 @@
 /* -*- 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 nsDOMWindowList_h___
 #define nsDOMWindowList_h___
 
 #include "nsCOMPtr.h"
-#include "nsISupports.h"
 #include "nsIDOMWindowCollection.h"
-#include "nsString.h"
 #include <stdint.h>
 #include "nsIDocShellTreeItem.h"
 
-class nsIDocShellTreeNode;
 class nsIDocShell;
 class nsIDOMWindow;
 
 class nsDOMWindowList : public nsIDOMWindowCollection
 {
 public:
   nsDOMWindowList(nsIDocShell *aDocShell);
   virtual ~nsDOMWindowList();
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1,97 +1,96 @@
 /* -*- 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 "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/PLayerTransactionChild.h"
-#include "nsIDocShell.h"
 #include "nsPresContext.h"
 #include "nsDOMClassInfoID.h"
 #include "nsError.h"
 #include "nsIDOMEvent.h"
 #include "nsDOMWindowUtils.h"
 #include "nsQueryContentEventResult.h"
 #include "nsGlobalWindow.h"
 #include "nsIDocument.h"
 #include "nsFocusManager.h"
 #include "nsEventStateManager.h"
 #include "nsFrameManager.h"
 #include "nsRefreshDriver.h"
-#include "nsDOMTouchEvent.h"
 #include "mozilla/dom/Touch.h"
-#include "nsObjectLoadingContent.h"
+#include "nsIObjectLoadingContent.h"
 #include "nsFrame.h"
+#include "mozilla/layers/ShadowLayers.h"
 
 #include "nsIScrollableFrame.h"
 
 #include "nsContentUtils.h"
-#include "nsLayoutUtils.h"
 
 #include "nsIFrame.h"
 #include "nsIWidget.h"
 #include "nsGUIEvent.h"
 #include "nsCharsetSource.h"
 #include "nsJSEnvironment.h"
 #include "nsJSUtils.h"
 
 #include "nsViewManager.h"
 
 #include "nsIDOMHTMLCanvasElement.h"
-#include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "nsLayoutUtils.h"
 #include "nsComputedDOMStyle.h"
 #include "nsIPresShell.h"
 #include "nsStyleAnimation.h"
 #include "nsCSSProps.h"
 #include "nsDOMFile.h"
-#include "BasicLayers.h"
 #include "nsTArrayHelpers.h"
 #include "nsIDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsClientRect.h"
 #include <algorithm>
 
 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #endif
 
 #include "Layers.h"
-#include "nsIIOService.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
 #include "mozilla/dom/quota/QuotaManager.h"
-#include "GeckoProfiler.h"
 #include "nsDOMBlobBuilder.h"
 #include "nsIDOMFileHandle.h"
 #include "nsPrintfCString.h"
 #include "nsViewportInfo.h"
 #include "nsIFormControl.h"
 #include "nsIScriptError.h"
 #include "nsIAppShell.h"
 #include "nsWidgetsCID.h"
 #include "FrameLayerBuilder.h"
 #include "nsDisplayList.h"
 #include "nsROCSSPrimitiveValue.h"
+#include "nsIBaseWindow.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIInterfaceRequestorUtils.h"
 
 #ifdef XP_WIN
 #undef GetClassName
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 
+class gfxContext;
+
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -1,17 +1,16 @@
 /* -*- 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 nsDOMWindowUtils_h_
 #define nsDOMWindowUtils_h_
 
-#include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 
 #include "nsIDOMWindowUtils.h"
 #include "nsEvent.h"
 #include "mozilla/Attributes.h"
 
 class nsGlobalWindow;
 class nsIPresShell;
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2,71 +2,64 @@
 /* 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/TabParent.h"
 
 #include "nsFocusManager.h"
 
-#include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
-#include "nsIDOMXULElement.h"
-#include "nsIDOMHTMLFrameElement.h"
-#include "nsIDOMHTMLInputElement.h"
-#include "nsIDOMHTMLMapElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMRange.h"
 #include "nsIHTMLDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsLayoutUtils.h"
 #include "nsIPresShell.h"
-#include "nsIContentViewer.h"
 #include "nsFrameTraversal.h"
-#include "nsObjectFrame.h"
 #include "nsEventDispatcher.h"
 #include "nsEventStateManager.h"
 #include "nsIMEStateManager.h"
 #include "nsIWebNavigation.h"
 #include "nsCaret.h"
 #include "nsIBaseWindow.h"
 #include "nsViewManager.h"
 #include "nsFrameSelection.h"
 #include "mozilla/Selection.h"
 #include "nsXULPopupManager.h"
-#include "nsIDOMNodeFilter.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
-#include "mozAutoDocUpdate.h"
-#include "nsFrameLoader.h"
 #include "nsIObserverService.h"
-#include "nsIScriptError.h"
+#include "nsIObjectFrame.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 #include <algorithm>
 
 #ifdef MOZ_XUL
 #include "nsIDOMXULTextboxElement.h"
 #include "nsIDOMXULMenuListElement.h"
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
+#ifndef XP_MACOSX
+#include "nsIScriptError.h"
+#endif
+
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::widget;
 
 #ifdef PR_LOGGING
 
 // Two types of focus pr logging are available:
 //   'Focus' for normal focus manager calls
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "base/basictypes.h"
 #include <algorithm>
 
-/* This must occur *after* base/basictypes.h to avoid typedefs conflicts. */
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Util.h"
 
 // Local Includes
 #include "nsGlobalWindow.h"
 #include "Navigator.h"
 #include "nsScreen.h"
 #include "nsHistory.h"
@@ -21,160 +19,138 @@
 #include "nsIDOMStorage.h"
 #include "nsIDOMStorageManager.h"
 #include "DOMStorage.h"
 #include "nsDOMOfflineResourceList.h"
 #include "nsError.h"
 #include "nsIIdleService.h"
 #include "nsIPowerManagerService.h"
 #include "nsISizeOfEventTarget.h"
-#include "nsIPermissionManager.h"
+#include "nsDOMJSUtils.h"
+#include "nsArrayUtils.h"
+#include "nsIDOMWindowCollection.h"
+#include "nsDOMWindowList.h"
+#include "nsIDOMWakeLock.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIScriptContext.h"
+#include "nsIScriptTimeoutHandler.h"
 
 #ifdef XP_WIN
+// Thanks so much, Microsoft! :(
 #ifdef GetClassName
 #undef GetClassName
 #endif // GetClassName
+#ifdef CreateEvent
+#undef CreateEvent
+#endif
 #endif // XP_WIN
 
 // Helper Classes
-#include "nsXPIDLString.h"
 #include "nsJSUtils.h"
 #include "jsapi.h"              // for JSAutoRequest
 #include "jsdbgapi.h"           // for JS_ClearWatchPointsForObject
 #include "jsfriendapi.h"        // for JS_GetGlobalForFrame
 #include "jswrapper.h"
 #include "nsReadableUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsJSEnvironment.h"
-#include "nsCharSeparatedTokenizer.h" // for Accept-Language parsing
-#include "nsUnicharUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 
 // Other Classes
 #include "nsEventListenerManager.h"
-#include "nsEscape.h"
-#include "nsStyleCoord.h"
-#include "nsMimeTypeArray.h"
-#include "nsNetUtil.h"
-#include "nsICachingChannel.h"
-#include "nsPluginArray.h"
-#include "nsIPluginHost.h"
-#include "nsPluginHost.h"
-#include "nsIPluginInstanceOwner.h"
-#include "nsGeolocation.h"
 #include "mozilla/dom/BarProps.h"
-#include "mozilla/dom/DesktopNotification.h"
 #include "nsContentCID.h"
 #include "nsLayoutStatics.h"
 #include "nsCCUncollectableMarker.h"
-#include "nsAutoJSValHolder.h"
-#include "nsDOMMediaQueryList.h"
 #include "mozilla/dom/workers/Workers.h"
 #include "nsJSPrincipals.h"
 #include "mozilla/Attributes.h"
 
 // Interfaces Needed
 #include "nsIFrame.h"
 #include "nsCanvasFrame.h"
 #include "nsIWidget.h"
 #include "nsIWidgetListener.h"
 #include "nsIBaseWindow.h"
 #include "nsDeviceSensors.h"
 #include "nsIContent.h"
-#include "nsIContentViewerEdit.h"
 #include "nsIDocShell.h"
-#include "nsIDocShellLoadInfo.h"
 #include "nsIDocCharset.h"
 #include "nsIDocument.h"
-#include "nsIHTMLDocument.h"
-#include "nsIDOMHTMLDocument.h"
-#include "nsIDOMHTMLElement.h"
+#ifdef MOZ_DISABLE_CRYPTOLEGACY
 #include "Crypto.h"
+#else
+#include "nsIDOMCryptoLegacy.h"
+#endif
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
-#include "nsIDOMHTMLAnchorElement.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIDOMMessageEvent.h"
 #include "nsIDOMPopupBlockedEvent.h"
 #include "nsIDOMPopStateEvent.h"
 #include "nsIDOMHashChangeEvent.h"
 #include "nsIDOMOfflineResourceList.h"
-#include "nsIDOMGeoGeolocation.h"
 #include "nsPIDOMStorage.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsThreadUtils.h"
-#include "nsEventStateManager.h"
-#include "nsIHttpProtocolHandler.h"
-#include "nsIJSRuntimeService.h"
 #include "nsILoadContext.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIPresShell.h"
-#include "nsIProgrammingLanguage.h"
-#include "nsIServiceManager.h"
-#include "nsIScriptGlobalObjectOwner.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsISelectionController.h"
 #include "nsISelection.h"
 #include "nsIPrompt.h"
 #include "nsIPromptService.h"
 #include "nsIPromptFactory.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsIWebNavigation.h"
-#include "nsIWebBrowser.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIWebBrowserFind.h"  // For window.find()
-#include "nsIWebContentHandlerRegistrar.h"
 #include "nsIWindowMediator.h"  // For window.find()
 #include "nsComputedDOMStyle.h"
 #include "nsIEntropyCollector.h"
 #include "nsDOMCID.h"
 #include "nsDOMWindowUtils.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIWindowWatcher.h"
 #include "nsIContentViewer.h"
-#include "nsIJSNativeInitializer.h"
 #include "nsIScriptError.h"
-#include "nsIConsoleService.h"
 #include "nsIControllers.h"
 #include "nsIControllerContext.h"
 #include "nsGlobalWindowCommands.h"
 #include "nsAutoPtr.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsCSSProps.h"
 #include "nsIDOMFile.h"
 #include "nsIDOMFileList.h"
 #include "nsIURIFixup.h"
+#ifndef DEBUG
 #include "nsIAppStartup.h"
 #include "nsToolkitCompsCID.h"
+#endif
 #include "nsCDefaultURIFixup.h"
 #include "nsEventDispatcher.h"
 #include "nsIObserverService.h"
-#include "nsIXULAppInfo.h"
-#include "nsNetUtil.h"
 #include "nsFocusManager.h"
 #include "nsIXULWindow.h"
 #include "nsEventStateManager.h"
 #include "nsITimedChannel.h"
-#include "nsICookiePermission.h"
 #include "nsServiceManagerUtils.h"
 #ifdef MOZ_XUL
-#include "nsXULPopupManager.h"
 #include "nsIDOMXULControlElement.h"
 #include "nsMenuPopupFrame.h"
 #endif
 
 #include "xpcprivate.h"
-#include "nsDOMEvent.h"
 
 #ifdef NS_PRINTING
 #include "nsIPrintSettings.h"
 #include "nsIPrintSettingsService.h"
 #include "nsIWebBrowserPrint.h"
 #endif
 
 #include "nsWindowRoot.h"
@@ -214,42 +190,44 @@
 
 #include "mozilla/dom/StructuredCloneTags.h"
 
 #ifdef MOZ_GAMEPAD
 #include "mozilla/dom/GamepadService.h"
 #endif
 
 #include "nsRefreshDriver.h"
-#include "mozAutoDocUpdate.h"
 
 #include "mozilla/Telemetry.h"
 #include "nsLocation.h"
 #include "nsHTMLDocument.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsDOMEventTargetHelper.h"
-#include "nsIAppsService.h"
 #include "prrng.h"
 #include "nsSandboxFlags.h"
 #include "TimeChangeObserver.h"
-#include "nsPISocketTransportService.h"
 #include "mozilla/dom/AudioContext.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/WindowBinding.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/SpeechSynthesis.h"
 #endif
 
 #ifdef MOZ_JSDEBUGGER
 #include "jsdIDebuggerService.h"
 #endif
 
+#ifdef MOZ_B2G
+#include "nsPISocketTransportService.h"
+#endif
+
 // Apple system headers seem to have a check() macro.  <sigh>
 #ifdef check
+class nsIScriptTimeoutHandler;
 #undef check
 #endif // check
 #include "AccessCheck.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -2,79 +2,59 @@
 /* vim: set ts=2 sw=2 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 nsGlobalWindow_h___
 #define nsGlobalWindow_h___
 
-#include "mozilla/XPCOM.h" // for TimeStamp/TimeDuration
+#include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "nsRefPtrHashtable.h"
 
 // Local Includes
 // Helper Classes
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsDataHashtable.h"
 #include "nsJSThingHashtable.h"
 #include "nsCycleCollectionParticipant.h"
 
 // Interfaces Needed
-#include "nsDOMWindowList.h"
-#include "nsIBaseWindow.h"
 #include "nsIBrowserDOMWindow.h"
-#include "nsIDocShellTreeOwner.h"
-#include "nsIDocShellTreeItem.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIInterfaceRequestor.h"
-#include "nsIInterfaceRequestorUtils.h"
 #include "nsIDOMJSWindow.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIScriptGlobalObject.h"
-#include "nsIScriptContext.h"
-#include "nsIScriptObjectPrincipal.h"
-#include "nsIScriptTimeoutHandler.h"
 #include "nsITimer.h"
-#include "nsIWebBrowserChrome.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMModalContentWindow.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsEventListenerManager.h"
-#include "nsIDOMDocument.h"
 #include "nsIPrincipal.h"
-#include "nsIXPCScriptable.h"
-#include "nsPoint.h"
 #include "nsSize.h"
 #include "nsRect.h"
 #include "mozFlushType.h"
 #include "prclist.h"
 #include "nsIDOMStorageEvent.h"
 #include "nsIDOMStorageIndexedDB.h"
-#include "nsIDOMOfflineResourceList.h"
-#include "nsIArray.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIInlineEventHandlers.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIIdleObserver.h"
-#include "nsIDOMWakeLock.h"
-#ifdef MOZ_GAMEPAD
-#include "mozilla/dom/Gamepad.h"
-#endif
 #include "nsIDocument.h"
 #include "nsIDOMTouchEvent.h"
 
 #include "mozilla/dom/EventTarget.h"
 #include "Units.h"
 
-// JS includes
-#include "jsapi.h"
-
 #ifdef MOZ_B2G
 #include "nsIDOMWindowB2G.h"
 #endif // MOZ_B2G
 
 #ifdef MOZ_WEBSPEECH
 #include "nsISpeechSynthesisGetter.h"
 #endif // MOZ_WEBSPEECH
 
@@ -90,45 +70,46 @@
 #define MAX_SUCCESSIVE_DIALOG_COUNT 5
 
 // Idle fuzz time upper limit
 #define MAX_IDLE_FUZZ_TIME_MS 90000
 
 // Min idle notification time in seconds.
 #define MIN_IDLE_NOTIFICATION_TIME_S 1
 
+class nsIArray;
+class nsIBaseWindow;
 class nsIContent;
-class nsIDocument;
-class nsPresContext;
+class nsIDocShellTreeOwner;
 class nsIDOMCrypto;
-class nsIDOMEvent;
+class nsIDOMOfflineResourceList;
+class nsIDOMMozWakeLock;
 class nsIScrollableFrame;
 class nsIControllers;
+class nsIScriptContext;
+class nsIScriptTimeoutHandler;
+class nsIWebBrowserChrome;
 
+class nsDOMWindowList;
 class nsLocation;
 class nsScreen;
 class nsHistory;
-class nsIDocShellLoadInfo;
-class WindowStateHolder;
 class nsGlobalWindowObserver;
 class nsGlobalWindow;
-class PostMessageEvent;
-class nsRunnable;
 class nsDOMEventTargetHelper;
-class nsDOMOfflineResourceList;
 class nsDOMWindowUtils;
 class nsIIdleService;
 
 class nsWindowSizes;
 
 namespace mozilla {
 namespace dom {
 class BarProp;
+class Gamepad;
 class Navigator;
-class URL;
 class SpeechSynthesis;
 namespace indexedDB {
 class IDBFactory;
 } // namespace indexedDB
 } // namespace dom
 } // namespace mozilla
 
 extern nsresult
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -30,16 +30,18 @@ class nsIURI;
 #define NS_ISCRIPTCONTEXT_IID \
 { 0x6219173f, 0x4a61, 0x4c99, \
   { 0xb1, 0xfd, 0x8e, 0x7a, 0xf0, 0xdc, 0xe0, 0x56 } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
+class nsIOffThreadScriptReceiver;
+
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
  */
 class nsIScriptContext : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTCONTEXT_IID)
@@ -171,10 +173,29 @@ public:
   /**
    * Tell the context we're done reinitializing it.
    */
   virtual void DidInitializeContext() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
 
+#define NS_IOFFTHREADSCRIPTRECEIVER_IID \
+{0x3a980010, 0x878d, 0x46a9,            \
+  {0x93, 0xad, 0xbc, 0xfd, 0xd3, 0x8e, 0xa0, 0xc2}}
+
+class nsIOffThreadScriptReceiver : public nsISupports
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IOFFTHREADSCRIPTRECEIVER_IID)
+
+  /**
+   * Notify this object that a previous CompileScript call specifying this as
+   * aOffThreadReceiver has completed. The script being passed in must be
+   * rooted before any call which could trigger GC.
+   */
+  NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIOffThreadScriptReceiver, NS_IOFFTHREADSCRIPTRECEIVER_IID)
+
 #endif // nsIScriptContext_h__
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -35,16 +35,17 @@
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsEventDispatcher.h"
 #include "nsIContent.h"
 #include "nsCycleCollector.h"
 #include "nsNetUtil.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsIXULRuntime.h"
+#include "nsTextFormatter.h"
 
 #include "xpcpublic.h"
 
 #include "jsdbgapi.h"
 #include "jswrapper.h"
 #include "nsIArray.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -1,30 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=78: */
 /* 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 "nsCOMPtr.h"
-#include "nsIScriptContext.h"
 #include "nsIDocument.h"
-#include "nsIArray.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsIXPConnect.h"
-#include "nsIJSRuntimeService.h"
 #include "nsJSUtils.h"
-#include "nsDOMJSUtils.h"
 #include "nsContentUtils.h"
-#include "nsJSEnvironment.h"
-#include "nsServiceManagerUtils.h"
 #include "nsError.h"
 #include "nsGlobalWindow.h"
 #include "nsIContentSecurityPolicy.h"
-#include "nsAlgorithm.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Likely.h"
 #include <algorithm>
 #include "mozilla/dom/FunctionBinding.h"
 
 static const char kSetIntervalStr[] = "setInterval";
 static const char kSetTimeoutStr[] = "setTimeout";
 
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -11,25 +11,25 @@
  * the generated code itself.
  */
 
 #include "nsJSUtils.h"
 #include "jsapi.h"
 #include "jsdbgapi.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
-#include "nsIServiceManager.h"
 #include "nsIXPConnect.h"
 #include "nsCOMPtr.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsPIDOMWindow.h"
 #include "GeckoProfiler.h"
 #include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
 #include "nsJSPrincipals.h"
-#include "mozilla/dom/BindingUtils.h"
+#include "xpcpublic.h"
+#include "nsContentUtils.h"
 
 bool
 nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
                               uint32_t* aLineno)
 {
   JSScript* script = nullptr;
   unsigned lineno = 0;
 
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -10,24 +10,21 @@
  * This is not a generated file. It contains common utility functions 
  * invoked from the JavaScript code generated from IDL interfaces.
  * The goal of the utility functions is to cut down on the size of
  * the generated code itself.
  */
 
 #include "mozilla/Assertions.h"
 
-#include "nsISupports.h"
 #include "jsapi.h"
 #include "nsString.h"
 
-class nsIDOMEventListener;
 class nsIScriptContext;
 class nsIScriptGlobalObject;
-class nsIPrincipal;
 
 class nsJSUtils
 {
 public:
   static bool GetCallingLocation(JSContext* aContext, const char* *aFilename,
                                  uint32_t* aLineno);
 
   static nsIScriptGlobalObject *GetStaticScriptGlobal(JSObject* aObj);
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -10,35 +10,28 @@
 #include "nsIScriptContext.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellLoadInfo.h"
 #include "nsIWebNavigation.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIURIFixup.h"
 #include "nsIURL.h"
 #include "nsIJARURI.h"
-#include "nsIIOService.h"
-#include "nsIServiceManager.h"
 #include "nsNetUtil.h"
 #include "nsCOMPtr.h"
 #include "nsEscape.h"
 #include "nsIDOMWindow.h"
-#include "nsIDOMDocument.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
-#include "nsXPIDLString.h"
 #include "nsError.h"
 #include "nsDOMClassInfoID.h"
-#include "nsCRT.h"
-#include "nsIProtocolHandler.h"
 #include "nsReadableUtils.h"
 #include "nsITextToSubURI.h"
 #include "nsJSUtils.h"
-#include "jsfriendapi.h"
 #include "nsContentUtils.h"
 #include "mozilla/Likely.h"
 #include "nsCycleCollectionParticipant.h"
 
 static nsresult
 GetDocumentCharacterSetForURI(const nsAString& aHref, nsACString& aCharset)
 {
   aCharset.Truncate();
--- a/dom/base/nsLocation.h
+++ b/dom/base/nsLocation.h
@@ -4,24 +4,23 @@
  * 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 nsLocation_h__
 #define nsLocation_h__
 
 #include "nsIDOMLocation.h"
 #include "nsString.h"
-#include "nsWeakReference.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIURI;
 class nsIDocShell;
 struct JSContext;
-class nsIDocument;
 class nsIDocShellLoadInfo;
 
 //*****************************************************************************
 // nsLocation: Script "location" object
 //*****************************************************************************
 
 class nsLocation : public nsIDOMLocation
                  , public nsWrapperCache
--- a/dom/base/nsMimeTypeArray.h
+++ b/dom/base/nsMimeTypeArray.h
@@ -3,24 +3,24 @@
 /* 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 nsMimeTypeArray_h___
 #define nsMimeTypeArray_h___
 
 #include "nsString.h"
-#include "nsCOMPtr.h"
 #include "nsTArray.h"
-#include "nsWeakReference.h"
 #include "nsWrapperCache.h"
-#include "nsPluginArray.h"
+#include "nsIWeakReferenceUtils.h"
+#include "nsAutoPtr.h"
 
 class nsPIDOMWindow;
 class nsMimeType;
+class nsPluginElement;
 
 class nsMimeTypeArray MOZ_FINAL : public nsISupports,
                                   public nsWrapperCache
 {
 public:
   nsMimeTypeArray(nsWeakPtr aWindow);
   virtual ~nsMimeTypeArray();
 
--- a/dom/base/nsPerformance.cpp
+++ b/dom/base/nsPerformance.cpp
@@ -1,18 +1,16 @@
 /* -*- 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 "nsPerformance.h"
 #include "TimeStamp.h"
 #include "nsCOMPtr.h"
-#include "nscore.h"
-#include "nsIDocShell.h"
 #include "nsITimedChannel.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsContentUtils.h"
 #include "nsIDOMWindow.h"
 #include "mozilla/dom/PerformanceBinding.h"
 #include "mozilla/dom/PerformanceTimingBinding.h"
 #include "mozilla/dom/PerformanceNavigationBinding.h"
 
--- a/dom/base/nsPerformance.h
+++ b/dom/base/nsPerformance.h
@@ -1,24 +1,22 @@
 /* -*- 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 nsPerformance_h___
 #define nsPerformance_h___
 
-#include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Attributes.h"
 #include "nsWrapperCache.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsContentUtils.h"
 
-class nsIURI;
 class nsITimedChannel;
 class nsIDOMWindow;
 class nsPerformance;
 class JSObject;
 struct JSContext;
 
 // Script "performance.timing" object
 class nsPerformanceTiming MOZ_FINAL : public nsWrapperCache
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -11,19 +11,17 @@
 #include "Navigator.h"
 #include "nsIDocShell.h"
 #include "nsIWebNavigation.h"
 #include "nsPluginHost.h"
 #include "nsPluginTags.h"
 #include "nsIObserverService.h"
 #include "nsIWeakReference.h"
 #include "mozilla/Services.h"
-#include "nsWeakReference.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsPluginArray::nsPluginArray(nsWeakPtr aWindow)
   : mWindow(aWindow)
 {
   SetIsDOMBinding();
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -2,28 +2,25 @@
 /* vim: set ts=2 sw=2 et tw=79: */
 /* 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 nsPluginArray_h___
 #define nsPluginArray_h___
 
-#include "nsString.h"
-#include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "nsIObserver.h"
 #include "nsWrapperCache.h"
 #include "nsPluginTags.h"
 
 class nsPIDOMWindow;
 class nsPluginElement;
 class nsMimeType;
-class nsPluginTag;
 
 class nsPluginArray MOZ_FINAL : public nsIObserver,
                                 public nsSupportsWeakReference,
                                 public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsPluginArray,
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -3,21 +3,19 @@
  * 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/Hal.h"
 #include "nsScreen.h"
 #include "nsIDocShell.h"
 #include "nsPresContext.h"
 #include "nsCOMPtr.h"
-#include "nsDOMClassInfoID.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsLayoutUtils.h"
 #include "nsDOMEvent.h"
-#include "nsGlobalWindow.h"
 #include "nsJSUtils.h"
 #include "mozilla/dom/ScreenBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 namespace {
 
--- a/dom/base/nsScreen.h
+++ b/dom/base/nsScreen.h
@@ -1,29 +1,24 @@
 /* -*- 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 nsScreen_h___
 #define nsScreen_h___
 
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/EventHandlerBinding.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Hal.h"
 #include "nsIDOMScreen.h"
-#include "nsISupports.h"
-#include "nsIScriptContext.h"
 #include "nsCOMPtr.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsRect.h"
 
-class nsIDocShell;
 class nsDeviceContext;
 
 // Script "screen" object
 class nsScreen : public nsDOMEventTargetHelper
                , public nsIDOMScreen
                , public mozilla::hal::ScreenConfigurationObserver
 {
   typedef mozilla::ErrorResult ErrorResult;
--- a/dom/base/nsScriptNameSpaceManager.h
+++ b/dom/base/nsScriptNameSpaceManager.h
@@ -24,16 +24,17 @@
 #include "mozilla/MemoryReporting.h"
 #include "nsIScriptNameSpaceManager.h"
 #include "nsString.h"
 #include "nsID.h"
 #include "pldhash.h"
 #include "nsDOMClassInfo.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
+#include "xpcpublic.h"
 
 
 struct nsGlobalNameStruct
 {
   struct ConstructorAlias
   {
     nsCID mCID;
     nsString mProtoName;
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -10,16 +10,17 @@
 #include "nsIDocument.h"
 #include "nsIEffectiveTLDService.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 #include "nsNetCID.h"
 #include "nsPrintfCString.h"
 #include "XPCJSMemoryReporter.h"
 #include "js/MemoryMetrics.h"
+#include "nsServiceManagerUtils.h"
 
 using namespace mozilla;
 
 nsWindowMemoryReporter::nsWindowMemoryReporter()
   : mCheckForGhostWindowsCallbackPending(false)
 {
   mDetachedWindows.Init();
 }
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -2295,31 +2295,31 @@ AddForDeferredFinalization(T* aObject)
 // This returns T's CC participant if it participates in CC or null if it
 // doesn't. This also returns null for classes that don't inherit from
 // nsISupports (QI should be used to get the participant for those).
 template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
 class GetCCParticipant
 {
   // Helper for GetCCParticipant for classes that participate in CC.
   template<class U>
-  static nsCycleCollectionParticipant*
+  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
   GetHelper(int, typename U::NS_CYCLE_COLLECTION_INNERCLASS* dummy=nullptr)
   {
     return T::NS_CYCLE_COLLECTION_INNERCLASS::GetParticipant();
   }
   // Helper for GetCCParticipant for classes that don't participate in CC.
   template<class U>
-  static nsCycleCollectionParticipant*
+  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
   GetHelper(double)
   {
     return nullptr;
   }
 
 public:
-  static nsCycleCollectionParticipant*
+  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
   Get()
   {
     // Passing int() here will try to call the GetHelper that takes an int as
     // its firt argument. If T doesn't participate in CC then substitution for
     // the second argument (with a default value) will fail and because of
     // SFINAE the next best match (the variant taking a double) will be called.
     return GetHelper<T>(int());
   }
--- a/dom/camera/DOMCameraManager.cpp
+++ b/dom/camera/DOMCameraManager.cpp
@@ -75,17 +75,16 @@ nsDOMCameraManager::CheckPermission(nsPI
 {
   nsCOMPtr<nsIPermissionManager> permMgr =
     do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
   NS_ENSURE_TRUE(permMgr, false);
 
   uint32_t permission = nsIPermissionManager::DENY_ACTION;
   permMgr->TestPermissionFromWindow(aWindow, "camera", &permission);
   if (permission != nsIPermissionManager::ALLOW_ACTION) {
-    NS_WARNING("No permission to access camera");
     return false;
   }
 
   return true;
 }
 
 // static creator
 already_AddRefed<nsDOMCameraManager>
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -19,17 +19,16 @@
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/dom/quota/Utilities.h"
 #include "mozilla/dom/TabContext.h"
 #include "mozilla/Services.h"
 #include "mozilla/storage.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsThreadUtils.h"
-#include "pratom.h"
 
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IDBKeyRange.h"
 #include "IDBRequest.h"
 
 // The two possible values for the data argument when receiving the disk space
 // observer notification.
@@ -41,18 +40,18 @@ using namespace mozilla::dom;
 USING_QUOTA_NAMESPACE
 
 static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 namespace {
 
 mozilla::StaticRefPtr<IndexedDatabaseManager> gInstance;
 
-int32_t gInitialized = 0;
-int32_t gClosed = 0;
+mozilla::Atomic<int32_t> gInitialized(0);
+mozilla::Atomic<int32_t> gClosed(0);
 
 class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIRUNNABLE
 
   AsyncDeleteFileRunnable(FileManager* aFileManager, int64_t aFileId);
@@ -136,17 +135,17 @@ IndexedDatabaseManager::IndexedDatabaseM
 }
 
 IndexedDatabaseManager::~IndexedDatabaseManager()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 bool IndexedDatabaseManager::sIsMainProcess = false;
-int32_t IndexedDatabaseManager::sLowDiskSpaceMode = 0;
+mozilla::Atomic<int32_t> IndexedDatabaseManager::sLowDiskSpaceMode(0);
 
 // static
 IndexedDatabaseManager*
 IndexedDatabaseManager::GetOrCreate()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (IsClosed()) {
@@ -175,17 +174,17 @@ IndexedDatabaseManager::GetOrCreate()
       }
     }
 
     nsRefPtr<IndexedDatabaseManager> instance(new IndexedDatabaseManager());
 
     nsresult rv = instance->Init();
     NS_ENSURE_SUCCESS(rv, nullptr);
 
-    if (PR_ATOMIC_SET(&gInitialized, 1)) {
+    if (gInitialized.exchange(1)) {
       NS_ERROR("Initialized more than once?!");
     }
 
     gInstance = instance;
 
     ClearOnShutdown(&gInstance);
   }
 
@@ -239,17 +238,17 @@ IndexedDatabaseManager::Init()
   return NS_OK;
 }
 
 void
 IndexedDatabaseManager::Destroy()
 {
   // Setting the closed flag prevents the service from being recreated.
   // Don't set it though if there's no real instance created.
-  if (!!gInitialized && PR_ATOMIC_SET(&gClosed, 1)) {
+  if (!!gInitialized && gClosed.exchange(1)) {
     NS_ERROR("Shutdown more than once?!");
   }
 
   delete this;
 }
 
 // static
 nsresult
@@ -584,20 +583,20 @@ IndexedDatabaseManager::Observe(nsISuppo
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!strcmp(aTopic, DISKSPACEWATCHER_OBSERVER_TOPIC)) {
     NS_ASSERTION(aData, "No data?!");
 
     const nsDependentString data(aData);
 
     if (data.EqualsLiteral(LOW_DISK_SPACE_DATA_FULL)) {
-      PR_ATOMIC_SET(&sLowDiskSpaceMode, 1);
+      sLowDiskSpaceMode = 1;
     }
     else if (data.EqualsLiteral(LOW_DISK_SPACE_DATA_FREE)) {
-      PR_ATOMIC_SET(&sLowDiskSpaceMode, 0);
+      sLowDiskSpaceMode = 0;
     }
     else {
       NS_NOTREACHED("Unknown data value!");
     }
 
     return NS_OK;
   }
 
--- a/dom/indexedDB/IndexedDatabaseManager.h
+++ b/dom/indexedDB/IndexedDatabaseManager.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_indexeddb_indexeddatabasemanager_h__
 #define mozilla_dom_indexeddb_indexeddatabasemanager_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
 #include "nsIIndexedDatabaseManager.h"
 #include "nsIObserver.h"
 
+#include "mozilla/Atomics.h"
 #include "mozilla/Mutex.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 
 #define INDEXEDDB_MANAGER_CONTRACTID "@mozilla.org/dom/indexeddb/manager;1"
 
 class nsIAtom;
 class nsPIDOMWindow;
@@ -141,14 +142,14 @@ private:
                    nsTArray<nsRefPtr<FileManager> > > mFileManagers;
 
   // Lock protecting FileManager.mFileInfos and nsDOMFileBase.mFileInfos
   // It's s also used to atomically update FileInfo.mRefCnt, FileInfo.mDBRefCnt
   // and FileInfo.mSliceRefCnt
   mozilla::Mutex mFileMutex;
 
   static bool sIsMainProcess;
-  static int32_t sLowDiskSpaceMode;
+  static mozilla::Atomic<int32_t> sLowDiskSpaceMode;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -25,16 +25,19 @@
 #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 "nsIMemoryReporter.h"
 #include "nsIMemoryInfoDumper.h"
 #include "nsIMutable.h"
 #include "nsIObserverService.h"
 #include "nsTObserverArray.h"
 #include "nsIObserver.h"
@@ -541,16 +544,23 @@ ContentChild::AllocPImageBridgeChild(moz
 bool
 ContentChild::RecvSetProcessPrivileges(const ChildPrivileges& aPrivs)
 {
   ChildPrivileges privs = (aPrivs == PRIVILEGES_DEFAULT) ?
                           GeckoChildProcessHost::DefaultChildPrivileges() :
                           aPrivs;
   // If this fails, we die.
   SetCurrentProcessPrivileges(privs);
+#ifdef MOZ_CONTENT_SANDBOX
+  // SetCurrentProcessSandbox should be moved close to process initialization
+  // time if/when possible. SetCurrentProcessPrivileges should probably be
+  // moved as well. Right now this is set ONLY if we receive the
+  // RecvSetProcessPrivileges message. See bug 880808.
+  SetCurrentProcessSandbox();
+#endif
   return true;
 }
 
 static CancelableTask* sFirstIdleTask;
 
 static void FirstIdle(void)
 {
     MOZ_ASSERT(sFirstIdleTask);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2447,33 +2447,16 @@ ContentParent::RecvCloseAlert(const nsSt
     if (sysAlerts) {
         sysAlerts->CloseAlert(aName);
     }
 
     return true;
 }
 
 bool
-ContentParent::RecvTestPermissionFromPrincipal(const IPC::Principal& aPrincipal,
-                                               const nsCString& aType,
-                                               uint32_t* permission)
-{
-    nsCOMPtr<nsIPermissionManager> permissionManager =
-        do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
-    NS_ENSURE_TRUE(permissionManager, false);
-
-    nsresult rv = permissionManager->TestPermissionFromPrincipal(aPrincipal,
-                                                                 aType.get(),
-                                                                 permission);
-    NS_ENSURE_SUCCESS(rv, false);
-
-    return true;
-}
-
-bool
 ContentParent::RecvSyncMessage(const nsString& aMsg,
                                const ClonedMessageData& aData,
                                const InfallibleTArray<CpowEntry>& aCpows,
                                InfallibleTArray<nsString>* aRetvals)
 {
   nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -366,20 +366,16 @@ private:
 
     virtual bool RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
                                            const nsString& aText, const bool& aTextClickable,
                                            const nsString& aCookie, const nsString& aName,
                                            const nsString& aBidi, const nsString& aLang);
 
     virtual bool RecvCloseAlert(const nsString& aName);
 
-    virtual bool RecvTestPermissionFromPrincipal(const IPC::Principal& aPrincipal,
-                                                 const nsCString& aType,
-                                                 uint32_t* permission);
-
     virtual bool RecvLoadURIExternal(const URIParams& uri);
 
     virtual bool RecvSyncMessage(const nsString& aMsg,
                                  const ClonedMessageData& aData,
                                  const InfallibleTArray<CpowEntry>& aCpows,
                                  InfallibleTArray<nsString>* aRetvals);
     virtual bool RecvAsyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -339,32 +339,16 @@ parent:
                           bool textClickable,
                           nsString cookie,
                           nsString name,
                           nsString bidi,
                           nsString lang);
 
     CloseAlert(nsString name);
 
-    /**
-     * Tests permission for a provided principal using the permission
-     * manager.
-     *
-     * @param principal
-     *   The principal to test for the permissions.
-     * @param type
-     *   The type of permission to for the principal.
-     *
-     * NOTE: The principal is untrusted in the parent process. Only
-     *       principals that can live in the content process should
-     *       be provided.
-     */
-    sync TestPermissionFromPrincipal(Principal principal, nsCString type)
-        returns (uint32_t permission);
-
     PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType,
                        nsCString aContentDisposition, bool aForceSave,
                        int64_t aContentLength, OptionalURIParams aReferrer);
 
     AddGeolocationListener(Principal principal, bool highAccuracy);
     RemoveGeolocationListener();
     SetGeolocationHigherAccuracy(bool enable);
 
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -8,16 +8,18 @@
 #include "nsIDOMFile.h"
 #include "nsIEventTarget.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIPopupWindowManager.h"
 #include "nsISupportsArray.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIInterfaceRequestorUtils.h"
 
 // For PR_snprintf
 #include "prprf.h"
 
 #include "nsJSUtils.h"
 #include "nsDOMFile.h"
 #include "nsGlobalWindow.h"
 
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -18,30 +18,30 @@
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsITimer.h"
 #include "nsIURI.h"
 #include "nsIUsageCallback.h"
 
 #include <algorithm>
 #include "GeckoProfiler.h"
+#include "mozilla/Atomics.h"
 #include "mozilla/dom/file/FileService.h"
 #include "mozilla/dom/indexedDB/Client.h"
 #include "mozilla/LazyIdleThread.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsCRTGlue.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsScriptSecurityManager.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
-#include "pratom.h"
 #include "xpcpublic.h"
 
 #include "AcquireListener.h"
 #include "CheckQuotaHelper.h"
 #include "OriginOrPatternString.h"
 #include "QuotaObject.h"
 #include "StorageMatcher.h"
 #include "UsageRunnable.h"
@@ -255,17 +255,17 @@ AssertIsOnIOThread()
 }
 #endif
 
 END_QUOTA_NAMESPACE
 
 namespace {
 
 QuotaManager* gInstance = nullptr;
-int32_t gShutdown = 0;
+mozilla::Atomic<uint32_t> gShutdown(0);
 
 int32_t gStorageQuotaMB = DEFAULT_QUOTA_MB;
 
 // A callback runnable used by the TransactionPool when it's safe to proceed
 // with a SetVersion/DeleteDatabase/etc.
 class WaitForTransactionsToFinishRunnable MOZ_FINAL : public nsIRunnable
 {
 public:
@@ -1195,17 +1195,17 @@ QuotaManager::Observe(nsISupports* aSubj
                       const char* aTopic,
                       const PRUnichar* aData)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_OBSERVER_ID)) {
     // Setting this flag prevents the service from being recreated and prevents
     // further storagess from being created.
-    if (PR_ATOMIC_SET(&gShutdown, 1)) {
+    if (gShutdown.exchange(1)) {
       NS_ERROR("Shutdown more than once?!");
     }
 
     if (IsMainProcess()) {
       FileService* service = FileService::Get();
       if (service) {
         // This should only wait for storages registered in this manager
         // to complete. Other storages may still have running locked files.
@@ -2166,17 +2166,17 @@ AsyncUsageRunnable::Run()
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AsyncUsageRunnable::Cancel()
 {
-  if (PR_ATOMIC_SET(&mCanceled, 1)) {
+  if (mCanceled.exchange(1)) {
     NS_WARNING("Canceled more than once?!");
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS1(WaitForTransactionsToFinishRunnable, nsIRunnable)
--- a/dom/quota/UsageRunnable.h
+++ b/dom/quota/UsageRunnable.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_quota_usagerunnable_h__
 #define mozilla_dom_quota_usagerunnable_h__
 
 #include "mozilla/dom/quota/QuotaCommon.h"
 
+#include "mozilla/Atomics.h"
 #include "Utilities.h"
 
 BEGIN_QUOTA_NAMESPACE
 
 class UsageRunnable
 {
 public:
   UsageRunnable()
@@ -64,17 +65,17 @@ public:
   void
   ResetUsage()
   {
     mDatabaseUsage = 0;
     mFileUsage = 0;
   }
 
 protected:
-  int32_t mCanceled;
+  mozilla::Atomic<int32_t> mCanceled;
 
 private:
   uint64_t mDatabaseUsage;
   uint64_t mFileUsage;
 };
 
 END_QUOTA_NAMESPACE
 
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -1,57 +1,35 @@
 /* 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 "nsContentPermissionHelper.h"
 #include "nsXULAppAPI.h"
 
-#include "mozilla/dom/PBrowserChild.h"
-#include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/dom/ContentChild.h"
-#include "nsNetUtil.h"
-
-#include "nsFrameManager.h"
-#include "nsFrameLoader.h"
-#include "nsIFrameLoader.h"
-
-#include "nsIDocShellTreeOwner.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsIWebProgressListener2.h"
+#include "mozilla/dom/TabChild.h"
 
 #include "nsISettingsService.h"
 
-#include "nsDOMEventTargetHelper.h"
-#include "TabChild.h"
-
 #include "nsGeolocation.h"
-#include "nsAutoPtr.h"
-#include "nsCOMPtr.h"
-#include "nsIDOMWindow.h"
 #include "nsDOMClassInfoID.h"
 #include "nsComponentManagerUtils.h"
-#include "nsICategoryManager.h"
-#include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
-#include "nsIURI.h"
-#include "nsIPermissionManager.h"
+#include "nsIDocument.h"
 #include "nsIObserverService.h"
+#include "nsPIDOMWindow.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/Attributes.h"
 #include "mozilla/ClearOnShutdown.h"
 
-#include <math.h>
-#include <algorithm>
-#include <limits>
+class nsIPrincipal;
 
 #ifdef MOZ_MAEMO_LIBLOCATION
 #include "MaemoLocationProvider.h"
 #endif
 
 #ifdef MOZ_ENABLE_QTMOBILITY
 #include "QTMLocationProvider.h"
 #endif
@@ -63,18 +41,16 @@
 #ifdef MOZ_WIDGET_GONK
 #include "GonkGPSGeolocationProvider.h"
 #endif
 
 #ifdef MOZ_WIDGET_COCOA
 #include "CoreLocationLocationProvider.h"
 #endif
 
-#include "nsIDocument.h"
-
 // Some limit to the number of get or watch geolocation requests
 // that a window can make.
 #define MAX_GEO_REQUESTS_PER_WINDOW  1500
 
 // The settings key.
 #define GEO_SETINGS_ENABLED          "geolocation.enabled"
 
 using mozilla::unused;          // <snicker>
@@ -410,21 +386,16 @@ nsGeolocationRequest::Cancel()
 {
   NotifyError(nsIDOMGeoPositionError::PERMISSION_DENIED);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::Allow()
 {
-  nsCOMPtr<nsIDOMWindow> window;
-  GetWindow(getter_AddRefs(window));
-  nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(window);
-  nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
-
   // Kick off the geo device, if it isn't already running
   nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
   nsresult rv = gs->StartDevice(GetPrincipal());
 
   if (NS_FAILED(rv)) {
     // Location provider error
     NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
     return NS_OK;
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -1,51 +1,47 @@
 /* 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 nsGeoLocation_h
 #define nsGeoLocation_h
 
-#include "mozilla/dom/PContentPermissionRequestChild.h"
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
 #include "mozilla/StaticPtr.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
-#include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
 #include "nsIObserver.h"
-#include "nsIURI.h"
 #include "nsWrapperCache.h"
 
 #include "nsWeakPtr.h"
 #include "nsCycleCollectionParticipant.h"
 
 #include "nsGeoPosition.h"
 #include "nsIDOMGeoGeolocation.h"
 #include "nsIDOMGeoPosition.h"
 #include "nsIDOMGeoPositionError.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIDOMGeoPositionErrorCallback.h"
 #include "mozilla/dom/GeolocationBinding.h"
 #include "mozilla/dom/PositionErrorBinding.h"
 #include "mozilla/dom/CallbackObject.h"
 
-#include "nsPIDOMWindow.h"
-
 #include "nsIGeolocationProvider.h"
 #include "nsIContentPermissionPrompt.h"
 #include "DictionaryHelpers.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "mozilla/Attributes.h"
 
 class nsGeolocationService;
+class nsIDOMWindow;
 
 namespace mozilla {
 namespace dom {
 class Geolocation;
 typedef CallbackObjectHolder<PositionCallback, nsIDOMGeoPositionCallback> GeoPositionCallback;
 typedef CallbackObjectHolder<PositionErrorCallback, nsIDOMGeoPositionErrorCallback> GeoPositionErrorCallback;
 }
 }
--- a/dom/src/notification/Notification.cpp
+++ b/dom/src/notification/Notification.cpp
@@ -1,16 +1,14 @@
 /* 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 "PCOMContentPermissionRequestChild.h"
-#include "mozilla/dom/PBrowserChild.h"
 #include "mozilla/dom/Notification.h"
-#include "mozilla/dom/ContentChild.h"
 #include "mozilla/Preferences.h"
 #include "TabChild.h"
 #include "nsContentUtils.h"
 #include "nsDOMEvent.h"
 #include "nsIAlertsService.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsIDocument.h"
 #include "nsIPermissionManager.h"
@@ -428,30 +426,22 @@ Notification::GetPermissionInternal(nsIS
       return NotificationPermission::Granted;
     } else {
       return NotificationPermission::Denied;
     }
   }
 
   uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
 
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    ContentChild* cpc = ContentChild::GetSingleton();
+  nsCOMPtr<nsIPermissionManager> permissionManager =
+    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
 
-    cpc->SendTestPermissionFromPrincipal(IPC::Principal(principal),
-                                         NS_LITERAL_CSTRING("desktop-notification"),
-                                         &permission);
-  } else {
-    nsCOMPtr<nsIPermissionManager> permissionManager =
-      do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
-
-    permissionManager->TestPermissionFromPrincipal(principal,
-                                                   "desktop-notification",
-                                                   &permission);
-  }
+  permissionManager->TestPermissionFromPrincipal(principal,
+                                                 "desktop-notification",
+                                                 &permission);
 
   // Convert the result to one of the enum types.
   switch (permission) {
   case nsIPermissionManager::ALLOW_ACTION:
     return NotificationPermission::Granted;
   case nsIPermissionManager::DENY_ACTION:
     return NotificationPermission::Denied;
   default:
--- a/dom/tests/mochitest/ajax/offline/Makefile.in
+++ b/dom/tests/mochitest/ajax/offline/Makefile.in
@@ -8,97 +8,18 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir	= @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES	= \
 	offlineTests.js \
-	test_badManifestMagic.html \
-	test_bypass.html \
-	test_missingFile.html \
-	test_noManifest.html \
-	test_simpleManifest.html \
-	test_identicalManifest.html \
-	test_changingManifest.html \
-	test_refetchManifest.html \
-	test_offlineIFrame.html \
 	test_bug445544.html \
-	test_bug460353.html \
-	test_bug474696.html \
-	test_bug544462.html \
-	test_bug744719.html \
-	744719.cacheManifest \
-	744719.cacheManifest^headers^ \
-	test_bug765203.html \
-	unknownSection.cacheManifest \
-	unknownSection.cacheManifest^headers^ \
-	test_bug744719-cancel.html \
-	744719-cancel.cacheManifest \
-	744719-cancel.cacheManifest^headers^ \
-	subresource744719.html \
-	test_foreign.html \
-	test_fallback.html \
-	test_overlap.html \
-	test_redirectManifest.html \
-	test_redirectUpdateItem.html \
-	overlap.cacheManifest \
-	overlap.cacheManifest^headers^ \
-	test_updatingManifest.html \
-	test_updateCheck.html \
 	445544_part1.html \
 	445544_part2.html \
 	445544.cacheManifest \
 	445544.cacheManifest^headers^ \
-	460353_iframe_nomanifest.html \
-	460353_iframe_ownmanifest.html \
-	460353_iframe_samemanifest.html \
-	test_obsolete.html \
-	obsolete.html \
-	obsoletingManifest.sjs \
-	badManifestMagic.cacheManifest \
-	badManifestMagic.cacheManifest^headers^ \
-	bypass.cacheManifest \
-	bypass.cacheManifest^headers^ \
-	bypass.html \
-	dynamicRedirect.sjs \
-	explicitRedirect.sjs \
-	fallback.html \
-	fallback2.html \
-	fallbackTop.html \
-	fallback.cacheManifest \
-	fallback.cacheManifest^headers^ \
-	foreign1.cacheManifest \
-	foreign1.cacheManifest^headers^ \
-	foreign2.cacheManifest \
-	foreign2.cacheManifest^headers^ \
-	foreign2.html \
-	notonwhitelist.html \
-	onwhitelist.html \
-	onwhitelist.html^headers^ \
-	updatingIframe.sjs \
-	updatingImplicit.html \
-	manifestRedirect.sjs \
-	missingFile.cacheManifest \
-	missingFile.cacheManifest^headers^ \
-	redirects.sjs \
-	simpleManifest.cacheManifest \
-	simpleManifest.cacheManifest^headers^ \
-	wildcardManifest.cacheManifest \
-	wildcardManifest.cacheManifest^headers^ \
-	updatingManifest.sjs \
-	changing1Sec.sjs \
-	changing1Hour.sjs \
-	changingManifest.sjs \
-	offlineChild.html \
-	test_xhtmlManifest.xhtml \
-	test_missingManifest.html \
-	missing.html \
-	jupiter.jpg \
-	test_cancelOfflineCache.html \
-	test_lowDeviceStorage.html \
-	test_lowDeviceStorageDuringUpdate.html \
 	$(NULL)
 
 # test_offlineMode.html disabled due to bug 656943
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -64,16 +64,19 @@ interface WebGL2RenderingContext : WebGL
     const GLenum QUERY_RESULT                = 0x8866;
     const GLenum QUERY_RESULT_AVAILABLE      = 0x8867;
 
     /* instanced array */
     const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
 
     void vertexAttribDivisor(GLuint index, GLuint divisor);
 
+    /* transform feedback */
+    const GLenum RASTERIZER_DISCARD          = 0x8C89;
+
 
     void beginQuery(GLenum target, WebGLQuery? queryObject);
     void bindVertexArray(WebGLVertexArray? arrayObject);
     WebGLQuery? createQuery();
     WebGLVertexArray? createVertexArray();
     void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
     void drawBuffers(sequence<GLenum> buffers);
     void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount);
--- a/gfx/2d/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_BASERECT_H_
 #define MOZILLA_GFX_BASERECT_H_
 
 #include <cmath>
 #include <mozilla/Assertions.h>
 #include <algorithm>
-#include "nsMathUtils.h"
 
 namespace mozilla {
 namespace gfx {
 
 /**
  * Rectangles have two interpretations: a set of (zero-size) points,
  * and a rectangular area of the plane. Most rectangle operations behave
  * the same no matter what interpretation is being used, but some operations
@@ -55,20 +54,20 @@ struct BaseRect {
   // Emptiness. An empty rect is one that has no area, i.e. its height or width
   // is <= 0
   bool IsEmpty() const { return height <= 0 || width <= 0; }
   void SetEmpty() { width = height = 0; }
 
   // "Finite" means not inf and not NaN
   bool IsFinite() const
   {
-    return (NS_finite(x) &&
-            NS_finite(y) &&
-            NS_finite(width) &&
-            NS_finite(height));
+    return (std::isfinite(x) &&
+            std::isfinite(y) &&
+            std::isfinite(width) &&
+            std::isfinite(height));
   }
 
   // Returns true if this rectangle contains the interior of aRect. Always
   // returns true if aRect is empty, and always returns false is aRect is
   // nonempty but this rect is empty.
   bool Contains(const Sub& aRect) const
   {
     return aRect.IsEmpty() ||
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -49,24 +49,26 @@ static const char *sExtensionNames[] = {
     "GL_ARB_framebuffer_object",
     "GL_ARB_texture_rectangle",
     "GL_EXT_bgra",
     "GL_EXT_texture_format_BGRA8888",
     "GL_OES_depth24",
     "GL_OES_depth32",
     "GL_OES_stencil8",
     "GL_OES_texture_npot",
+    "GL_ARB_depth_texture",
     "GL_OES_depth_texture",
     "GL_OES_packed_depth_stencil",
     "GL_IMG_read_format",
     "GL_EXT_read_format_bgra",
     "GL_APPLE_client_storage",
     "GL_ARB_texture_non_power_of_two",
     "GL_ARB_pixel_buffer_object",
     "GL_ARB_ES2_compatibility",
+    "GL_ARB_ES3_compatibility",
     "GL_OES_texture_float",
     "GL_OES_texture_float_linear",
     "GL_ARB_texture_float",
     "GL_EXT_unpack_subimage",
     "GL_OES_standard_derivatives",
     "GL_EXT_texture_filter_anisotropic",
     "GL_EXT_texture_compression_s3tc",
     "GL_EXT_texture_compression_dxt1",
@@ -96,16 +98,19 @@ static const char *sExtensionNames[] = {
     "GL_EXT_blend_minmax",
     "GL_ARB_draw_instanced",
     "GL_EXT_draw_instanced",
     "GL_NV_draw_instanced",
     "GL_ARB_instanced_arrays",
     "GL_NV_instanced_arrays",
     "GL_ANGLE_instanced_arrays",
     "GL_EXT_occlusion_query_boolean",
+    "GL_ARB_occlusion_query2",
+    "GL_EXT_transform_feedback",
+    "GL_NV_transform_feedback",
     nullptr
 };
 
 static int64_t sTextureMemoryUsage = 0;
 
 static int64_t
 GetTextureMemoryUsage()
 {
@@ -312,24 +317,16 @@ GLContext::InitWithPrefix(const char *pr
         } else {
             SymLoadStruct symbols_desktop[] = {
                 { (PRFuncPtr*) &mSymbols.fClearDepth, { "ClearDepth", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDepthRange, { "DepthRange", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fMapBuffer, { "MapBuffer", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fPointParameterf, { "PointParameterf", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectiv", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", nullptr } },
-                { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQuery", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDrawBuffer, { "DrawBuffer", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(&symbols_desktop[0], trygl, prefix)) {
                 NS_ERROR("Desktop symbols failed to load.");
                 mInitialized = false;
@@ -652,44 +649,60 @@ GLContext::InitWithPrefix(const char *pr
             if (!LoadSymbols(instancedArraySymbols, trygl, prefix)) {
                 NS_ERROR("GL supports array instanced without supplying it function.");
 
                 mInitialized &= MarkExtensionGroupUnsupported(XXX_instanced_arrays);
                 mSymbols.fVertexAttribDivisor = nullptr;
             }
         }
 
-        if (IsGLES2() &&
-            IsExtensionSupported(EXT_occlusion_query_boolean)) {
+        if (IsExtensionSupported(XXX_query_objects)) {
             SymLoadStruct queryObjectsSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", "BeginQueryEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", "GenQueriesEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", "DeleteQueriesEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", "EndQueryEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", "GetQueryivEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", "GetQueryObjectuivEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQuery", "IsQueryEXT", nullptr } },
                 { nullptr, { nullptr } },
             };
 
             if (!LoadSymbols(queryObjectsSymbols, trygl, prefix)) {
-                NS_ERROR("GL ES supports query objects without supplying its functions.");
-
-                MarkExtensionUnsupported(EXT_occlusion_query_boolean);
+                NS_ERROR("GL supports query objects without supplying its functions.");
+
+                mInitialized &= MarkExtensionGroupUnsupported(XXX_query_objects);
+                mInitialized &= MarkExtensionGroupUnsupported(XXX_get_query_object_iv);
+                mInitialized &= MarkExtensionGroupUnsupported(XXX_occlusion_query);
+                MarkExtensionGroupUnsupported(XXX_occlusion_query_boolean);
+                MarkExtensionGroupUnsupported(XXX_occlusion_query2);
                 mSymbols.fBeginQuery = nullptr;
                 mSymbols.fGenQueries = nullptr;
                 mSymbols.fDeleteQueries = nullptr;
                 mSymbols.fEndQuery = nullptr;
                 mSymbols.fGetQueryiv = nullptr;
-                mSymbols.fGetQueryObjectiv = nullptr;
                 mSymbols.fGetQueryObjectuiv = nullptr;
                 mSymbols.fIsQuery = nullptr;
             }
         }
 
+        if (IsExtensionSupported(XXX_get_query_object_iv)) {
+            SymLoadStruct queryObjectsSymbols[] = {
+                { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectiv", "GetQueryObjectivEXT", nullptr } },
+                { nullptr, { nullptr } },
+            };
+
+            if (!LoadSymbols(queryObjectsSymbols, trygl, prefix)) {
+                NS_ERROR("GL supports query objects iv getter without supplying its function.");
+
+                mInitialized &= MarkExtensionGroupUnsupported(XXX_get_query_object_iv);
+                mSymbols.fGetQueryObjectiv = nullptr;
+            }
+        }
+
 
         // Load developer symbols, don't fail if we can't find them.
         SymLoadStruct auxSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } },
                 { nullptr, { nullptr } },
         };
         bool warnOnFailures = DebugMode();
@@ -2951,17 +2964,17 @@ void
 GLContext::CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames)
 {
     for (GLsizei i = 0; i < aCount; ++i) {
         mTrackedRenderbuffers.AppendElement(NamedResource(aOrigin, aNames[i]));
     }
 }
 
 static void
-RemoveNamesFromArray(GLContext *aOrigin, GLsizei aCount, GLuint *aNames, nsTArray<GLContext::NamedResource>& aArray)
+RemoveNamesFromArray(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames, nsTArray<GLContext::NamedResource>& aArray)
 {
     for (GLsizei j = 0; j < aCount; ++j) {
         GLuint name = aNames[j];
         // name 0 can be ignored
         if (name == 0)
             continue;
 
         for (uint32_t i = 0; i < aArray.Length(); ++i) {
@@ -2987,17 +3000,17 @@ GLContext::DeletedShader(GLContext *aOri
 
 void
 GLContext::DeletedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames)
 {
     RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedBuffers);
 }
 
 void
-GLContext::DeletedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames)
+GLContext::DeletedQueries(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames)
 {
     RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedQueries);
 }
 
 void
 GLContext::DeletedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames)
 {
     RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedTextures);
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -268,24 +268,16 @@ public:
      * If this context is the GLES2 API, returns TRUE.
      * This means that various GLES2 restrictions might be in effect (modulo
      * extensions).
      */
     inline bool IsGLES2() const {
         return IsAtLeast(ContextProfile::OpenGLES, 200);
     }
 
-    /**
-     * Returns true if either this is the GLES2 API, or had the GL_ARB_ES2_compatibility extension
-     * We would like to introduce a XXX_ES2_compatibility
-     */
-    bool HasES2Compatibility() const {
-        return IsGLES2() || IsExtensionSupported(ARB_ES2_compatibility);
-    }
-
 
 protected:
 
     bool mInitialized;
     bool mIsOffscreen;
     bool mIsGlobalSharedContext;
     bool mContextLost;
 
@@ -332,24 +324,26 @@ public:
         ARB_framebuffer_object,
         ARB_texture_rectangle,
         EXT_bgra,
         EXT_texture_format_BGRA8888,
         OES_depth24,
         OES_depth32,
         OES_stencil8,
         OES_texture_npot,
+        ARB_depth_texture,
         OES_depth_texture,
         OES_packed_depth_stencil,
         IMG_read_format,
         EXT_read_format_bgra,
         APPLE_client_storage,
         ARB_texture_non_power_of_two,
         ARB_pixel_buffer_object,
         ARB_ES2_compatibility,
+        ARB_ES3_compatibility,
         OES_texture_float,
         OES_texture_float_linear,
         ARB_texture_float,
         EXT_unpack_subimage,
         OES_standard_derivatives,
         EXT_texture_filter_anisotropic,
         EXT_texture_compression_s3tc,
         EXT_texture_compression_dxt1,
@@ -379,16 +373,19 @@ public:
         EXT_blend_minmax,
         ARB_draw_instanced,
         EXT_draw_instanced,
         NV_draw_instanced,
         ARB_instanced_arrays,
         NV_instanced_arrays,
         ANGLE_instanced_arrays,
         EXT_occlusion_query_boolean,
+        ARB_occlusion_query2,
+        EXT_transform_feedback,
+        NV_transform_feedback,
         Extensions_Max,
         Extensions_End
     };
 
     bool IsExtensionSupported(GLExtensions aKnownExtension) const {
         return mAvailableExtensions[aKnownExtension];
     }
 
@@ -472,25 +469,38 @@ protected:
  * regardless if it is an ARB, EXT, OES, etc.
  */
 public:
 
     /**
      * This enum should be sorted by name.
      */
     enum GLExtensionGroup {
+        XXX_depth_texture,
         XXX_draw_buffers,
         XXX_draw_instanced,
+        XXX_element_index_uint,
+        XXX_ES2_compatibility,
+        XXX_ES3_compatibility,
         XXX_framebuffer_blit,
         XXX_framebuffer_multisample,
         XXX_framebuffer_object,
+        XXX_get_query_object_iv,
         XXX_instanced_arrays,
+        XXX_occlusion_query,
+        XXX_occlusion_query_boolean,
+        XXX_occlusion_query2,
+        XXX_packed_depth_stencil,
+        XXX_query_objects,
         XXX_robustness,
+        XXX_standard_derivatives,
         XXX_texture_float,
+        XXX_texture_float_linear,
         XXX_texture_non_power_of_two,
+        XXX_transform_feedback,
         XXX_vertex_array_object,
         ExtensionGroup_Max
     };
 
     bool IsExtensionSupported(GLExtensionGroup extensionGroup) const;
 
     static const char* GetExtensionGroupName(GLExtensionGroup extensionGroup);
 
@@ -1039,37 +1049,16 @@ public:
 
     GLint fGetAttribLocation (GLuint program, const GLchar* name) {
         BEFORE_GL_CALL;
         GLint retval = mSymbols.fGetAttribLocation(program, name);
         AFTER_GL_CALL;
         return retval;
     }
 
-    void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fGetQueryiv);
-        mSymbols.fGetQueryiv(target, pname, params);
-        AFTER_GL_CALL;
-    }
-
-    void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
-        mSymbols.fGetQueryObjectiv(id, pname, params);
-        AFTER_GL_CALL;
-    }
-
-    void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
-        mSymbols.fGetQueryObjectuiv(id, pname, params);
-        AFTER_GL_CALL;
-    }
-
 private:
     void raw_fGetIntegerv(GLenum pname, GLint *params) {
         BEFORE_GL_CALL;
         mSymbols.fGetIntegerv(pname, params);
         AFTER_GL_CALL;
     }
 
 public:
@@ -1268,24 +1257,16 @@ public:
 
     realGLboolean fIsProgram(GLuint program) {
         BEFORE_GL_CALL;
         realGLboolean retval = mSymbols.fIsProgram(program);
         AFTER_GL_CALL;
         return retval;
     }
 
-    realGLboolean fIsQuery(GLuint query) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fIsQuery);
-        realGLboolean retval = mSymbols.fIsQuery(query);
-        AFTER_GL_CALL;
-        return retval;
-    }
-
     realGLboolean fIsShader(GLuint shader) {
         BEFORE_GL_CALL;
         realGLboolean retval = mSymbols.fIsShader(shader);
         AFTER_GL_CALL;
         return retval;
     }
 
     realGLboolean fIsTexture(GLuint texture) {
@@ -1836,23 +1817,16 @@ private:
     }
 
     void GLAPIENTRY raw_fGenFramebuffers(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenFramebuffers(n, names);
         AFTER_GL_CALL;
     }
 
-    void GLAPIENTRY raw_fGenQueries(GLsizei n, GLuint* names) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fGenQueries);
-        mSymbols.fGenQueries(n, names);
-        AFTER_GL_CALL;
-    }
-
     void GLAPIENTRY raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
         mSymbols.fGenRenderbuffers(n, names);
         AFTER_GL_CALL;
     }
 
     void GLAPIENTRY raw_fGenTextures(GLsizei n, GLuint* names) {
         BEFORE_GL_CALL;
@@ -1878,21 +1852,16 @@ public:
         TRACKING_CONTEXT(CreatedBuffers(this, n, names));
     }
 
     void fGenFramebuffers(GLsizei n, GLuint* names) {
         raw_fGenFramebuffers(n, names);
         TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
     }
 
-    void fGenQueries(GLsizei n, GLuint* names) {
-        raw_fGenQueries(n, names);
-        TRACKING_CONTEXT(CreatedQueries(this, n, names));
-    }
-
     void fGenRenderbuffers(GLsizei n, GLuint* names) {
         raw_fGenRenderbuffers(n, names);
         TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
     }
 
     void fGenTextures(GLsizei n, GLuint* names) {
         raw_fGenTextures(n, names);
         TRACKING_CONTEXT(CreatedTextures(this, n, names));
@@ -1930,28 +1899,17 @@ private:
     }
 
     void GLAPIENTRY raw_fDeleteTextures(GLsizei n, GLuint *names) {
         BEFORE_GL_CALL;
         mSymbols.fDeleteTextures(n, names);
         AFTER_GL_CALL;
     }
 
-    void GLAPIENTRY raw_fDeleteQueries(GLsizei n, GLuint* names) {
-        BEFORE_GL_CALL;
-        ASSERT_SYMBOL_PRESENT(fDeleteQueries);
-        mSymbols.fDeleteQueries(n, names);
-        AFTER_GL_CALL;
-    }
-
 public:
-    void GLAPIENTRY fDeleteQueries(GLsizei n, GLuint* names) {
-        raw_fDeleteQueries(n, names);
-        TRACKING_CONTEXT(DeletedQueries(this, n, names));
-    }
 
     void fDeleteProgram(GLuint program) {
         raw_fDeleteProgram(program);
         TRACKING_CONTEXT(DeletedProgram(this, program));
     }
 
     void fDeleteShader(GLuint shader) {
         raw_fDeleteShader(shader);
@@ -2151,16 +2109,90 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
         mSymbols.fVertexAttribDivisor(index, divisor);
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
+// Package XXX_query_objects
+/**
+ * XXX_query_objects:
+ *  - provide all followed entry points
+ *
+ * XXX_occlusion_query2:
+ *  - depends on XXX_query_objects
+ *  - provide ANY_SAMPLES_PASSED
+ *
+ * XXX_occlusion_query_boolean:
+ *  - depends on XXX_occlusion_query2
+ *  - provide ANY_SAMPLES_PASSED_CONSERVATIVE
+ */
+public:
+    void fDeleteQueries(GLsizei n, const GLuint* names) {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fDeleteQueries);
+        mSymbols.fDeleteQueries(n, names);
+        AFTER_GL_CALL;
+        TRACKING_CONTEXT(DeletedQueries(this, n, names));
+    }
+
+    void fGenQueries(GLsizei n, GLuint* names) {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGenQueries);
+        mSymbols.fGenQueries(n, names);
+        AFTER_GL_CALL;
+        TRACKING_CONTEXT(CreatedQueries(this, n, names));
+    }
+
+    void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGetQueryiv);
+        mSymbols.fGetQueryiv(target, pname, params);
+        AFTER_GL_CALL;
+    }
+
+    void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
+        mSymbols.fGetQueryObjectuiv(id, pname, params);
+        AFTER_GL_CALL;
+    }
+
+    realGLboolean fIsQuery(GLuint query) {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fIsQuery);
+        realGLboolean retval = mSymbols.fIsQuery(query);
+        AFTER_GL_CALL;
+        return retval;
+    }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_get_query_object_iv
+/**
+ * XXX_get_query_object_iv:
+ *  - depends on XXX_query_objects
+ *  - provide the followed entry point
+ *
+ * XXX_occlusion_query:
+ *  - depends on XXX_get_query_object_iv
+ *  - provide LOCAL_GL_SAMPLES_PASSED
+ */
+public:
+    void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
+        mSymbols.fGetQueryObjectiv(id, pname, params);
+        AFTER_GL_CALL;
+    }
+
+
+// -----------------------------------------------------------------------------
 // Package XXX_vertex_array_object
 public:
     void GLAPIENTRY fBindVertexArray(GLuint array)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fBindVertexArray);
         mSymbols.fBindVertexArray(array);
         AFTER_GL_CALL;
@@ -3281,17 +3313,17 @@ public:
     void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void DeletedProgram(GLContext *aOrigin, GLuint aName);
     void DeletedShader(GLContext *aOrigin, GLuint aName);
     void DeletedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
-    void DeletedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
+    void DeletedQueries(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
     void DeletedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void DeletedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void DeletedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
 
     void SharedContextDestroyed(GLContext *aChild);
     void ReportOutstandingNames();
 
     struct NamedResource {
--- a/gfx/gl/GLContextExtensionGroupQueries.cpp
+++ b/gfx/gl/GLContextExtensionGroupQueries.cpp
@@ -7,26 +7,42 @@
 #include "GLContext.h"
 #include "nsPrintfCString.h"
 
 namespace mozilla {
 namespace gl {
 
 const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
 
+// ARB_ES2_compatibility is natively supported in OpenGL 4.1.
+static const unsigned int kGLCoreVersionForES2Compat = 410;
+
+// ARB_ES3_compatibility is natively supported in OpenGL 4.3.
+static const unsigned int kGLCoreVersionForES3Compat = 430;
+
 struct ExtensionGroupInfo
 {
     const char* mName;
     unsigned int mOpenGLVersion;
     unsigned int mOpenGLESVersion;
     GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
 };
 
 static const ExtensionGroupInfo sExtensionGroupInfoArr[] = {
     {
+        "XXX_depth_texture",
+        200, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::ARB_depth_texture,
+            GLContext::OES_depth_texture,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "XXX_draw_buffers",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_draw_buffers,
             GLContext::EXT_draw_buffers,
             GLContext::Extensions_End
         }
@@ -39,16 +55,43 @@ static const ExtensionGroupInfo sExtensi
             GLContext::ARB_draw_instanced,
             GLContext::EXT_draw_instanced,
             GLContext::NV_draw_instanced,
             GLContext::ANGLE_instanced_arrays,
             GLContext::Extensions_End
         }
     },
     {
+        "XXX_element_index_uint",
+        200, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::OES_element_index_uint,
+            GLContext::Extensions_End
+        }
+    },
+    {
+        "XXX_ES2_compatibility",
+        kGLCoreVersionForES2Compat,
+        200, // OpenGL ES version
+        {
+            GLContext::ARB_ES2_compatibility,
+            GLContext::Extensions_End
+        }
+    },
+    {
+        "XXX_ES3_compatibility",
+        kGLCoreVersionForES3Compat,
+        300, // OpenGL ES version
+        {
+            GLContext::ARB_ES3_compatibility,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "XXX_framebuffer_blit",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::EXT_framebuffer_blit,
             GLContext::ANGLE_framebuffer_blit,
             GLContext::Extensions_End
         }
@@ -69,57 +112,163 @@ static const ExtensionGroupInfo sExtensi
         200, // OpenGL ES version
         {
             GLContext::ARB_framebuffer_object,
             GLContext::EXT_framebuffer_object,
             GLContext::Extensions_End
         }
     },
     {
+        "XXX_get_query_object_iv",
+        200, // OpenGL version
+        0,   // OpenGL ES version
+        {
+            GLContext::Extensions_End
+        }
+        /*
+         * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
+         * ARB_occlusion_query (added by OpenGL 2.0).
+         */
+    },
+    {
         "XXX_instanced_arrays",
         330, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_instanced_arrays,
             GLContext::NV_instanced_arrays,
             GLContext::ANGLE_instanced_arrays,
             GLContext::Extensions_End
         }
     },
     {
+        "XXX_occlusion_query",
+        200, // OpenGL version
+        0,   // OpenGL ES version
+        {
+            GLContext::Extensions_End
+        }
+        // XXX_occlusion_query depend on ARB_occlusion_query (added in OpenGL 2.0)
+    },
+    {
+        "XXX_occlusion_query_boolean",
+        kGLCoreVersionForES3Compat,
+        300, // OpenGL ES version
+        {
+            GLContext::ARB_ES3_compatibility,
+            GLContext::EXT_occlusion_query_boolean,
+            GLContext::Extensions_End
+        }
+        /*
+         * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
+         * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
+         * it is supported on desktop if ARB_ES3_compatibility because 
+         * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
+         */
+    },
+    {
+        "XXX_occlusion_query2",
+        330, // = min(330, kGLCoreVersionForES3Compat),
+        300, // OpenGL ES version
+        {
+            GLContext::ARB_occlusion_query2,
+            GLContext::ARB_ES3_compatibility,
+            GLContext::EXT_occlusion_query_boolean,
+            GLContext::Extensions_End
+        }
+        /*
+         * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
+         * which is provided by ARB_occlusion_query2, EXT_occlusion_query_boolean
+         * (added in OpenGL ES 3.0) and ARB_ES3_compatibility
+         */
+    },
+    {
+        "XXX_packed_depth_stencil",
+        300, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::EXT_packed_depth_stencil,
+            GLContext::OES_packed_depth_stencil,
+            GLContext::Extensions_End
+        }
+    },
+    {
+        "XXX_query_objects",
+        200, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::EXT_occlusion_query_boolean,
+            GLContext::Extensions_End
+        }
+        /*
+         * XXX_query_objects only provide entry points commonly supported by
+         * ARB_occlusion_query (added in OpenGL 2.0) and EXT_occlusion_query_boolean
+         * (added in OpenGL ES 3.0)
+         */
+    },
+    {
         "XXX_robustness",
         0,   // OpenGL version
         0,   // OpenGL ES version
         {
             GLContext::ARB_robustness,
             GLContext::EXT_robustness,
             GLContext::Extensions_End
         }
     },
     {
+        "XXX_standard_derivatives",
+        200, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::OES_standard_derivatives,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "XXX_texture_float",
         310, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_texture_float,
             GLContext::OES_texture_float,
             GLContext::Extensions_End
         }
     },
     {
+        "XXX_texture_float_linear",
+        310, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::ARB_texture_float,
+            GLContext::OES_texture_float_linear,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "XXX_texture_non_power_of_two",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_texture_non_power_of_two,
             GLContext::OES_texture_npot,
             GLContext::Extensions_End
         }
     },
     {
+        "XXX_transform_feedback",
+        300, // OpenGL version
+        300, // OpenGL ES version
+        {
+            GLContext::EXT_transform_feedback,
+            GLContext::NV_transform_feedback,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "XXX_vertex_array_object",
         300, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_vertex_array_object,
             GLContext::OES_vertex_array_object,
             GLContext::APPLE_vertex_array_object,
             GLContext::Extensions_End
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -34,17 +34,17 @@ using namespace mozilla::ipc;
 using namespace android;
 using mozilla::gfx::DataSourceSurface;
 using mozilla::gfx::SourceSurface;
 
 
 namespace mozilla {
 namespace layers {
 
-int32_t Image::sSerialCounter = 0;
+Atomic<int32_t> Image::sSerialCounter(0);
 
 already_AddRefed<Image>
 ImageFactory::CreateImage(const ImageFormat *aFormats,
                           uint32_t aNumFormats,
                           const gfxIntSize &,
                           BufferRecycleBin *aRecycleBin)
 {
   if (!aNumFormats) {
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -1,24 +1,24 @@
 /* -*- Mode: C++; tab-width: 20; 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 GFX_IMAGECONTAINER_H
 #define GFX_IMAGECONTAINER_H
 
+#include "mozilla/Atomics.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "gfxASurface.h" // for gfxImageFormat
 #include "mozilla/layers/LayersTypes.h" // for LayersBackend
 #include "mozilla/TimeStamp.h"
 #include "ImageTypes.h"
 #include "nsTArray.h"
-#include "pratom.h"
 
 #ifdef XP_WIN
 struct ID3D10Texture2D;
 struct ID3D10Device;
 struct ID3D10ShaderResourceView;
 #endif
 
 typedef void* HANDLE;
@@ -98,27 +98,27 @@ public:
   int32_t GetSerial() { return mSerial; }
 
   void MarkSent() { mSent = true; }
   bool IsSentToCompositor() { return mSent; }
 
 protected:
   Image(void* aImplData, ImageFormat aFormat) :
     mImplData(aImplData),
-    mSerial(PR_ATOMIC_INCREMENT(&sSerialCounter)),
+    mSerial(++sSerialCounter),
     mFormat(aFormat),
     mSent(false)
   {}
 
   nsAutoPtr<ImageBackendData> mBackendData[mozilla::layers::LAYERS_LAST];
 
   void* mImplData;
   int32_t mSerial;
   ImageFormat mFormat;
-  static int32_t sSerialCounter;
+  static mozilla::Atomic<int32_t> sSerialCounter;
   bool mSent;
 };
 
 /**
  * A RecycleBin is owned by an ImageContainer. We store buffers in it that we
  * want to recycle from one image to the next.It's a separate object from 
  * ImageContainer because images need to store a strong ref to their RecycleBin
  * and we must avoid creating a reference loop between an ImageContainer and
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -679,17 +679,16 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         NS_ASSERTION(destBufferOnWhite, "Must have a white buffer!");
         nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBufferOnWhite);
         tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
         tmpCtx->Translate(gfxPoint(offset.x, offset.y));
         DrawBufferWithRotation(tmpCtx, BUFFER_WHITE);
       }
     }
 
-    MOZ_ASSERT(!IsAzureBuffer());
     mBuffer = destBuffer.forget();
     mDTBuffer = nullptr;
     mBufferRect = destBufferRect;
     mBufferOnWhite = destBufferOnWhite.forget();
     mDTBufferOnWhite = nullptr;
     mBufferRotation = nsIntPoint(0,0);
   } else if (destDTBuffer) {
     if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
--- a/gfx/layers/client/ClientContainerLayer.h
+++ b/gfx/layers/client/ClientContainerLayer.h
@@ -166,17 +166,17 @@ public:
           !(GetContentFlags() & Layer::CONTENT_OPAQUE))
       {
         const gfx3DMatrix& transform3D = GetEffectiveTransform();
         gfxMatrix transform;
         if (HasOpaqueAncestorLayer(this) &&
             transform3D.Is2D(&transform) && 
             !transform.HasNonIntegerTranslation()) {
           SetSupportsComponentAlphaChildren(
-            gfxPlatform::ComponentAlphaEnabled);
+            gfxPlatform::ComponentAlphaEnabled());
         }
       }
     } else {
       SetSupportsComponentAlphaChildren(
         (GetContentFlags() & Layer::CONTENT_OPAQUE) ||
         (GetParent() && GetParent()->SupportsComponentAlphaChildren()));
     }
 
--- a/image/src/DiscardTracker.cpp
+++ b/image/src/DiscardTracker.cpp
@@ -3,41 +3,40 @@
  * 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 "nsComponentManagerUtils.h"
 #include "nsITimer.h"
 #include "RasterImage.h"
 #include "DiscardTracker.h"
 #include "mozilla/Preferences.h"
-#include "pratom.h"
 
 namespace mozilla {
 namespace image {
 
 static const char* sDiscardTimeoutPref = "image.mem.min_discard_timeout_ms";
 
 /* static */ LinkedList<DiscardTracker::Node> DiscardTracker::sDiscardableImages;
 /* static */ nsCOMPtr<nsITimer> DiscardTracker::sTimer;
 /* static */ bool DiscardTracker::sInitialized = false;
 /* static */ bool DiscardTracker::sTimerOn = false;
-/* static */ int32_t DiscardTracker::sDiscardRunnablePending = 0;
+/* static */ Atomic<int32_t> DiscardTracker::sDiscardRunnablePending(0);
 /* static */ int64_t DiscardTracker::sCurrentDecodedImageBytes = 0;
 /* static */ uint32_t DiscardTracker::sMinDiscardTimeoutMs = 10000;
 /* static */ uint32_t DiscardTracker::sMaxDecodedImageKB = 42 * 1024;
 /* static */ PRLock * DiscardTracker::sAllocationLock = NULL;
 
 /*
  * When we notice we're using too much memory for decoded images, we enqueue a
  * DiscardRunnable, which runs this code.
  */
 NS_IMETHODIMP
 DiscardTracker::DiscardRunnable::Run()
 {
-  PR_ATOMIC_SET(&sDiscardRunnablePending, 0);
+  sDiscardRunnablePending = 0;
 
   DiscardTracker::DiscardNow();
   return NS_OK;
 }
 
 int
 DiscardTimeoutChangedCallback(const char* aPref, void *aClosure)
 {
@@ -289,17 +288,17 @@ DiscardTracker::DiscardNow()
 void
 DiscardTracker::MaybeDiscardSoon()
 {
   // Are we carrying around too much decoded image data?  If so, enqueue an
   // event to try to get us down under our limit.
   if (sCurrentDecodedImageBytes > sMaxDecodedImageKB * 1024 &&
       !sDiscardableImages.isEmpty()) {
     // Check if the value of sDiscardRunnablePending used to be false
-    if (!PR_ATOMIC_SET(&sDiscardRunnablePending, 1)) {
+    if (!sDiscardRunnablePending.exchange(1)) {
       nsRefPtr<DiscardRunnable> runnable = new DiscardRunnable();
       NS_DispatchToMainThread(runnable);
     }
   }
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/src/DiscardTracker.h
+++ b/image/src/DiscardTracker.h
@@ -1,16 +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 mozilla_imagelib_DiscardTracker_h_
 #define mozilla_imagelib_DiscardTracker_h_
 
+#include "mozilla/Atomics.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/TimeStamp.h"
 #include "prlock.h"
 
 class nsITimer;
 
 namespace mozilla {
 namespace image {
@@ -106,17 +107,17 @@ class DiscardTracker
     static void MaybeDiscardSoon();
     static void TimerCallback(nsITimer *aTimer, void *aClosure);
     static void DiscardNow();
 
     static LinkedList<Node> sDiscardableImages;
     static nsCOMPtr<nsITimer> sTimer;
     static bool sInitialized;
     static bool sTimerOn;
-    static int32_t sDiscardRunnablePending;
+    static mozilla::Atomic<int32_t> sDiscardRunnablePending;
     static int64_t sCurrentDecodedImageBytes;
     static uint32_t sMinDiscardTimeoutMs;
     static uint32_t sMaxDecodedImageKB;
     // Lock for safegarding the 64-bit sCurrentDecodedImageBytes
     static PRLock *sAllocationLock;
 };
 
 } // namespace image
--- a/intl/uconv/src/nsScriptableUConv.cpp
+++ b/intl/uconv/src/nsScriptableUConv.cpp
@@ -8,32 +8,27 @@
 #include "nsIServiceManager.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIScriptableUConv.h"
 #include "nsScriptableUConv.h"
 #include "nsIStringStream.h"
 #include "nsCRT.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCharsetAlias.h"
-#include "pratom.h"
-
-static int32_t          gInstanceCount = 0;
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS1(nsScriptableUnicodeConverter, nsIScriptableUnicodeConverter)
 
 nsScriptableUnicodeConverter::nsScriptableUnicodeConverter()
 : mIsInternal(false)
 {
-  PR_ATOMIC_INCREMENT(&gInstanceCount);
 }
 
 nsScriptableUnicodeConverter::~nsScriptableUnicodeConverter()
 {
-  PR_ATOMIC_DECREMENT(&gInstanceCount);
 }
 
 nsresult
 nsScriptableUnicodeConverter::ConvertFromUnicodeWithLength(const nsAString& aSrc,
                                                            int32_t* aOutLen,
                                                            char **_retval)
 {
   if (!mEncoder)
--- a/ipc/chromium/src/base/message_loop.cc
+++ b/ipc/chromium/src/base/message_loop.cc
@@ -1,16 +1,17 @@
 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "base/message_loop.h"
 
 #include <algorithm>
 
+#include "mozilla/Atomics.h"
 #include "base/compiler_specific.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/message_pump_default.h"
 #include "base/string_util.h"
 #include "base/thread_local.h"
 
 #if defined(OS_MACOSX)
@@ -27,17 +28,16 @@
 #include "base/message_pump_qt.h"
 #endif
 #endif
 #ifdef ANDROID
 #include "base/message_pump_android.h"
 #endif
 
 #include "MessagePump.h"
-#include "pratom.h"
 
 using base::Time;
 using base::TimeDelta;
 using base::TimeTicks;
 
 // A lazily created thread local storage for quick access to a thread's message
 // loop, if one exists.  This should be safe and free of static constructors.
 static base::LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr(
@@ -82,21 +82,21 @@ static LPTOP_LEVEL_EXCEPTION_FILTER GetT
 // static
 MessageLoop* MessageLoop::current() {
   // TODO(darin): sadly, we cannot enable this yet since people call us even
   // when they have no intention of using us.
   //DCHECK(loop) << "Ouch, did you forget to initialize me?";
   return lazy_tls_ptr.Pointer()->Get();
 }
 
-int32_t message_loop_id_seq = 0;
+static mozilla::Atomic<int32_t> message_loop_id_seq(0);
 
 MessageLoop::MessageLoop(Type type)
     : type_(type),
-      id_(PR_ATOMIC_INCREMENT(&message_loop_id_seq)),
+      id_(++message_loop_id_seq),
       nestable_tasks_allowed_(true),
       exception_restoration_(false),
       state_(NULL),
       run_depth_base_(1),
 #ifdef OS_WIN
       os_modal_loop_(false),
 #endif  // OS_WIN
       next_sequence_num_(0) {
--- a/js/src/assembler/jit/ExecutableAllocator.cpp
+++ b/js/src/assembler/jit/ExecutableAllocator.cpp
@@ -39,18 +39,16 @@ size_t ExecutableAllocator::largeAllocSi
 ExecutablePool::~ExecutablePool()
 {
     m_allocator->releasePoolPages(this);
 }
 
 void
 ExecutableAllocator::sizeOfCode(JS::CodeSizes *sizes) const
 {
-    *sizes = JS::CodeSizes();
-
     if (m_pools.initialized()) {
         for (ExecPoolHashSet::Range r = m_pools.all(); !r.empty(); r.popFront()) {
             ExecutablePool* pool = r.front();
             sizes->ion      += pool->m_ionCodeBytes;
             sizes->baseline += pool->m_baselineCodeBytes;
             sizes->asmJS    += pool->m_asmJSCodeBytes;
             sizes->regexp   += pool->m_regexpCodeBytes;
             sizes->other    += pool->m_otherCodeBytes;
@@ -58,11 +56,38 @@ ExecutableAllocator::sizeOfCode(JS::Code
                                                        - pool->m_baselineCodeBytes
                                                        - pool->m_asmJSCodeBytes
                                                        - pool->m_regexpCodeBytes
                                                        - pool->m_otherCodeBytes;
         }
     }
 }
 
+void
+ExecutableAllocator::toggleAllCodeAsAccessible(bool accessible)
+{
+    if (!m_pools.initialized())
+        return;
+
+    for (ExecPoolHashSet::Range r = m_pools.all(); !r.empty(); r.popFront()) {
+        ExecutablePool* pool = r.front();
+        pool->toggleAllCodeAsAccessible(accessible);
+    }
+}
+
+bool
+ExecutableAllocator::codeContains(char* address)
+{
+    if (!m_pools.initialized())
+        return false;
+
+    for (ExecPoolHashSet::Range r = m_pools.all(); !r.empty(); r.popFront()) {
+        ExecutablePool* pool = r.front();
+        if (pool->codeContains(address))
+            return true;
+    }
+
+    return false;
+}
+
 }
 
 #endif // HAVE(ASSEMBLER)
--- a/js/src/assembler/jit/ExecutableAllocator.h
+++ b/js/src/assembler/jit/ExecutableAllocator.h
@@ -166,16 +166,22 @@ private:
         }
         return result;
     }
 
     size_t available() const {
         JS_ASSERT(m_end >= m_freePtr);
         return m_end - m_freePtr;
     }
+
+    void toggleAllCodeAsAccessible(bool accessible);
+
+    bool codeContains(char* address) {
+        return address >= m_allocation.pages && address < m_freePtr;
+    }
 };
 
 enum AllocationBehavior
 {
     AllocationCanRandomize,
     AllocationDeterministic
 };
 
@@ -250,16 +256,18 @@ public:
         if (destroyCallback)
             destroyCallback(pool->m_allocation.pages, pool->m_allocation.size);
         systemRelease(pool->m_allocation);
         JS_ASSERT(m_pools.initialized());
         m_pools.remove(m_pools.lookup(pool));   // this asserts if |pool| is not in m_pools
     }
 
     void sizeOfCode(JS::CodeSizes *sizes) const;
+    void toggleAllCodeAsAccessible(bool accessible);
+    bool codeContains(char* address);
 
     void setDestroyCallback(DestroyCallback destroyCallback) {
         this->destroyCallback = destroyCallback;
     }
 
     void setRandomize(bool enabled) {
         allocBehavior = enabled ? AllocationCanRandomize : AllocationDeterministic;
     }
--- a/js/src/assembler/jit/ExecutableAllocatorOS2.cpp
+++ b/js/src/assembler/jit/ExecutableAllocatorOS2.cpp
@@ -48,15 +48,21 @@ ExecutablePool::Allocation ExecutableAll
     return alloc;
 }
 
 void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
 {
     DosFreeMem(alloc.pages);
 }
 
+void
+ExecutablePool::toggleAllCodeAsAccessible(bool accessible)
+{
+    MOZ_CRASH();
+}
+
 #if ENABLE_ASSEMBLER_WX_EXCLUSIVE
 #error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
 #endif
 
 }
 
 #endif // HAVE(ASSEMBLER)
--- a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp
+++ b/js/src/assembler/jit/ExecutableAllocatorPosix.cpp
@@ -86,11 +86,23 @@ void ExecutableAllocator::reprotectRegio
     add r7, r7, #0x2
     mov r2, #0x0
     svc #0x0
     pop {r7}
     bx lr
 }
 #endif
 
+void
+ExecutablePool::toggleAllCodeAsAccessible(bool accessible)
+{
+    char* begin = m_allocation.pages;
+    size_t size = m_freePtr - begin;
+
+    if (size) {
+        if (mprotect(begin, size, accessible ? PROT_READ | PROT_WRITE | PROT_EXEC : PROT_NONE))
+            MOZ_CRASH();
+    }
+}
+
 }
 
 #endif // HAVE(ASSEMBLER)
--- a/js/src/assembler/jit/ExecutableAllocatorWin.cpp
+++ b/js/src/assembler/jit/ExecutableAllocatorWin.cpp
@@ -111,15 +111,28 @@ ExecutablePool::Allocation ExecutableAll
     return alloc;
 }
 
 void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
 {
     VirtualFree(alloc.pages, 0, MEM_RELEASE);
 }
 
+void
+ExecutablePool::toggleAllCodeAsAccessible(bool accessible)
+{
+    char* begin = m_allocation.pages;
+    size_t size = m_freePtr - begin;
+
+    if (size) {
+        DWORD oldProtect;
+        if (!VirtualProtect(begin, size, accessible ? PAGE_EXECUTE_READWRITE : PAGE_NOACCESS, &oldProtect))
+            MOZ_CRASH();
+    }
+}
+
 #if ENABLE_ASSEMBLER_WX_EXCLUSIVE
 #error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
 #endif
 
 }
 
 #endif // HAVE(ASSEMBLER)
--- a/js/src/build/autoconf/compiler-opts.m4
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -76,16 +76,28 @@ if test -z "$_MOZ_USE_RTTI"; then
         esac
     fi
 fi
 ])
 
 dnl A high level macro for selecting compiler options.
 AC_DEFUN([MOZ_COMPILER_OPTS],
 [
+  DEVELOPER_OPTIONS=1
+  MOZ_ARG_ENABLE_BOOL(release,
+  [  --enable-release        Build with more conservative, release engineering-oriented options.
+                          This may slow down builds.],
+      DEVELOPER_OPTIONS=)
+
+  if test -n "$MOZILLA_OFFICIAL" -a -n "$DEVELOPER_OPTIONS"; then
+    AC_MSG_ERROR([You cannot set MOZILLA_OFFICIAL without --enable-release])
+  fi
+  AC_SUBST(DEVELOPER_OPTIONS)
+
+  MOZ_DEBUGGING_OPTS
   MOZ_RTTI
 if test "$CLANG_CXX"; then
     ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
     ## returned by C functions. This is possible because we use knowledge about the ABI
     ## to typedef it to a C type with the same layout when the headers are included
     ## from C.
     ##
     ## mismatched-tags is disabled (bug 780474) mostly because it's useless.
@@ -98,31 +110,58 @@ if test -z "$GNU_CC"; then
     case "$target" in
     *-mingw*)
         ## Warning 4099 (equivalent of mismatched-tags) is disabled (bug 780474)
         ## for the same reasons as above.
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -wd4099"
     esac
 fi
 
+if test "$GNU_CC" -a -n "$DEVELOPER_OPTIONS"; then
+    dnl if the default linker is BFD ld, check if gold is available and try to use it
+    dnl for local builds only.
+    if $CC -Wl,--version 2>&1 | grep -q "GNU ld"; then
+        GOLD=$($CC -print-prog-name=ld.gold)
+        case "$GOLD" in
+        /*)
+            ;;
+        *)
+            GOLD=$(which $GOLD)
+            ;;
+        esac
+        if test -n "$GOLD"; then
+            mkdir -p $_objdir/build/unix/gold
+            ln -s "$GOLD" $_objdir/build/unix/gold/ld
+            if $CC -B $_objdir/build/unix/gold -Wl,--version 2>&1 | grep -q "GNU gold"; then
+                LDFLAGS="$LDFLAGS -B $_objdir/build/unix/gold"
+            else
+                rm -rf $_objdir/build/unix/gold
+            fi
+        fi
+    fi
+fi
+
 if test "$GNU_CC"; then
-    CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
-    CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
+    if test -z "$DEVELOPER_OPTIONS"; then
+        CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
+        CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
+    fi
+    CXXFLAGS="$CXXFLAGS -fno-exceptions"
 fi
 
 dnl ========================================================
 dnl = Identical Code Folding
 dnl ========================================================
 
 MOZ_ARG_DISABLE_BOOL(icf,
 [  --disable-icf          Disable Identical Code Folding],
     MOZ_DISABLE_ICF=1,
     MOZ_DISABLE_ICF= )
 
-if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$MOZ_DISABLE_ICF"; then
+if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$MOZ_DISABLE_ICF" -a -z "$DEVELOPER_OPTIONS"; then
     AC_CACHE_CHECK([whether the linker supports Identical Code Folding],
         LD_SUPPORTS_ICF,
         [echo 'int foo() {return 42;}' \
               'int bar() {return 42;}' \
               'int main() {return foo() - bar();}' > conftest.${ac_ext}
         # If the linker supports ICF, foo and bar symbols will have
         # the same address
         if AC_TRY_COMMAND([${CC-cc} -o conftest${ac_exeext} $LDFLAGS -Wl,--icf=safe -ffunction-sections conftest.${ac_ext} $LIBS 1>&2]) &&
@@ -143,17 +182,17 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
         LDFLAGS="$_SAVE_LDFLAGS"
     fi
 fi
 
 dnl ========================================================
 dnl = Automatically remove dead symbols
 dnl ========================================================
 
-if test "$GNU_CC" -a "$GCC_USE_GNU_LD"; then
+if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -a -z "$DEVELOPER_OPTIONS"; then
     if test -n "$MOZ_DEBUG_FLAGS"; then
         dnl See bug 670659
         AC_CACHE_CHECK([whether removing dead symbols breaks debugging],
             GC_SECTIONS_BREAKS_DEBUG_RANGES,
             [echo 'int foo() {return 42;}' \
                   'int bar() {return 1;}' \
                   'int main() {return foo();}' > conftest.${ac_ext}
             if AC_TRY_COMMAND([${CC-cc} -o conftest.${ac_objext} $CFLAGS $MOZ_DEBUG_FLAGS -c conftest.${ac_ext} 1>&2]) &&
--- a/js/src/build/autoconf/config.status.m4
+++ b/js/src/build/autoconf/config.status.m4
@@ -62,17 +62,16 @@ dnl Picked from autoconf 2.13
 trap '' 1 2 15
 AC_CACHE_SAVE
 
 test "x$prefix" = xNONE && prefix=$ac_default_prefix
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
 trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
 : ${CONFIG_STATUS=./config.status}
 
 dnl We're going to need [ ] for python syntax.
 changequote(<<<, >>>)dnl
 echo creating $CONFIG_STATUS
 
 extra_python_path=${COMM_BUILD:+"'mozilla', "}
 
@@ -172,10 +171,13 @@ dnl Don't rely on virtualenv here. Stand
     sys.path.append(os.path.join(topsrcdir, ${extra_python_path}'build'))
     from ConfigStatus import config_status
     config_status(**args)
 EOF
 changequote([, ])
 chmod +x $CONFIG_STATUS
 rm -fr confdefs* $ac_clean_files
 dnl Execute config.status, unless --no-create was passed to configure.
-test "$no_create" = yes || ${PYTHON} $CONFIG_STATUS || exit 1
+if test "$no_create" != yes && ! ${PYTHON} $CONFIG_STATUS; then
+    trap '' EXIT
+    exit 1
+fi
 ])
--- a/js/src/build/autoconf/hooks.m4
+++ b/js/src/build/autoconf/hooks.m4
@@ -19,8 +19,12 @@ MOZ_CONFIG_LOG_TRAP
 
 dnl Disable the trap when running sub-configures.
 define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS]))
 define([AC_OUTPUT_SUBDIRS],
 [trap '' EXIT
 _MOZ_AC_OUTPUT_SUBDIRS($1)
 MOZ_CONFIG_LOG_TRAP
 ])
+
+dnl Print error messages in config.log as well as stderr
+define([AC_MSG_ERROR],
+[{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
--- a/js/src/config/rebuild_check.py
+++ b/js/src/config/rebuild_check.py
@@ -1,30 +1,44 @@
 # 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/.
 
 import os
+import errno
 
 def mtime(path):
-    return os.stat(path).st_mtime
+    try:
+        return os.stat(path).st_mtime
+    except OSError as e:
+        if e.errno == errno.ENOENT:
+            return -1
+        raise
 
 def rebuild_check(args):
     target = args[0]
     deps = args[1:]
-    if not os.path.exists(target):
+    t = mtime(target)
+    if t < 0:
         print target
         return
-    t = mtime(target)
 
     newer = []
+    removed = []
     for dep in deps:
-        if mtime(dep) > t:
+        deptime = mtime(dep)
+        if deptime < 0:
+            removed.append(dep)
+        elif mtime(dep) > t:
             newer.append(dep)
 
-    if newer:
+    if newer and removed:
+        print 'Rebuilding %s because %s changed and %s was removed' % (target, ', '.join(newer), ', '.join(removed))
+    elif newer:
         print 'Rebuilding %s because %s changed' % (target, ', '.join(newer))
+    elif removed:
+        print 'Rebuilding %s because %s was removed' % (target, ', '.join(removed))
     else:
         print 'Rebuilding %s for an unknown reason' % target
 
 if __name__ == '__main__':
     import sys
     rebuild_check(sys.argv[1:])
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -427,31 +427,34 @@ endif
 
 ifdef MOZ_UPDATE_XTERM
 # Its good not to have a newline at the end of the titlebar string because it
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick printf into doing it.
 UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ;
 endif
 
+ifdef MACH
+BUILDSTATUS=@echo BUILDSTATUS $1
+endif
 # Static directories are largely independent of our build system. But, they
 # could share the same build mechanism (like moz.build files). We need to
 # prevent leaking of our backend state to these independent build systems. This
 # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static
 # directories.
 define SUBMAKE # $(call SUBMAKE,target,directory,static)
 +@$(UPDATE_TITLE)
 +$(if $(3), MOZBUILD_BACKEND_CHECKED=,) $(MAKE) $(if $(2),-C $(2)) $(1)
 
 endef # The extra line is important here! don't delete it
 
 define TIER_DIR_SUBMAKE
-@echo "BUILDSTATUS TIERDIR_START  $(2)"
+$(call BUILDSTATUS,TIERDIR_START  $(2))
 $(call SUBMAKE,$(1),$(2),$(3))
-@echo "BUILDSTATUS TIERDIR_FINISH $(2)"
+$(call BUILDSTATUS,TIERDIR_FINISH $(2))
 
 endef # Ths empty line is important.
 
 
 ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
   $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
@@ -677,17 +680,17 @@ SUBMAKEFILES += $(addsuffix /Makefile, $
 
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
 ifdef TIERS
 default all alldep::
-	@echo "BUILDSTATUS TIERS $(TIERS)"
+	$(call BUILDSTATUS,TIERS $(TIERS))
 	$(foreach tier,$(TIERS),$(call SUBMAKE,tier_$(tier)))
 else
 
 default all::
 ifneq (,$(strip $(STATIC_DIRS)))
 	$(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,,$(dir),1))
 endif
 	$(MAKE) export
@@ -714,43 +717,36 @@ endif
 
 # This function is called and evaluated to produce the rule to build the
 # specified tier. Each tier begins by building the "static" directories.
 # The BUILDSTATUS echo commands are used to faciliate easier parsing
 # of build output. Build drivers are encouraged to filter these lines
 # from the user.
 define CREATE_TIER_RULE
 tier_$(1)::
-	@echo "BUILDSTATUS TIER_START $(1)"
-	@printf "BUILDSTATUS SUBTIERS"
+	$(call BUILDSTATUS,TIER_START $(1))
+	$(call BUILDSTATUS,SUBTIERS $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
+	$(call BUILDSTATUS,STATICDIRS $$($$@_staticdirs))
+	$(call BUILDSTATUS,DIRS $$($$@_dirs))
 ifneq (,$(tier_$(1)_staticdirs))
-	@printf " static"
+	$(call BUILDSTATUS,SUBTIER_START $(1) static)
+	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1))
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) static)
 endif
 ifneq (,$(tier_$(1)_dirs))
-	@printf " export libs tools"
-endif
-	@printf "\n"
-	@echo "BUILDSTATUS STATICDIRS $$($$@_staticdirs)"
-	@echo "BUILDSTATUS DIRS $$($$@_dirs)"
-ifneq (,$(tier_$(1)_staticdirs))
-	@echo "BUILDSTATUS SUBTIER_START $(1) static"
-	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1))
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) static"
-endif
-ifneq (,$(tier_$(1)_dirs))
-	@echo "BUILDSTATUS SUBTIER_START $(1) export"
+	$(call BUILDSTATUS,SUBTIER_START $(1) export)
 	$$(MAKE) export_$$@
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) export"
-	@echo "BUILDSTATUS SUBTIER_START $(1) libs"
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) export)
+	$(call BUILDSTATUS,SUBTIER_START $(1) libs)
 	$$(MAKE) libs_$$@
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) libs"
-	@echo "BUILDSTATUS SUBTIER_START $(1) tools"
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) libs)
+	$(call BUILDSTATUS,SUBTIER_START $(1) tools)
 	$$(MAKE) tools_$$@
-	@echo "BUILDSTATUS SUBTIER_FINISH $(1) tools"
-	@echo "BUILDSTATUS TIER_FINISH $(1)"
+	$(call BUILDSTATUS,SUBTIER_FINISH $(1) tools)
+	$(call BUILDSTATUS TIER_FINISH $(1))
 endif
 endef
 
 $(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier))))
 
 # Do everything from scratch
 everything::
 	$(MAKE) clean
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -189,17 +189,18 @@ frontend::CompileScript(ExclusiveContext
     if (options.filename && !ss->setFilename(cx, options.filename))
         return NULL;
 
     JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
     if (!sourceObject)
         return NULL;
 
     // Saving source is not yet supported when parsing off thread.
-    JS_ASSERT_IF(!cx->isJSContext(), !extraSct && options.sourcePolicy == CompileOptions::NO_SOURCE);
+    JS_ASSERT_IF(!cx->isJSContext(),
+                 !extraSct && options.sourcePolicy != CompileOptions::SAVE_SOURCE);
 
     SourceCompressionToken *sct = extraSct;
     Maybe<SourceCompressionToken> mysct;
     if (cx->isJSContext() && !sct) {
         mysct.construct(cx->asJSContext());
         sct = mysct.addr();
     }
 
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -3538,17 +3538,18 @@ ParseNode::getConstantValue(ExclusiveCon
         }
         JS_ASSERT(idx == pn_count);
 
         types::FixArrayType(cx, obj);
         vp.setObject(*obj);
         return true;
       }
       case PNK_OBJECT: {
-        JS_ASSERT(isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST));
+        JS_ASSERT(isOp(JSOP_NEWINIT));
+        JS_ASSERT(!(pn_xflags & PNX_NONCONST));
 
         gc::AllocKind kind = GuessObjectGCKind(pn_count);
         RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, kind, MaybeSingletonObject));
         if (!obj)
             return false;
 
         RootedValue value(cx), idvalue(cx);
         for (ParseNode *pn = pn_head; pn; pn = pn->pn_next) {
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -608,17 +608,17 @@ Fold(ExclusiveContext *cx, ParseNode **p
         JS_ASSERT(pn->isArity(PN_BINARY));
         if (pn1->isKind(PNK_STRING) || pn2->isKind(PNK_STRING)) {
             if (!FoldType(cx, !pn1->isKind(PNK_STRING) ? pn1 : pn2, PNK_STRING))
                 return false;
             if (!pn1->isKind(PNK_STRING) || !pn2->isKind(PNK_STRING))
                 return true;
             RootedString left(cx, pn1->pn_atom);
             RootedString right(cx, pn2->pn_atom);
-            RootedString str(cx, ConcatStrings<CanGC>(cx->asJSContext(), left, right));
+            RootedString str(cx, ConcatStrings<CanGC>(cx, left, right));
             if (!str)
                 return false;
             pn->pn_atom = AtomizeString<CanGC>(cx, str);
             if (!pn->pn_atom)
                 return false;
             pn->setKind(PNK_STRING);
             pn->setOp(JSOP_STRING);
             pn->setArity(PN_NULLARY);
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -138,20 +138,16 @@ class FullParseHandler
             return null();
         return new_<RegExpLiteral>(objbox, pos);
     }
 
     ParseNode *newConditional(ParseNode *cond, ParseNode *thenExpr, ParseNode *elseExpr) {
         return new_<ConditionalExpression>(cond, thenExpr, elseExpr);
     }
 
-    ParseNode *newElision() {
-        return new_<NullaryNode>(PNK_ELISION, pos());
-    }
-
     void markAsSetCall(ParseNode *pn) {
         pn->pn_xflags |= PNX_SETCALL;
     }
 
     ParseNode *newDelete(uint32_t begin, ParseNode *expr) {
         if (expr->getKind() == PNK_NAME) {
             expr->pn_dflags |= PND_DEOPTIMIZED;
             expr->setOp(JSOP_DELNAME);
@@ -184,16 +180,95 @@ class FullParseHandler
 
     ParseNode *newTernary(ParseNodeKind kind,
                           ParseNode *first, ParseNode *second, ParseNode *third,
                           JSOp op = JSOP_NOP)
     {
         return new_<TernaryNode>(kind, op, first, second, third);
     }
 
+    // Expressions
+
+    ParseNode *newArrayLiteral(uint32_t begin, unsigned blockid) {
+        ParseNode *literal = new_<ListNode>(PNK_ARRAY, TokenPos(begin, begin + 1));
+        // Later in this stack: remove dependency on this opcode.
+        if (literal) {
+            literal->setOp(JSOP_NEWINIT);
+            literal->pn_blockid = blockid;
+        }
+        return literal;
+    }
+
+    bool addElision(ParseNode *literal, const TokenPos &pos) {
+        ParseNode *elision = new_<NullaryNode>(PNK_ELISION, pos);
+        if (!elision)
+            return false;
+        literal->append(elision);
+        literal->pn_xflags |= PNX_SPECIALARRAYINIT | PNX_NONCONST;
+        return true;
+    }
+
+    bool addSpreadElement(ParseNode *literal, uint32_t begin, ParseNode *inner) {
+        TokenPos pos(begin, inner->pn_pos.end);
+        ParseNode *spread = new_<UnaryNode>(PNK_SPREAD, JSOP_NOP, pos, inner);
+        if (!spread)
+            return null();
+        literal->append(spread);
+        literal->pn_xflags |= PNX_SPECIALARRAYINIT | PNX_NONCONST;
+        return true;
+    }
+
+    bool addArrayElement(ParseNode *literal, ParseNode *element) {
+        if (!element->isConstant())
+            literal->pn_xflags |= PNX_NONCONST;
+        literal->append(element);
+        return true;
+    }
+
+    ParseNode *newObjectLiteral(uint32_t begin) {
+        ParseNode *literal = new_<ListNode>(PNK_OBJECT, TokenPos(begin, begin + 1));
+        // Later in this stack: remove dependency on this opcode.
+        if (literal)
+            literal->setOp(JSOP_NEWINIT);
+        return literal;
+    }
+
+    bool addPropertyDefinition(ParseNode *literal, ParseNode *name, ParseNode *expr) {
+        ParseNode *propdef = newBinary(PNK_COLON, name, expr, JSOP_INITPROP);
+        if (!propdef)
+            return false;
+        literal->append(propdef);
+        return true;
+    }
+
+    bool addShorthandPropertyDefinition(ParseNode *literal, ParseNode *name) {
+        JS_ASSERT(literal->isArity(PN_LIST));
+        literal->pn_xflags |= PNX_DESTRUCT | PNX_NONCONST;  // XXX why PNX_DESTRUCT?
+
+        ParseNode *propdef = newBinary(PNK_COLON, name, name, JSOP_INITPROP);
+        if (!propdef)
+            return false;
+        literal->append(propdef);
+        return true;
+    }
+
+    bool addAccessorPropertyDefinition(ParseNode *literal, ParseNode *name, ParseNode *fn, JSOp op)
+    {
+        JS_ASSERT(literal->isArity(PN_LIST));
+        literal->pn_xflags |= PNX_NONCONST;
+
+        ParseNode *propdef = newBinary(PNK_COLON, name, fn, op);
+        if (!propdef)
+            return false;
+        literal->append(propdef);
+        return true;
+    }
+
+    // Statements
+
     ParseNode *newStatementList(unsigned blockid, const TokenPos &pos) {
         ParseNode *pn = new_<ListNode>(PNK_STATEMENTLIST, pos);
         if (pn)
             pn->pn_blockid = blockid;
         return pn;
     }
 
     template <typename PC>
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -143,23 +143,19 @@ class NameResolver
                         break;
                     }
                     cur = parents[tmp];
                 }
                 break;
 
               case PNK_COLON:
                 /*
-                 * If this is a PNK_COLON, but our parent is not a PNK_OBJECT,
-                 * then this is a label and we're done naming. Otherwise we
-                 * record the PNK_COLON but skip the PNK_OBJECT so we're not
+                 * Record the PNK_COLON but skip the PNK_OBJECT so we're not
                  * flagged as a contributor.
                  */
-                if (pos == 0 || !parents[pos - 1]->isKind(PNK_OBJECT))
-                    return NULL;
                 pos--;
                 /* fallthrough */
 
               default:
                 /* Save any other nodes we encounter on the way up. */
                 JS_ASSERT(*size < MaxParents);
                 nameable[(*size)++] = cur;
                 break;
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -1403,17 +1403,18 @@ ParseNode::isConstant()
       case PNK_NUMBER:
       case PNK_STRING:
       case PNK_NULL:
       case PNK_FALSE:
       case PNK_TRUE:
         return true;
       case PNK_ARRAY:
       case PNK_OBJECT:
-        return isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST);
+        JS_ASSERT(isOp(JSOP_NEWINIT));
+        return !(pn_xflags & PNX_NONCONST);
       default:
         return false;
     }
 }
 
 class ObjectBox
 {
   public:
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -1227,37 +1227,31 @@ Parser<ParseHandler>::newFunction(Generi
      * function's parent slot to pc->sc->as<GlobalObject>()->scopeChain. If the
      * global context is a compile-and-go one, we leave the pre-set parent
      * intact; otherwise we clear parent and proto.
      */
     while (pc->parent)
         pc = pc->parent;
 
     RootedObject parent(context);
-    parent = pc->sc->isFunctionBox() ? NULL : pc->sc->asGlobalSharedContext()->scopeChain();
+    if (!pc->sc->isFunctionBox() && options().compileAndGo)
+        parent = pc->sc->asGlobalSharedContext()->scopeChain();
 
     RootedFunction fun(context);
     JSFunction::Flags flags = (kind == Expression)
                               ? JSFunction::INTERPRETED_LAMBDA
                               : (kind == Arrow)
                                 ? JSFunction::INTERPRETED_LAMBDA_ARROW
                                 : JSFunction::INTERPRETED;
     fun = NewFunction(context, NullPtr(), NULL, 0, flags, parent, atom,
                       JSFunction::FinalizeKind, MaybeSingletonObject);
+    if (!fun)
+        return NULL;
     if (options().selfHostingMode)
         fun->setIsSelfHostedBuiltin();
-    if (fun && !options().compileAndGo) {
-        if (!context->shouldBeJSContext())
-            return NULL;
-        if (!JSObject::clearParent(context->asJSContext(), fun))
-            return NULL;
-        if (!JSObject::clearType(context->asJSContext(), fun))
-            return NULL;
-        fun->setEnvironment(NULL);
-    }
     return fun;
 }
 
 static bool
 MatchOrInsertSemicolon(TokenStream &ts)
 {
     TokenKind tt = ts.peekTokenSameLine(TokenStream::Operand);
     if (tt == TOK_ERROR)
@@ -6233,385 +6227,389 @@ Parser<ParseHandler>::newRegExp()
     if (!reobj)
         return null();
 
     return handler.newRegExp(reobj, pos(), *this);
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
-Parser<ParseHandler>::primaryExpr(TokenKind tt)
+Parser<ParseHandler>::arrayInitializer()
 {
-    JS_ASSERT(tokenStream.isCurrentTokenType(tt));
-
-    Node pn, pn2, pn3;
-    JSOp op;
-
-    JS_CHECK_RECURSION(context, return null());
-
-    switch (tt) {
-      case TOK_FUNCTION:
-        return functionExpr();
-
-      case TOK_LB:
-      {
-        pn = handler.newList(PNK_ARRAY, null(), JSOP_NEWINIT);
-        if (!pn)
-            return null();
-        handler.setBlockId(pn, pc->blockidGen);
-
-        if (tokenStream.matchToken(TOK_RB, TokenStream::Operand)) {
-            /*
-             * Mark empty arrays as non-constant, since we cannot easily
-             * determine their type.
-             */
-            handler.setListFlag(pn, PNX_NONCONST);
-        } else {
-            bool spread = false, missingTrailingComma = false;
-            unsigned index = 0;
-            for (; ; index++) {
-                if (index == JSObject::NELEMENTS_LIMIT) {
-                    report(ParseError, false, null(), JSMSG_ARRAY_INIT_TOO_BIG);
+    JS_ASSERT(tokenStream.isCurrentTokenType(TOK_LB));
+
+    Node literal = handler.newArrayLiteral(pos().begin, pc->blockidGen);
+    if (!literal)
+        return null();
+
+    if (tokenStream.matchToken(TOK_RB, TokenStream::Operand)) {
+        /*
+         * Mark empty arrays as non-constant, since we cannot easily
+         * determine their type.
+         */
+        handler.setListFlag(literal, PNX_NONCONST);
+    } else {
+        bool spread = false, missingTrailingComma = false;
+        uint32_t index = 0;
+        for (; ; index++) {
+            if (index == JSObject::NELEMENTS_LIMIT) {
+                report(ParseError, false, null(), JSMSG_ARRAY_INIT_TOO_BIG);
+                return null();
+            }
+
+            TokenKind tt = tokenStream.peekToken(TokenStream::Operand);
+            if (tt == TOK_RB)
+                break;
+
+            if (tt == TOK_COMMA) {
+                tokenStream.consumeKnownToken(TOK_COMMA);
+                if (!handler.addElision(literal, pos()))
                     return null();
-                }
-
-                tt = tokenStream.peekToken(TokenStream::Operand);
-                if (tt == TOK_RB)
+            } else if (tt == TOK_TRIPLEDOT) {
+                spread = true;
+                tokenStream.consumeKnownToken(TOK_TRIPLEDOT);
+                uint32_t begin = pos().begin;
+                Node inner = assignExpr();
+                if (!inner)
+                    return null();
+                if (!handler.addSpreadElement(literal, begin, inner))
+                    return null();
+            } else {
+                Node element = assignExpr();
+                if (!element)
+                    return null();
+                if (foldConstants && !FoldConstants(context, &element, this))
+                    return null();
+                if (!handler.addArrayElement(literal, element))
+                    return null();
+            }
+
+            if (tt != TOK_COMMA) {
+                /* If we didn't already match TOK_COMMA in above case. */
+                if (!tokenStream.matchToken(TOK_COMMA)) {
+                    missingTrailingComma = true;
                     break;
-
-                if (tt == TOK_COMMA) {
-                    tokenStream.consumeKnownToken(TOK_COMMA);
-                    pn2 = handler.newElision();
-                    if (!pn2)
-                        return null();
-                    handler.setListFlag(pn, PNX_SPECIALARRAYINIT | PNX_NONCONST);
-                } else if (tt == TOK_TRIPLEDOT) {
-                    spread = true;
-                    handler.setListFlag(pn, PNX_SPECIALARRAYINIT | PNX_NONCONST);
-
-                    tokenStream.consumeKnownToken(TOK_TRIPLEDOT);
-                    uint32_t begin = pos().begin;
-                    Node inner = assignExpr();
-                    if (!inner)
-                        return null();
-
-                    pn2 = handler.newUnary(PNK_SPREAD, JSOP_NOP, begin, inner);
-                    if (!pn2)
-                        return null();
-                } else {
-                    pn2 = assignExpr();
-                    if (!pn2)
-                        return null();
-                    if (foldConstants && !FoldConstants(context, &pn2, this))
-                        return null();
-                    if (!handler.isConstant(pn2))
-                        handler.setListFlag(pn, PNX_NONCONST);
-                }
-                handler.addList(pn, pn2);
-
-                if (tt != TOK_COMMA) {
-                    /* If we didn't already match TOK_COMMA in above case. */
-                    if (!tokenStream.matchToken(TOK_COMMA)) {
-                        missingTrailingComma = true;
-                        break;
-                    }
                 }
             }
-
-            /*
-             * At this point, (index == 0 && missingTrailingComma) implies one
-             * element initialiser was parsed.
-             *
-             * An array comprehension of the form:
-             *
-             *   [i * j for (i in o) for (j in p) if (i != j)]
-             *
-             * translates to roughly the following let expression:
-             *
-             *   let (array = new Array, i, j) {
-             *     for (i in o) let {
-             *       for (j in p)
-             *         if (i != j)
-             *           array.push(i * j)
-             *     }
-             *     array
-             *   }
-             *
-             * where array is a nameless block-local variable. The "roughly"
-             * means that an implementation may optimize away the array.push.
-             * An array comprehension opens exactly one block scope, no matter
-             * how many for heads it contains.
-             *
-             * Each let () {...} or for (let ...) ... compiles to:
-             *
-             *   JSOP_ENTERBLOCK <o> ... JSOP_LEAVEBLOCK <n>
-             *
-             * where <o> is a literal object representing the block scope,
-             * with <n> properties, naming each var declared in the block.
-             *
-             * Each var declaration in a let-block binds a name in <o> at
-             * compile time, and allocates a slot on the operand stack at
-             * runtime via JSOP_ENTERBLOCK. A block-local var is accessed by
-             * the JSOP_GETLOCAL and JSOP_SETLOCAL ops. These ops have an
-             * immediate operand, the local slot's stack index from fp->spbase.
-             *
-             * The array comprehension iteration step, array.push(i * j) in
-             * the example above, is done by <i * j>; JSOP_ARRAYPUSH <array>,
-             * where <array> is the index of array's stack slot.
-             */
-            if (index == 0 && !spread && tokenStream.matchToken(TOK_FOR) && missingTrailingComma) {
-                if (!arrayInitializerComprehensionTail(pn))
-                    return null();
-            }
-
-            MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
         }
-        handler.setEndPosition(pn, pos().end);
-        return pn;
-      }
-
-      case TOK_LC:
-      {
-        Node pnval;
 
         /*
-         * A map from property names we've seen thus far to a mask of property
-         * assignment types, stored and retrieved with ALE_SET_INDEX/ALE_INDEX.
+         * At this point, (index == 0 && missingTrailingComma) implies one
+         * element initialiser was parsed.
+         *
+         * An array comprehension of the form:
+         *
+         *   [i * j for (i in o) for (j in p) if (i != j)]
+         *
+         * translates to roughly the following let expression:
+         *
+         *   let (array = new Array, i, j) {
+         *     for (i in o) let {
+         *       for (j in p)
+         *         if (i != j)
+         *           array.push(i * j)
+         *     }
+         *     array
+         *   }
+         *
+         * where array is a nameless block-local variable. The "roughly"
+         * means that an implementation may optimize away the array.push.
+         * An array comprehension opens exactly one block scope, no matter
+         * how many for heads it contains.
+         *
+         * Each let () {...} or for (let ...) ... compiles to:
+         *
+         *   JSOP_ENTERBLOCK <o> ... JSOP_LEAVEBLOCK <n>
+         *
+         * where <o> is a literal object representing the block scope,
+         * with <n> properties, naming each var declared in the block.
+         *
+         * Each var declaration in a let-block binds a name in <o> at
+         * compile time, and allocates a slot on the operand stack at
+         * runtime via JSOP_ENTERBLOCK. A block-local var is accessed by
+         * the JSOP_GETLOCAL and JSOP_SETLOCAL ops. These ops have an
+         * immediate operand, the local slot's stack index from fp->spbase.
+         *
+         * The array comprehension iteration step, array.push(i * j) in
+         * the example above, is done by <i * j>; JSOP_ARRAYPUSH <array>,
+         * where <array> is the index of array's stack slot.
          */
-        AtomIndexMap seen;
-
-        enum AssignmentType {
-            GET     = 0x1,
-            SET     = 0x2,
-            VALUE   = 0x4 | GET | SET
-        };
-
-        pn = handler.newList(PNK_OBJECT, null(), JSOP_NEWINIT);
-        if (!pn)
-            return null();
-
-        RootedAtom atom(context);
-        Value tmp;
-        for (;;) {
-            TokenKind ltok = tokenStream.getToken(TokenStream::KeywordIsName);
-            switch (ltok) {
-              case TOK_NUMBER:
-                tmp = DoubleValue(tokenStream.currentToken().number());
+        if (index == 0 && !spread && tokenStream.matchToken(TOK_FOR) && missingTrailingComma) {
+            if (!arrayInitializerComprehensionTail(literal))
+                return null();
+        }
+
+        MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
+    }
+    handler.setEndPosition(literal, pos().end);
+    return literal;
+}
+
+template <typename ParseHandler>
+typename ParseHandler::Node
+Parser<ParseHandler>::objectLiteral()
+{
+    JS_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
+
+    /*
+     * A map from property names we've seen thus far to a mask of property
+     * assignment types.
+     */
+    AtomIndexMap seen;
+
+    enum AssignmentType {
+        GET     = 0x1,
+        SET     = 0x2,
+        VALUE   = 0x4 | GET | SET
+    };
+
+    Node literal = handler.newObjectLiteral(pos().begin);
+    if (!literal)
+        return null();
+
+    RootedAtom atom(context);
+    Value tmp;
+    for (;;) {
+        TokenKind ltok = tokenStream.getToken(TokenStream::KeywordIsName);
+        if (ltok == TOK_RC)
+            break;
+
+        JSOp op = JSOP_INITPROP;
+        Node propname;
+        switch (ltok) {
+          case TOK_NUMBER:
+            tmp = DoubleValue(tokenStream.currentToken().number());
+            atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+            if (!atom)
+                return null();
+            propname = newNumber(tokenStream.currentToken());
+            break;
+
+          case TOK_NAME: {
+            atom = tokenStream.currentToken().name();
+            if (atom == context->names().get) {
+                op = JSOP_INITPROP_GETTER;
+            } else if (atom == context->names().set) {
+                op = JSOP_INITPROP_SETTER;
+            } else {
+                propname = handler.newIdentifier(atom, pos());
+                if (!propname)
+                    return null();
+                break;
+            }
+
+            // We have parsed |get| or |set|. Look for an accessor property
+            // name next.
+            TokenKind tt = tokenStream.getToken(TokenStream::KeywordIsName);
+            if (tt == TOK_NAME) {
+                atom = tokenStream.currentToken().name();
+                propname = newName(atom->asPropertyName());
+                if (!propname)
+                    return null();
+            } else if (tt == TOK_STRING) {
+                atom = tokenStream.currentToken().atom();
+
+                uint32_t index;
+                if (atom->isIndex(&index)) {
+                    propname = handler.newNumber(index, NoDecimal, pos());
+                    if (!propname)
+                        return null();
+                    tmp = DoubleValue(index);
+                    atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+                    if (!atom)
+                        return null();
+                } else {
+                    propname = stringLiteral();
+                    if (!propname)
+                        return null();
+                }
+            } else if (tt == TOK_NUMBER) {
+                double number = tokenStream.currentToken().number();
+                tmp = DoubleValue(number);
                 atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
                 if (!atom)
                     return null();
-                pn3 = newNumber(tokenStream.currentToken());
+                propname = newNumber(tokenStream.currentToken());
+                if (!propname)
+                    return null();
+            } else {
+                // Not an accessor property after all.
+                tokenStream.ungetToken();
+                propname = handler.newIdentifier(atom, pos());
+                if (!propname)
+                    return null();
+                op = JSOP_INITPROP;
                 break;
-              case TOK_NAME:
-                {
-                    atom = tokenStream.currentToken().name();
-                    if (atom == context->names().get) {
-                        op = JSOP_INITPROP_GETTER;
-                    } else if (atom == context->names().set) {
-                        op = JSOP_INITPROP_SETTER;
-                    } else {
-                        pn3 = handler.newIdentifier(atom, pos());
-                        if (!pn3)
-                            return null();
-                        break;
-                    }
-
-                    tt = tokenStream.getToken(TokenStream::KeywordIsName);
-                    if (tt == TOK_NAME) {
-                        atom = tokenStream.currentToken().name();
-                        pn3 = newName(atom->asPropertyName());
-                        if (!pn3)
-                            return null();
-                    } else if (tt == TOK_STRING) {
-                        atom = tokenStream.currentToken().atom();
-
-                        uint32_t index;
-                        if (atom->isIndex(&index)) {
-                            pn3 = handler.newNumber(index, NoDecimal, pos());
-                            if (!pn3)
-                                return null();
-                            tmp = DoubleValue(index);
-                            atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
-                            if (!atom)
-                                return null();
-                        } else {
-                            pn3 = stringLiteral();
-                            if (!pn3)
-                                return null();
-                        }
-                    } else if (tt == TOK_NUMBER) {
-                        double number = tokenStream.currentToken().number();
-                        tmp = DoubleValue(number);
-                        atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
-                        if (!atom)
-                            return null();
-                        pn3 = newNumber(tokenStream.currentToken());
-                        if (!pn3)
-                            return null();
-                    } else {
-                        tokenStream.ungetToken();
-                        pn3 = handler.newIdentifier(atom, pos());
-                        if (!pn3)
-                            return null();
-                        break;
-                    }
-
-                    JS_ASSERT(op == JSOP_INITPROP_GETTER || op == JSOP_INITPROP_SETTER);
-
-                    handler.setListFlag(pn, PNX_NONCONST);
-
-                    /* NB: Getter function in { get x(){} } is unnamed. */
-                    Rooted<PropertyName*> funName(context, NULL);
-                    TokenStream::Position start(keepAtoms);
-                    tokenStream.tell(&start);
-                    pn2 = functionDef(funName, start, op == JSOP_INITPROP_GETTER ? Getter : Setter,
-                                      Expression);
-                    if (!pn2)
-                        return null();
-                    pn2 = handler.newBinary(PNK_COLON, pn3, pn2, op);
-                    goto skip;
-                }
-              case TOK_STRING: {
-                atom = tokenStream.currentToken().atom();
-                uint32_t index;
-                if (atom->isIndex(&index)) {
-                    pn3 = handler.newNumber(index, NoDecimal, pos());
-                    if (!pn3)
-                        return null();
-                } else {
-                    pn3 = stringLiteral();
-                    if (!pn3)
-                        return null();
-                }
-                break;
-              }
-              case TOK_RC:
-                goto end_obj_init;
-              default:
-                report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
-                return null();
+            }
+
+            JS_ASSERT(op == JSOP_INITPROP_GETTER || op == JSOP_INITPROP_SETTER);
+            break;
+          }
+
+          case TOK_STRING: {
+            atom = tokenStream.currentToken().atom();
+            uint32_t index;
+            if (atom->isIndex(&index)) {
+                propname = handler.newNumber(index, NoDecimal, pos());
+                if (!propname)
+                    return null();
+            } else {
+                propname = stringLiteral();
+                if (!propname)
+                    return null();
             }
-
-            op = JSOP_INITPROP;
-            tt = tokenStream.getToken();
+            break;
+          }
+
+          default:
+            report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+            return null();
+        }
+
+        if (op == JSOP_INITPROP) {
+            TokenKind tt = tokenStream.getToken();
+            Node propexpr;
             if (tt == TOK_COLON) {
-                pnval = assignExpr();
-                if (!pnval)
+                propexpr = assignExpr();
+                if (!propexpr)
                     return null();
 
-                if (foldConstants && !FoldConstants(context, &pnval, this))
+                if (foldConstants && !FoldConstants(context, &propexpr, this))
                     return null();
 
                 /*
                  * Treat initializers which mutate __proto__ as non-constant,
                  * so that we can later assume singleton objects delegate to
                  * the default Object.prototype.
                  */
-                if (!handler.isConstant(pnval) || atom == context->names().proto)
-                    handler.setListFlag(pn, PNX_NONCONST);
+                if (!handler.isConstant(propexpr) || atom == context->names().proto)
+                    handler.setListFlag(literal, PNX_NONCONST);
+
+                if (!handler.addPropertyDefinition(literal, propname, propexpr))
+                    return null();
             }
 #if JS_HAS_DESTRUCTURING_SHORTHAND
             else if (ltok == TOK_NAME && (tt == TOK_COMMA || tt == TOK_RC)) {
                 /*
                  * Support, e.g., |var {x, y} = o| as destructuring shorthand
                  * for |var {x: x, y: y} = o|, per proposed JS2/ES4 for JS1.8.
                  */
                 if (!abortIfSyntaxParser())
                     return null();
                 tokenStream.ungetToken();
                 if (!tokenStream.checkForKeyword(atom->charsZ(), atom->length(), NULL))
                     return null();
-                handler.setListFlag(pn, PNX_DESTRUCT | PNX_NONCONST);
-                PropertyName *name = handler.isName(pn3);
+                PropertyName *name = handler.isName(propname);
                 JS_ASSERT(atom);
-                pn3 = newName(name);
-                if (!pn3)
+                propname = newName(name);
+                if (!propname)
                     return null();
-                pnval = pn3;
+                if (!handler.addShorthandPropertyDefinition(literal, propname))
+                    return null();
             }
 #endif
             else {
                 report(ParseError, false, null(), JSMSG_COLON_AFTER_ID);
                 return null();
             }
-
-            pn2 = handler.newBinary(PNK_COLON, pn3, pnval, op);
-          skip:
-            if (!pn2)
+        } else {
+            /* NB: Getter function in { get x(){} } is unnamed. */
+            Rooted<PropertyName*> funName(context, NULL);
+            TokenStream::Position start(keepAtoms);
+            tokenStream.tell(&start);
+            Node accessor = functionDef(funName, start, op == JSOP_INITPROP_GETTER ? Getter : Setter,
+                                        Expression);
+            if (!accessor)
+                return null();
+            if (!handler.addAccessorPropertyDefinition(literal, propname, accessor, op))
                 return null();
-            handler.addList(pn, pn2);
-
-            /*
-             * Check for duplicate property names.  Duplicate data properties
-             * only conflict in strict mode.  Duplicate getter or duplicate
-             * setter halves always conflict.  A data property conflicts with
-             * any part of an accessor property.
-             */
-            AssignmentType assignType;
-            if (op == JSOP_INITPROP) {
-                assignType = VALUE;
-            } else if (op == JSOP_INITPROP_GETTER) {
-                assignType = GET;
-            } else if (op == JSOP_INITPROP_SETTER) {
-                assignType = SET;
-            } else {
-                MOZ_ASSUME_UNREACHABLE("bad opcode in object initializer");
-            }
-
-            AtomIndexAddPtr p = seen.lookupForAdd(atom);
-            if (p) {
-                jsatomid index = p.value();
-                AssignmentType oldAssignType = AssignmentType(index);
-                if ((oldAssignType & assignType) &&
-                    (oldAssignType != VALUE || assignType != VALUE || pc->sc->needStrictChecks()))
+        }
+
+        /*
+         * Check for duplicate property names.  Duplicate data properties
+         * only conflict in strict mode.  Duplicate getter or duplicate
+         * setter halves always conflict.  A data property conflicts with
+         * any part of an accessor property.
+         */
+        AssignmentType assignType;
+        if (op == JSOP_INITPROP)
+            assignType = VALUE;
+        else if (op == JSOP_INITPROP_GETTER)
+            assignType = GET;
+        else if (op == JSOP_INITPROP_SETTER)
+            assignType = SET;
+        else
+            MOZ_ASSUME_UNREACHABLE("bad opcode in object initializer");
+
+        AtomIndexAddPtr p = seen.lookupForAdd(atom);
+        if (p) {
+            jsatomid index = p.value();
+            AssignmentType oldAssignType = AssignmentType(index);
+            if ((oldAssignType & assignType) &&
+                (oldAssignType != VALUE || assignType != VALUE || pc->sc->needStrictChecks()))
+            {
+                JSAutoByteString name;
+                if (!AtomToPrintableString(context, atom, &name))
+                    return null();
+
+                ParseReportKind reportKind =
+                    (oldAssignType == VALUE && assignType == VALUE && !pc->sc->needStrictChecks())
+                    ? ParseWarning
+                    : (pc->sc->needStrictChecks() ? ParseStrictError : ParseError);
+                if (!report(reportKind, pc->sc->strict, null(),
+                            JSMSG_DUPLICATE_PROPERTY, name.ptr()))
                 {
-                    JSAutoByteString name;
-                    if (!AtomToPrintableString(context, atom, &name))
-                        return null();
-
-                    ParseReportKind reportKind =
-                        (oldAssignType == VALUE && assignType == VALUE && !pc->sc->needStrictChecks())
-                        ? ParseWarning
-                        : (pc->sc->needStrictChecks() ? ParseStrictError : ParseError);
-                    if (!report(reportKind, pc->sc->strict, null(),
-                                JSMSG_DUPLICATE_PROPERTY, name.ptr()))
-                    {
-                        return null();
-                    }
+                    return null();
                 }
-                p.value() = assignType | oldAssignType;
-            } else {
-                if (!seen.add(p, atom, assignType))
-                    return null();
             }
-
-            tt = tokenStream.getToken();
-            if (tt == TOK_RC)
-                goto end_obj_init;
-            if (tt != TOK_COMMA) {
-                report(ParseError, false, null(), JSMSG_CURLY_AFTER_LIST);
+            p.value() = assignType | oldAssignType;
+        } else {
+            if (!seen.add(p, atom, assignType))
                 return null();
-            }
+        }
+
+        TokenKind tt = tokenStream.getToken();
+        if (tt == TOK_RC)
+            break;
+        if (tt != TOK_COMMA) {
+            report(ParseError, false, null(), JSMSG_CURLY_AFTER_LIST);
+            return null();
         }
-
-      end_obj_init:
-        handler.setEndPosition(pn, pos().end);
-        return pn;
-      }
+    }
+
+    handler.setEndPosition(literal, pos().end);
+    return literal;
+}
+
+template <typename ParseHandler>
+typename ParseHandler::Node
+Parser<ParseHandler>::primaryExpr(TokenKind tt)
+{
+    JS_ASSERT(tokenStream.isCurrentTokenType(tt));
+    JS_CHECK_RECURSION(context, return null());
+
+    switch (tt) {
+      case TOK_FUNCTION:
+        return functionExpr();
+
+      case TOK_LB:
+        return arrayInitializer();
+
+      case TOK_LC:
+        return objectLiteral();
 
 #if JS_HAS_BLOCK_SCOPE
       case TOK_LET:
         return letBlock(LetExpresion);
 #endif
 
       case TOK_LP:
       {
         bool genexp;
-
-        pn = parenExpr(&genexp);
+        Node pn = parenExpr(&genexp);
         if (!pn)
             return null();
         pn = handler.setInParens(pn);
 
         if (!genexp)
             MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
         return pn;
       }
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -566,17 +566,20 @@ class Parser : private AutoGCRooter, pub
     bool checkStrictAssignment(Node lhs, AssignmentFlavor flavor);
     bool checkStrictBinding(PropertyName *name, Node pn);
     bool defineArg(Node funcpn, HandlePropertyName name,
                    bool disallowDuplicateArgs = false, Node *duplicatedArg = NULL);
     Node pushLexicalScope(StmtInfoPC *stmt);
     Node pushLexicalScope(Handle<StaticBlockObject*> blockObj, StmtInfoPC *stmt);
     Node pushLetScope(Handle<StaticBlockObject*> blockObj, StmtInfoPC *stmt);
     bool noteNameUse(HandlePropertyName name, Node pn);
+    Node objectLiteral();
+    Node arrayInitializer();
     Node newRegExp();
+
     Node newBindingNode(PropertyName *name, bool functionScope, VarContext varContext = HoistVars);
     bool checkDestructuring(BindData<ParseHandler> *data, Node left, bool toplevel = true);
     bool bindDestructuringVar(BindData<ParseHandler> *data, Node pn);
     bool bindDestructuringLHS(Node pn);
     bool makeSetCall(Node pn, unsigned msg);
     Node cloneLeftHandSide(Node opn);
     Node cloneParseTree(Node opn);
 
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -100,16 +100,30 @@ class SyntaxParseHandler
                            ParseContext<SyntaxParseHandler> *pc, JSOp op = JSOP_NOP) {
         return NodeGeneric;
     }
 
     Node newTernary(ParseNodeKind kind, Node first, Node second, Node third, JSOp op = JSOP_NOP) {
         return NodeGeneric;
     }
 
+    // Expressions
+
+    Node newArrayLiteral(uint32_t begin, unsigned blockid) { return NodeGeneric; }
+    bool addElision(Node literal, const TokenPos &pos) { return true; }
+    bool addSpreadElement(Node literal, uint32_t begin, Node inner) { return true; }
+    bool addArrayElement(Node literal, Node element) { return true; }
+
+    Node newObjectLiteral(uint32_t begin) { return NodeGeneric; }
+    bool addPropertyDefinition(Node literal, Node name, Node expr) { return true; }
+    bool addShorthandPropertyDefinition(Node literal, Node name) { return true; }
+    bool addAccessorPropertyDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
+
+    // Statements
+
     Node newStatementList(unsigned blockid, const TokenPos &pos) { return NodeGeneric; }
     void addStatementToList(Node list, Node stmt, ParseContext<SyntaxParseHandler> *pc) {}
     Node newEmptyStatement(const TokenPos &pos) { return NodeGeneric; }
 
     Node newExprStatement(Node expr, uint32_t end) {
         return expr == NodeString ? NodeStringExprStatement : NodeGeneric;
     }
 
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -300,17 +300,17 @@ StoreBuffer::mark(JSTracer *trc)
     bufferRelocCell.mark(trc);
     bufferGeneric.mark(trc);
 }
 
 void
 StoreBuffer::setAboutToOverflow()
 {
     aboutToOverflow = true;
-    runtime->triggerOperationCallback();
+    runtime->triggerOperationCallback(JSRuntime::TriggerCallbackMainThread);
 }
 
 bool
 StoreBuffer::inParallelSection() const
 {
     return InParallelSection();
 }
 
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -68,16 +68,19 @@ Zone::setNeedsBarrier(bool needs, Should
 {
 #ifdef JS_ION
     if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
         ion::ToggleBarriers(this, needs);
         ionUsingBarriers_ = needs;
     }
 #endif
 
+    if (needs && runtimeFromMainThread()->isAtomsZone(this))
+        JS_ASSERT(!runtimeFromMainThread()->exclusiveThreadsPresent());
+
     needsBarrier_ = needs;
 }
 
 void
 Zone::markTypes(JSTracer *trc)
 {
     /*
      * Mark all scripts, type objects and singleton JS objects in the
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/proxy/bug-862848-1.js
@@ -0,0 +1,24 @@
+// obj.hasOwnProperty(id), Object.getOwnPropertyDescriptor(obj, id), and
+// Object.defineProperty(obj, id, desc) do not look at obj's prototype.
+
+var angryHandler = new Proxy({}, {
+    has: () => true,
+    get: (t, id) => {
+        throw new Error("angryHandler should not be queried (" + id + ")");
+    }
+});
+var angryProto = new Proxy({}, angryHandler);
+
+var obj = Object.create(angryProto, {
+    // Define hasOwnProperty directly on obj since we are poisoning its
+    // prototype chain.
+    hasOwnProperty: {
+        value: Object.prototype.hasOwnProperty
+    }
+});
+
+assertEq(Object.getOwnPropertyDescriptor(obj, "foo"), undefined);
+assertEq(obj.hasOwnProperty("foo"), false);
+Object.defineProperty(obj, "foo", {value: 5});
+assertEq(obj.hasOwnProperty("foo"), true);
+assertEq(obj.foo, 5);
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -15,16 +15,17 @@
 #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"
 #include "jit/CodeGenerator.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/PerfSpewer.h"
 #include "vm/Interpreter.h"
 
 #include "jsinferinlines.h"
 
@@ -6290,19 +6291,16 @@ CheckModule(JSContext *cx, AsmJSParser &
 
 static bool
 Warn(JSContext *cx, int code, const char *str)
 {
     return JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, js_GetErrorMessage,
                                         NULL, code, str ? str : "");
 }
 
-extern bool
-EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt);
-
 bool
 js::CompileAsmJS(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList, bool *validated)
 {
     *validated = false;
 
     if (!JSC::MacroAssembler::supportsFloatingPoint())
         return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by lack of floating point support");
 
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -296,17 +296,23 @@ class AsmJSModule
 
         ProfiledFunction(JSAtom *name, unsigned start, unsigned end,
                          unsigned line = 0U, unsigned column = 0U)
           : name(name),
             startCodeOffset(start),
             endCodeOffset(end),
             lineno(line),
             columnIndex(column)
-        { }
+        {
+            JS_ASSERT(name->isTenured());
+        }
+
+        void trace(JSTracer *trc) {
+            MarkStringUnbarriered(trc, &name, "asm.js profiled function name");
+        }
     };
 #endif
 
 #if defined(JS_ION_PERF)
     struct ProfiledBlocksFunction : public ProfiledFunction
     {
         ion::PerfSpewer::BasicBlocksVector blocks;
 
@@ -386,16 +392,26 @@ class AsmJSModule
         for (unsigned i = 0; i < globals_.length(); i++)
             globals_[i].trace(trc);
         for (unsigned i = 0; i < exports_.length(); i++)
             exports_[i].trace(trc);
         for (unsigned i = 0; i < exits_.length(); i++) {
             if (exitIndexToGlobalDatum(i).fun)
                 MarkObject(trc, &exitIndexToGlobalDatum(i).fun, "asm.js imported function");
         }
+#if defined(MOZ_VTUNE)
+        for (unsigned i = 0; i < profiledFunctions_.length(); i++)
+            profiledFunctions_[i].trace(trc);
+#endif
+#if defined(JS_ION_PERF)
+        for (unsigned i = 0; i < perfProfiledFunctions_.length(); i++)
+            perfProfiledFunctions_[i].trace(trc);
+        for (unsigned i = 0; i < perfProfiledBlocksFunctions_.length(); i++)
+            perfProfiledBlocksFunctions_[i].trace(trc);
+#endif
         if (maybeHeap_)
             MarkObject(trc, &maybeHeap_, "asm.js heap");
 
         if (globalArgumentName_)
             MarkString(trc, &globalArgumentName_, "asm.js global argument name");
         if (importArgumentName_)
             MarkString(trc, &importArgumentName_, "asm.js import argument name");
         if (bufferArgumentName_)
--- a/js/src/jit/AsmJSSignalHandlers.cpp
+++ b/js/src/jit/AsmJSSignalHandlers.cpp
@@ -138,17 +138,51 @@ static AsmJSActivation *
 InnermostAsmJSActivation()
 {
     PerThreadData *threadData = TlsPerThreadData.get();
     if (!threadData)
         return NULL;
 
     return threadData->asmJSActivationStackFromOwnerThread();
 }
-#endif
+
+static JSRuntime *
+RuntimeForCurrentThread()
+{
+    PerThreadData *threadData = TlsPerThreadData.get();
+    if (!threadData)
+        return NULL;
+
+    return threadData->runtimeFromMainThread();
+}
+#endif // !defined(XP_MACOSX)
+
+// Crashing inside the signal handler can cause the handler to be recursively
+// invoked, eventually blowing the stack without actually showing a crash
+// report dialog via Breakpad. To guard against this we watch for such
+// recursion and fall through to the next handler immediately rather than
+// trying to handle it.
+class AutoSetHandlingSignal
+{
+    JSRuntime *rt;
+
+  public:
+    AutoSetHandlingSignal(JSRuntime *rt)
+      : rt(rt)
+    {
+        JS_ASSERT(!rt->handlingSignal);
+        rt->handlingSignal = true;
+    }
+
+    ~AutoSetHandlingSignal()
+    {
+        JS_ASSERT(rt->handlingSignal);
+        rt->handlingSignal = false;
+    }
+};
 
 // For platforms that install a single, process-wide signal handler (Unix and
 // Windows), the InstallSignalHandlersMutex prevents races between JSRuntimes
 // installing signal handlers.
 #if !defined(XP_MACOSX)
 # ifdef JS_THREADSAFE
 #  include "jslock.h"
 
@@ -403,33 +437,43 @@ static bool
 HandleException(PEXCEPTION_POINTERS exception)
 {
     EXCEPTION_RECORD *record = exception->ExceptionRecord;
     CONTEXT *context = exception->ContextRecord;
 
     if (record->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
         return false;
 
-    AsmJSActivation *activation = InnermostAsmJSActivation();
-    if (!activation)
-        return false;
-
     uint8_t **ppc = ContextToPC(context);
     uint8_t *pc = *ppc;
     JS_ASSERT(pc == record->ExceptionAddress);
 
+    if (record->NumberParameters < 2)
+        return false;
+
+    void *faultingAddress = (void*)record->ExceptionInformation[1];
+
+    JSRuntime *rt = RuntimeForCurrentThread();
+
+    // Don't allow recursive handling of signals, see AutoSetHandlingSignal.
+    if (!rt || rt->handlingSignal)
+        return false;
+    AutoSetHandlingSignal handling(rt);
+
+    if (rt->ionRuntime() && rt->ionRuntime()->handleAccessViolation(rt, faultingAddress))
+        return true;
+
+    AsmJSActivation *activation = InnermostAsmJSActivation();
+    if (!activation)
+        return false;
+
     const AsmJSModule &module = activation->module();
     if (!module.containsPC(pc))
         return false;
 
-	if (record->NumberParameters < 2)
-		return false;
-
-    void *faultingAddress = (void*)record->ExceptionInformation[1];
-
     // If we faulted trying to execute code in 'module', this must be an
     // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
     // execution to a trampoline which will call js_HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
         *ppc = module.operationCallbackExit();
@@ -582,43 +626,51 @@ struct ExceptionRequest
 {
     Request__mach_exception_raise_t body;
     mach_msg_trailer_t trailer;
 };
 
 static bool
 HandleMachException(JSRuntime *rt, const ExceptionRequest &request)
 {
+    // Don't allow recursive handling of signals, see AutoSetHandlingSignal.
+    if (rt->handlingSignal)
+        return false;
+    AutoSetHandlingSignal handling(rt);
+
     // Get the port of the JSRuntime's thread from the message.
     mach_port_t rtThread = request.body.thread.name;
 
     // Read out the JSRuntime thread's register state.
     x86_thread_state_t state;
     unsigned int count = x86_THREAD_STATE_COUNT;
     kern_return_t kret;
     kret = thread_get_state(rtThread, x86_THREAD_STATE, (thread_state_t)&state, &count);
     if (kret != KERN_SUCCESS)
         return false;
 
-    AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
-    if (!activation)
-        return false;
-
     uint8_t **ppc = ContextToPC(state);
     uint8_t *pc = *ppc;
 
-    const AsmJSModule &module = activation->module();
-    if (!module.containsPC(pc))
-        return false;
-
     if (request.body.exception != EXC_BAD_ACCESS || request.body.codeCnt != 2)
         return false;
 
     void *faultingAddress = (void*)request.body.code[1];
 
+    if (rt->ionRuntime() && rt->ionRuntime()->handleAccessViolation(rt, faultingAddress))
+        return true;
+
+    AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
+    if (!activation)
+        return false;
+
+    const AsmJSModule &module = activation->module();
+    if (!module.containsPC(pc))
+        return false;
+
     // If we faulted trying to execute code in 'module', this must be an
     // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
     // execution to a trampoline which will call js_HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
         *ppc = module.operationCallbackExit();
@@ -819,30 +871,40 @@ AsmJSMachExceptionHandler::install(JSRun
 
 # else  // If not Windows or Mac, assume Unix
 
 // Be very cautious and default to not handling; we don't want to accidentally
 // silence real crashes from real bugs.
 static bool
 HandleSignal(int signum, siginfo_t *info, void *ctx)
 {
+    CONTEXT *context = (CONTEXT *)ctx;
+    uint8_t **ppc = ContextToPC(context);
+    uint8_t *pc = *ppc;
+
+    void *faultingAddress = info->si_addr;
+
+    JSRuntime *rt = RuntimeForCurrentThread();
+
+    // Don't allow recursive handling of signals, see AutoSetHandlingSignal.
+    if (!rt || rt->handlingSignal)
+        return false;
+    AutoSetHandlingSignal handling(rt);
+
+    if (rt->ionRuntime() && rt->ionRuntime()->handleAccessViolation(rt, faultingAddress))
+        return true;
+
     AsmJSActivation *activation = InnermostAsmJSActivation();
     if (!activation)
         return false;
 
-    CONTEXT *context = (CONTEXT *)ctx;
-    uint8_t **ppc = ContextToPC(context);
-    uint8_t *pc = *ppc;
-
     const AsmJSModule &module = activation->module();
     if (!module.containsPC(pc))
         return false;
 
-    void *faultingAddress = info->si_addr;
-
     // If we faulted trying to execute code in 'module', this must be an
     // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
     // execution to a trampoline which will call js_HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
         *ppc = module.operationCallbackExit();
@@ -911,17 +973,17 @@ AsmJSFaultHandler(int signum, siginfo_t 
     } else {
         prevHandler->sa_handler(signum);
         exit(signum);  // backstop
     }
 }
 # endif
 
 bool
-EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt)
+js::EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt)
 {
 #if defined(XP_MACOSX)
     // On OSX, each JSRuntime gets its own handler.
     return rt->asmJSMachExceptionHandler.installed() || rt->asmJSMachExceptionHandler.install(rt);
 #else
     // Assume Windows or Unix. For these platforms, there is a single,
     // process-wide signal handler installed. Take care to only install it once.
     InstallSignalHandlersMutex::Lock lock;
@@ -930,17 +992,22 @@ EnsureAsmJSSignalHandlersInstalled(JSRun
 
 # if defined(XP_WIN)
     if (!AddVectoredExceptionHandler(/* FirstHandler = */true, AsmJSExceptionHandler))
         return false;
 # else  // assume Unix
     struct sigaction sigAction;
     sigAction.sa_sigaction = &AsmJSFaultHandler;
     sigemptyset(&sigAction.sa_mask);
-    sigAction.sa_flags = SA_SIGINFO;
+
+    // Note: SA_NODEFER allows us to reenter the signal handler if we crash
+    // while handling the signal, and fall through to the Breakpad handler
+    // by testing handlingSignal.
+    sigAction.sa_flags = SA_SIGINFO | SA_NODEFER;
+
     if (sigaction(SIGSEGV, &sigAction, &sPrevSegvHandler))
         return false;
     if (sigaction(SIGBUS, &sigAction, &sPrevBusHandler))
         return false;
 # endif
 
     lock.setHandlersInstalled();
 #endif
--- a/js/src/jit/AsmJSSignalHandlers.h
+++ b/js/src/jit/AsmJSSignalHandlers.h
@@ -11,16 +11,21 @@ struct JSRuntime;
 
 #ifdef XP_MACOSX
 # include <mach/mach.h>
 # include <pthread.h>
 #endif
 
 namespace js {
 
+// Returns whether signal handlers for asm.js and for IonRuntime access
+// violations have been installed.
+bool
+EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt);
+
 // Force any currently-executing asm.js code to call
 // js_HandleExecutionInterrupt.
 extern void
 TriggerOperationCallbackForAsmJSCode(JSRuntime *rt);
 
 // On OSX we are forced to use the lower-level Mach exception mechanism instead
 // of Unix signals. Mach exceptions are not handled on the victim's stack but
 // rather require an extra thread. For simplicity, we create one such thread
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -1325,33 +1325,16 @@ BacktrackingAllocator::computePriority(c
     size_t priority = 0;
     for (size_t j = 0; j < group->registers.length(); j++) {
         uint32_t vreg = group->registers[j];
         priority += computePriority(vregs[vreg].getInterval(0));
     }
     return priority;
 }
 
-CodePosition
-BacktrackingAllocator::minimalDefEnd(LInstruction *ins)
-{
-    // Compute the shortest interval that captures vregs defined by ins.
-    // Watch for instructions that are followed by an OSI point and/or Nop.
-    // If moves are introduced between the instruction and the OSI point then
-    // safepoint information for the instruction may be incorrect. This is
-    // pretty disgusting and should be fixed somewhere else in the compiler.
-    while (true) {
-        LInstruction *next = insData[outputOf(ins).next()].ins();
-        if (!next->isNop() && !next->isOsiPoint())
-            break;
-        ins = next;
-    }
-    return outputOf(ins);
-}
-
 bool
 BacktrackingAllocator::minimalDef(const LiveInterval *interval, LInstruction *ins)
 {
     // Whether interval is a minimal interval capturing a definition at ins.
     return (interval->end() <= minimalDefEnd(ins).next()) &&
         (interval->start() == inputOf(ins) || interval->start() == outputOf(ins));
 }
 
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -207,17 +207,16 @@ class BacktrackingAllocator : public Liv
     bool populateSafepoints();
 
     void dumpRegisterGroups();
     void dumpLiveness();
     void dumpAllocations();
 
     struct PrintLiveIntervalRange;
 
-    CodePosition minimalDefEnd(LInstruction *ins);
     bool minimalDef(const LiveInterval *interval, LInstruction *ins);
     bool minimalUse(const LiveInterval *interval, LInstruction *ins);
     bool minimalInterval(const LiveInterval *interval, bool *pfixed = NULL);
 
     // Heuristic methods.
 
     size_t computePriority(const LiveInterval *interval);
     size_t computeSpillWeight(const LiveInterval *interval);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -464,46 +464,72 @@ CodeGenerator::testValueTruthy(const Val
 
     // If we reach here the value is a double.
     masm.unboxDouble(value, fr);
     cond = masm.testDoubleTruthy(false, fr);
     masm.j(cond, ifFalsy);
     masm.jump(ifTruthy);
 }
 
+Label *
+CodeGenerator::getJumpLabelForBranch(MBasicBlock *block)
+{
+    if (!labelForBackedgeWithImplicitCheck(block))
+        return block->lir()->label();
+
+    // We need to use a patchable jump for this backedge, but want to treat
+    // this as a normal label target to simplify codegen. Efficiency isn't so
+    // important here as these tests are extremely unlikely to be used in loop
+    // backedges, so emit inline code for the patchable jump. Heap allocating
+    // the label allows it to be used by out of line blocks.
+    Label *res = GetIonContext()->temp->lifoAlloc()->new_<Label>();
+    Label after;
+    masm.jump(&after);
+    masm.bind(res);
+    jumpToBlock(block);
+    masm.bind(&after);
+    return res;
+}
+
 bool
 CodeGenerator::visitTestOAndBranch(LTestOAndBranch *lir)
 {
     MOZ_ASSERT(lir->mir()->operandMightEmulateUndefined(),
                "Objects which can't emulate undefined should have been constant-folded");
 
     OutOfLineTestObject *ool = new OutOfLineTestObject();
     if (!addOutOfLineCode(ool))
         return false;
 
-    testObjectTruthy(ToRegister(lir->input()), lir->ifTruthy(), lir->ifFalsy(),
+    Label *truthy = getJumpLabelForBranch(lir->ifTruthy());
+    Label *falsy = getJumpLabelForBranch(lir->ifFalsy());
+
+    testObjectTruthy(ToRegister(lir->input()), truthy, falsy,
                      ToRegister(lir->temp()), ool);
     return true;
 
 }
 
 bool
 CodeGenerator::visitTestVAndBranch(LTestVAndBranch *lir)
 {
     OutOfLineTestObject *ool = NULL;
     if (lir->mir()->operandMightEmulateUndefined()) {
         ool = new OutOfLineTestObject();
         if (!addOutOfLineCode(ool))
             return false;
     }
 
+    Label *truthy = getJumpLabelForBranch(lir->ifTruthy());
+    Label *falsy = getJumpLabelForBranch(lir->ifFalsy());
+
     testValueTruthy(ToValue(lir, LTestVAndBranch::Input),
                     lir->temp1(), lir->temp2(),
                     ToFloatRegister(lir->tempFloat()),
-                    lir->ifTruthy(), lir->ifFalsy(), ool);
+                    truthy, falsy, ool);
     return true;
 }
 
 bool
 CodeGenerator::visitFunctionDispatch(LFunctionDispatch *lir)
 {
     MFunctionDispatch *mir = lir->mir();
     Register input = ToRegister(lir->input());
@@ -793,23 +819,73 @@ CodeGenerator::visitOsiPoint(LOsiPoint *
     JS_ASSERT(!safepoint->osiCallPointOffset());
     safepoint->setOsiCallPointOffset(osiCallPointOffset);
     return true;
 }
 
 bool
 CodeGenerator::visitGoto(LGoto *lir)
 {
-    LBlock *target = lir->target()->lir();
-
-    // No jump necessary if we can fall through to the next block.
-    if (isNextBlock(target))
-        return true;
-
-    masm.jump(target->label());
+    jumpToBlock(lir->target());
+    return true;
+}
+
+// Out-of-line path to execute any move groups between the start of a loop
+// header and its interrupt check, then invoke the interrupt handler.
+class OutOfLineInterruptCheckImplicit : public OutOfLineCodeBase<CodeGenerator>
+{
+  public:
+    LBlock *block;
+    LInterruptCheckImplicit *lir;
+
+    OutOfLineInterruptCheckImplicit(LBlock *block, LInterruptCheckImplicit *lir)
+      : block(block), lir(lir)
+    { }
+
+    bool accept(CodeGenerator *codegen) {
+        return codegen->visitOutOfLineInterruptCheckImplicit(this);
+    }
+};
+
+bool
+CodeGenerator::visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit *ool)
+{
+    LInstructionIterator iter = ool->block->begin();
+    for (; iter != ool->block->end(); iter++) {
+        if (iter->isLabel()) {
+            // Nothing to do.
+        } else if (iter->isMoveGroup()) {
+            // Replay this move group that preceds the interrupt check at the
+            // start of the loop header. Any incoming jumps here will be from
+            // the backedge and will skip over the move group emitted inline.
+            visitMoveGroup(iter->toMoveGroup());
+        } else {
+            break;
+        }
+    }
+    JS_ASSERT(*iter == ool->lir);
+
+    saveLive(ool->lir);
+    if (!callVM(InterruptCheckInfo, ool->lir))
+        return false;
+    restoreLive(ool->lir);
+    masm.jump(ool->rejoin());
+
+    return true;
+}
+
+bool
+CodeGenerator::visitInterruptCheckImplicit(LInterruptCheckImplicit *lir)
+{
+    OutOfLineInterruptCheckImplicit *ool = new OutOfLineInterruptCheckImplicit(current, lir);
+    if (!addOutOfLineCode(ool))
+        return false;
+
+    lir->setOolEntry(ool->entry());
+    masm.bind(ool->rejoin());
     return true;
 }
 
 bool
 CodeGenerator::visitTableSwitch(LTableSwitch *ins)
 {
     MTableSwitch *mir = ins->mir();
     Label *defaultcase = mir->getDefault()->lir()->label();
@@ -3951,18 +4027,19 @@ CodeGenerator::visitIsNullOrLikeUndefine
         OutOfLineTestObject *ool = NULL;
         if (lir->mir()->operandMightEmulateUndefined()) {
             ool = new OutOfLineTestObject();
             if (!addOutOfLineCode(ool))
                 return false;
         }
 
         Register tag = masm.splitTagForTest(value);
-        Label *ifTrueLabel = ifTrue->lir()->label();
-        Label *ifFalseLabel = ifFalse->lir()->label();
+
+        Label *ifTrueLabel = getJumpLabelForBranch(ifTrue);
+        Label *ifFalseLabel = getJumpLabelForBranch(ifFalse);
 
         masm.branchTestNull(Assembler::Equal, tag, ifTrueLabel);
         masm.branchTestUndefined(Assembler::Equal, tag, ifTrueLabel);
 
         if (ool) {
             masm.branchTestObject(Assembler::NotEqual, tag, ifFalseLabel);
 
             // Objects that emulate undefined are loosely equal to null/undefined.
@@ -4048,18 +4125,18 @@ CodeGenerator::visitEmulatesUndefinedAnd
             ifFalse = lir->ifFalse();
         } else {
             // Swap branches.
             ifTrue = lir->ifFalse();
             ifFalse = lir->ifTrue();
             op = JSOP_EQ;
         }
 
-        equal = ifTrue->lir()->label();
-        unequal = ifFalse->lir()->label();
+        equal = getJumpLabelForBranch(ifTrue);
+        unequal = getJumpLabelForBranch(ifFalse);
     }
 
     Register objreg = ToRegister(lir->input());
 
     testObjectTruthy(objreg, unequal, equal, ToRegister(lir->temp()), ool);
     return true;
 }
 
@@ -5444,26 +5521,42 @@ CodeGenerator::generate()
     return !masm.oom();
 }
 
 bool
 CodeGenerator::link()
 {
     JSContext *cx = GetIonContext()->cx;
 
+    // Lock the runtime against operation callbacks during the link.
+    // We don't want an operation callback to protect the code for the script
+    // before it has been filled in, as we could segv before the runtime's
+    // patchable backedges have been fully updated.
+    JSRuntime::AutoLockForOperationCallback lock(cx->runtime());
+
+    // Make sure we don't segv while filling in the code, to avoid deadlocking
+    // inside the signal handler.
+    cx->runtime()->ionRuntime()->ensureIonCodeAccessible(cx->runtime());
+
+    // Implicit interrupts are used only for sequential code. In parallel mode
+    // use the normal executable allocator so that we cannot segv during
+    // execution off the main thread.
+    ExecutionMode executionMode = gen->info().executionMode();
+
     Linker linker(masm);
-    IonCode *code = linker.newCode(cx, JSC::ION_CODE);
+    IonCode *code = (executionMode == SequentialExecution)
+                    ? linker.newCodeForIonScript(cx)
+                    : linker.newCode(cx, JSC::ION_CODE);
     if (!code)
         return false;
 
     // We encode safepoints after the OSI-point offsets have been determined.
     encodeSafepoints();
 
     JSScript *script = gen->info().script();
-    ExecutionMode executionMode = gen->info().executionMode();
     JS_ASSERT(!HasIonScript(script, executionMode));
 
     uint32_t scriptFrameSize = frameClass_ == FrameSizeClass::None()
                            ? frameDepth_
                            : FrameSizeClass::FromDepth(frameDepth_).frameSize();
 
     // Check to make sure we didn't have a mid-build invalidation. If so, we
     // will trickle to ion::Compile() and return Method_Skipped.
@@ -5477,17 +5570,17 @@ CodeGenerator::link()
         AddPossibleCallees(graph.mir(), callTargets);
 
     IonScript *ionScript =
       IonScript::New(cx, graph.totalSlotCount(), scriptFrameSize, snapshots_.size(),
                      bailouts_.length(), graph.numConstants(),
                      safepointIndices_.length(), osiIndices_.length(),
                      cacheList_.length(), runtimeData_.length(),
                      safepoints_.size(), graph.mir().numScripts(),
-                     callTargets.length());
+                     callTargets.length(), patchableBackedges_.length());
 
     ionScript->setMethod(code);
     ionScript->setSkipArgCheckEntryOffset(getSkipArgCheckEntryOffset());
 
     // If SPS is enabled, mark IonScript as having been instrumented with SPS
     if (sps_.enabled())
         ionScript->setHasSPSInstrumentation();
 
@@ -5540,16 +5633,18 @@ CodeGenerator::link()
     if (snapshots_.size())
         ionScript->copySnapshots(&snapshots_);
     if (graph.numConstants())
         ionScript->copyConstants(graph.constantPool());
     JS_ASSERT(graph.mir().numScripts() > 0);
     ionScript->copyScriptEntries(graph.mir().scripts());
     if (callTargets.length() > 0)
         ionScript->copyCallTargetEntries(callTargets.begin());
+    if (patchableBackedges_.length() > 0)
+        ionScript->copyPatchableBackedges(cx, code, patchableBackedges_.begin());
 
     switch (executionMode) {
       case SequentialExecution:
         // The correct state for prebarriers is unknown until the end of compilation,
         // since a GC can occur during code generation. All barriers are emitted
         // off-by-default, and are toggled on here if necessary.
         if (cx->zone()->needsBarrier())
             ionScript->toggleBarriers(true);
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -24,16 +24,17 @@ namespace ion {
 
 class OutOfLineNewParallelArray;
 class OutOfLineTestObject;
 class OutOfLineNewArray;
 class OutOfLineNewObject;
 class CheckOverRecursedFailure;
 class CheckOverRecursedFailurePar;
 class OutOfLineCheckInterruptPar;
+class OutOfLineInterruptCheckImplicit;
 class OutOfLineUnboxDouble;
 class OutOfLineStoreElementHole;
 class OutOfLineTypeOfV;
 class OutOfLineLoadTypedArray;
 class OutOfLineNewGCThingPar;
 class OutOfLineUpdateCache;
 class OutOfLineCallPostWriteBarrier;
 
@@ -259,16 +260,19 @@ class CodeGenerator : public CodeGenerat
     bool visitAsmJSCheckOverRecursed(LAsmJSCheckOverRecursed *lir);
 
     bool visitCheckOverRecursedPar(LCheckOverRecursedPar *lir);
     bool visitCheckOverRecursedFailurePar(CheckOverRecursedFailurePar *ool);
 
     bool visitCheckInterruptPar(LCheckInterruptPar *lir);
     bool visitOutOfLineCheckInterruptPar(OutOfLineCheckInterruptPar *ool);
 
+    bool visitInterruptCheckImplicit(LInterruptCheckImplicit *ins);
+    bool visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit *ins);
+
     bool visitUnboxDouble(LUnboxDouble *lir);
     bool visitOutOfLineUnboxDouble(OutOfLineUnboxDouble *ool);
     bool visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool);
 
     bool visitOutOfLineNewGCThingPar(OutOfLineNewGCThingPar *ool);
     bool visitOutOfLineAbortPar(OutOfLineAbortPar *ool);
     bool visitOutOfLinePropagateAbortPar(OutOfLinePropagateAbortPar *ool);
     void loadJSScriptForBlock(MBasicBlock *block, Register reg);
@@ -338,16 +342,20 @@ class CodeGenerator : public CodeGenerat
                          OutOfLineTestObject *ool);
 
     // Like testValueTruthy but takes an object, and |ool| must be non-null.
     // (If it's known that an object can never emulate |undefined| it shouldn't
     // be tested in the first place.)
     void testObjectTruthy(Register objreg, Label *ifTruthy, Label *ifFalsy, Register scratch,
                           OutOfLineTestObject *ool);
 
+    // Get a label for the start of block which can be used for jumping, in
+    // place of jumpToBlock.
+    Label *getJumpLabelForBranch(MBasicBlock *block);
+
     // Bailout if an element about to be written to is a hole.
     bool emitStoreHoleCheck(Register elements, const LAllocation *index, LSnapshot *snapshot);
 
     // Script counts created when compiling code with no associated JSScript.
     IonScriptCounts *unassociatedScriptCounts_;
 
     PerfSpewer perfSpewer_;
 };
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -12,16 +12,17 @@
 #include "jsworkers.h"
 #if JS_TRACE_LOGGING
 #include "TraceLogging.h"
 #endif
 
 #include "gc/Marking.h"
 #include "jit/AliasAnalysis.h"
 #include "jit/AsmJSModule.h"
+#include "jit/AsmJSSignalHandlers.h"
 #include "jit/BacktrackingAllocator.h"
 #include "jit/BaselineCompiler.h"
 #include "jit/BaselineInspector.h"
 #include "jit/BaselineJIT.h"
 #include "jit/CodeGenerator.h"
 #include "jit/CompilerRoot.h"
 #include "jit/EdgeCaseAnalysis.h"
 #include "jit/EffectiveAddressAnalysis.h"
@@ -164,40 +165,49 @@ ion::InitializeIon()
 #endif
     CheckLogging();
     CheckPerf();
     return true;
 }
 
 IonRuntime::IonRuntime()
   : execAlloc_(NULL),
+    ionAlloc_(NULL),
     exceptionTail_(NULL),
     bailoutTail_(NULL),
     enterJIT_(NULL),
     bailoutHandler_(NULL),
     argumentsRectifier_(NULL),
     argumentsRectifierReturnAddr_(NULL),
     parallelArgumentsRectifier_(NULL),
     invalidator_(NULL),
     debugTrapHandler_(NULL),
     functionWrappers_(NULL),
     osrTempData_(NULL),
-    flusher_(NULL)
+    flusher_(NULL),
+    signalHandlersInstalled_(false),
+    ionCodeProtected_(false)
 {
 }
 
 IonRuntime::~IonRuntime()
 {
     js_delete(functionWrappers_);
     freeOsrTempData();
+
+    // Note: the operation callback lock is not taken here as IonRuntime is
+    // only destroyed along with its containing JSRuntime.
+    js_delete(ionAlloc_);
 }
 
 bool
 IonRuntime::initialize(JSContext *cx)
 {
+    JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
+
     AutoLockForExclusiveAccess lock(cx);
     AutoCompartment ac(cx, cx->atomsCompartment());
 
     IonContext ictx(cx, NULL);
     AutoFlushCache afc("IonRuntime::initialize");
 
     execAlloc_ = cx->runtime()->getExecAlloc(cx);
     if (!execAlloc_)
@@ -268,16 +278,18 @@ IonRuntime::initialize(JSContext *cx)
     if (!shapePreBarrier_)
         return false;
 
     for (VMFunction *fun = VMFunction::functions; fun; fun = fun->next) {
         if (!generateVMWrapper(cx, *fun))
             return false;
     }
 
+    signalHandlersInstalled_ = EnsureAsmJSSignalHandlersInstalled(cx->runtime());
+
     return true;
 }
 
 IonCode *
 IonRuntime::debugTrapHandler(JSContext *cx)
 {
     if (!debugTrapHandler_) {
         // IonRuntime code stubs are shared across compartments and have to
@@ -298,16 +310,158 @@ IonRuntime::allocateOsrTempData(size_t s
 
 void
 IonRuntime::freeOsrTempData()
 {
     js_free(osrTempData_);
     osrTempData_ = NULL;
 }
 
+JSC::ExecutableAllocator *
+IonRuntime::createIonAlloc(JSContext *cx)
+{
+    JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
+
+    JSC::AllocationBehavior randomize =
+        cx->runtime()->jitHardening ? JSC::AllocationCanRandomize : JSC::AllocationDeterministic;
+    ionAlloc_ = js_new<JSC::ExecutableAllocator>(randomize);
+    if (!ionAlloc_)
+        js_ReportOutOfMemory(cx);
+    return ionAlloc_;
+}
+
+void
+IonRuntime::ensureIonCodeProtected(JSRuntime *rt)
+{
+    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+
+    if (!signalHandlersInstalled_ || ionCodeProtected_ || !ionAlloc_)
+        return;
+
+    // Protect all Ion code in the runtime to trigger an access violation the
+    // next time any of it runs on the main thread.
+    ionAlloc_->toggleAllCodeAsAccessible(false);
+    ionCodeProtected_ = true;
+}
+
+bool
+IonRuntime::handleAccessViolation(JSRuntime *rt, void *faultingAddress)
+{
+    if (!signalHandlersInstalled_ || !ionAlloc_ || !ionAlloc_->codeContains((char *) faultingAddress))
+        return false;
+
+#ifdef JS_THREADSAFE
+    // All places where the operation callback lock is taken must either ensure
+    // that Ion code memory won't be accessed within, or call ensureIonCodeAccessible
+    // to render the memory safe for accessing. Otherwise taking the lock below
+    // will deadlock the process.
+    JS_ASSERT(!rt->currentThreadOwnsOperationCallbackLock());
+#endif
+
+    // Taking this lock is necessary to prevent the interrupting thread from marking
+    // the memory as inaccessible while we are patching backedges. This will cause us
+    // to SEGV while still inside the signal handler, and the process will terminate.
+    JSRuntime::AutoLockForOperationCallback lock(rt);
+
+    ensureIonCodeAccessible(rt);
+    return true;
+}
+
+void
+IonRuntime::ensureIonCodeAccessible(JSRuntime *rt)
+{
+    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+
+    // This can only be called on the main thread and while handling signals,
+    // which happens on a separate thread in OS X.
+#ifndef XP_MACOSX
+    JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
+#endif
+
+    if (!ionCodeProtected_)
+        return;
+
+    // Ion code in the runtime faulted after it was made inaccessible. Reset
+    // the code privileges and patch all loop backedges to perform an interrupt
+    // check instead.
+    ionAlloc_->toggleAllCodeAsAccessible(true);
+    ionCodeProtected_ = false;
+
+    if (rt->interrupt) {
+        // The interrupt handler needs to be invoked by this thread, but we
+        // are inside a signal handler and have no idea what is above us on the
+        // stack (probably we are executing Ion code at an arbitrary point, but
+        // we could be elsewhere, say repatching a jump for an IonCache).
+        // Patch all backedges in the runtime so they will invoke the interrupt
+        // handler the next time they execute.
+        patchIonBackedges(rt, BackedgeInterruptCheck);
+    }
+}
+
+void
+IonRuntime::patchIonBackedges(JSRuntime *rt, BackedgeTarget target)
+{
+#ifndef XP_MACOSX
+    JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
+#endif
+
+    // Patch all loop backedges in Ion code so that they either jump to the
+    // normal loop header or to an interrupt handler each time they run.
+    for (InlineListIterator<PatchableBackedge> iter(backedgeList_.begin());
+         iter != backedgeList_.end();
+         iter++)
+    {
+        PatchableBackedge *patchableBackedge = *iter;
+        PatchJump(patchableBackedge->backedge, target == BackedgeLoopHeader
+                                               ? patchableBackedge->loopHeader
+                                               : patchableBackedge->interruptCheck);
+    }
+}
+
+void
+ion::TriggerOperationCallbackForIonCode(JSRuntime *rt,
+                                        JSRuntime::OperationCallbackTrigger trigger)
+{
+    IonRuntime *ion = rt->ionRuntime();
+    if (!ion)
+        return;
+
+    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+
+    // The mechanism for interrupting normal ion code varies between how the
+    // interrupt is being triggered.
+    switch (trigger) {
+      case JSRuntime::TriggerCallbackMainThread:
+        // When triggering an interrupt from the main thread, Ion loop
+        // backedges can be patched directly. Make sure we don't segv while
+        // patching the backedges, to avoid deadlocking inside the signal
+        // handler.
+        JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
+        ion->ensureIonCodeAccessible(rt);
+        break;
+
+      case JSRuntime::TriggerCallbackAnyThread:
+        // When triggering an interrupt from off the main thread, protect
+        // Ion code memory so that the main thread will fault and enter a
+        // signal handler when trying to execute the code. The signal
+        // handler will unprotect the code and patch loop backedges so
+        // that the interrupt handler is invoked afterwards.
+        ion->ensureIonCodeProtected(rt);
+        break;
+
+      case JSRuntime::TriggerCallbackAnyThreadDontStopIon:
+        // When the trigger does not require Ion code to be interrupted,