Merge m-c to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 27 Sep 2013 12:48:22 +0200
changeset 149091 6b28fcac0f0669d38aba5d28f6918e10d2254b13
parent 149090 72a469699ec39b75f8557e7862745a83fe8ab6b0 (current diff)
parent 148971 3ad5ecf34c9e55a4c7040d0bdd02387ba2495183 (diff)
child 149092 061c17bbab44543d27b820d3c49fb8bba5e1978b
push id34439
push userkwierso@gmail.com
push dateSat, 28 Sep 2013 03:39:12 +0000
treeherdermozilla-inbound@caec8c0c4963 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team
config/makefiles/precompile/Makefile.in
config/makefiles/precompile/moz.build
--- a/Makefile.in
+++ b/Makefile.in
@@ -222,12 +222,12 @@ ifdef ENABLE_TESTS
 # Incorporate static tier directories into tests. This should be incorporated
 # into moz.build files someday.
 check::
 	$(call SUBMAKE,$@,js/src)
 endif
 
 ifdef MOZ_PSEUDO_DERECURSE
 # Interdependencies for parallel export.
-js/xpconnect/src/export: config/makefiles/precompile/export
-accessible/src/xpcom/export: config/makefiles/precompile/export
+js/xpconnect/src/export: dom/bindings/export
+accessible/src/xpcom/export: xpcom/xpidl/export
 js/src/export: mfbt/export
 endif
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -224,16 +224,19 @@ class PluginTimerCallBack MOZ_FINAL : pu
 {
 public:
   PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
 
   NS_DECL_ISUPPORTS
 
   NS_IMETHODIMP Notify(nsITimer* aTimer) MOZ_FINAL
   {
+    if (!mContent->IsInDoc())
+      return NS_OK;
+
     nsIPresShell* ps = mContent->OwnerDoc()->GetShell();
     if (ps) {
       DocAccessible* doc = ps->GetDocAccessible();
       if (doc) {
         // Make sure that if we created an accessible for the plugin that wasn't
         // a plugin accessible we remove it before creating the right accessible.
         doc->RecreateAccessible(mContent);
         sPluginTimers->RemoveElement(aTimer);
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "c9f88878f616a439db6c6be66378af79249f7528", 
+    "revision": "6b82ab58ac7e7cbce89a6718659311a1ce6b7436", 
     "repo_path": "/integration/gaia-central"
 }
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -166,16 +166,22 @@ AC_DEFUN([MOZ_COMPILER_OPTS],
   MOZ_ARG_ENABLE_BOOL(release,
   [  --enable-release        Build with more conservative, release engineering-oriented options.
                           This may slow down builds.],
       DEVELOPER_OPTIONS=,
       DEVELOPER_OPTIONS=1)
 
   AC_SUBST(DEVELOPER_OPTIONS)
 
+  if test -n "$DEVELOPER_OPTIONS" -a "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
+    dnl Don't enable on pymake, because of bug 918652. Bug 912979 is an annoyance
+    dnl with pymake, too.
+    MOZ_PSEUDO_DERECURSE=no-parallel-export,no-pymake
+  fi
+
   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.
     ##
@@ -189,30 +195,41 @@ 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
+if test -n "$DEVELOPER_OPTIONS"; then
+    MOZ_FORCE_GOLD=1
+fi
+
+MOZ_ARG_ENABLE_BOOL(gold,
+[  --enable-gold           Enable GNU Gold Linker when it is not already the default],
+    MOZ_FORCE_GOLD=1,
+    MOZ_FORCE_GOLD=
+    )
+
+if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; 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
+            rm -f $_objdir/build/unix/gold/ld
             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
--- a/config/config.mk
+++ b/config/config.mk
@@ -94,16 +94,25 @@ BUILD_TOOLS	= $(WIN_TOP_SRC)/build/unix
 else
 win_srcdir	:= $(srcdir)
 BUILD_TOOLS	= $(topsrcdir)/build/unix
 endif
 
 CONFIG_TOOLS	= $(MOZ_BUILD_ROOT)/config
 AUTOCONF_TOOLS	= $(topsrcdir)/build/autoconf
 
+# Disable MOZ_PSEUDO_DERECURSE when it contains no-pymake and we're running
+# pymake. This can be removed when no-pymake is removed from the default in
+# build/autoconf/compiler-opts.m4.
+ifdef .PYMAKE
+comma = ,
+ifneq (,$(filter no-pymake,$(subst $(comma), ,$(MOZ_PSEUDO_DERECURSE))))
+MOZ_PSEUDO_DERECURSE :=
+endif
+endif
 #
 # Strip off the excessively long version numbers on these platforms,
 # but save the version to allow multiple versions of the same base
 # platform to be built in the same tree.
 #
 ifneq (,$(filter FreeBSD HP-UX Linux NetBSD OpenBSD SunOS,$(OS_ARCH)))
 OS_RELEASE	:= $(basename $(OS_RELEASE))
 
--- a/config/expandlibs.py
+++ b/config/expandlibs.py
@@ -63,16 +63,23 @@ def relativize(path):
         return relpath
     return path
 
 def isObject(path):
     '''Returns whether the given path points to an object file, that is,
     ends with OBJ_SUFFIX or .i_o'''
     return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
 
+def isDynamicLib(path):
+    '''Returns whether the given path points to a dynamic library, that is,
+    ends with DLL_SUFFIX.'''
+    # On mac, the xul library is named XUL, instead of libxul.dylib. Assume any
+    # file by that name is a dynamic library.
+    return os.path.splitext(path)[1] == conf.DLL_SUFFIX or os.path.basename(path) == 'XUL'
+
 class LibDescriptor(dict):
     KEYS = ['OBJS', 'LIBS']
 
     def __init__(self, content=None):
         '''Creates an instance of a lib descriptor, initialized with contents
         from a list of strings when given. This is intended for use with
         file.readlines()'''
         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -18,24 +18,32 @@ See https://bugzilla.mozilla.org/show_bu
 
 With the --symbol-order argument, followed by a file name, it will add the
 relevant linker options to change the order in which the linker puts the
 symbols appear in the resulting binary. Only works for ELF targets.
 '''
 from __future__ import with_statement
 import sys
 import os
-from expandlibs import ExpandArgs, relativize, isObject, ensureParentDir, ExpandLibsDeps
+from expandlibs import (
+    ExpandArgs,
+    relativize,
+    isDynamicLib,
+    isObject,
+    ensureParentDir,
+    ExpandLibsDeps,
+)
 import expandlibs_config as conf
 from optparse import OptionParser
 import subprocess
 import tempfile
 import shutil
 import subprocess
 import re
+from mozbuild.makeutil import Makefile
 
 # The are the insert points for a GNU ld linker script, assuming a more
 # or less "standard" default linker script. This is not a dict because
 # order is important.
 SECTION_INSERT_BEFORE = [
   ('.text', '.fini'),
   ('.rodata', '.rodata1'),
   ('.data.rel.ro', '.dynamic'),
@@ -328,17 +336,20 @@ def main():
             print_command(sys.stderr, args)
         sys.stderr.write(stdout)
         sys.stderr.flush()
         if proc.returncode:
             exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
-    with open(options.depend, 'w') as depfile:
-        depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
+    mk = Makefile()
+    deps = [dep for dep in deps if os.path.isfile(dep) and dep != options.target]
+    no_dynamic_lib = [dep for dep in deps if not isDynamicLib(dep)]
+    mk.create_rule([options.target]).add_dependencies(no_dynamic_lib)
+    if len(deps) != len(no_dynamic_lib):
+        mk.create_rule(['%s_order_only' % options.target]).add_dependencies(dep for dep in deps if isDynamicLib(dep))
 
-        for dep in deps:
-            if os.path.isfile(dep) and dep != options.target:
-                depfile.write("%s :\n" % dep)
+    with open(options.depend, 'w') as depfile:
+        mk.dump(depfile, removal_guard=True)
 
 if __name__ == '__main__':
     main()
deleted file mode 100644
--- a/config/makefiles/precompile/Makefile.in
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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/.
-
-# This make file defines the precompile tier. This tier effectively fans out
-# to other make files and specialized targets.
-
-SUPPRESS_DEFAULT_RULES := 1
-
-default::
-	+$(MAKE) export
-
-export:: ipdl webidl xpidl
-
-ipdl:
-	$(call SUBMAKE,ipdl,$(DEPTH)/ipc/ipdl)
-
-webidl:
-	$(call SUBMAKE,webidl,$(DEPTH)/dom/bindings)
-
-xpidl:
-	$(call SUBMAKE,xpidl-parser,$(DEPTH)/xpcom/idl-parser)
-	$(call py_action,process_install_manifest,$(DIST)/idl $(DEPTH)/_build_manifests/install/dist_idl)
-	$(call SUBMAKE,xpidl,$(DEPTH)/config/makefiles/xpidl)
deleted file mode 100644
--- a/config/makefiles/precompile/moz.build
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
--- a/configure.in
+++ b/configure.in
@@ -889,19 +889,18 @@ MOZ_JPEG_CFLAGS=
 MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,mozjpeg,$(DEPTH)/media/libjpeg)'
 MOZ_BZ2_CFLAGS=
 MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)'
 MOZ_PNG_CFLAGS=
 MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/media/libpng)'
 
 MOZ_JS_STATIC_LIBS='$(call EXPAND_LIBNAME_PATH,js_static,$(LIBXUL_DIST)/lib)'
 MOZ_JS_SHARED_LIBS='$(call EXPAND_LIBNAME_PATH,mozjs,$(LIBXUL_DIST)/lib)'
-DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/bin -lxul -lxpcom_core -lmozalloc'
 MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(prefix)/lib'
-XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/bin -lxul -lmozalloc'
+XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/bin)'
 LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS)'
 XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
 XPCOM_STANDALONE_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX)'
 
 # These are specially defined on Windows only
 case "$target" in
 *-mingw*)
   XPCOM_STATICRUNTIME_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_staticruntime_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
@@ -1973,16 +1972,17 @@ ia64*-hpux*)
 *-mingw*)
     DSO_CFLAGS=
     DSO_PIC_CFLAGS=
     DLL_SUFFIX=.dll
     RC=rc.exe
     MC=mc.exe
     # certain versions of cygwin's makedepend barf on the
     # #include <string> vs -I./dist/include/string issue so don't use it
+    XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/lib)'
     if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
         CC="$CC -mwindows"
         CXX="$CXX -mwindows"
         CPP="$CPP -mwindows"
         CFLAGS="$CFLAGS -mms-bitfields"
         CXXFLAGS="$CXXFLAGS -mms-bitfields"
         DSO_LDOPTS='-shared'
         MKSHLIB='$(CXX) $(DSO_LDOPTS) -o $@'
@@ -1991,18 +1991,16 @@ ia64*-hpux*)
         # Use static libgcc and libstdc++
         LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++"
         NSPR_LDFLAGS="$NSPR_LDFLAGS -static-libgcc"
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32 -luserenv -lsecur32 -lnetapi32"
         MOZ_FIX_LINK_PATHS=
-        DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxul -lxpcom_core -lmozalloc'
-        XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxul -lmozalloc'
         DLL_PREFIX=
         IMPORT_LIB_SUFFIX=dll.a
 
         # We use mix of both POSIX and Win32 printf format across the tree, so format
         # warnings are useless on mingw.
         MOZ_C_SUPPORTS_WARNING(-Wno-, format, ac_c_has_wno_format)
         MOZ_CXX_SUPPORTS_WARNING(-Wno-, format, ac_cxx_has_wno_format)
     else
@@ -2067,19 +2065,16 @@ ia64*-hpux*)
         CFLAGS="$CFLAGS -we4553"
         CXXFLAGS="$CXXFLAGS -we4553"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib secur32.lib netapi32.lib"
         MOZ_DEBUG_FLAGS='-Zi'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
         MOZ_OPTIMIZE_FLAGS='-O1'
         MOZ_FIX_LINK_PATHS=
-        DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
-        XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
-        LIBXUL_LIBS='$(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
         MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
         LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
         if test -z "$DEVELOPER_OPTIONS"; then
             LDFLAGS="$LDFLAGS -RELEASE"
         fi
         dnl For profile-guided optimization
         PROFILE_GEN_CFLAGS="-GL"
         PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
@@ -2241,17 +2236,16 @@ ia64*-hpux*)
     BIN_FLAGS='-Zlinker /ST:0x100000'
     IMPLIB='emximp -o'
     FILTER='true'
     LDFLAGS='-Zmap'
     WARNINGS_AS_ERRORS='-Werror'
     MOZ_DEBUG_FLAGS="-g -fno-inline"
     MOZ_OPTIMIZE_FLAGS="-O2"
     MOZ_OPTIMIZE_LDFLAGS="-s -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
-    DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
     LIBXUL_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
     TARGET_MD_ARCH=os2
     _PLATFORM_DEFAULT_TOOLKIT="cairo-os2"
     RC=rc.exe
     MC=mc.exe
     RCFLAGS='-n'
     MOZ_USER_DIR="Mozilla"
     ZIP="$ZIP -X"
@@ -3193,17 +3187,16 @@ AC_CACHE_CHECK(
             iconv_close(h);
         ],
         [ac_cv_func_iconv=yes],
         [ac_cv_func_iconv=no]
         )]
     )
 if test "$ac_cv_func_iconv" = "yes"; then
     AC_DEFINE(HAVE_ICONV)
-    DYNAMIC_XPCOM_LIBS="$DYNAMIC_XPCOM_LIBS $_ICONV_LIBS"
     LIBXUL_LIBS="$LIBXUL_LIBS $_ICONV_LIBS"
     LIBICONV="$_ICONV_LIBS"
     AC_CACHE_CHECK(
         [for iconv() with const input],
         ac_cv_func_const_iconv,
         [AC_TRY_COMPILE([
             #include <stdlib.h>
             #include <iconv.h>
@@ -4424,49 +4417,48 @@ cairo-os2)
 cairo-cocoa)
     MOZ_WIDGET_TOOLKIT=cocoa
     AC_DEFINE(MOZ_WIDGET_COCOA)
     LDFLAGS="$LDFLAGS -framework Cocoa -lobjc"
     TK_LIBS='-framework CoreLocation -framework QuartzCore -framework Carbon -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework AddressBook -framework OpenGL'
     TK_CFLAGS="-DNO_X11"
     CFLAGS="$CFLAGS $TK_CFLAGS"
     CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
-    DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/bin/XUL -lxpcom_core -lmozalloc'
-    XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL -lmozalloc'
+    XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL $(call EXPAND_LIBNAME_PATH,mozalloc,$(LIBXUL_DIST)/bin)'
     MOZ_USER_DIR="Mozilla"
     MOZ_FS_LAYOUT=bundle
     MOZ_WEBGL=1
     MOZ_INSTRUMENT_EVENT_LOOP=1
     ;;
 
 cairo-uikit)
     MOZ_WIDGET_TOOLKIT=uikit
     AC_DEFINE(MOZ_WIDGET_UIKIT)
     LDFLAGS="$LDFLAGS -framework UIKit -lobjc"
     TK_CFLAGS="-DNO_X11"
     TK_LIBS='-framework Foundation -framework CoreFoundation -framework CoreGraphics -framework CoreText'
     CFLAGS="$CFLAGS $TK_CFLAGS"
     CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
-    DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/bin/XUL -lxpcom_core -lmozalloc'
-    XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL -lmozalloc'
+    XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL $(call EXPAND_LIBNAME_PATH,mozalloc,$(LIBXUL_DIST)/bin)'
     MOZ_USER_DIR="Mozilla"
     MOZ_FS_LAYOUT=bundle
     ;;
 
 cairo-android)
     AC_DEFINE(MOZ_WIDGET_ANDROID)
     MOZ_WIDGET_TOOLKIT=android
     TK_CFLAGS='$(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)'
     TK_LIBS='$(MOZ_CAIRO_LIBS) $(MOZ_PIXMAN_LIBS)'
     MOZ_WEBGL=1
     MOZ_PDF_PRINTING=1
     MOZ_INSTRUMENT_EVENT_LOOP=1
     ;;
 
 cairo-gonk)
+    XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/lib)'
     AC_DEFINE(MOZ_WIDGET_GONK)
     AC_DEFINE(MOZ_TOUCH)
     MOZ_WIDGET_TOOLKIT=gonk
     TK_CFLAGS='$(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS)'
     TK_LIBS='$(MOZ_CAIRO_LIBS) $(MOZ_PIXMAN_LIBS)'
     MOZ_WEBGL=1
     MOZ_PDF_PRINTING=1
     MOZ_TOUCH=1
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -1031,17 +1031,17 @@ nsEventListenerManager::HandleEventInter
           }
         }
       }
     }
   }
 
   aEvent->currentTarget = nullptr;
 
-  if (!hasListener) {
+  if (mIsMainThreadELM && !hasListener) {
     mNoListenerForEvent = aEvent->message;
     mNoListenerForEventAtom = aEvent->userType;
   }
 
   if (aEvent->mFlags.mDefaultPrevented) {
     *aEventStatus = nsEventStatus_eConsumeNoDefault;
   }
 }
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -114,17 +114,17 @@ INSTALL_TARGETS += EXPORTS_GENERATED
 globalgen_headers_FILES := \
   GeneratedAtomList.h \
   PrototypeList.h \
   RegisterBindings.h \
   UnionConversions.h \
   UnionTypes.h \
   $(NULL)
 globalgen_headers_DEST = $(DIST)/include/mozilla/dom
-globalgen_headers_TARGET := webidl
+globalgen_headers_TARGET := export
 INSTALL_TARGETS += globalgen_headers
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifdef GNU_CC
 CXXFLAGS += -Wno-uninitialized
 endif
@@ -266,26 +266,18 @@ GARBAGE += \
   $(binding_dependency_trackers) \
   $(NULL)
 
 # Make sure all binding header files are created during the export stage, so we
 # don't have issues with .cpp files being compiled before we've generated the
 # headers they depend on.  This is really only needed for the test files, since
 # the non-test headers are all exported above anyway.  Note that this means that
 # we do all of our codegen during export.
-webidl:: $(generated_header_files)
-
-.PHONY: webidl
+export:: $(generated_header_files)
 
 distclean::
 	-$(RM) \
         $(generated_header_files) \
         $(generated_cpp_files) \
         $(all_webidl_files) \
         $(globalgen_targets) \
         ParserResults.pkl \
         $(NULL)
-
-# This is only needed to support |make| from this leaf directory/Makefile.
-NONRECURSIVE_TARGETS := export
-NONRECURSIVE_TARGETS_export := webidl
-NONRECURSIVE_TARGETS_export_webidl_DIRECTORY := .
-NONRECURSIVE_TARGETS_export_webidl_TARGETS := webidl
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
 
 #include "IDBIndex.h"
 
 #include "nsIIDBKeyRange.h"
 
+#include <algorithm>
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/storage.h"
 #include "nsEventDispatcher.h"
 #include "nsThreadUtils.h"
 #include "xpcpublic.h"
 
@@ -558,16 +559,17 @@ already_AddRefed<IDBRequest>
 IDBIndex::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit,
                              ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   IDBTransaction* transaction = mObjectStore->Transaction();
   if (!transaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
   }
 
   nsRefPtr<IDBRequest> request = GenerateRequest(this);
   if (!request) {
     NS_WARNING("Failed to generate request!");
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
     return nullptr;
   }
@@ -1362,20 +1364,21 @@ GetHelper::UnpackResponseFromParentProce
   IDBObjectStore::ConvertActorsToBlobs(getResponse.blobsChild(),
                                        mCloneReadInfo.mFiles);
   return NS_OK;
 }
 
 nsresult
 GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
 {
-  NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
-
-  PROFILER_LABEL("IndexedDB", "GetAllKeysHelper::DoDatabaseWork");
+  MOZ_ASSERT(!NS_IsMainThread());
+  MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
+
+  PROFILER_LABEL("IndexedDB",
+                 "GetAllKeysHelper::DoDatabaseWork [IDBIndex.cpp]");
 
   nsCString tableName;
   if (mIndex->IsUnique()) {
     tableName.AssignLiteral("unique_index_data");
   }
   else {
     tableName.AssignLiteral("index_data");
   }
@@ -1405,17 +1408,17 @@ GetAllKeysHelper::DoDatabaseWork(mozISto
                                       mIndex->Id());
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   if (mKeyRange) {
     rv = mKeyRange->BindToStatement(stmt);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  mKeys.SetCapacity(50);
+  mKeys.SetCapacity(std::min<uint32_t>(50, mLimit));
 
   bool hasResult;
   while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
     if (mKeys.Capacity() == mKeys.Length()) {
       mKeys.SetCapacity(mKeys.Capacity() * 2);
     }
 
     Key* key = mKeys.AppendElement();
@@ -1428,17 +1431,22 @@ GetAllKeysHelper::DoDatabaseWork(mozISto
 
   return NS_OK;
 }
 
 nsresult
 GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
                                    JS::MutableHandle<JS::Value> aVal)
 {
-  NS_ASSERTION(mKeys.Length() <= mLimit, "Too many results!");
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mKeys.Length() <= mLimit);
+
+  PROFILER_MAIN_THREAD_LABEL("IndexedDB",
+                             "GetAllKeysHelper::GetSuccessResult "
+                             "[IDBIndex.cpp]");
 
   nsTArray<Key> keys;
   mKeys.SwapElements(keys);
 
   JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, NULL));
   if (!array) {
     NS_WARNING("Failed to make array!");
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
@@ -1470,21 +1478,22 @@ GetAllKeysHelper::GetSuccessResult(JSCon
 
   aVal.setObject(*array);
   return NS_OK;
 }
 
 nsresult
 GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
 
   PROFILER_MAIN_THREAD_LABEL("IndexedDB",
-                             "GetAllKeysHelper::PackArgumentsForParentProcess");
+                             "GetAllKeysHelper::PackArgumentsForParentProcess "
+                             "[IDBIndex.cpp]");
 
   GetAllKeysParams params;
 
   if (mKeyRange) {
     KeyRange keyRange;
     mKeyRange->ToSerializedKeyRange(keyRange);
     params.optionalKeyRange() = keyRange;
   }
@@ -1496,21 +1505,22 @@ GetAllKeysHelper::PackArgumentsForParent
 
   aParams = params;
   return NS_OK;
 }
 
 AsyncConnectionHelper::ChildProcessSendResult
 GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
 
   PROFILER_MAIN_THREAD_LABEL("IndexedDB",
-                             "GetAllKeysHelper::SendResponseToChildProcess");
+                             "GetAllKeysHelper::SendResponseToChildProcess "
+                             "[IDBIndex.cpp]");
 
   IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
   NS_ASSERTION(actor, "How did we get this far without an actor?");
 
   ResponseValue response;
   if (NS_FAILED(aResultCode)) {
     response = aResultCode;
   }
@@ -1526,18 +1536,19 @@ GetAllKeysHelper::SendResponseToChildPro
 
   return Success_Sent;
 }
 
 nsresult
 GetAllKeysHelper::UnpackResponseFromParentProcess(
                                             const ResponseValue& aResponseValue)
 {
-  NS_ASSERTION(aResponseValue.type() == ResponseValue::TGetAllKeysResponse,
-               "Bad response type!");
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
+  MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse);
 
   mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys());
   return NS_OK;
 }
 
 nsresult
 GetAllHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
 {
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -6,16 +6,17 @@
 
 #include "base/basictypes.h"
 
 #include "IDBObjectStore.h"
 
 #include "mozilla/dom/ipc/nsIRemoteBlob.h"
 #include "nsIOutputStream.h"
 
+#include <algorithm>
 #include "jsfriendapi.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/FileHandleBinding.h"
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/dom/quota/FileStreams.h"
 #include "mozilla/storage.h"
@@ -436,16 +437,56 @@ protected:
   nsRefPtr<IDBKeyRange> mKeyRange;
   const uint32_t mLimit;
 
 private:
   // Out-params.
   nsTArray<StructuredCloneReadInfo> mCloneReadInfos;
 };
 
+class GetAllKeysHelper MOZ_FINAL : public ObjectStoreHelper
+{
+public:
+  GetAllKeysHelper(IDBTransaction* aTransaction,
+                   IDBRequest* aRequest,
+                   IDBObjectStore* aObjectStore,
+                   IDBKeyRange* aKeyRange,
+                   const uint32_t aLimit)
+  : ObjectStoreHelper(aTransaction, aRequest, aObjectStore),
+    mKeyRange(aKeyRange), mLimit(aLimit)
+  { }
+
+  virtual nsresult
+  DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
+
+  virtual nsresult
+  GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal) MOZ_OVERRIDE;
+
+  virtual void
+  ReleaseMainThreadObjects() MOZ_OVERRIDE;
+
+  virtual nsresult
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+
+  virtual ChildProcessSendResult
+  SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
+
+  virtual nsresult
+  UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
+                                  MOZ_OVERRIDE;
+
+private:
+  ~GetAllKeysHelper()
+  { }
+
+  nsRefPtr<IDBKeyRange> mKeyRange;
+  const uint32_t mLimit;
+  nsTArray<Key> mKeys;
+};
+
 class CountHelper : public ObjectStoreHelper
 {
 public:
   CountHelper(IDBTransaction* aTransaction,
               IDBRequest* aRequest,
               IDBObjectStore* aObjectStore,
               IDBKeyRange* aKeyRange)
   : ObjectStoreHelper(aTransaction, aRequest, aObjectStore),
@@ -2077,16 +2118,57 @@ IDBObjectStore::GetAllInternal(IDBKeyRan
                     IDB_PROFILER_STRING(Transaction()),
                     IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange),
                     aLimit);
 
   return request.forget();
 }
 
 already_AddRefed<IDBRequest>
+IDBObjectStore::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit,
+                                   ErrorResult& aRv)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!mTransaction->IsOpen()) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
+  }
+
+  nsRefPtr<IDBRequest> request = GenerateRequest(this);
+  if (!request) {
+    NS_WARNING("Failed to generate request!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
+
+  nsRefPtr<GetAllKeysHelper> helper =
+    new GetAllKeysHelper(mTransaction, request, this, aKeyRange, aLimit);
+
+  nsresult rv = helper->DispatchToTransactionPool();
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Failed to dispatch!");
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+    return nullptr;
+  }
+
+  IDB_PROFILER_MARK("IndexedDB Request %llu: "
+                    "database(%s).transaction(%s).objectStore(%s)."
+                    "getAllKeys(%s, %lu)",
+                    "IDBRequest[%llu] MT IDBObjectStore.getAllKeys()",
+                    request->GetSerialNumber(),
+                    IDB_PROFILER_STRING(Transaction()->Database()),
+                    IDB_PROFILER_STRING(Transaction()),
+                    IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange),
+                    aLimit);
+
+  return request.forget();
+}
+
+already_AddRefed<IDBRequest>
 IDBObjectStore::DeleteInternal(IDBKeyRange* aKeyRange,
                                ErrorResult& aRv)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(aKeyRange, "Null key range!");
 
   if (!mTransaction->IsOpen()) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
@@ -2762,16 +2844,42 @@ IDBObjectStore::Count(JSContext* aCx,
   if (aKey.WasPassed()) {
     aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
     ENSURE_SUCCESS(aRv, nullptr);
   }
 
   return CountInternal(keyRange, aRv);
 }
 
+already_AddRefed<IDBRequest>
+IDBObjectStore::GetAllKeys(JSContext* aCx,
+                           const Optional<JS::HandleValue>& aKey,
+                           const Optional<uint32_t>& aLimit, ErrorResult& aRv)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (!mTransaction->IsOpen()) {
+    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
+    return nullptr;
+  }
+
+  nsRefPtr<IDBKeyRange> keyRange;
+  if (aKey.WasPassed()) {
+    aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
+    ENSURE_SUCCESS(aRv, nullptr);
+  }
+
+  uint32_t limit = UINT32_MAX;
+  if (aLimit.WasPassed() && aLimit.Value() != 0) {
+    limit = aLimit.Value();
+  }
+
+  return GetAllKeysInternal(keyRange, limit, aRv);
+}
+
 inline nsresult
 CopyData(nsIInputStream* aInputStream, nsIOutputStream* aOutputStream)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
 
   PROFILER_LABEL("IndexedDB", "CopyData");
 
@@ -4293,16 +4401,205 @@ GetAllHelper::UnpackResponseFromParentPr
 
     IDBObjectStore::ConvertActorsToBlobs(blobs, destInfo->mFiles);
   }
 
   return NS_OK;
 }
 
 nsresult
+GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+  MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
+
+  PROFILER_LABEL("IndexedDB",
+                 "GetAllKeysHelper::DoDatabaseWork [IDObjectStore.cpp]");
+
+  NS_NAMED_LITERAL_CSTRING(keyValue, "key_value");
+
+  nsAutoCString keyRangeClause;
+  if (mKeyRange) {
+    mKeyRange->GetBindingClause(keyValue, keyRangeClause);
+  }
+
+  nsAutoCString limitClause;
+  if (mLimit != UINT32_MAX) {
+    limitClause = NS_LITERAL_CSTRING(" LIMIT ");
+    limitClause.AppendInt(mLimit);
+  }
+
+  NS_NAMED_LITERAL_CSTRING(osid, "osid");
+
+  nsCString query = NS_LITERAL_CSTRING("SELECT ") + keyValue +
+                    NS_LITERAL_CSTRING(" FROM object_data WHERE "
+                                       "object_store_id = :") +
+                    osid + keyRangeClause +
+                    NS_LITERAL_CSTRING(" ORDER BY key_value ASC") +
+                    limitClause;
+
+  nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
+  NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+  mozStorageStatementScoper scoper(stmt);
+
+  nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
+  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+  if (mKeyRange) {
+    rv = mKeyRange->BindToStatement(stmt);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  mKeys.SetCapacity(std::min<uint32_t>(50, mLimit));
+
+  bool hasResult;
+  while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
+    if (mKeys.Capacity() == mKeys.Length()) {
+      mKeys.SetCapacity(mKeys.Capacity() * 2);
+    }
+
+    Key* key = mKeys.AppendElement();
+    NS_ASSERTION(key, "This shouldn't fail!");
+
+    rv = key->SetFromStatement(stmt, 0);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+
+  return NS_OK;
+}
+
+nsresult
+GetAllKeysHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mKeys.Length() <= mLimit);
+
+  PROFILER_MAIN_THREAD_LABEL("IndexedDB",
+                             "GetAllKeysHelper::GetSuccessResult "
+                             "[IDBObjectStore.cpp]");
+
+  nsTArray<Key> keys;
+  mKeys.SwapElements(keys);
+
+  JS::RootedObject array(aCx, JS_NewArrayObject(aCx, 0, NULL));
+  if (!array) {
+    NS_WARNING("Failed to make array!");
+    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+  }
+
+  if (!keys.IsEmpty()) {
+    if (!JS_SetArrayLength(aCx, array, keys.Length())) {
+      NS_WARNING("Failed to set array length!");
+      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+    }
+
+    for (uint32_t index = 0, count = keys.Length(); index < count; index++) {
+      const Key& key = keys[index];
+      MOZ_ASSERT(!key.IsUnset());
+
+      JS::RootedValue value(aCx);
+      nsresult rv = key.ToJSVal(aCx, &value);
+      if (NS_FAILED(rv)) {
+        NS_WARNING("Failed to get jsval for key!");
+        return rv;
+      }
+
+      if (!JS_SetElement(aCx, array, index, &value)) {
+        NS_WARNING("Failed to set array element!");
+        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+      }
+    }
+  }
+
+  aVal.setObject(*array);
+  return NS_OK;
+}
+
+void
+GetAllKeysHelper::ReleaseMainThreadObjects()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  mKeyRange = nullptr;
+
+  ObjectStoreHelper::ReleaseMainThreadObjects();
+}
+
+nsresult
+GetAllKeysHelper::PackArgumentsForParentProcess(
+                                              ObjectStoreRequestParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
+
+  PROFILER_MAIN_THREAD_LABEL("IndexedDB",
+                             "GetAllKeysHelper::PackArgumentsForParentProcess "
+                             "[IDBObjectStore.cpp]");
+
+  GetAllKeysParams params;
+
+  if (mKeyRange) {
+    KeyRange keyRange;
+    mKeyRange->ToSerializedKeyRange(keyRange);
+    params.optionalKeyRange() = keyRange;
+  } else {
+    params.optionalKeyRange() = mozilla::void_t();
+  }
+
+  params.limit() = mLimit;
+
+  aParams = params;
+  return NS_OK;
+}
+
+AsyncConnectionHelper::ChildProcessSendResult
+GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
+
+  PROFILER_MAIN_THREAD_LABEL("IndexedDB",
+                             "GetAllKeysHelper::SendResponseToChildProcess "
+                             "[IDBObjectStore.cpp]");
+
+  IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
+  MOZ_ASSERT(actor);
+
+  ResponseValue response;
+  if (NS_FAILED(aResultCode)) {
+    response = aResultCode;
+  }
+  else {
+    GetAllKeysResponse getAllKeysResponse;
+    getAllKeysResponse.keys().AppendElements(mKeys);
+    response = getAllKeysResponse;
+  }
+
+  if (!actor->SendResponse(response)) {
+    return Error;
+  }
+
+  return Success_Sent;
+}
+
+nsresult
+GetAllKeysHelper::UnpackResponseFromParentProcess(
+                                            const ResponseValue& aResponseValue)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
+  MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse);
+
+  mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys());
+  return NS_OK;
+}
+
+nsresult
 CountHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
 
   PROFILER_LABEL("IndexedDB",
                  "CountHelper::DoDatabaseWork [IDBObjectStore.cpp]");
 
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.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_indexeddb_idbobjectstore_h__
 #define mozilla_dom_indexeddb_idbobjectstore_h__
 
 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
 
+#include "js/TypeDecls.h"
 #include "mozilla/dom/IDBCursorBinding.h"
 #include "mozilla/dom/IDBIndexBinding.h"
 #include "mozilla/dom/IDBObjectStoreBinding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "MainThreadUtils.h"
 
 #include "mozilla/dom/indexedDB/IDBRequest.h"
 #include "mozilla/dom/indexedDB/IDBTransaction.h"
@@ -216,29 +217,35 @@ public:
               ErrorResult& aRv);
 
   already_AddRefed<IDBRequest>
   GetAllInternal(IDBKeyRange* aKeyRange,
                  uint32_t aLimit,
                  ErrorResult& aRv);
 
   already_AddRefed<IDBRequest>
+  GetAllKeysInternal(IDBKeyRange* aKeyRange,
+                     uint32_t aLimit,
+                     ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
   DeleteInternal(IDBKeyRange* aKeyRange,
                  ErrorResult& aRv);
 
   already_AddRefed<IDBRequest>
   CountInternal(IDBKeyRange* aKeyRange,
                 ErrorResult& aRv);
 
   already_AddRefed<IDBRequest>
   OpenCursorInternal(IDBKeyRange* aKeyRange,
                      size_t aDirection,
                      ErrorResult& aRv);
 
-  nsresult OpenCursorFromChildProcess(
+  nsresult
+  OpenCursorFromChildProcess(
                             IDBRequest* aRequest,
                             size_t aDirection,
                             const Key& aKey,
                             const SerializedStructuredCloneReadInfo& aCloneInfo,
                             nsTArray<StructuredCloneFile>& aBlobs,
                             IDBCursor** _retval);
 
   void
@@ -314,32 +321,36 @@ public:
              IDBCursorDirection aDirection, ErrorResult& aRv);
 
   already_AddRefed<IDBIndex>
   CreateIndex(JSContext* aCx, const nsAString& aName, const nsAString& aKeyPath,
               const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
 
   already_AddRefed<IDBIndex>
   CreateIndex(JSContext* aCx, const nsAString& aName,
-              const Sequence<nsString >& aKeyPath,
+              const Sequence<nsString>& aKeyPath,
               const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
 
   already_AddRefed<IDBIndex>
   Index(const nsAString& aName, ErrorResult &aRv);
 
   void
   DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
 
   already_AddRefed<IDBRequest>
   Count(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
         ErrorResult& aRv);
 
   already_AddRefed<IDBRequest>
   GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
-         const Optional<uint32_t >& aLimit, ErrorResult& aRv);
+         const Optional<uint32_t>& aLimit, ErrorResult& aRv);
+
+  already_AddRefed<IDBRequest>
+  GetAllKeys(JSContext* aCx, const Optional<JS::HandleValue>& aKey,
+             const Optional<uint32_t>& aLimit, ErrorResult& aRv);
 
 protected:
   IDBObjectStore();
   ~IDBObjectStore();
 
   nsresult GetAddInfo(JSContext* aCx,
                       JS::Handle<JS::Value> aValue,
                       JS::Handle<JS::Value> aKeyVal,
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -8,34 +8,47 @@
 
 #include "nsIConsoleService.h"
 #include "nsIDiskSpaceWatcher.h"
 #include "nsIFile.h"
 #include "nsIFileStorage.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 
+#include "jsapi.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/quota/OriginOrPatternString.h"
 #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 "mozilla/Util.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsThreadUtils.h"
 
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IDBKeyRange.h"
 #include "IDBRequest.h"
 
+// Bindings for ResolveConstructors
+#include "mozilla/dom/IDBCursorBinding.h"
+#include "mozilla/dom/IDBDatabaseBinding.h"
+#include "mozilla/dom/IDBFactoryBinding.h"
+#include "mozilla/dom/IDBIndexBinding.h"
+#include "mozilla/dom/IDBObjectStoreBinding.h"
+#include "mozilla/dom/IDBOpenDBRequestBinding.h"
+#include "mozilla/dom/IDBRequestBinding.h"
+#include "mozilla/dom/IDBTransactionBinding.h"
+#include "mozilla/dom/IDBVersionChangeEventBinding.h"
+
 // The two possible values for the data argument when receiving the disk space
 // observer notification.
 #define LOW_DISK_SPACE_DATA_FULL "full"
 #define LOW_DISK_SPACE_DATA_FREE "free"
 
 USING_INDEXEDDB_NAMESPACE
 using namespace mozilla::dom;
 USING_QUOTA_NAMESPACE
@@ -89,16 +102,42 @@ END_INDEXEDDB_NAMESPACE
 
 namespace {
 
 mozilla::StaticRefPtr<IndexedDatabaseManager> gInstance;
 
 mozilla::Atomic<int32_t> gInitialized(0);
 mozilla::Atomic<int32_t> gClosed(0);
 
+// See ResolveConstructors below.
+struct ConstructorInfo {
+  const char* const name;
+  JS::Handle<JSObject*> (* const resolve)(JSContext*, JS::Handle<JSObject*>,
+                                          bool);
+  jsid id;
+};
+
+ConstructorInfo gConstructorInfo[] = {
+
+#define BINDING_ENTRY(_name) \
+  { #_name, _name##Binding::GetConstructorObject, JSID_VOID },
+
+  BINDING_ENTRY(IDBFactory)
+  BINDING_ENTRY(IDBDatabase)
+  BINDING_ENTRY(IDBTransaction)
+  BINDING_ENTRY(IDBObjectStore)
+  BINDING_ENTRY(IDBIndex)
+  BINDING_ENTRY(IDBCursor)
+  BINDING_ENTRY(IDBRequest)
+  BINDING_ENTRY(IDBOpenDBRequest)
+  BINDING_ENTRY(IDBVersionChangeEvent)
+
+#undef BINDING_ENTRY
+};
+
 class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIRUNNABLE
 
   AsyncDeleteFileRunnable(FileManager* aFileManager, int64_t aFileId);
 
@@ -879,8 +918,53 @@ GetFileReferencesHelper::Run()
   mozilla::MutexAutoLock lock(mMutex);
   NS_ASSERTION(mWaiting, "Huh?!");
 
   mWaiting = false;
   mCondVar.Notify();
 
   return NS_OK;
 }
+
+BEGIN_INDEXEDDB_NAMESPACE
+
+bool
+ResolveConstructors(JSContext* aCx, JS::HandleObject aObj, JS::HandleId aId,
+                    JS::MutableHandleObject aObjp)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // The first time this function is called we need to intern all the strings we
+  // care about.
+  if (JSID_IS_VOID(gConstructorInfo[0].id)) {
+    for (uint32_t i = 0; i < mozilla::ArrayLength(gConstructorInfo); i++) {
+      JS::RootedString str(aCx, JS_InternString(aCx, gConstructorInfo[i].name));
+      if (!str) {
+        NS_WARNING("Failed to intern string!");
+        while (i) {
+          gConstructorInfo[--i].id = JSID_VOID;
+        }
+        return false;
+      }
+      gConstructorInfo[i].id = INTERNED_STRING_TO_JSID(aCx, str);
+    }
+  }
+
+  // Now resolve.
+  for (uint32_t i = 0; i < mozilla::ArrayLength(gConstructorInfo); i++) {
+    if (gConstructorInfo[i].id == aId) {
+      JS::RootedObject constructor(aCx,
+        gConstructorInfo[i].resolve(aCx, aObj, true));
+      if (!constructor) {
+        return false;
+      }
+
+      aObjp.set(aObj);
+      return true;
+    }
+  }
+
+  // Not resolved.
+  aObjp.set(nullptr);
+  return true;
+}
+
+END_INDEXEDDB_NAMESPACE
--- 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 "js/TypeDecls.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/dom/quota/PersistenceType.h"
 #include "mozilla/Mutex.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 
 #define INDEXEDDB_MANAGER_CONTRACTID "@mozilla.org/dom/indexeddb/manager;1"
 
@@ -161,11 +162,15 @@ private:
   // It's s also used to atomically update FileInfo.mRefCnt, FileInfo.mDBRefCnt
   // and FileInfo.mSliceRefCnt
   mozilla::Mutex mFileMutex;
 
   static bool sIsMainProcess;
   static mozilla::Atomic<int32_t> sLowDiskSpaceMode;
 };
 
+bool
+ResolveConstructors(JSContext* aCx, JS::HandleObject aObj, JS::HandleId aId,
+                    JS::MutableHandleObject aObjp);
+
 END_INDEXEDDB_NAMESPACE
 
 #endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -1064,16 +1064,19 @@ IndexedDBObjectStoreRequestChild::Recv__
     case ResponseValue::Tnsresult:
       break;
     case ResponseValue::TGetResponse:
       MOZ_ASSERT(mRequestType == ParamsUnionType::TGetParams);
       break;
     case ResponseValue::TGetAllResponse:
       MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
       break;
+    case ResponseValue::TGetAllKeysResponse:
+      MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
+      break;
     case ResponseValue::TAddResponse:
       MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams);
       break;
     case ResponseValue::TPutResponse:
       MOZ_ASSERT(mRequestType == ParamsUnionType::TPutParams);
       break;
     case ResponseValue::TDeleteResponse:
       MOZ_ASSERT(mRequestType == ParamsUnionType::TDeleteParams);
--- a/dom/indexedDB/ipc/IndexedDBParams.ipdlh
+++ b/dom/indexedDB/ipc/IndexedDBParams.ipdlh
@@ -35,16 +35,22 @@ struct GetParams
 };
 
 struct GetAllParams
 {
   OptionalKeyRange optionalKeyRange;
   uint32_t limit;
 };
 
+struct GetAllKeysParams
+{
+  OptionalKeyRange optionalKeyRange;
+  uint32_t limit;
+};
+
 struct CountParams
 {
   OptionalKeyRange optionalKeyRange;
 };
 
 struct OpenCursorParams
 {
   OptionalKeyRange optionalKeyRange;
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -1092,16 +1092,19 @@ IndexedDBObjectStoreParent::RecvPIndexed
 
   switch (aParams.type()) {
     case ObjectStoreRequestParams::TGetParams:
       return actor->Get(aParams.get_GetParams());
 
     case ObjectStoreRequestParams::TGetAllParams:
       return actor->GetAll(aParams.get_GetAllParams());
 
+    case ObjectStoreRequestParams::TGetAllKeysParams:
+      return actor->GetAllKeys(aParams.get_GetAllKeysParams());
+
     case ObjectStoreRequestParams::TAddParams:
       return actor->Add(aParams.get_AddParams());
 
     case ObjectStoreRequestParams::TPutParams:
       return actor->Put(aParams.get_PutParams());
 
     case ObjectStoreRequestParams::TDeleteParams:
       return actor->Delete(aParams.get_DeleteParams());
@@ -1550,16 +1553,54 @@ IndexedDBObjectStoreRequestParent::GetAl
   }
 
   request->SetActor(this);
   mRequest.swap(request);
   return true;
 }
 
 bool
+IndexedDBObjectStoreRequestParent::GetAllKeys(const GetAllKeysParams& aParams)
+{
+  MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
+  MOZ_ASSERT(mObjectStore);
+
+  nsRefPtr<IDBRequest> request;
+
+  const ipc::OptionalKeyRange keyRangeUnion = aParams.optionalKeyRange();
+
+  nsRefPtr<IDBKeyRange> keyRange;
+
+  switch (keyRangeUnion.type()) {
+    case ipc::OptionalKeyRange::TKeyRange:
+      keyRange =
+        IDBKeyRange::FromSerializedKeyRange(keyRangeUnion.get_KeyRange());
+      break;
+
+    case ipc::OptionalKeyRange::Tvoid_t:
+      break;
+
+    default:
+      MOZ_CRASH("Unknown param type!");
+  }
+
+  {
+    AutoSetCurrentTransaction asct(mObjectStore->Transaction());
+
+    ErrorResult rv;
+    request = mObjectStore->GetAllKeysInternal(keyRange, aParams.limit(), rv);
+    ENSURE_SUCCESS(rv, false);
+  }
+
+  request->SetActor(this);
+  mRequest.swap(request);
+  return true;
+}
+
+bool
 IndexedDBObjectStoreRequestParent::Add(const AddParams& aParams)
 {
   MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams);
   MOZ_ASSERT(mObjectStore);
 
   ipc::AddPutParams params = aParams.commonParams();
 
   nsTArray<nsCOMPtr<nsIDOMBlob> > blobs;
--- a/dom/indexedDB/ipc/IndexedDBParent.h
+++ b/dom/indexedDB/ipc/IndexedDBParent.h
@@ -702,31 +702,35 @@ class IndexedDBObjectStoreRequestParent 
   DebugOnly<RequestType> mRequestType;
 
   typedef ipc::AddParams AddParams;
   typedef ipc::PutParams PutParams;
   typedef ipc::ClearParams ClearParams;
   typedef ipc::DeleteParams DeleteParams;
   typedef ipc::GetParams GetParams;
   typedef ipc::GetAllParams GetAllParams;
+  typedef ipc::GetAllKeysParams GetAllKeysParams;
   typedef ipc::CountParams CountParams;
   typedef ipc::OpenCursorParams OpenCursorParams;
 
 public:
   IndexedDBObjectStoreRequestParent(IDBObjectStore* aObjectStore,
                                     RequestType aRequestType);
   virtual ~IndexedDBObjectStoreRequestParent();
 
   bool
   Get(const GetParams& aParams);
 
   bool
   GetAll(const GetAllParams& aParams);
 
   bool
+  GetAllKeys(const GetAllKeysParams& aParams);
+
+  bool
   Add(const AddParams& aParams);
 
   bool
   Put(const PutParams& aParams);
 
   bool
   Delete(const DeleteParams& aParams);
 
--- a/dom/indexedDB/ipc/PIndexedDBIndex.ipdl
+++ b/dom/indexedDB/ipc/PIndexedDBIndex.ipdl
@@ -17,22 +17,16 @@ namespace indexedDB {
 
 namespace ipc {
 
 struct GetKeyParams
 {
   KeyRange keyRange;
 };
 
-struct GetAllKeysParams
-{
-  OptionalKeyRange optionalKeyRange;
-  uint32_t limit;
-};
-
 struct OpenKeyCursorParams
 {
   OptionalKeyRange optionalKeyRange;
   Direction direction;
 };
 
 union IndexRequestParams
 {
--- a/dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl
+++ b/dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl
@@ -47,16 +47,17 @@ struct DeleteParams
 struct ClearParams
 {
 };
 
 union ObjectStoreRequestParams
 {
   GetParams;
   GetAllParams;
+  GetAllKeysParams;
   AddParams;
   PutParams;
   DeleteParams;
   ClearParams;
   CountParams;
   OpenCursorParams;
 };
 
--- a/dom/indexedDB/ipc/unit/xpcshell.ini
+++ b/dom/indexedDB/ipc/unit/xpcshell.ini
@@ -31,16 +31,17 @@ tail =
 [test_indexes.js]
 [test_indexes_bad_values.js]
 [test_key_requirements.js]
 [test_keys.js]
 [test_multientry.js]
 [test_names_sorted.js]
 [test_object_identity.js]
 [test_objectCursors.js]
+[test_objectStore_getAllKeys.js]
 [test_objectStore_inline_autoincrement_key_added_on_put.js]
 [test_objectStore_remove_values.js]
 [test_odd_result_order.js]
 [test_open_empty_db.js]
 [test_open_objectStore.js]
 [test_optionalArguments.js]
 [test_overlapping_transactions.js]
 [test_put_get_values.js]
--- a/dom/indexedDB/test/Makefile.in
+++ b/dom/indexedDB/test/Makefile.in
@@ -65,16 +65,17 @@ MOCHITEST_FILES = \
   test_invalid_version.html \
   test_key_requirements.html \
   test_keys.html \
   test_leaving_page.html \
   test_lowDiskSpace.html \
   test_multientry.html \
   test_names_sorted.html \
   test_objectCursors.html \
+  test_objectStore_getAllKeys.html \
   test_objectStore_inline_autoincrement_key_added_on_put.html \
   test_objectStore_remove_values.html \
   test_object_identity.html \
   test_odd_result_order.html \
   test_open_empty_db.html \
   test_open_for_principal.html \
   test_open_objectStore.html \
   test_optionalArguments.html \
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_objectStore_getAllKeys.html
@@ -0,0 +1,19 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>Indexed Database Property Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <script type="text/javascript;version=1.7" src="unit/test_objectStore_getAllKeys.js"></script>
+  <script type="text/javascript;version=1.7" src="helpers.js"></script>
+
+</head>
+
+<body onload="runTest();"></body>
+
+</html>
--- a/dom/indexedDB/test/unit/Makefile.in
+++ b/dom/indexedDB/test/unit/Makefile.in
@@ -33,16 +33,17 @@ MOCHITEST_FILES = \
   test_invalid_version.js \
   test_key_requirements.js \
   test_keys.js \
   test_lowDiskSpace.js \
   test_multientry.js \
   test_names_sorted.js \
   test_object_identity.js \
   test_objectCursors.js \
+  test_objectStore_getAllKeys.js \
   test_objectStore_inline_autoincrement_key_added_on_put.js \
   test_objectStore_remove_values.js \
   test_odd_result_order.js \
   test_open_empty_db.js \
   test_open_for_principal.js \
   test_open_objectStore.js \
   test_optionalArguments.js \
   test_overlapping_transactions.js \
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_objectStore_getAllKeys.js
@@ -0,0 +1,123 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+let testGenerator = testSteps();
+
+function testSteps() {
+  const dbName = this.window ?
+                 window.location.pathname :
+                 "test_objectStore_getAllKeys";
+  const dbVersion = 1;
+  const objectStoreName = "foo";
+  const keyCount = 200;
+
+  let request = indexedDB.open(dbName, dbVersion);
+  request.onerror = errorHandler;
+  request.onupgradeneeded = grabEventAndContinueHandler;
+  request.onsuccess = unexpectedSuccessHandler;
+
+  let event = yield undefined;
+
+  info("Creating database");
+
+  let db = event.target.result;
+  let objectStore = db.createObjectStore(objectStoreName);
+  for (let i = 0; i < keyCount; i++) {
+    objectStore.add(true, i);
+  }
+
+  request.onupgradeneeded = unexpectedSuccessHandler;
+  request.onsuccess = grabEventAndContinueHandler;
+
+  event = yield undefined;
+
+  db = event.target.result;
+  objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
+
+  info("Getting all keys");
+  objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler;
+  event = yield undefined;
+
+  ok(Array.isArray(event.target.result), "Got an array result");
+  is(event.target.result.length, keyCount, "Got correct array length");
+
+  let match = true;
+  for (let i = 0; i < keyCount; i++) {
+    if (event.target.result[i] != i) {
+      match = false;
+      break;
+    }
+  }
+  ok(match, "Got correct keys");
+
+  info("Getting all keys with key range");
+  let keyRange = IDBKeyRange.bound(10, 20, false, true);
+  objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
+  event = yield undefined;
+
+  ok(Array.isArray(event.target.result), "Got an array result");
+  is(event.target.result.length, 10, "Got correct array length");
+
+  match = true;
+  for (let i = 10; i < 20; i++) {
+    if (event.target.result[i - 10] != i) {
+      match = false;
+      break;
+    }
+  }
+  ok(match, "Got correct keys");
+
+  info("Getting all keys with unmatched key range");
+  keyRange = IDBKeyRange.bound(10000, 200000);
+  objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
+  event = yield undefined;
+
+  ok(Array.isArray(event.target.result), "Got an array result");
+  is(event.target.result.length, 0, "Got correct array length");
+
+  info("Getting all keys with limit");
+  objectStore.getAllKeys(null, 5).onsuccess = grabEventAndContinueHandler;
+  event = yield undefined;
+
+  ok(Array.isArray(event.target.result), "Got an array result");
+  is(event.target.result.length, 5, "Got correct array length");
+
+  match = true;
+  for (let i = 0; i < 5; i++) {
+    if (event.target.result[i] != i) {
+      match = false;
+      break;
+    }
+  }
+  ok(match, "Got correct keys");
+
+  info("Getting all keys with key range and limit");
+  keyRange = IDBKeyRange.bound(10, 20, false, true);
+  objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
+  event = yield undefined;
+
+  ok(Array.isArray(event.target.result), "Got an array result");
+  is(event.target.result.length, 5, "Got correct array length");
+
+  match = true;
+  for (let i = 10; i < 15; i++) {
+    if (event.target.result[i - 10] != i) {
+      match = false;
+      break;
+    }
+  }
+  ok(match, "Got correct keys");
+
+  info("Getting all keys with unmatched key range and limit");
+  keyRange = IDBKeyRange.bound(10000, 200000);
+  objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
+  event = yield undefined;
+
+  ok(Array.isArray(event.target.result), "Got an array result");
+  is(event.target.result.length, 0, "Got correct array length");
+
+  finishTest();
+  yield undefined;
+}
--- a/dom/indexedDB/test/unit/xpcshell.ini
+++ b/dom/indexedDB/test/unit/xpcshell.ini
@@ -34,16 +34,17 @@ tail =
 [test_invalid_version.js]
 [test_key_requirements.js]
 [test_keys.js]
 [test_lowDiskSpace.js]
 [test_multientry.js]
 [test_names_sorted.js]
 [test_object_identity.js]
 [test_objectCursors.js]
+[test_objectStore_getAllKeys.js]
 [test_objectStore_inline_autoincrement_key_added_on_put.js]
 [test_objectStore_remove_values.js]
 [test_odd_result_order.js]
 [test_open_empty_db.js]
 [test_open_for_principal.js]
 [test_open_objectStore.js]
 [test_optionalArguments.js]
 [test_overlapping_transactions.js]
--- a/dom/webidl/IDBObjectStore.webidl
+++ b/dom/webidl/IDBObjectStore.webidl
@@ -60,9 +60,15 @@ interface IDBObjectStore {
     [Throws]
     IDBRequest count (optional any key);
 };
 
 partial interface IDBObjectStore {
     // Success fires IDBTransactionEvent, result == array of values for given keys
     [Throws]
     IDBRequest mozGetAll (optional any key, optional unsigned long limit);
+
+    [Pref="dom.indexedDB.experimental", Throws]
+    IDBRequest getAll (optional any key, optional unsigned long limit);
+
+    [Pref="dom.indexedDB.experimental", Throws]
+    IDBRequest getAllKeys (optional any key, optional unsigned long limit);
 };
--- a/gfx/2d/ScaleFactor.h
+++ b/gfx/2d/ScaleFactor.h
@@ -31,20 +31,16 @@ struct ScaleFactor {
   MOZ_CONSTEXPR ScaleFactor() : scale(1.0) {}
   MOZ_CONSTEXPR ScaleFactor(const ScaleFactor<src, dst>& aCopy) : scale(aCopy.scale) {}
   explicit MOZ_CONSTEXPR ScaleFactor(float aScale) : scale(aScale) {}
 
   explicit ScaleFactor(float aX, float aY) : scale(aX) {
     MOZ_ASSERT(fabs(aX - aY) < 1e-6);
   }
 
-  explicit ScaleFactor(gfxSize aScale) : scale(aScale.width) {
-    MOZ_ASSERT(fabs(aScale.width - aScale.height) < 1e-6);
-  }
-
   ScaleFactor<dst, src> Inverse() {
     return ScaleFactor<dst, src>(1 / scale);
   }
 
   bool operator==(const ScaleFactor<src, dst>& aOther) const {
     return scale == aOther.scale;
   }
 
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -2080,16 +2080,33 @@ GetActualReadFormats(GLContext* gl, GLen
 void
 GLContext::ReadScreenIntoImageSurface(gfxImageSurface* dest)
 {
     ScopedBindFramebuffer autoFB(this, 0);
 
     ReadPixelsIntoImageSurface(dest);
 }
 
+TemporaryRef<SourceSurface>
+GLContext::ReadPixelsToSourceSurface(const gfx::IntSize &aSize)
+{
+    // XXX we should do this properly one day without using the gfxImageSurface
+    RefPtr<DataSourceSurface> dataSourceSurface =
+        Factory::CreateDataSourceSurface(aSize, gfx::FORMAT_B8G8R8A8);
+    nsRefPtr<gfxImageSurface> surf =
+        new gfxImageSurface(dataSourceSurface->GetData(),
+                            gfxIntSize(aSize.width, aSize.height),
+                            dataSourceSurface->Stride(),
+                            gfxImageFormatARGB32);
+    ReadPixelsIntoImageSurface(surf);
+    dataSourceSurface->MarkDirty();
+
+    return dataSourceSurface;
+}
+
 void
 GLContext::ReadPixelsIntoImageSurface(gfxImageSurface* dest)
 {
     MakeCurrent();
     MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0));
 
     /* gfxImageFormatARGB32:
      * RGBA+UByte: be[RGBA], le[ABGR]
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -47,16 +47,17 @@ class nsIThread;
 
 namespace android {
     class GraphicBuffer;
 }
 
 namespace mozilla {
     namespace gfx {
         class SharedSurface;
+        class SourceSurface;
         class DataSourceSurface;
         struct SurfaceCaps;
     }
 
     namespace gl {
         class GLContext;
         class GLLibraryEGL;
         class GLScreenBuffer;
@@ -2696,16 +2697,18 @@ public:
      * ReadScreenIntoImageSurface call dest->Flush/MarkDirty.
      */
     void ReadPixelsIntoImageSurface(gfxImageSurface* dest);
 
     // Similar to ReadPixelsIntoImageSurface, but pulls from the screen
     // instead of the currently bound framebuffer.
     void ReadScreenIntoImageSurface(gfxImageSurface* dest);
 
+    TemporaryRef<gfx::SourceSurface> ReadPixelsToSourceSurface(const gfx::IntSize &aSize);
+
     /**
      * Copy a rectangle from one TextureImage into another.  The
      * source and destination are given in integer coordinates, and
      * will be converted to texture coordinates.
      *
      * For the source texture, the wrap modes DO apply -- it's valid
      * to use REPEAT or PAD and expect appropriate behaviour if the source
      * rectangle extends beyond its bounds.
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -2,17 +2,16 @@
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_COMPOSITOR_H
 #define MOZILLA_GFX_COMPOSITOR_H
 
 #include "Units.h"                      // for ScreenPoint
-#include "gfxPoint.h"                   // for gfxIntSize
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for TemporaryRef, RefCounted
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float
 #include "mozilla/layers/CompositorTypes.h"  // for DiagnosticTypes, etc
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
@@ -97,24 +96,24 @@
  * under gfx/layers/. To add a new backend, implement at least the following
  * interfaces:
  * - Compositor (ex. CompositorOGL)
  * - TextureHost (ex. SharedTextureHostOGL)
  * Depending on the type of data that needs to be serialized, you may need to
  * add specific TextureClient implementations.
  */
 
-class gfxContext;
 class nsIWidget;
 struct gfxMatrix;
 struct nsIntSize;
 
 namespace mozilla {
 namespace gfx {
 class Matrix4x4;
+class DrawTarget;
 }
 
 namespace layers {
 
 struct Effect;
 struct EffectChain;
 class Image;
 class ISurfaceAllocator;
@@ -205,27 +204,27 @@ public:
    * across process or thread boundaries that are compatible with this
    * compositor.
    */
   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0;
 
   /**
    * Properties of the compositor.
    */
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize& aSize) = 0;
+  virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0;
   virtual int32_t GetMaxTextureSize() const = 0;
 
   /**
    * Set the target for rendering. Results will have been written to aTarget by
    * the time that EndFrame returns.
    *
    * If this method is not used, or we pass in nullptr, we target the compositor's
    * usual swap chain and render to the screen.
    */
-  virtual void SetTargetContext(gfxContext* aTarget) = 0;
+  virtual void SetTargetContext(gfx::DrawTarget* aTarget) = 0;
 
   typedef uint32_t MakeCurrentFlags;
   static const MakeCurrentFlags ForceMakeCurrent = 0x1;
   /**
    * Make this compositor's rendering context the current context for the
    * underlying graphics API. This may be a global operation, depending on the
    * API. Our context will remain the current one until someone else changes it.
    *
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1166,19 +1166,20 @@ void WriteSnapshotToDumpFile(Layer* aLay
   WriteSnapshotToDumpFile_internal(aLayer, aSurf);
 }
 
 void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf)
 {
   WriteSnapshotToDumpFile_internal(aManager, aSurf);
 }
 
-void WriteSnapshotToDumpFile(Compositor* aCompositor, gfxASurface* aSurf)
+void WriteSnapshotToDumpFile(Compositor* aCompositor, DrawTarget* aTarget)
 {
-  WriteSnapshotToDumpFile_internal(aCompositor, aSurf);
+  nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(aTarget);
+  WriteSnapshotToDumpFile_internal(aCompositor, surf);
 }
 #endif
 
 void
 Layer::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
 {
   if (aDumpHtml) {
     fprintf(aFile, "<li><a id=\"%p\" ", this);
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1955,15 +1955,15 @@ protected:
   Layer* mTempReferent;
   // 0 is a special value that means "no ID".
   uint64_t mId;
 };
 
 #ifdef MOZ_DUMP_PAINTING
 void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf);
 void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf);
-void WriteSnapshotToDumpFile(Compositor* aCompositor, gfxASurface* aSurf);
+void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget);
 #endif
 
 }
 }
 
 #endif /* GFX_LAYERS_H */
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -464,30 +464,27 @@ BasicCompositor::BeginFrame(const gfx::R
   }
 }
 
 void
 BasicCompositor::EndFrame()
 {
   mRenderTarget->mDrawTarget->PopClip();
 
+  RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
   if (mCopyTarget) {
-    nsRefPtr<gfxASurface> thebes = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mRenderTarget->mDrawTarget);
-    gfxContextAutoSaveRestore restore(mCopyTarget);
-    mCopyTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
-    mCopyTarget->SetSource(thebes);
-    mCopyTarget->Paint();
-    mCopyTarget = nullptr;
+    mCopyTarget->CopySurface(source,
+                             IntRect(0, 0, mWidgetSize.width, mWidgetSize.height),
+                             IntPoint(0, 0));
   } else {
     // Most platforms require us to buffer drawing to the widget surface.
     // That's why we don't draw to mDrawTarget directly.
-    RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
     mDrawTarget->CopySurface(source,
-	                     IntRect(0, 0, mWidgetSize.width, mWidgetSize.height),
-			     IntPoint(0, 0));
+	                           IntRect(0, 0, mWidgetSize.width, mWidgetSize.height),
+			                       IntPoint(0, 0));
     mWidget->EndRemoteDrawing();
   }
   mDrawTarget = nullptr;
   mRenderTarget = nullptr;
 }
 
 void
 BasicCompositor::AbortFrame()
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -89,20 +89,20 @@ public:
   virtual void EndFrame() MOZ_OVERRIDE;
   virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE
   {
     NS_RUNTIMEABORT("We shouldn't ever hit this");
   }
   virtual void AbortFrame() MOZ_OVERRIDE;
 
   virtual bool SupportsPartialTextureUpdate() { return true; }
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE { return true; }
+  virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE { return true; }
   virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE { return INT32_MAX; }
   virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE { }
-  virtual void SetTargetContext(gfxContext* aTarget) MOZ_OVERRIDE
+  virtual void SetTargetContext(gfx::DrawTarget* aTarget) MOZ_OVERRIDE
   {
     mCopyTarget = aTarget;
   }
   
   virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) MOZ_OVERRIDE {
   }
 
   virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) { }
@@ -128,15 +128,15 @@ private:
   nsIntSize mWidgetSize;
 
   // The final destination surface
   RefPtr<gfx::DrawTarget> mDrawTarget;
   // The current render target for drawing
   RefPtr<BasicCompositingRenderTarget> mRenderTarget;
   // An optional destination target to copy the results
   // to after drawing is completed.
-  nsRefPtr<gfxContext> mCopyTarget;
+  RefPtr<gfx::DrawTarget> mCopyTarget;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_BASICCOMPOSITOR_H */
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -143,17 +143,17 @@ LayerManagerComposite::UpdateRenderBound
 
 void
 LayerManagerComposite::BeginTransaction()
 {
   mInTransaction = true;
 }
 
 void
-LayerManagerComposite::BeginTransactionWithTarget(gfxContext *aTarget)
+LayerManagerComposite::BeginTransactionWithDrawTarget(DrawTarget* aTarget)
 {
   mInTransaction = true;
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   MOZ_LAYERS_LOG(("[----- BeginTransaction"));
   Log();
 #endif
 
@@ -757,17 +757,18 @@ void
 LayerManagerComposite::NotifyShadowTreeTransaction()
 {
   mCompositor->NotifyLayersTransaction();
 }
 
 bool
 LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
 {
-  return mCompositor->CanUseCanvasLayerForSize(aSize);
+  return mCompositor->CanUseCanvasLayerForSize(gfx::IntSize(aSize.width,
+                                                            aSize.height));
 }
 
 TextureFactoryIdentifier
 LayerManagerComposite::GetTextureFactoryIdentifier()
 {
   return mCompositor->GetTextureFactoryIdentifier();
 }
 
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -97,18 +97,22 @@ public:
    */
   virtual LayerManagerComposite* AsLayerManagerComposite() MOZ_OVERRIDE
   {
     return this;
   }
 
   void UpdateRenderBounds(const nsIntRect& aRect);
 
-  void BeginTransaction() MOZ_OVERRIDE;
-  void BeginTransactionWithTarget(gfxContext* aTarget) MOZ_OVERRIDE;
+  virtual void BeginTransaction() MOZ_OVERRIDE;
+  virtual void BeginTransactionWithTarget(gfxContext* aTarget) MOZ_OVERRIDE
+  {
+    MOZ_CRASH("Use BeginTransactionWithDrawTarget");
+  }
+  void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget);
 
   void NotifyShadowTreeTransaction();
 
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE;
   virtual void EndTransaction(DrawThebesLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE;
 
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -344,17 +344,17 @@ CompositorD3D11::GetTextureFactoryIdenti
   TextureFactoryIdentifier ident;
   ident.mMaxTextureSize = GetMaxTextureSize();
   ident.mParentProcessId = XRE_GetProcessType();
   ident.mParentBackend = LAYERS_D3D11;
   return ident;
 }
 
 bool
-CompositorD3D11::CanUseCanvasLayerForSize(const gfxIntSize& aSize)
+CompositorD3D11::CanUseCanvasLayerForSize(const gfx::IntSize& aSize)
 {
   int32_t maxTextureSize = GetMaxTextureSize();
 
   if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) {
     return false;
   }
 
   return true;
@@ -902,24 +902,22 @@ CompositorD3D11::PaintToTarget()
 
   nsRefPtr<ID3D11Texture2D> readTexture;
 
   HRESULT hr = mDevice->CreateTexture2D(&softDesc, nullptr, getter_AddRefs(readTexture));
   mContext->CopyResource(readTexture, backBuf);
 
   D3D11_MAPPED_SUBRESOURCE map;
   mContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &map);
-
-  nsRefPtr<gfxImageSurface> tmpSurface =
-    new gfxImageSurface((unsigned char*)map.pData,
-                        gfxIntSize(bbDesc.Width, bbDesc.Height),
-                        map.RowPitch,
-                        gfxImageFormatARGB32);
-
-  mTarget->SetSource(tmpSurface);
-  mTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
-  mTarget->Paint();
-
+  RefPtr<DataSourceSurface> sourceSurface =
+    Factory::CreateWrappingDataSourceSurface((uint8_t*)map.pData,
+                                             map.RowPitch,
+                                             IntSize(bbDesc.Width, bbDesc.Height),
+                                             FORMAT_B8G8R8A8);
+  mTarget->CopySurface(sourceSurface,
+                       IntRect(0, 0, bbDesc.Width, bbDesc.Height),
+                       IntPoint());
+  mTarget->Flush();
   mContext->Unmap(readTexture, 0);
 }
 
 }
 }
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -1,16 +1,17 @@
 /* -*- 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 MOZILLA_GFX_COMPOSITORD3D11_H
 #define MOZILLA_GFX_COMPOSITORD3D11_H
 
+#include "mozilla/gfx/2D.h"
 #include "mozilla/layers/Compositor.h"
 #include "TextureD3D11.h"
 #include <d3d11.h>
 
 class nsWidget;
 
 namespace mozilla {
 namespace layers {
@@ -45,20 +46,20 @@ public:
   virtual void Destroy() MOZ_OVERRIDE {}
 
   virtual TextureFactoryIdentifier
     GetTextureFactoryIdentifier() MOZ_OVERRIDE;
 
   virtual TemporaryRef<DataTextureSource>
     CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE { return nullptr; }
 
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize& aSize) MOZ_OVERRIDE;
+  virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) MOZ_OVERRIDE;
   virtual int32_t GetMaxTextureSize() const MOZ_FINAL;
 
-  virtual void SetTargetContext(gfxContext* aTarget)  MOZ_OVERRIDE
+  virtual void SetTargetContext(gfx::DrawTarget* aTarget)  MOZ_OVERRIDE
   {
     mTarget = aTarget;
   }
 
   virtual void MakeCurrent(MakeCurrentFlags aFlags = 0)  MOZ_OVERRIDE {}
 
   virtual TemporaryRef<CompositingRenderTarget>
     CreateRenderTarget(const gfx::IntRect &aRect,
@@ -162,17 +163,17 @@ private:
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
 
   DeviceAttachmentsD3D11* mAttachments;
 
-  nsRefPtr<gfxContext> mTarget;
+  RefPtr<gfx::DrawTarget> mTarget;
 
   nsIWidget* mWidget;
 
   nsIntSize mSize;
 
   HWND mHwnd;
 
   D3D_FEATURE_LEVEL mFeatureLevel;
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -60,17 +60,17 @@ CompositorD3D9::GetTextureFactoryIdentif
   TextureFactoryIdentifier ident;
   ident.mMaxTextureSize = GetMaxTextureSize();
   ident.mParentBackend = LAYERS_D3D9;
   ident.mParentProcessId = XRE_GetProcessType();
   return ident;
 }
 
 bool
-CompositorD3D9::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
+CompositorD3D9::CanUseCanvasLayerForSize(const IntSize &aSize)
 {
   int32_t maxTextureSize = GetMaxTextureSize();
 
   if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) {
     return false;
   }
 
   return true;
@@ -560,24 +560,25 @@ CompositorD3D9::PaintToTarget()
   device()->CreateOffscreenPlainSurface(desc.Width, desc.Height,
                                         D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
                                         getter_AddRefs(destSurf), NULL);
 
   device()->GetRenderTargetData(backBuff, destSurf);
 
   D3DLOCKED_RECT rect;
   destSurf->LockRect(&rect, NULL, D3DLOCK_READONLY);
-  mTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
-  nsRefPtr<gfxImageSurface> imageSurface =
-    new gfxImageSurface((unsigned char*)rect.pBits,
-                        gfxIntSize(desc.Width, desc.Height),
-                        rect.Pitch,
-                        gfxImageFormatARGB32);
-  mTarget->SetSource(imageSurface);
-  mTarget->Paint();
+  RefPtr<DataSourceSurface> sourceSurface =
+    Factory::CreateWrappingDataSourceSurface((uint8_t*)rect.pBits,
+                                             rect.Pitch,
+                                             IntSize(desc.Width, desc.Height),
+                                             FORMAT_B8G8R8A8);
+  mTarget->CopySurface(sourceSurface,
+                       IntRect(0, 0, desc.Width, desc.Height),
+                       IntPoint());
+  mTarget->Flush();
   destSurf->UnlockRect();
 }
 
 void
 CompositorD3D9::ReportFailure(const nsACString &aMsg, HRESULT aCode)
 {
   // We could choose to abort here when hr == E_OUTOFMEMORY.
   nsCString msg;
--- a/gfx/layers/d3d9/CompositorD3D9.h
+++ b/gfx/layers/d3d9/CompositorD3D9.h
@@ -1,16 +1,17 @@
 /* -*- 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 MOZILLA_GFX_COMPOSITORD3D9_H
 #define MOZILLA_GFX_COMPOSITORD3D9_H
 
+#include "mozilla/gfx/2D.h"
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/TextureD3D9.h"
 #include "DeviceManagerD3D9.h"
 
 class nsWidget;
 
 namespace mozilla {
 namespace layers {
@@ -22,20 +23,20 @@ public:
   ~CompositorD3D9();
 
   virtual bool Initialize() MOZ_OVERRIDE;
   virtual void Destroy() MOZ_OVERRIDE {}
 
   virtual TextureFactoryIdentifier
     GetTextureFactoryIdentifier() MOZ_OVERRIDE;
 
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
+  virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE;
   virtual int32_t GetMaxTextureSize() const MOZ_FINAL;
 
-  virtual void SetTargetContext(gfxContext *aTarget) MOZ_OVERRIDE
+  virtual void SetTargetContext(gfx::DrawTarget *aTarget) MOZ_OVERRIDE
   {
     mTarget = aTarget;
   }
 
   virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE {}
 
   virtual TemporaryRef<CompositingRenderTarget>
     CreateRenderTarget(const gfx::IntRect &aRect,
@@ -123,17 +124,17 @@ private:
   nsRefPtr<SwapChainD3D9> mSwapChain;
 
   /* Widget associated with this layer manager */
   nsIWidget *mWidget;
 
   /*
    * Context target, NULL when drawing directly to our swap chain.
    */
-  nsRefPtr<gfxContext> mTarget;
+  RefPtr<gfx::DrawTarget> mTarget;
 
   RefPtr<CompositingRenderTargetD3D9> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D9> mCurrentRT;
 
   nsIntSize mSize;
 };
 
 }
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -18,16 +18,17 @@
 #include "base/task.h"                  // for CancelableTask, etc
 #include "base/thread.h"                // for Thread
 #include "base/tracked.h"               // for FROM_HERE
 #include "gfxContext.h"                 // for gfxContext
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "ipc/ShadowLayersManager.h"    // for ShadowLayersManager
 #include "mozilla/AutoRestore.h"        // for AutoRestore
 #include "mozilla/DebugOnly.h"          // for DebugOnly
+#include "mozilla/gfx/2D.h"          // for DrawTarget
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/layers/APZCTreeManager.h"  // for APZCTreeManager
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include "mozilla/layers/BasicCompositor.h"  // for BasicCompositor
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/CompositorOGL.h"  // for CompositorOGL
 #include "mozilla/layers/CompositorTypes.h"
@@ -47,16 +48,17 @@
 #include "mozilla/layers/CompositorD3D11.h"
 #include "mozilla/layers/CompositorD3D9.h"
 #endif
 #include "GeckoProfiler.h"
 
 using namespace base;
 using namespace mozilla;
 using namespace mozilla::ipc;
+using namespace mozilla::gfx;
 using namespace std;
 
 namespace mozilla {
 namespace layers {
 
 CompositorParent::LayerTreeState::LayerTreeState()
   : mParent(nullptr)
 {
@@ -290,17 +292,23 @@ CompositorParent::RecvResume()
   return true;
 }
 
 bool
 CompositorParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
                                    SurfaceDescriptor* aOutSnapshot)
 {
   AutoOpenSurface opener(OPEN_READ_WRITE, aInSnapshot);
-  nsRefPtr<gfxContext> target = new gfxContext(opener.Get());
+  gfxIntSize size = opener.Size();
+  // XXX CreateDrawTargetForSurface will always give us a Cairo surface, we can
+  // do better if AutoOpenSurface uses Moz2D directly.
+  RefPtr<DrawTarget> target =
+    gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(opener.Get(),
+                                                           IntSize(size.width,
+                                                                   size.height));
   ComposeToTarget(target);
   *aOutSnapshot = aInSnapshot;
   return true;
 }
 
 bool
 CompositorParent::RecvFlushRendering()
 {
@@ -536,26 +544,26 @@ CompositorParent::Composite()
   if (mExpectedComposeTime + TimeDuration::FromMilliseconds(15) < TimeStamp::Now()) {
     printf_stderr("Compositor: Composite took %i ms.\n",
                   15 + (int)(TimeStamp::Now() - mExpectedComposeTime).ToMilliseconds());
   }
 #endif
 }
 
 void
-CompositorParent::ComposeToTarget(gfxContext* aTarget)
+CompositorParent::ComposeToTarget(DrawTarget* aTarget)
 {
   PROFILER_LABEL("CompositorParent", "ComposeToTarget");
   AutoRestore<bool> override(mOverrideComposeReadiness);
   mOverrideComposeReadiness = true;
 
   if (!CanComposite()) {
     return;
   }
-  mLayerManager->BeginTransactionWithTarget(aTarget);
+  mLayerManager->BeginTransactionWithDrawTarget(aTarget);
   // Since CanComposite() is true, Composite() must end the layers txn
   // we opened above.
   Composite();
 }
 
 bool
 CompositorParent::CanComposite()
 {
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -34,16 +34,20 @@
 #include "nsSize.h"                     // for nsIntSize
 
 class CancelableTask;
 class MessageLoop;
 class gfxContext;
 class nsIWidget;
 
 namespace mozilla {
+namespace gfx {
+class DrawTarget;
+}
+
 namespace layers {
 
 class APZCTreeManager;
 class AsyncCompositionManager;
 class LayerManagerComposite;
 class LayerTransactionParent;
 
 struct ScopedLayerTreeRegistration
@@ -216,17 +220,17 @@ protected:
   virtual PLayerTransactionParent*
     AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
                                  const uint64_t& aId,
                                  TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                  bool* aSuccess);
   virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers);
   virtual void ScheduleTask(CancelableTask*, int);
   virtual void Composite();
-  virtual void ComposeToTarget(gfxContext* aTarget);
+  virtual void ComposeToTarget(gfx::DrawTarget* aTarget);
 
   void SetEGLSurfaceSize(int width, int height);
 
 private:
   void InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints);
   void PauseComposition();
   void ResumeComposition();
   void ResumeCompositionAndResize(int width, int height);
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -195,17 +195,17 @@ LayerTransactionParent::RecvUpdate(const
   MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
 
   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     return true;
   }
 
   EditReplyVector replyv;
 
-  layer_manager()->BeginTransactionWithTarget(nullptr);
+  layer_manager()->BeginTransactionWithDrawTarget(nullptr);
 
   for (EditArray::index_type i = 0; i < cset.Length(); ++i) {
     const Edit& edit = cset[i];
 
     switch (edit.type()) {
     // Create* ops
     case Edit::TOpCreateThebesLayer: {
       MOZ_LAYERS_LOG(("[ParentSide] CreateThebesLayer"));
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -1256,21 +1256,20 @@ CompositorOGL::EndFrame()
 #ifdef MOZ_DUMP_PAINTING
   if (gfxUtils::sDumpPainting) {
     nsIntRect rect;
     if (mUseExternalSurfaceSize) {
       rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
     } else {
       mWidget->GetBounds(rect);
     }
-    nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(rect.Size(), GFX_CONTENT_COLOR_ALPHA);
-    nsRefPtr<gfxContext> ctx = new gfxContext(surf);
-    CopyToTarget(ctx, mCurrentRenderTarget->GetTransform());
+    RefPtr<DrawTarget> target = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(rect.width, rect.height), FORMAT_B8G8R8A8);
+    CopyToTarget(target, mCurrentRenderTarget->GetTransform());
 
-    WriteSnapshotToDumpFile(this, surf);
+    WriteSnapshotToDumpFile(this, target);
   }
 #endif
 
   mFrameInProgress = false;
 
   if (mTarget) {
     CopyToTarget(mTarget, mCurrentRenderTarget->GetTransform());
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
@@ -1330,60 +1329,55 @@ CompositorOGL::AbortFrame()
 void
 CompositorOGL::SetDestinationSurfaceSize(const gfx::IntSize& aSize)
 {
   mSurfaceSize.width = aSize.width;
   mSurfaceSize.height = aSize.height;
 }
 
 void
-CompositorOGL::CopyToTarget(gfxContext *aTarget, const gfxMatrix& aTransform)
+CompositorOGL::CopyToTarget(DrawTarget *aTarget, const gfxMatrix& aTransform)
 {
-  nsIntRect rect;
+  IntRect rect;
   if (mUseExternalSurfaceSize) {
-    rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
+    rect = IntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
   } else {
-    rect = nsIntRect(0, 0, mWidgetSize.width, mWidgetSize.height);
+    rect = IntRect(0, 0, mWidgetSize.width, mWidgetSize.height);
   }
   GLint width = rect.width;
   GLint height = rect.height;
 
   if ((int64_t(width) * int64_t(height) * int64_t(4)) > PR_INT32_MAX) {
     NS_ERROR("Widget size too big - integer overflow!");
     return;
   }
 
-  nsRefPtr<gfxImageSurface> imageSurface =
-    new gfxImageSurface(gfxIntSize(width, height),
-                        gfxImageFormatARGB32);
-
   mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
   if (!mGLContext->IsGLES2()) {
     // GLES2 promises that binding to any custom FBO will attach
     // to GL_COLOR_ATTACHMENT0 attachment point.
     mGLContext->fReadBuffer(LOCAL_GL_BACK);
   }
 
-  NS_ASSERTION(imageSurface->Stride() == width * 4,
-               "Image Surfaces being created with weird stride!");
-
-  mGLContext->ReadPixelsIntoImageSurface(imageSurface);
+  RefPtr<SourceSurface> source =
+    mGLContext->ReadPixelsToSourceSurface(IntSize(width, height));
 
   // Map from GL space to Cairo space and reverse the world transform.
-  gfxMatrix glToCairoTransform = aTransform;
+  Matrix glToCairoTransform = MatrixForThebesMatrix(aTransform);
   glToCairoTransform.Invert();
   glToCairoTransform.Scale(1.0, -1.0);
-  glToCairoTransform.Translate(-gfxPoint(0.0, height));
+  glToCairoTransform.Translate(0.0, -height);
 
-  gfxContextAutoSaveRestore restore(aTarget);
-  aTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
-  aTarget->SetMatrix(glToCairoTransform);
-  aTarget->SetSource(imageSurface);
-  aTarget->Paint();
+  Matrix oldMatrix = aTarget->GetTransform();
+  aTarget->SetTransform(glToCairoTransform);
+  Rect floatRect = Rect(rect.x, rect.y, rect.width, rect.height);
+  aTarget->DrawSurface(source, floatRect, floatRect, DrawSurfaceOptions(), DrawOptions(1.0f, OP_SOURCE));
+  aTarget->SetTransform(oldMatrix);
+  aTarget->Flush();
 }
 
 double
 CompositorOGL::AddFrameAndGetFps(const TimeStamp& timestamp)
 {
   if (sDrawFPS) {
     if (!mFPS) {
       mFPS = new FPSState();
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -5,32 +5,30 @@
 
 #ifndef MOZILLA_GFX_COMPOSITOROGL_H
 #define MOZILLA_GFX_COMPOSITOROGL_H
 
 #include "GLContextTypes.h"             // for GLContext, etc
 #include "GLDefs.h"                     // for GLuint, LOCAL_GL_TEXTURE_2D, etc
 #include "LayerManagerOGLProgram.h"     // for ShaderProgramOGL, etc
 #include "Units.h"                      // for ScreenPoint
-#include "gfxContext.h"                 // for gfxContext
-#include "gfxPoint.h"                   // for gfxIntSize
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE, MOZ_FINAL
 #include "mozilla/RefPtr.h"             // for TemporaryRef, RefPtr
+#include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float, SurfaceFormat, etc
 #include "mozilla/layers/Compositor.h"  // for SurfaceInitMode, Compositor, etc
 #include "mozilla/layers/CompositorTypes.h"  // for MaskType::NumMaskTypes, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING
-#include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
 #include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsAutoTArray, nsTArray, etc
 #include "nsThreadUtils.h"              // for nsRunnable
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType
 #include "nscore.h"                     // for NS_IMETHOD
 #include "VBOArena.h"                   // for gl::VBOArena
 
@@ -101,39 +99,39 @@ public:
                         const gfx::Point& aOffset) MOZ_OVERRIDE;
 
   virtual void EndFrame() MOZ_OVERRIDE;
   virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE;
   virtual void AbortFrame() MOZ_OVERRIDE;
 
   virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE;
 
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE
+  virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE
   {
     if (!mGLContext)
       return false;
     int32_t maxSize = GetMaxTextureSize();
-    return aSize <= gfxIntSize(maxSize, maxSize);
+    return aSize <= gfx::IntSize(maxSize, maxSize);
   }
 
   virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE;
 
   /**
    * Set the size of the EGL surface we're rendering to, if we're rendering to
    * an EGL surface.
    */
   virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE;
 
   virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) MOZ_OVERRIDE {
     mRenderOffset = aOffset;
   }
 
   virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE;
 
-  virtual void SetTargetContext(gfxContext* aTarget) MOZ_OVERRIDE
+  virtual void SetTargetContext(gfx::DrawTarget* aTarget) MOZ_OVERRIDE
   {
     mTarget = aTarget;
   }
 
   virtual void PrepareViewport(const gfx::IntSize& aSize,
                                const gfxMatrix& aWorldTransform) MOZ_OVERRIDE;
 
 
@@ -166,17 +164,17 @@ public:
    * Doing so lets us use gralloc the way it has been designed to be used
    * (see https://wiki.mozilla.org/Platform/GFX/Gralloc)
    */
   GLuint GetTemporaryTexture(GLenum aUnit);
 private:
   /** 
    * Context target, nullptr when drawing directly to our swap chain.
    */
-  nsRefPtr<gfxContext> mTarget;
+  RefPtr<gfx::DrawTarget> mTarget;
 
   /** Widget associated with this compositor */
   nsIWidget *mWidget;
   nsIntSize mWidgetSize;
   nsRefPtr<GLContext> mGLContext;
 
   /** The size of the surface we are rendering to */
   nsIntSize mSurfaceSize;
@@ -295,17 +293,17 @@ private:
                                       TextureSource *aTexture);
 
   void CleanupResources();
 
   /**
    * Copies the content of our backbuffer to the set transaction target.
    * Does not restore the target FBO, so only call from EndFrame.
    */
-  void CopyToTarget(gfxContext *aTarget, const gfxMatrix& aWorldMatrix);
+  void CopyToTarget(gfx::DrawTarget* aTarget, const gfxMatrix& aWorldMatrix);
 
   /**
    * Records the passed frame timestamp and returns the current estimated FPS.
    */
   double AddFrameAndGetFps(const TimeStamp& timestamp);
 
   bool mDestroyed;
 
--- a/gfx/thebes/gfx2DGlue.h
+++ b/gfx/thebes/gfx2DGlue.h
@@ -194,16 +194,22 @@ inline JoinStyle ToJoinStyle(gfxContext:
 }
 
 inline gfxMatrix ThebesMatrix(const Matrix &aMatrix)
 {
   return gfxMatrix(aMatrix._11, aMatrix._12, aMatrix._21,
                    aMatrix._22, aMatrix._31, aMatrix._32);
 }
 
+inline Matrix MatrixForThebesMatrix(const gfxMatrix &aMatrix)
+{
+  return Matrix(aMatrix.xx, aMatrix.yx, aMatrix.xy,
+                aMatrix.yy, aMatrix.x0, aMatrix.y0);
+}
+
 inline gfxImageFormat SurfaceFormatToImageFormat(SurfaceFormat aFormat)
 {
   switch (aFormat) {
   case FORMAT_B8G8R8A8:
     return gfxImageFormatARGB32;
   case FORMAT_B8G8R8X8:
     return gfxImageFormatRGB24;
   case FORMAT_R5G6B5:
--- a/ipc/ipdl/Makefile.in
+++ b/ipc/ipdl/Makefile.in
@@ -16,28 +16,20 @@ LOCAL_INCLUDES += -I$(DEPTH)/ipc/ipdl/_i
 
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 
 # NB: the IPDL compiler manages .ipdl-->.h/.cpp dependencies itself,
 # which is why we don't have explicit .h/.cpp targets here
-ipdl: $(ALL_IPDLSRCS)
+export:: $(ALL_IPDLSRCS)
 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
 	  $(PLY_INCLUDE) \
 	  $(srcdir)/ipdl.py \
 	  --outheaders-dir=_ipdlheaders \
 	  --outcpp-dir=. \
 	  $(IPDLDIRS:%=-I%) \
 	  $^
 
-.PHONY: ipdl
-
 # We #include some things in the dom/plugins/ directory that rely on
 # toolkit libraries.
 CXXFLAGS    += $(TK_CFLAGS)
-
-# This is only needed to support |make| from this leaf directory/Makefile.
-NONRECURSIVE_TARGETS := export
-NONRECURSIVE_TARGETS_export := ipdl
-NONRECURSIVE_TARGETS_export_ipdl_DIRECTORY := .
-NONRECURSIVE_TARGETS_export_ipdl_TARGETS := ipdl
--- a/js/public/CharacterEncoding.h
+++ b/js/public/CharacterEncoding.h
@@ -5,19 +5,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_CharacterEncoding_h
 #define js_CharacterEncoding_h
 
 #include "mozilla/NullPtr.h"
 #include "mozilla/Range.h"
 
-#include "jspubtd.h"
+#include "js/TypeDecls.h"
+#include "js/Utility.h"
 
-#include "js/Utility.h"
+namespace js {
+struct ThreadSafeContext;
+}
 
 namespace JS {
 
 /*
  * By default, all C/C++ 1-byte-per-character strings passed into the JSAPI
  * are treated as ISO/IEC 8859-1, also known as Latin-1. That is, each
  * byte is treated as a 2-byte character, and there is no way to pass in a
  * string containing characters beyond U+00FF.
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -68,26 +68,26 @@ enum {
     IsLiveGCThing,
     NotLiveGCThing
 };
 
 struct ZoneStatsPod
 {
 #define FOR_EACH_SIZE(macro) \
     macro(NotLiveGCThing, gcHeapArenaAdmin) \
-    macro(NotLiveGCThing, gcHeapUnusedGcThings) \
-    macro(IsLiveGCThing,  gcHeapStringsNormal) \
-    macro(IsLiveGCThing,  gcHeapStringsShort) \
-    macro(IsLiveGCThing,  gcHeapLazyScripts) \
-    macro(IsLiveGCThing,  gcHeapTypeObjects) \
-    macro(IsLiveGCThing,  gcHeapIonCodes) \
-    macro(NotLiveGCThing, stringCharsNonNotable) \
-    macro(NotLiveGCThing, lazyScripts) \
-    macro(NotLiveGCThing, typeObjects) \
-    macro(NotLiveGCThing, typePool)
+    macro(NotLiveGCThing, unusedGCThings) \
+    macro(IsLiveGCThing,  lazyScriptsGCHeap) \
+    macro(NotLiveGCThing, lazyScriptsMallocHeap) \
+    macro(IsLiveGCThing,  ionCodesGCHeap) \
+    macro(IsLiveGCThing,  typeObjectsGCHeap) \
+    macro(NotLiveGCThing, typeObjectsMallocHeap) \
+    macro(NotLiveGCThing, typePool) \
+    macro(IsLiveGCThing,  stringsShortGCHeap) \
+    macro(IsLiveGCThing,  stringsNormalGCHeap) \
+    macro(NotLiveGCThing, stringsNormalMallocHeap)
 
     ZoneStatsPod()
       : FOR_EACH_SIZE(ZERO_SIZE)
         extra()
     {}
 
     void add(const ZoneStatsPod &other) {
         FOR_EACH_SIZE(ADD_OTHER_SIZE)
@@ -110,26 +110,26 @@ struct ZoneStatsPod
 } // namespace js
 
 namespace JS {
 
 // Data for tracking memory usage of things hanging off objects.
 struct ObjectsExtraSizes
 {
 #define FOR_EACH_SIZE(macro) \
-    macro(js::NotLiveGCThing, slots) \
-    macro(js::NotLiveGCThing, elementsNonAsmJS) \
-    macro(js::NotLiveGCThing, elementsAsmJSHeap) \
-    macro(js::NotLiveGCThing, elementsAsmJSNonHeap) \
-    macro(js::NotLiveGCThing, asmJSModuleCode) \
-    macro(js::NotLiveGCThing, asmJSModuleData) \
-    macro(js::NotLiveGCThing, argumentsData) \
-    macro(js::NotLiveGCThing, regExpStatics) \
-    macro(js::NotLiveGCThing, propertyIteratorData) \
-    macro(js::NotLiveGCThing, ctypesData)
+    macro(js::NotLiveGCThing, mallocHeapSlots) \
+    macro(js::NotLiveGCThing, mallocHeapElementsNonAsmJS) \
+    macro(js::NotLiveGCThing, mallocHeapElementsAsmJS) \
+    macro(js::NotLiveGCThing, nonHeapElementsAsmJS) \
+    macro(js::NotLiveGCThing, nonHeapCodeAsmJS) \
+    macro(js::NotLiveGCThing, mallocHeapAsmJSModuleData) \
+    macro(js::NotLiveGCThing, mallocHeapArgumentsData) \
+    macro(js::NotLiveGCThing, mallocHeapRegExpStatics) \
+    macro(js::NotLiveGCThing, mallocHeapPropertyIteratorData) \
+    macro(js::NotLiveGCThing, mallocHeapCtypesData)
 
     ObjectsExtraSizes()
       : FOR_EACH_SIZE(ZERO_SIZE)
         dummy()
     {}
 
     void add(const ObjectsExtraSizes &other) {
         FOR_EACH_SIZE(ADD_OTHER_SIZE)
@@ -201,62 +201,61 @@ struct CodeSizes
 };
 
 // This class holds information about the memory taken up by identical copies of
 // a particular string.  Multiple JSStrings may have their sizes aggregated
 // together into one StringInfo object.
 struct StringInfo
 {
     StringInfo()
-      : length(0), numCopies(0), sizeOfShortStringGCThings(0),
-        sizeOfNormalStringGCThings(0), sizeOfAllStringChars(0)
+      : length(0), numCopies(0), shortGCHeap(0), normalGCHeap(0), normalMallocHeap(0)
     {}
 
     StringInfo(size_t len, size_t shorts, size_t normals, size_t chars)
       : length(len),
         numCopies(1),
-        sizeOfShortStringGCThings(shorts),
-        sizeOfNormalStringGCThings(normals),
-        sizeOfAllStringChars(chars)
+        shortGCHeap(shorts),
+        normalGCHeap(normals),
+        normalMallocHeap(chars)
     {}
 
     void add(size_t shorts, size_t normals, size_t chars) {
-        sizeOfShortStringGCThings += shorts;
-        sizeOfNormalStringGCThings += normals;
-        sizeOfAllStringChars += chars;
+        shortGCHeap += shorts;
+        normalGCHeap += normals;
+        normalMallocHeap += chars;
         numCopies++;
     }
 
     void add(const StringInfo& info) {
         MOZ_ASSERT(length == info.length);
 
-        sizeOfShortStringGCThings += info.sizeOfShortStringGCThings;
-        sizeOfNormalStringGCThings += info.sizeOfNormalStringGCThings;
-        sizeOfAllStringChars += info.sizeOfAllStringChars;
+        shortGCHeap += info.shortGCHeap;
+        normalGCHeap += info.normalGCHeap;
+        normalMallocHeap += info.normalMallocHeap;
         numCopies += info.numCopies;
     }
 
     size_t totalSizeOf() const {
-        return sizeOfShortStringGCThings + sizeOfNormalStringGCThings + sizeOfAllStringChars;
+        return shortGCHeap + normalGCHeap + normalMallocHeap;
     }
 
-    size_t totalGCThingSizeOf() const {
-        return sizeOfShortStringGCThings + sizeOfNormalStringGCThings;
+    size_t totalGCHeapSizeOf() const {
+        return shortGCHeap + normalGCHeap;
     }
 
     // The string's length, excluding the null-terminator.
     size_t length;
 
     // How many copies of the string have we seen?
     size_t numCopies;
 
     // These are all totals across all copies of the string we've seen.
-    size_t sizeOfShortStringGCThings;
-    size_t sizeOfNormalStringGCThings;
-    size_t sizeOfAllStringChars;
+    size_t shortGCHeap;
+    size_t normalGCHeap;
+    size_t normalMallocHeap;
 };
 
 // Holds data about a notable string (one which uses more than
 // NotableStringInfo::notableSize() bytes of memory), so we can report it
 // individually.
 //
 // Essentially the only difference between this class and StringInfo is that
 // NotableStringInfo holds a copy of the string's chars.
@@ -342,44 +341,53 @@ struct ZoneStats : js::ZoneStatsPod
                 p->value.add(r.front().value);
             } else {
                 // We haven't seen this string before; add it to the hashtable.
                 strings.add(p, r.front().key, r.front().value);
             }
         }
     }
 
+    size_t sizeOfLiveGCThings() const {
+        size_t n = ZoneStatsPod::sizeOfLiveGCThings();
+        for (size_t i = 0; i < notableStrings.length(); i++) {
+            const JS::NotableStringInfo& info = notableStrings[i];
+            n += info.totalGCHeapSizeOf();
+        }
+        return n;
+    }
+
     typedef js::HashMap<JSString*,
                         StringInfo,
                         js::InefficientNonFlatteningStringHashPolicy,
                         js::SystemAllocPolicy> StringsHashMap;
 
     StringsHashMap strings;
     js::Vector<NotableStringInfo, 0, js::SystemAllocPolicy> notableStrings;
 };
 
 struct CompartmentStats
 {
 #define FOR_EACH_SIZE(macro) \
-    macro(js::IsLiveGCThing,  gcHeapObjectsOrdinary) \
-    macro(js::IsLiveGCThing,  gcHeapObjectsFunction) \
-    macro(js::IsLiveGCThing,  gcHeapObjectsDenseArray) \
-    macro(js::IsLiveGCThing,  gcHeapObjectsSlowArray) \
-    macro(js::IsLiveGCThing,  gcHeapObjectsCrossCompartmentWrapper) \
-    macro(js::IsLiveGCThing,  gcHeapShapesTreeGlobalParented) \
-    macro(js::IsLiveGCThing,  gcHeapShapesTreeNonGlobalParented) \
-    macro(js::IsLiveGCThing,  gcHeapShapesDict) \
-    macro(js::IsLiveGCThing,  gcHeapShapesBase) \
-    macro(js::IsLiveGCThing,  gcHeapScripts) \
+    macro(js::IsLiveGCThing,  objectsGCHeapOrdinary) \
+    macro(js::IsLiveGCThing,  objectsGCHeapFunction) \
+    macro(js::IsLiveGCThing,  objectsGCHeapDenseArray) \
+    macro(js::IsLiveGCThing,  objectsGCHeapSlowArray) \
+    macro(js::IsLiveGCThing,  objectsGCHeapCrossCompartmentWrapper) \
     macro(js::NotLiveGCThing, objectsPrivate) \
-    macro(js::NotLiveGCThing, shapesExtraTreeTables) \
-    macro(js::NotLiveGCThing, shapesExtraDictTables) \
-    macro(js::NotLiveGCThing, shapesExtraTreeShapeKids) \
-    macro(js::NotLiveGCThing, shapesCompartmentTables) \
-    macro(js::NotLiveGCThing, scriptData) \
+    macro(js::IsLiveGCThing,  shapesGCHeapTreeGlobalParented) \
+    macro(js::IsLiveGCThing,  shapesGCHeapTreeNonGlobalParented) \
+    macro(js::IsLiveGCThing,  shapesGCHeapDict) \
+    macro(js::IsLiveGCThing,  shapesGCHeapBase) \
+    macro(js::NotLiveGCThing, shapesMallocHeapTreeTables) \
+    macro(js::NotLiveGCThing, shapesMallocHeapDictTables) \
+    macro(js::NotLiveGCThing, shapesMallocHeapTreeShapeKids) \
+    macro(js::NotLiveGCThing, shapesMallocHeapCompartmentTables) \
+    macro(js::IsLiveGCThing,  scriptsGCHeap) \
+    macro(js::NotLiveGCThing, scriptsMallocHeapData) \
     macro(js::NotLiveGCThing, baselineData) \
     macro(js::NotLiveGCThing, baselineStubsFallback) \
     macro(js::NotLiveGCThing, baselineStubsOptimized) \
     macro(js::NotLiveGCThing, ionData) \
     macro(js::NotLiveGCThing, compartmentObject) \
     macro(js::NotLiveGCThing, crossCompartmentWrappersTable) \
     macro(js::NotLiveGCThing, regexpCompartment) \
     macro(js::NotLiveGCThing, debuggeesSet) \
@@ -424,19 +432,18 @@ struct CompartmentStats
 
 struct RuntimeStats
 {
 #define FOR_EACH_SIZE(macro) \
     macro(_, gcHeapChunkTotal) \
     macro(_, gcHeapDecommittedArenas) \
     macro(_, gcHeapUnusedChunks) \
     macro(_, gcHeapUnusedArenas) \
-    macro(_, gcHeapUnusedGcThings) \
     macro(_, gcHeapChunkAdmin) \
-    macro(_, gcHeapGcThings) \
+    macro(_, gcHeapGCThings) \
 
     RuntimeStats(mozilla::MallocSizeOf mallocSizeOf)
       : FOR_EACH_SIZE(ZERO_SIZE)
         runtime(),
         cTotals(),
         zTotals(),
         compartmentStatsVector(),
         zoneStatsVector(),
@@ -447,21 +454,22 @@ struct RuntimeStats
     // Here's a useful breakdown of the GC heap.
     //
     // - rtStats.gcHeapChunkTotal
     //   - decommitted bytes
     //     - rtStats.gcHeapDecommittedArenas (decommitted arenas in non-empty chunks)
     //   - unused bytes
     //     - rtStats.gcHeapUnusedChunks (empty chunks)
     //     - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks)
-    //     - rtStats.total.gcHeapUnusedGcThings (empty GC thing slots within non-empty arenas)
+    //     - rtStats.zTotals.unusedGCThings (empty GC thing slots within non-empty arenas)
     //   - used bytes
     //     - rtStats.gcHeapChunkAdmin
-    //     - rtStats.total.gcHeapArenaAdmin
-    //     - rtStats.gcHeapGcThings (in-use GC things)
+    //     - rtStats.zTotals.gcHeapArenaAdmin
+    //     - rtStats.gcHeapGCThings (in-use GC things)
+    //       == rtStats.zTotals.sizeOfLiveGCThings() + rtStats.cTotals.sizeOfLiveGCThings()
     //
     // It's possible that some arenas in empty chunks may be decommitted, but
     // we don't count those under rtStats.gcHeapDecommittedArenas because (a)
     // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a
     // multiple of the chunk size, which is good.
 
     FOR_EACH_SIZE(DECL_SIZE)
 
--- a/js/src/assembler/assembler/MacroAssemblerCodeRef.h
+++ b/js/src/assembler/assembler/MacroAssemblerCodeRef.h
@@ -25,16 +25,17 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  * 
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef assembler_assembler_MacroAssemblerCodeRef_h
 #define assembler_assembler_MacroAssemblerCodeRef_h
 
+#include "assembler/wtf/Assertions.h"
 #include "assembler/wtf/Platform.h"
 #include "assembler/jit/ExecutableAllocator.h"
 
 #if ENABLE_ASSEMBLER
 
 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
 // instruction address on the platform (for example, check any alignment requirements).
 #if WTF_CPU_ARM_THUMB2
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -2454,16 +2454,23 @@ public:
     void movmskpd_rr(XMMRegisterID src, RegisterID dst)
     {
         spew("movmskpd   %s, %s",
              nameFPReg(src), nameIReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_MOVMSKPD_EdVd, dst, (RegisterID)src);
     }
 
+    void movmskps_rr(XMMRegisterID src, RegisterID dst)
+    {
+        spew("movmskps   %s, %s",
+             nameFPReg(src), nameIReg(dst));
+        m_formatter.twoByteOp(OP2_MOVMSKPD_EdVd, dst, (RegisterID)src);
+    }
+
     void ptest_rr(XMMRegisterID lhs, XMMRegisterID rhs) {
         spew("ptest      %s, %s",
              nameFPReg(lhs), nameFPReg(rhs));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.threeByteOp(OP3_PTEST_VdVd, ESCAPE_PTEST, (RegisterID)rhs, (RegisterID)lhs);
     }
 
     void movd_rr(XMMRegisterID src, RegisterID dst)
--- a/js/src/build/autoconf/compiler-opts.m4
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -166,16 +166,22 @@ AC_DEFUN([MOZ_COMPILER_OPTS],
   MOZ_ARG_ENABLE_BOOL(release,
   [  --enable-release        Build with more conservative, release engineering-oriented options.
                           This may slow down builds.],
       DEVELOPER_OPTIONS=,
       DEVELOPER_OPTIONS=1)
 
   AC_SUBST(DEVELOPER_OPTIONS)
 
+  if test -n "$DEVELOPER_OPTIONS" -a "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
+    dnl Don't enable on pymake, because of bug 918652. Bug 912979 is an annoyance
+    dnl with pymake, too.
+    MOZ_PSEUDO_DERECURSE=no-parallel-export,no-pymake
+  fi
+
   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.
     ##
@@ -189,30 +195,41 @@ 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
+if test -n "$DEVELOPER_OPTIONS"; then
+    MOZ_FORCE_GOLD=1
+fi
+
+MOZ_ARG_ENABLE_BOOL(gold,
+[  --enable-gold           Enable GNU Gold Linker when it is not already the default],
+    MOZ_FORCE_GOLD=1,
+    MOZ_FORCE_GOLD=
+    )
+
+if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; 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
+            rm -f $_objdir/build/unix/gold/ld
             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
--- a/js/src/builtin/Intl.h
+++ b/js/src/builtin/Intl.h
@@ -4,18 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef builtin_Intl_h
 #define builtin_Intl_h
 
 #include "NamespaceImports.h"
 
-#include "js/RootingAPI.h"
-
 /*
  * The Intl module specified by standard ECMA-402,
  * ECMAScript Internationalization API Specification.
  */
 
 /**
  * Initializes the Intl Object and its standard built-in properties.
  * Spec: ECMAScript Internationalization API Specification, 8.0, 8.1
--- a/js/src/builtin/Object.h
+++ b/js/src/builtin/Object.h
@@ -2,28 +2,29 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 builtin_Object_h
 #define builtin_Object_h
 
-#include "jsobj.h"
+#include "jsapi.h"
+#include "js/Value.h"
 
 namespace js {
 
 extern const JSFunctionSpec object_methods[];
 extern const JSFunctionSpec object_static_methods[];
 
 // Object constructor native. Exposed only so the JIT can know its address.
 bool
-obj_construct(JSContext *cx, unsigned argc, js::Value *vp);
+obj_construct(JSContext *cx, unsigned argc, JS::Value *vp);
 
 #if JS_HAS_TOSOURCE
 // Object.prototype.toSource. Function.prototype.toSource and uneval use this.
 JSString *
-ObjectToSource(JSContext *cx, HandleObject obj);
+ObjectToSource(JSContext *cx, JS::HandleObject obj);
 #endif // JS_HAS_TOSOURCE
 
 } /* namespace js */
 
 #endif /* builtin_Object_h */
--- a/js/src/builtin/ParallelArray.h
+++ b/js/src/builtin/ParallelArray.h
@@ -4,18 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef builtin_ParallelArray_h
 #define builtin_ParallelArray_h
 
 #include "jsobj.h"
 
-#include "jit/Ion.h"
-
 namespace js {
 
 class ParallelArrayObject : public JSObject
 {
     static const Class protoClass;
     static const JSFunctionSpec methods[];
     static const uint32_t NumFixedSlots = 4;
     static const uint32_t NumCtors = 4;
--- a/js/src/builtin/Profilers.cpp
+++ b/js/src/builtin/Profilers.cpp
@@ -6,22 +6,26 @@
 
 /* Profiling-related API */
 
 #include "builtin/Profilers.h"
 
 #include <stdarg.h>
 
 #ifdef MOZ_CALLGRIND
-#include <valgrind/callgrind.h>
+# include <valgrind/callgrind.h>
 #endif
 
 #ifdef __APPLE__
-#include "devtools/Instruments.h"
-#include "devtools/sharkctl.h"
+#ifdef MOZ_INSTRUMENTS
+# include "devtools/Instruments.h"
+#endif
+#ifdef MOZ_SHARK
+# include "devtools/sharkctl.h"
+#endif
 #endif
 
 #include "vm/Probes.h"
 
 #include "jscntxtinlines.h"
 
 using namespace js;
 
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -94,16 +94,25 @@ BUILD_TOOLS	= $(WIN_TOP_SRC)/build/unix
 else
 win_srcdir	:= $(srcdir)
 BUILD_TOOLS	= $(topsrcdir)/build/unix
 endif
 
 CONFIG_TOOLS	= $(MOZ_BUILD_ROOT)/config
 AUTOCONF_TOOLS	= $(topsrcdir)/build/autoconf
 
+# Disable MOZ_PSEUDO_DERECURSE when it contains no-pymake and we're running
+# pymake. This can be removed when no-pymake is removed from the default in
+# build/autoconf/compiler-opts.m4.
+ifdef .PYMAKE
+comma = ,
+ifneq (,$(filter no-pymake,$(subst $(comma), ,$(MOZ_PSEUDO_DERECURSE))))
+MOZ_PSEUDO_DERECURSE :=
+endif
+endif
 #
 # Strip off the excessively long version numbers on these platforms,
 # but save the version to allow multiple versions of the same base
 # platform to be built in the same tree.
 #
 ifneq (,$(filter FreeBSD HP-UX Linux NetBSD OpenBSD SunOS,$(OS_ARCH)))
 OS_RELEASE	:= $(basename $(OS_RELEASE))
 
--- a/js/src/config/expandlibs.py
+++ b/js/src/config/expandlibs.py
@@ -63,16 +63,23 @@ def relativize(path):
         return relpath
     return path
 
 def isObject(path):
     '''Returns whether the given path points to an object file, that is,
     ends with OBJ_SUFFIX or .i_o'''
     return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
 
+def isDynamicLib(path):
+    '''Returns whether the given path points to a dynamic library, that is,
+    ends with DLL_SUFFIX.'''
+    # On mac, the xul library is named XUL, instead of libxul.dylib. Assume any
+    # file by that name is a dynamic library.
+    return os.path.splitext(path)[1] == conf.DLL_SUFFIX or os.path.basename(path) == 'XUL'
+
 class LibDescriptor(dict):
     KEYS = ['OBJS', 'LIBS']
 
     def __init__(self, content=None):
         '''Creates an instance of a lib descriptor, initialized with contents
         from a list of strings when given. This is intended for use with
         file.readlines()'''
         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
--- a/js/src/config/expandlibs_exec.py
+++ b/js/src/config/expandlibs_exec.py
@@ -18,24 +18,32 @@ See https://bugzilla.mozilla.org/show_bu
 
 With the --symbol-order argument, followed by a file name, it will add the
 relevant linker options to change the order in which the linker puts the
 symbols appear in the resulting binary. Only works for ELF targets.
 '''
 from __future__ import with_statement
 import sys
 import os
-from expandlibs import ExpandArgs, relativize, isObject, ensureParentDir, ExpandLibsDeps
+from expandlibs import (
+    ExpandArgs,
+    relativize,
+    isDynamicLib,
+    isObject,
+    ensureParentDir,
+    ExpandLibsDeps,
+)
 import expandlibs_config as conf
 from optparse import OptionParser
 import subprocess
 import tempfile
 import shutil
 import subprocess
 import re
+from mozbuild.makeutil import Makefile
 
 # The are the insert points for a GNU ld linker script, assuming a more
 # or less "standard" default linker script. This is not a dict because
 # order is important.
 SECTION_INSERT_BEFORE = [
   ('.text', '.fini'),
   ('.rodata', '.rodata1'),
   ('.data.rel.ro', '.dynamic'),
@@ -328,17 +336,20 @@ def main():
             print_command(sys.stderr, args)
         sys.stderr.write(stdout)
         sys.stderr.flush()
         if proc.returncode:
             exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
-    with open(options.depend, 'w') as depfile:
-        depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
+    mk = Makefile()
+    deps = [dep for dep in deps if os.path.isfile(dep) and dep != options.target]
+    no_dynamic_lib = [dep for dep in deps if not isDynamicLib(dep)]
+    mk.create_rule([options.target]).add_dependencies(no_dynamic_lib)
+    if len(deps) != len(no_dynamic_lib):
+        mk.create_rule(['%s_order_only' % options.target]).add_dependencies(dep for dep in deps if isDynamicLib(dep))
 
-        for dep in deps:
-            if os.path.isfile(dep) and dep != options.target:
-                depfile.write("%s :\n" % dep)
+    with open(options.depend, 'w') as depfile:
+        mk.dump(depfile, removal_guard=True)
 
 if __name__ == '__main__':
     main()
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1444,17 +1444,16 @@ case "$target" in
     CFLAGS="$CFLAGS -fno-common"
     CXXFLAGS="$CXXFLAGS -fno-common"
     DLL_SUFFIX=".dylib"
     DSO_LDOPTS=''
     STRIP="$STRIP -x -S"
     _PLATFORM_DEFAULT_TOOLKIT='cairo-cocoa'
     TARGET_NSPR_MDCPUCFG='\"md/_darwin.cfg\"'
     LDFLAGS="$LDFLAGS -lobjc"
-    LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) $(LIBXUL_DIST)/bin/XUL'
     # The ExceptionHandling framework is needed for Objective-C exception
     # logging code in nsObjCExceptions.h. Currently we only use that in debug
     # builds.
     _SAVE_LDFLAGS=$LDFLAGS
      AC_MSG_CHECKING([for -framework ExceptionHandling])
     LDFLAGS="$LDFLAGS -framework ExceptionHandling"
     AC_TRY_LINK(,[return 0;],
                 ac_cv_have_framework_exceptionhandling="yes",
@@ -1587,18 +1586,16 @@ ia64*-hpux*)
         RC='$(WINDRES)'
         # Use static libgcc and libstdc++
         LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++"
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -lgdi32 -lwinmm -lwsock32 -lpsapi"
         MOZ_FIX_LINK_PATHS=
-        DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxpcom -lxpcom_core -lmozalloc'
-        XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxpcom -lmozalloc'
         DLL_PREFIX=
         IMPORT_LIB_SUFFIX=dll.a
 
         # We use mix of both POSIX and Win32 printf format across the tree, so format
         # warnings are useless on mingw.
         MOZ_C_SUPPORTS_WARNING(-Wno-, format, ac_c_has_wno_format)
         MOZ_CXX_SUPPORTS_WARNING(-Wno-, format, ac_cxx_has_wno_format)
     else
@@ -1650,19 +1647,16 @@ ia64*-hpux*)
         CFLAGS="$CFLAGS -we4553"
         CXXFLAGS="$CXXFLAGS -we4553"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib psapi.lib"
         MOZ_DEBUG_FLAGS='-Zi'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
         MOZ_OPTIMIZE_FLAGS="-O2"
         MOZ_FIX_LINK_PATHS=
-        DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
-        XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
-        LIBXUL_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
         MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
         LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
         if test -z "$DEVELOPER_OPTIONS"; then
             LDFLAGS="$LDFLAGS -RELEASE"
         fi
         dnl For profile-guided optimization
         PROFILE_GEN_CFLAGS="-GL"
         PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
@@ -1812,18 +1806,16 @@ ia64*-hpux*)
     BIN_FLAGS='-Zlinker /ST:0x100000'
     IMPLIB='emximp -o'
     FILTER='true'
     LDFLAGS='-Zmap'
     WARNINGS_AS_ERRORS='-Werror'
     MOZ_DEBUG_FLAGS="-g -fno-inline"
     MOZ_OPTIMIZE_FLAGS="-O2"
     MOZ_OPTIMIZE_LDFLAGS="-s -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
-    DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
-    LIBXUL_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
     TARGET_MD_ARCH=os2
     _PLATFORM_DEFAULT_TOOLKIT="cairo-os2"
     RC=rc.exe
     MC=mc.exe
     RCFLAGS='-n'
     MOZ_USER_DIR="Mozilla"
 
     if test "$MOZTOOLS"; then
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -26,23 +26,21 @@
 #endif
 
 #if defined(XP_UNIX)
 #include <errno.h>
 #elif defined(XP_WIN)
 #include <windows.h>
 #endif
 
-#include "jscompartment.h"
 #include "jsnum.h"
 #include "jsprf.h"
 
 #include "builtin/TypeRepresentation.h"
 #include "ctypes/Library.h"
-#include "vm/TypedArrayObject.h"
 
 using namespace std;
 
 namespace js {
 namespace ctypes {
 
 size_t
 GetDeflatedUTF8StringLength(JSContext *maybecx, const jschar *chars,
@@ -4756,23 +4754,25 @@ StructType::DefineInternal(JSContext* cx
          nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT))
     return false;
 
   // Create a FieldInfoHash to stash on the type object, and an array to root
   // its constituents. (We cannot simply stash the hash in a reserved slot now
   // to get GC safety for free, since if anything in this function fails we
   // do not want to mutate 'typeObj'.)
   AutoPtr<FieldInfoHash> fields(cx->new_<FieldInfoHash>());
-  Array<jsval, 16> fieldRootsArray;
-  if (!fields || !fields->init(len) || !fieldRootsArray.appendN(JSVAL_VOID, len)) {
+  if (!fields || !fields->init(len)) {
     JS_ReportOutOfMemory(cx);
     return false;
   }
-  js::AutoArrayRooter fieldRoots(cx, fieldRootsArray.length(),
-    fieldRootsArray.begin());
+  JS::AutoValueVector fieldRoots(cx);
+  if (!fieldRoots.resize(len)) {
+    JS_ReportOutOfMemory(cx);
+    return false;
+  }
 
   // Process the field types.
   size_t structSize, structAlign;
   if (len != 0) {
     structSize = 0;
     structAlign = 0;
 
     for (uint32_t i = 0; i < len; ++i) {
@@ -4782,17 +4782,17 @@ StructType::DefineInternal(JSContext* cx
 
       RootedObject fieldType(cx, nullptr);
       JSFlatString* flat = ExtractStructField(cx, item, fieldType.address());
       if (!flat)
         return false;
       Rooted<JSStableString*> name(cx, flat->ensureStable(cx));
       if (!name)
         return false;
-      fieldRootsArray[i] = OBJECT_TO_JSVAL(fieldType);
+      fieldRoots[i] = JS::ObjectValue(*fieldType);
 
       // Make sure each field name is unique
       FieldInfoHash::AddPtr entryPtr = fields->lookupForAdd(name);
       if (entryPtr) {
         JS_ReportError(cx, "struct fields must have unique names");
         return false;
       }
 
@@ -5083,20 +5083,19 @@ StructType::BuildFieldsArray(JSContext* 
   JS_ASSERT(CType::IsCType(obj));
   JS_ASSERT(CType::GetTypeCode(obj) == TYPE_struct);
   JS_ASSERT(CType::IsSizeDefined(obj));
 
   const FieldInfoHash* fields = GetFieldInfo(obj);
   size_t len = fields->count();
 
   // Prepare a new array for the 'fields' property of the StructType.
-  Array<jsval, 16> fieldsVec;
-  if (!fieldsVec.appendN(JSVAL_VOID, len))
+  JS::AutoValueVector fieldsVec(cx);
+  if (!fieldsVec.resize(len))
     return nullptr;
-  js::AutoArrayRooter root(cx, fieldsVec.length(), fieldsVec.begin());
 
   for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
     const FieldInfoHash::Entry& entry = r.front();
     // Add the field descriptor to the array.
     if (!AddFieldToArray(cx, &fieldsVec[entry.value.mIndex],
                          entry.key, entry.value.mType))
       return nullptr;
   }
@@ -5892,17 +5891,17 @@ FunctionType::ArgTypesGetter(JSContext* 
   vp.set(JS_GetReservedSlot(obj, SLOT_ARGS_T));
   if (!JSVAL_IS_VOID(vp))
     return true;
 
   FunctionInfo* fninfo = GetFunctionInfo(obj);
   size_t len = fninfo->mArgTypes.length();
 
   // Prepare a new array.
-  Array<jsval, 16> vec;
+  JS::AutoValueVector vec(cx);
   if (!vec.resize(len))
     return false;
 
   for (size_t i = 0; i < len; ++i)
     vec[i] = OBJECT_TO_JSVAL(fninfo->mArgTypes[i]);
 
   RootedObject argTypes(cx, JS_NewArrayObject(cx, len, vec.begin()));
   if (!argTypes)
@@ -6131,23 +6130,22 @@ CClosure::ClosureStub(ffi_cif* cif, void
       break;
     default:
       break;
     }
     memset(result, 0, rvSize);
   }
 
   // Set up an array for converted arguments.
-  Array<jsval, 16> argv;
-  if (!argv.appendN(JSVAL_VOID, cif->nargs)) {
+  JS::AutoValueVector argv(cx);
+  if (!argv.resize(cif->nargs)) {
     JS_ReportOutOfMemory(cx);
     return;
   }
 
-  js::AutoArrayRooter roots(cx, argv.length(), argv.begin());
   for (uint32_t i = 0; i < cif->nargs; ++i) {
     // Convert each argument, and have any CData objects created depend on
     // the existing buffers.
     RootedObject argType(cx, fninfo->mArgTypes[i]);
     if (!ConvertToJS(cx, argType, NullPtr(), args[i], false, false, &argv[i]))
       return;
   }
 
--- a/js/src/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.h
@@ -2,20 +2,22 @@
 /* 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 ctypes_CTypes_h
 #define ctypes_CTypes_h
 
 #include "ffi.h"
-#include "jscntxt.h"
+#include "jsalloc.h"
 #include "prlink.h"
 
 #include "js/HashTable.h"
+#include "js/Vector.h"
+#include "vm/String.h"
 
 namespace js {
 namespace ctypes {
 
 /*******************************************************************************
 ** Utility classes
 *******************************************************************************/
 
@@ -51,16 +53,18 @@ private:
 
   T* mPtr;
 };
 
 // Container class for Vector, using SystemAllocPolicy.
 template<class T, size_t N = 0>
 class Array : public Vector<T, N, SystemAllocPolicy>
 {
+  static_assert(!mozilla::IsSame<T, JS::Value>::value,
+                "use JS::AutoValueVector instead");
 };
 
 // String and AutoString classes, based on Vector.
 typedef Vector<jschar,  0, SystemAllocPolicy> String;
 typedef Vector<jschar, 64, SystemAllocPolicy> AutoString;
 typedef Vector<char,    0, SystemAllocPolicy> CString;
 typedef Vector<char,   64, SystemAllocPolicy> AutoCString;
 
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=2 sw=2 et tw=99:
  * 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 "ctypes/Library.h"
 
-#include "jscntxt.h"
-#include "jsstr.h"
 #include "prlink.h"
 
 #include "ctypes/CTypes.h"
 
 namespace js {
 namespace ctypes {
 
 /*******************************************************************************
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -28,23 +28,21 @@
 #include "jsutil.h"
 
 #include "frontend/Parser.h"
 #include "frontend/TokenStream.h"
 #include "jit/AsmJSLink.h"
 #include "vm/Debugger.h"
 
 #include "jsatominlines.h"
-#include "jsfuninlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "frontend/ParseMaps-inl.h"
 #include "frontend/ParseNode-inl.h"
-#include "vm/ScopeObject-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::frontend;
 
 using mozilla::DebugOnly;
 using mozilla::DoubleIsInt32;
 using mozilla::PodCopy;
--- a/js/src/frontend/ParseMaps.h
+++ b/js/src/frontend/ParseMaps.h
@@ -7,17 +7,16 @@
 #ifndef frontend_ParseMaps_h
 #define frontend_ParseMaps_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/TypeTraits.h"
 
 #include "ds/InlineMap.h"
 #include "gc/Barrier.h"
-#include "js/HashTable.h"
 #include "js/Vector.h"
 
 class JSAtom;
 
 typedef uintptr_t jsatomid;
 
 namespace js {
 
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -4,18 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef frontend_ParseNode_h
 #define frontend_ParseNode_h
 
 #include "mozilla/Attributes.h"
 
-#include "jsscript.h"
-
 #include "builtin/Module.h"
 #include "frontend/TokenStream.h"
 
 namespace js {
 namespace frontend {
 
 template <typename ParseHandler>
 struct ParseContext;
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -230,32 +230,51 @@ struct TokenPos {
 
     bool encloses(const TokenPos& pos) const {
         return begin <= pos.begin && pos.end <= end;
     }
 };
 
 enum DecimalPoint { NoDecimal = false, HasDecimal = true };
 
-struct Token {
+struct Token
+{
     TokenKind           type;           // char value or above enumerator
     TokenPos            pos;            // token position in file
     union {
       private:
         friend struct Token;
         PropertyName    *name;          // non-numeric atom
         JSAtom          *atom;          // potentially-numeric atom
         struct {
             double      value;          // floating point number
             DecimalPoint decimalPoint;  // literal contains '.'
         } number;
         RegExpFlag      reflags;        // regexp flags; use tokenbuf to access
                                         //   regexp chars
     } u;
 
+    // This constructor is necessary only for MSVC 2013 and how it compiles the
+    // initialization of TokenStream::tokens.  That field is initialized as
+    // tokens() in the constructor init-list.  This *should* zero the entire
+    // array, then (because Token has a non-trivial constructor, because
+    // TokenPos has a user-provided constructor) call the implicit Token
+    // constructor on each element, which would call the TokenPos constructor
+    // for Token::pos and do nothing.  (All of which is equivalent to just
+    // zeroing TokenStream::tokens.)  But MSVC 2013 (2010/2012 don't have this
+    // bug) doesn't zero out each element, so we need this extra constructor to
+    // make it do the right thing.  (Token is used primarily by reference or
+    // pointer, and it's only initialized a very few places, so having a
+    // user-defined constructor won't hurt perf.)  See also bug 920318.
+    Token()
+      : type(TOK_ERROR),
+        pos(0, 0)
+    {
+    }
+
     // Mutators
 
     void setName(PropertyName *name) {
         JS_ASSERT(type == TOK_NAME);
         JS_ASSERT(!IsPoisonedPtr(name));
         u.name = name;
     }
 
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -5,17 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef gc_Barrier_h
 #define gc_Barrier_h
 
 #include "NamespaceImports.h"
 
 #include "gc/Heap.h"
-#include "gc/StoreBuffer.h"
+#ifdef JSGC_GENERATIONAL
+# include "gc/StoreBuffer.h"
+#endif
 #include "js/HashTable.h"
 #include "js/Id.h"
 #include "js/RootingAPI.h"
 
 /*
  * A write barrier is a mechanism used by incremental or generation GCs to
  * ensure that every value that needs to be marked is marked. In general, the
  * write barrier should be invoked whenever a write can cause the set of things
--- a/js/src/gc/FindSCCs.h
+++ b/js/src/gc/FindSCCs.h
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 gc_FindSCCs_h
 #define gc_FindSCCs_h
 
+#include "jsfriendapi.h"
 #include "jsutil.h"
 
 namespace js {
 namespace gc {
 
 template<class Node>
 struct GraphNodeBase
 {
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -12,17 +12,19 @@
 #include "vm/ArgumentsObject.h"
 #include "vm/ScopeObject.h"
 #include "vm/Shape.h"
 #include "vm/TypedArrayObject.h"
 
 #include "jscompartmentinlines.h"
 #include "jsinferinlines.h"
 
-#include "gc/Nursery-inl.h"
+#ifdef JSGC_GENERATIONAL
+# include "gc/Nursery-inl.h"
+#endif
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
 using mozilla::DebugOnly;
 
 void * const js::NullPtr::constNullValue = nullptr;
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -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/. */
 
 #ifndef gc_Marking_h
 #define gc_Marking_h
 
 #include "gc/Barrier.h"
-#include "js/TypeDecls.h"
 
 class JSAtom;
 class JSLinearString;
 
 namespace js {
 
 class ArgumentsObject;
 class ArrayBufferObject;
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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/DebugOnly.h"
 #include "mozilla/Util.h"
 
 #ifdef MOZ_VALGRIND
 # include <valgrind/memcheck.h>
 #endif
 
 #include "jsapi.h"
 #include "jscntxt.h"
@@ -18,17 +17,16 @@
 #include "jsprf.h"
 #include "jswatchpoint.h"
 
 #include "builtin/MapObject.h"
 #include "frontend/BytecodeCompiler.h"
 #include "gc/GCInternals.h"
 #include "gc/Marking.h"
 #ifdef JS_ION
-# include "jit/IonFrameIterator.h"
 # include "jit/IonMacroAssembler.h"
 #endif
 #include "js/HashTable.h"
 #include "vm/Debugger.h"
 
 #include "jsgcinlines.h"
 #include "jsobjinlines.h"
 
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -11,16 +11,17 @@
 #ifdef MOZ_VTUNE
 # include "vtune/VTuneWrapper.h"
 #endif
 
 #include "jsprf.h"
 #include "jsworkers.h"
 #include "prmjtime.h"
 
+#include "assembler/assembler/MacroAssembler.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"
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -13,16 +13,17 @@
 
 #include "jsscript.h"
 
 #include "gc/Marking.h"
 #include "jit/AsmJS.h"
 #include "jit/IonMacroAssembler.h"
 #include "jit/PerfSpewer.h"
 #include "jit/RegisterSets.h"
+#include "vm/TypedArrayObject.h"
 
 namespace js {
 
 // These EcmaScript-defined coercions form the basis of the asm.js type system.
 enum AsmJSCoercion
 {
     AsmJS_ToInt32,
     AsmJS_ToNumber
@@ -400,17 +401,17 @@ class AsmJSModule
 #endif
 #if defined(JS_ION_PERF)
         for (unsigned i = 0; i < profiledFunctions_.length(); i++)
             profiledFunctions_[i].trace(trc);
         for (unsigned i = 0; i < perfProfiledBlocksFunctions_.length(); i++)
             perfProfiledBlocksFunctions_[i].trace(trc);
 #endif
         if (maybeHeap_)
-            MarkObject(trc, &maybeHeap_, "asm.js heap");
+            gc::MarkObject(trc, &maybeHeap_, "asm.js heap");
 
         if (globalArgumentName_)
             MarkStringUnbarriered(trc, &globalArgumentName_, "asm.js global argument name");
         if (importArgumentName_)
             MarkStringUnbarriered(trc, &importArgumentName_, "asm.js import argument name");
         if (bufferArgumentName_)
             MarkStringUnbarriered(trc, &bufferArgumentName_, "asm.js buffer argument name");
     }
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BacktrackingAllocator.h"
-
 #include "jsprf.h"
+#include "jit/BitSet.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 bool
 BacktrackingAllocator::init()
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -1,22 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BaselineCompiler.h"
 #include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
 #include "jit/CompileInfo.h"
 #include "jit/IonSpewer.h"
 #include "vm/ArgumentsObject.h"
 
-#include "jsfuninlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/IonFrames-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 // BaselineStackBuilder may reallocate its buffer if the current one is too
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -7,17 +7,16 @@
 #include "jit/BaselineCompiler.h"
 
 #include "jit/BaselineHelpers.h"
 #include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
 #include "jit/FixedList.h"
 #include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
-#include "jit/PerfSpewer.h"
 #include "jit/VMFunctions.h"
 
 #include "jsscriptinlines.h"
 
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
 using namespace js::jit;
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -4,22 +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 jit_BaselineCompiler_h
 #define jit_BaselineCompiler_h
 
 #ifdef JS_ION
 
-#include "jit/BaselineIC.h"
-#include "jit/BaselineJIT.h"
-#include "jit/BytecodeAnalysis.h"
 #include "jit/FixedList.h"
-#include "jit/IonAllocPolicy.h"
-#include "jit/IonCode.h"
 #if defined(JS_CPU_X86)
 # include "jit/x86/BaselineCompiler-x86.h"
 #elif defined(JS_CPU_X64)
 # include "jit/x64/BaselineCompiler-x64.h"
 #else
 # include "jit/arm/BaselineCompiler-arm.h"
 #endif
 
--- a/js/src/jit/BaselineFrame-inl.h
+++ b/js/src/jit/BaselineFrame-inl.h
@@ -9,17 +9,16 @@
 
 #ifdef JS_ION
 
 #include "jit/BaselineFrame.h"
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 
-#include "jit/IonFrames.h"
 #include "vm/ScopeObject.h"
 
 namespace js {
 namespace jit {
 
 inline void
 BaselineFrame::pushOnScopeChain(ScopeObject &scope)
 {
--- a/js/src/jit/BaselineFrame.cpp
+++ b/js/src/jit/BaselineFrame.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BaselineFrame-inl.h"
 
-#include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
 #include "jit/Ion.h"
 #include "vm/Debugger.h"
 #include "vm/ScopeObject.h"
 
 #include "jit/IonFrames-inl.h"
 #include "vm/Stack-inl.h"
 
--- a/js/src/jit/BaselineFrame.h
+++ b/js/src/jit/BaselineFrame.h
@@ -4,19 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_BaselineFrame_h
 #define jit_BaselineFrame_h
 
 #ifdef JS_ION
 
-#include "jscntxt.h"
-#include "jscompartment.h"
-
 #include "jit/IonFrames.h"
 #include "vm/Stack.h"
 
 namespace js {
 namespace jit {
 
 // The stack looks like this, fp is the frame pointer:
 //
--- a/js/src/jit/BaselineFrameInfo.cpp
+++ b/js/src/jit/BaselineFrameInfo.cpp
@@ -1,18 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BaselineFrameInfo.h"
 
-#include "jit/IonSpewer.h"
-#include "jit/shared/BaselineCompiler-shared.h"
+#ifdef DEBUG
+# include "jit/BytecodeAnalysis.h"
+#endif
 
 using namespace js;
 using namespace js::jit;
 
 bool
 FrameInfo::init() {
     // One slot is always needed for this/arguments type checks.
     size_t nstack = Max(script->nslots - script->nfixed, 1);
--- a/js/src/jit/BaselineFrameInfo.h
+++ b/js/src/jit/BaselineFrameInfo.h
@@ -7,25 +7,25 @@
 #ifndef jit_BaselineFrameInfo_h
 #define jit_BaselineFrameInfo_h
 
 #ifdef JS_ION
 
 #include "mozilla/Alignment.h"
 
 #include "jit/BaselineFrame.h"
-#include "jit/BaselineJIT.h"
 #include "jit/BaselineRegisters.h"
-#include "jit/BytecodeAnalysis.h"
 #include "jit/FixedList.h"
 #include "jit/IonMacroAssembler.h"
 
 namespace js {
 namespace jit {
 
+struct BytecodeInfo;
+
 // FrameInfo overview.
 //
 // FrameInfo is used by the compiler to track values stored in the frame. This
 // includes locals, arguments and stack values. Locals and arguments are always
 // fully synced. Stack values can either be synced, stored as constant, stored in
 // a Value register or refer to a local slot. Syncing a StackValue ensures it's
 // stored on the stack, e.g. kind == Stack.
 //
@@ -155,18 +155,16 @@ class StackValue
     void setStack() {
         kind_ = Stack;
         knownType_ = JSVAL_TYPE_UNKNOWN;
     }
 };
 
 enum StackAdjustment { AdjustStack, DontAdjustStack };
 
-class BaselineCompilerShared;
-
 class FrameInfo
 {
     RootedScript script;
     MacroAssembler &masm;
 
     FixedList<StackValue> stack;
     size_t spIndex;
 
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -5,23 +5,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/BaselineIC.h"
 
 #include "jsautooplen.h"
 #include "jslibmath.h"
 
 #include "builtin/Eval.h"
-#include "jit/BaselineCompiler.h"
 #include "jit/BaselineHelpers.h"
 #include "jit/BaselineJIT.h"
 #include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
 #include "jit/Lowering.h"
-#include "jit/PerfSpewer.h"
 #include "jit/VMFunctions.h"
 
 #include "jsboolinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/Interpreter-inl.h"
 #include "vm/ScopeObject-inl.h"
 
--- a/js/src/jit/BytecodeAnalysis.cpp
+++ b/js/src/jit/BytecodeAnalysis.cpp
@@ -2,17 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BytecodeAnalysis.h"
 
 #include "jsopcode.h"
-
+#include "jit/IonSpewer.h"
 #include "jsopcodeinlines.h"
 
 using namespace js;
 using namespace js::jit;
 
 BytecodeAnalysis::BytecodeAnalysis(JSScript *script)
   : script_(script),
     infos_(),
--- a/js/src/jit/BytecodeAnalysis.h
+++ b/js/src/jit/BytecodeAnalysis.h
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_BytecodeAnalysis_h
 #define jit_BytecodeAnalysis_h
 
+#include "jsscript.h"
 #include "jit/IonAllocPolicy.h"
 #include "js/Vector.h"
 
 namespace js {
 namespace jit {
 
 // Basic information about bytecodes in the script.  Used to help baseline compilation.
 struct BytecodeInfo
--- a/js/src/jit/C1Spewer.cpp
+++ b/js/src/jit/C1Spewer.cpp
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef DEBUG
 
 #include "jit/C1Spewer.h"
 
 #include <time.h>
 
-#include "jit/Ion.h"
-#include "jit/IonBuilder.h"
 #include "jit/LinearScan.h"
 #include "jit/LIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace js::jit;
 
 bool
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4,34 +4,34 @@
  * 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 "jit/CodeGenerator.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
-#include "mozilla/Util.h"
 
 #include "jslibmath.h"
 #include "jsmath.h"
 #include "jsnum.h"
 
 #include "builtin/Eval.h"
 #include "builtin/TypedObject.h"
-#include "gc/Nursery.h"
+#ifdef JSGC_GENERATIONAL
+# include "gc/Nursery.h"
+#endif
 #include "jit/ExecutionModeInlines.h"
+#include "jit/IonCaches.h"
 #include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
-#include "jit/Lowering.h"
 #include "jit/MIRGenerator.h"
 #include "jit/MoveEmitter.h"
 #include "jit/ParallelFunctions.h"
 #include "jit/ParallelSafetyAnalysis.h"
-#include "jit/PerfSpewer.h"
 #include "jit/RangeAnalysis.h"
 #include "vm/ForkJoin.h"
 
 #include "jsboolinlines.h"
 
 #include "jit/shared/CodeGenerator-shared-inl.h"
 #include "vm/Interpreter-inl.h"
 
@@ -356,16 +356,28 @@ CodeGenerator::visitDoubleToInt32(LDoubl
     FloatRegister input = ToFloatRegister(lir->input());
     Register output = ToRegister(lir->output());
     masm.convertDoubleToInt32(input, output, &fail, lir->mir()->canBeNegativeZero());
     if (!bailoutFrom(&fail, lir->snapshot()))
         return false;
     return true;
 }
 
+bool
+CodeGenerator::visitFloat32ToInt32(LFloat32ToInt32 *lir)
+{
+    Label fail;
+    FloatRegister input = ToFloatRegister(lir->input());
+    Register output = ToRegister(lir->output());
+    masm.convertFloat32ToInt32(input, output, &fail, lir->mir()->canBeNegativeZero());
+    if (!bailoutFrom(&fail, lir->snapshot()))
+        return false;
+    return true;
+}
+
 void
 CodeGenerator::emitOOLTestObject(Register objreg, Label *ifTruthy, Label *ifFalsy, Register scratch)
 {
     saveVolatile(scratch);
     masm.setupUnalignedABICall(1, scratch);
     masm.passABIArg(objreg);
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::EmulatesUndefined));
     masm.storeCallResult(scratch);
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -2,17 +2,20 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_CodeGenerator_h
 #define jit_CodeGenerator_h
 
-#include "jit/PerfSpewer.h"
+#include "jit/IonCaches.h"
+#if defined(JS_ION_PERF)
+# include "jit/PerfSpewer.h"
+#endif
 
 #if defined(JS_CPU_X86)
 # include "jit/x86/CodeGenerator-x86.h"
 #elif defined(JS_CPU_X64)
 # include "jit/x64/CodeGenerator-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/CodeGenerator-arm.h"
 #else
@@ -112,16 +115,17 @@ class CodeGenerator : public CodeGenerat
     void emitPushArguments(LApplyArgsGeneric *apply, Register extraStackSpace);
     void emitPopArguments(LApplyArgsGeneric *apply, Register extraStackSize);
     bool visitApplyArgsGeneric(LApplyArgsGeneric *apply);
     bool visitBail(LBail *lir);
     bool visitGetDynamicName(LGetDynamicName *lir);
     bool visitFilterArguments(LFilterArguments *lir);
     bool visitCallDirectEval(LCallDirectEval *lir);
     bool visitDoubleToInt32(LDoubleToInt32 *lir);
+    bool visitFloat32ToInt32(LFloat32ToInt32 *lir);
     bool visitNewSlots(LNewSlots *lir);
     bool visitNewParallelArrayVMCall(LNewParallelArray *lir);
     bool visitNewParallelArray(LNewParallelArray *lir);
     bool visitOutOfLineNewParallelArray(OutOfLineNewParallelArray *ool);
     bool visitNewArrayCallVM(LNewArray *lir);
     bool visitNewArray(LNewArray *lir);
     bool visitOutOfLineNewArray(OutOfLineNewArray *ool);
     bool visitNewObjectVMCall(LNewObject *lir);
--- a/js/src/jit/EdgeCaseAnalysis.cpp
+++ b/js/src/jit/EdgeCaseAnalysis.cpp
@@ -1,19 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/EdgeCaseAnalysis.h"
 
-#include "jit/Ion.h"
-#include "jit/IonBuilder.h"
-#include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace js::jit;
 
 EdgeCaseAnalysis::EdgeCaseAnalysis(MIRGenerator *mir, MIRGraph &graph)
   : mir(mir), graph(graph)
--- a/js/src/jit/EffectiveAddressAnalysis.cpp
+++ b/js/src/jit/EffectiveAddressAnalysis.cpp
@@ -1,15 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/EffectiveAddressAnalysis.h"
+#include "jit/MIR.h"
+#include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace jit;
 
 static void
 AnalyzeLsh(MBasicBlock *block, MLsh *lsh)
 {
     if (lsh->specialization() != MIRType_Int32)
--- a/js/src/jit/EffectiveAddressAnalysis.h
+++ b/js/src/jit/EffectiveAddressAnalysis.h
@@ -2,22 +2,21 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_EffectiveAddressAnalysis_h
 #define jit_EffectiveAddressAnalysis_h
 
-#include "jit/MIR.h"
-#include "jit/MIRGraph.h"
-
 namespace js {
 namespace jit {
 
+class MIRGraph;
+
 class EffectiveAddressAnalysis
 {
     MIRGraph &graph_;
 
   public:
     EffectiveAddressAnalysis(MIRGraph &graph)
       : graph_(graph)
     {}
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -12,47 +12,38 @@
 #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/BaselineFrame.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"
 #include "jit/ExecutionModeInlines.h"
 #include "jit/IonAnalysis.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonCompartment.h"
-#include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
 #include "jit/LICM.h"
 #include "jit/LinearScan.h"
 #include "jit/LIR.h"
+#include "jit/Lowering.h"
 #include "jit/ParallelSafetyAnalysis.h"
 #include "jit/PerfSpewer.h"
 #include "jit/RangeAnalysis.h"
 #include "jit/StupidAllocator.h"
 #include "jit/UnreachableCodeElimination.h"
 #include "jit/ValueNumbering.h"
-#if defined(JS_CPU_X86)
-# include "jit/x86/Lowering-x86.h"
-#elif defined(JS_CPU_X64)
-# include "jit/x64/Lowering-x64.h"
-#elif defined(JS_CPU_ARM)
-# include "jit/arm/Lowering-arm.h"
-#endif
 #include "vm/ForkJoin.h"
 
 #include "jscompartmentinlines.h"
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 
 using namespace js;
 using namespace js::jit;
--- a/js/src/jit/Ion.h
+++ b/js/src/jit/Ion.h
@@ -10,17 +10,16 @@
 #ifdef JS_ION
 
 #include "mozilla/MemoryReporting.h"
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 
 #include "jit/CompileInfo.h"
-#include "jit/IonCode.h"
 
 namespace js {
 namespace jit {
 
 class TempAllocator;
 
 // Possible register allocators which may be used.
 enum IonRegisterAllocator {
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -13,17 +13,16 @@
 #include "builtin/Eval.h"
 #include "builtin/TypedObject.h"
 #include "builtin/TypeRepresentation.h"
 #include "frontend/SourceNotes.h"
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineInspector.h"
 #include "jit/ExecutionModeInlines.h"
 #include "jit/Ion.h"
-#include "jit/IonAnalysis.h"
 #include "jit/IonSpewer.h"
 #include "jit/Lowering.h"
 #include "jit/MIRGraph.h"
 
 #include "vm/ArgumentsObject.h"
 
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -9,16 +9,17 @@
 
 #ifdef JS_ION
 
 // This file declares the data structures for building a MIRGraph from a
 // JSScript.
 
 #include "jit/BytecodeAnalysis.h"
 #include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 #include "jit/TypeRepresentationSet.h"
 
 namespace js {
 namespace jit {
 
 class CodeGenerator;
 class CallInfo;
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -6,22 +6,20 @@
 
 #include "jit/IonCaches.h"
 
 #include "mozilla/DebugOnly.h"
 
 #include "jsproxy.h"
 
 #include "builtin/TypeRepresentation.h"
-#include "jit/CodeGenerator.h"
 #include "jit/Ion.h"
 #include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
 #include "jit/Lowering.h"
-#include "jit/PerfSpewer.h"
 #include "jit/VMFunctions.h"
 #include "vm/Shape.h"
 
 #include "vm/Interpreter-inl.h"
 #include "vm/Shape-inl.h"
 
 using namespace js;
 using namespace js::jit;
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_IonCaches_h
 #define jit_IonCaches_h
 
 #ifdef JS_CPU_ARM
 # include "jit/arm/Assembler-arm.h"
 #endif
-#include "jit/IonCode.h"
 #include "jit/Registers.h"
 #include "jit/shared/Assembler-shared.h"
 
 namespace js {
 
 class LockedJSContext;
 class TypedArrayObject;
 
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -13,24 +13,24 @@
 #include "gc/Marking.h"
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
 #include "jit/Ion.h"
 #include "jit/IonCompartment.h"
 #include "jit/IonMacroAssembler.h"
 #include "jit/IonSpewer.h"
+#include "jit/ParallelFunctions.h"
 #include "jit/PcScriptCache.h"
 #include "jit/Safepoints.h"
 #include "jit/SnapshotReader.h"
 #include "jit/VMFunctions.h"
+#include "vm/ForkJoin.h"
 #include "vm/Interpreter.h"
 
-#include "jsfuninlines.h"
-
 #include "jit/IonFrameIterator-inl.h"
 #include "vm/Probes-inl.h"
 
 namespace js {
 namespace jit {
 
 IonFrameIterator::IonFrameIterator(const ActivationIterator &activations)
     : current_(activations.jitTop()),
--- a/js/src/jit/IonFrames.h
+++ b/js/src/jit/IonFrames.h
@@ -8,22 +8,18 @@
 #define jit_IonFrames_h
 
 #ifdef JS_ION
 
 #include "mozilla/DebugOnly.h"
 
 #include "jscntxt.h"
 #include "jsfun.h"
-#include "jstypes.h"
-#include "jsutil.h"
 
-#include "jit/IonCode.h"
 #include "jit/IonFrameIterator.h"
-#include "jit/Registers.h"
 
 namespace js {
 namespace jit {
 
 typedef void * CalleeToken;
 
 enum CalleeTokenTag
 {
--- a/js/src/jit/IonMacroAssembler.cpp
+++ b/js/src/jit/IonMacroAssembler.cpp
@@ -9,22 +9,24 @@
 #include "jsinfer.h"
 #include "jsprf.h"
 
 #include "builtin/TypeRepresentation.h"
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineIC.h"
 #include "jit/BaselineJIT.h"
-#include "jit/BaselineRegisters.h"
 #include "jit/Lowering.h"
 #include "jit/MIR.h"
+#include "jit/ParallelFunctions.h"
 #include "vm/ForkJoin.h"
 
-#include "jsgcinlines.h"
+#ifdef JSGC_GENERATIONAL
+# include "jsgcinlines.h"
+#endif
 #include "jsinferinlines.h"
 
 using namespace js;
 using namespace js::jit;
 
 using JS::GenericNaN;
 
 namespace {
--- a/js/src/jit/IonMacroAssembler.h
+++ b/js/src/jit/IonMacroAssembler.h
@@ -15,21 +15,19 @@
 # include "jit/x86/MacroAssembler-x86.h"
 #elif defined(JS_CPU_X64)
 # include "jit/x64/MacroAssembler-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/MacroAssembler-arm.h"
 #endif
 #include "jit/IonCompartment.h"
 #include "jit/IonInstrumentation.h"
-#include "jit/ParallelFunctions.h"
 #include "jit/VMFunctions.h"
 #include "vm/ProxyObject.h"
 #include "vm/Shape.h"
-#include "vm/TypedArrayObject.h"
 
 namespace js {
 namespace jit {
 
 // The public entrypoint for emitting assembly. Note that a MacroAssembler can
 // use cx->lifoAlloc, so take care not to interleave masm use with other
 // lifoAlloc use if one will be destroyed before the other.
 class MacroAssembler : public MacroAssemblerSpecific
--- a/js/src/jit/IonSpewer.h
+++ b/js/src/jit/IonSpewer.h
@@ -8,16 +8,17 @@
 #define jit_IonSpewer_h
 
 #include "mozilla/DebugOnly.h"
 
 #include <stdarg.h>
 
 #include "jit/C1Spewer.h"
 #include "jit/JSONSpewer.h"
+#include "js/RootingAPI.h"
 
 namespace js {
 namespace jit {
 
 // New channels may be added below.
 #define IONSPEW_CHANNEL_LIST(_)             \
     /* Used to abort SSA construction */    \
     _(Abort)                                \
@@ -89,38 +90,38 @@ enum IonSpewChannel {
 static const int NULL_ID = -1;
 
 #ifdef DEBUG
 
 class IonSpewer
 {
   private:
     MIRGraph *graph;
-    HandleScript function;
+    JS::HandleScript function;
     C1Spewer c1Spewer;
     JSONSpewer jsonSpewer;
     bool inited_;
 
   public:
     IonSpewer()
       : graph(NULL), function(NullPtr()), inited_(false)
     { }
 
     // File output is terminated safely upon destruction.
     ~IonSpewer();
 
     bool init();
-    void beginFunction(MIRGraph *graph, HandleScript);
+    void beginFunction(MIRGraph *graph, JS::HandleScript);
     bool isSpewingFunction() const;
     void spewPass(const char *pass);
     void spewPass(const char *pass, LinearScanAllocator *ra);
     void endFunction();
 };
 
-void IonSpewNewFunction(MIRGraph *graph, HandleScript function);
+void IonSpewNewFunction(MIRGraph *graph, JS::HandleScript function);
 void IonSpewPass(const char *pass);
 void IonSpewPass(const char *pass, LinearScanAllocator *ra);
 void IonSpewEndFunction();
 
 void CheckLogging();
 extern FILE *IonSpewFile;
 void IonSpew(IonSpewChannel channel, const char *fmt, ...);
 void IonSpewStart(IonSpewChannel channel, const char *fmt, ...);
@@ -133,17 +134,17 @@ void IonSpewStartVA(IonSpewChannel chann
 void IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap);
 
 void EnableChannel(IonSpewChannel channel);
 void DisableChannel(IonSpewChannel channel);
 void EnableIonDebugLogging();
 
 #else
 
-static inline void IonSpewNewFunction(MIRGraph *graph, HandleScript function)
+static inline void IonSpewNewFunction(MIRGraph *graph, JS::HandleScript function)
 { }
 static inline void IonSpewPass(const char *pass)
 { }
 static inline void IonSpewPass(const char *pass, LinearScanAllocator *ra)
 { }
 static inline void IonSpewEndFunction()
 { }
 
--- a/js/src/jit/LICM.cpp
+++ b/js/src/jit/LICM.cpp
@@ -3,20 +3,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 "jit/LICM.h"
 
 #include <stdio.h>
 
-#include "jit/Ion.h"
-#include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace js::jit;
 
 namespace {
 
 typedef Vector<MBasicBlock*, 1, IonAllocPolicy> BlockQueue;
--- a/js/src/jit/LICM.h
+++ b/js/src/jit/LICM.h
@@ -2,26 +2,24 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_LICM_h
 #define jit_LICM_h
 
-#include "jit/IonAllocPolicy.h"
-#include "jit/IonAnalysis.h"
-#include "jit/MIR.h"
-#include "jit/MIRGraph.h"
-
 // This file represents the Loop Invariant Code Motion optimization pass
 
 namespace js {
 namespace jit {
 
+class MIRGenerator;
+class MIRGraph;
+
 class LICM
 {
     MIRGenerator *mir;
     MIRGraph &graph;
 
   public:
     LICM(MIRGenerator *mir, MIRGraph &graph);
     bool analyze();
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -2667,16 +2667,33 @@ class LDoubleToInt32 : public LInstructi
         setOperand(0, in);
     }
 
     MToInt32 *mir() const {
         return mir_->toToInt32();
     }
 };
 
+// Convert a float32 to an int32.
+//   Input: floating-point register
+//   Output: 32-bit integer
+//   Bailout: if the float32 cannot be converted to an integer.
+class LFloat32ToInt32 : public LInstructionHelper<1, 1, 0>
+{
+  public:
+    LIR_HEADER(Float32ToInt32)
+
+    LFloat32ToInt32(const LAllocation &in) {
+        setOperand(0, in);
+    }
+
+    MToInt32 *mir() const {
+        return mir_->toToInt32();
+    }
+};
 
 // Convert a double to a truncated int32.
 //   Input: floating-point register
 //   Output: 32-bit integer
 class LTruncateDToInt32 : public LInstructionHelper<1, 1, 1>
 {
   public:
     LIR_HEADER(TruncateDToInt32)
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -7,18 +7,17 @@
 #include "jit/LIR.h"
 
 #include <ctype.h>
 
 #include "jsprf.h"
 
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
-#include "jit/MIRGraph.h"
-#include "jit/shared/CodeGenerator-shared.h"
+#include "jit/MIRGenerator.h"
 
 using namespace js;
 using namespace js::jit;
 
 LIRGraph::LIRGraph(MIRGraph *mir)
   : numVirtualRegisters_(0),
     numInstructions_(1), // First id is 1.
     localSlotCount_(0),
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -15,18 +15,16 @@
 #include "jit/Bailouts.h"
 #include "jit/InlineList.h"
 #include "jit/IonAllocPolicy.h"
 #include "jit/LOpcodes.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/Registers.h"
 #include "jit/Safepoints.h"
-#include "jit/shared/Assembler-shared.h"
-#include "jit/VMFunctions.h"
 
 namespace js {
 namespace jit {
 
 class LUse;
 class LGeneralReg;
 class LFloatReg;
 class LStackSlot;
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -122,16 +122,17 @@
     _(Int32ToDouble)                \
     _(Float32ToDouble)              \
     _(DoubleToFloat32)              \
     _(Int32ToFloat32)               \
     _(ValueToDouble)                \
     _(ValueToInt32)                 \
     _(ValueToFloat32)               \
     _(DoubleToInt32)                \
+    _(Float32ToInt32)               \
     _(TruncateDToInt32)             \
     _(IntToString)                  \
     _(DoubleToString)               \
     _(Start)                        \
     _(OsrEntry)                     \
     _(OsrValue)                     \
     _(OsrScopeChain)                \
     _(OsrArgumentsObject)           \
--- a/js/src/jit/LinearScan.cpp
+++ b/js/src/jit/LinearScan.cpp
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/LinearScan.h"
 
 #include "mozilla/DebugOnly.h"
 
 #include "jit/BitSet.h"
-#include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 /*
--- a/js/src/jit/LinearScan.h
+++ b/js/src/jit/LinearScan.h
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_LinearScan_h
 #define jit_LinearScan_h
 
-#include "jit/BitSet.h"
 #include "jit/LiveRangeAllocator.h"
 #include "js/Vector.h"
 
 namespace js {
 namespace jit {
 
 class LinearScanVirtualRegister : public VirtualRegister
 {
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -1,19 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/LiveRangeAllocator.h"
-
 #include "mozilla/DebugOnly.h"
-
 #include "jit/BacktrackingAllocator.h"
+#include "jit/BitSet.h"
 #include "jit/LinearScan.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 
 int
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -9,17 +9,16 @@
 #include "mozilla/DebugOnly.h"
 
 #include "jsanalyze.h"
 
 #include "jit/IonSpewer.h"
 #include "jit/LIR.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
-#include "jit/RangeAnalysis.h"
 
 #include "jsinferinlines.h"
 
 #include "jit/shared/Lowering-shared-inl.h"
 
 using namespace js;
 using namespace jit;
 
@@ -1666,16 +1665,22 @@ LIRGenerator::visitToInt32(MToInt32 *con
 
       case MIRType_Null:
         return define(new LInteger(0), convert);
 
       case MIRType_Int32:
       case MIRType_Boolean:
         return redefine(convert, opd);
 
+      case MIRType_Float32:
+      {
+        LFloat32ToInt32 *lir = new LFloat32ToInt32(useRegister(opd));
+        return assignSnapshot(lir) && define(lir, convert);
+      }
+
       case MIRType_Double:
       {
         LDoubleToInt32 *lir = new LDoubleToInt32(useRegister(opd));
         return assignSnapshot(lir) && define(lir, convert);
       }
 
       case MIRType_String:
         // Strings are complicated - we don't handle them yet.
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -5,19 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_Lowering_h
 #define jit_Lowering_h
 
 // This file declares the structures that are used for attaching LIR to a
 // MIRGraph.
 
-#include "jit/IonAllocPolicy.h"
 #include "jit/LIR.h"
-#include "jit/MOpcodes.h"
 #if defined(JS_CPU_X86)
 # include "jit/x86/Lowering-x86.h"
 #elif defined(JS_CPU_X64)
 # include "jit/x64/Lowering-x64.h"
 #elif defined(JS_CPU_ARM)
 # include "jit/arm/Lowering-arm.h"
 #else
 # error "CPU!"
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -9,20 +9,18 @@
 #include "mozilla/FloatingPoint.h"
 
 #include <ctype.h>
 
 #include "jslibmath.h"
 #include "jsstr.h"
 
 #include "jit/BaselineInspector.h"
-#include "jit/EdgeCaseAnalysis.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
-#include "jit/LICM.h" // For LinearSum
 #include "jit/MIRGraph.h"
 #include "jit/RangeAnalysis.h"
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 
 using namespace js;
 using namespace js::jit;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -11,26 +11,26 @@
 
 #ifndef jit_MIR_h
 #define jit_MIR_h
 
 #include "mozilla/Array.h"
 
 #include "jsinfer.h"
 
-#include "jit/Bailouts.h"
 #include "jit/CompilerRoot.h"
 #include "jit/FixedList.h"
 #include "jit/InlineList.h"
 #include "jit/IonAllocPolicy.h"
 #include "jit/IonMacroAssembler.h"
 #include "jit/MOpcodes.h"
 #include "jit/TypePolicy.h"
 #include "jit/TypeRepresentationSet.h"
 #include "vm/ScopeObject.h"
+#include "vm/TypedArrayObject.h"
 
 namespace js {
 
 class StringObject;
 
 namespace jit {
 
 class BaselineInspector;
@@ -2844,19 +2844,17 @@ class MAsmJSUnsignedToDouble
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
 // Converts a primitive (either typed or untyped) to an int32. If the input is
 // not primitive at runtime, a bailout occurs. If the input cannot be converted
 // to an int32 without loss (i.e. "5.5" or undefined) then a bailout occurs.
-class MToInt32
-  : public MUnaryInstruction,
-    public NoFloatPolicy<0>
+class MToInt32 : public MUnaryInstruction
 {
     bool canBeNegativeZero_;
 
     MToInt32(MDefinition *def)
       : MUnaryInstruction(def),
         canBeNegativeZero_(true)
     {
         setResultType(MIRType_Int32);
@@ -2886,19 +2884,19 @@ class MToInt32
         return congruentIfOperandsEqual(ins);
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     void computeRange();
 
-    TypePolicy *typePolicy() {
-        return this;
-    }
+#ifdef DEBUG
+    bool isConsistentFloat32Use() const { return true; }
+#endif
 };
 
 // Converts a value or typed input to a truncated int32, for use with bitwise
 // operations. This is an infallible ValueToECMAInt32.
 class MTruncateToInt32 : public MUnaryInstruction
 {
     MTruncateToInt32(MDefinition *def)
       : MUnaryInstruction(def)
--- a/js/src/jit/MIRGraph.cpp
+++ b/js/src/jit/MIRGraph.cpp
@@ -1,25 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/MIRGraph.h"
 
-#include "jsanalyze.h"
-
 #include "jit/AsmJS.h"
+#include "jit/BytecodeAnalysis.h"
 #include "jit/Ion.h"
-#include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
-
-#include "jsinferinlines.h"
+#include "jit/MIRGenerator.h"
 
 using namespace js;
 using namespace js::jit;
 
 MIRGenerator::MIRGenerator(JSCompartment *compartment,
                            TempAllocator *temp, MIRGraph *graph, CompileInfo *info)
   : compartment(compartment),
     info_(info),
--- a/js/src/jit/MIRGraph.h
+++ b/js/src/jit/MIRGraph.h
@@ -8,17 +8,16 @@
 #define jit_MIRGraph_h
 
 // This file declares the data structures used to build a control-flow graph
 // containing MIR.
 
 #include "jit/FixedList.h"
 #include "jit/IonAllocPolicy.h"
 #include "jit/MIR.h"
-#include "jit/MIRGenerator.h"
 
 namespace js {
 namespace jit {
 
 class BytecodeAnalysis;
 class MBasicBlock;
 class MIRGraph;
 class MStart;
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/ParallelFunctions.h"
 
-#include "jit/IonSpewer.h"
 #include "vm/ArrayObject.h"
 
 #include "jsgcinlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace jit;
 
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/ParallelSafetyAnalysis.h"
 
 #include "jit/Ion.h"
 #include "jit/IonAnalysis.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 #include "jit/UnreachableCodeElimination.h"
 
 #include "jsinferinlines.h"
 
 using namespace js;
 using namespace jit;
 
--- a/js/src/jit/ParallelSafetyAnalysis.h
+++ b/js/src/jit/ParallelSafetyAnalysis.h
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_ParallelSafetyAnalysis_h
 #define jit_ParallelSafetyAnalysis_h
 
-#include "jit/CompileInfo.h"
 #include "jit/MIR.h"
 
 namespace js {
 
 class StackFrame;
 
 namespace jit {
 
--- a/js/src/jit/PerfSpewer.cpp
+++ b/js/src/jit/PerfSpewer.cpp
@@ -5,21 +5,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/PerfSpewer.h"
 
 #if defined(__linux__)
 # include <unistd.h>
 #endif
 
-#include "jit/IonSpewer.h"
-#include "jit/LinearScan.h"
-#include "jit/LIR.h"
-#include "jit/MIR.h"
-#include "jit/MIRGraph.h"
+#ifdef JS_ION_PERF
+# include "jit/IonSpewer.h"
+# include "jit/LinearScan.h"
+# include "jit/LIR.h"
+# include "jit/MIR.h"
+# include "jit/MIRGraph.h"
+#endif
 
 // perf expects its data to be in a file /tmp/perf-PID.map, but for Android
 // and B2G the map files are written to /data/local/tmp/perf-PID.map
 //
 // Except that Android 4.3 no longer allows the browser to write to /data/local/tmp/
 // so also try /sdcard/.
 
 #ifndef PERF_SPEW_DIR
--- a/js/src/jit/PerfSpewer.h
+++ b/js/src/jit/PerfSpewer.h
@@ -2,19 +2,20 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_PerfSpewer_h
 #define jit_PerfSpewer_h
 
-#include <stdio.h>
-
-#include "jit/IonMacroAssembler.h"
+#ifdef JS_ION_PERF
+# include <stdio.h>
+# include "jit/IonMacroAssembler.h"
+#endif
 
 namespace js {
 namespace jit {
 
 class MBasicBlock;
 class MacroAssembler;
 
 #ifdef JS_ION_PERF
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/MathAlgorithms.h"
 
 #include "jsanalyze.h"
 
 #include "jit/Ion.h"
 #include "jit/IonAnalysis.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 #include "vm/NumericConversions.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::Abs;
 using mozilla::CountLeadingZeroes32;
--- a/js/src/jit/RangeAnalysis.h
+++ b/js/src/jit/RangeAnalysis.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_RangeAnalysis_h
 #define jit_RangeAnalysis_h
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 
-#include "jit/CompileInfo.h"
 #include "jit/IonAnalysis.h"
 #include "jit/MIR.h"
 
 namespace js {
 namespace jit {
 
 class MBasicBlock;
 class MIRGraph;
--- a/js/src/jit/RegisterAllocator.h
+++ b/js/src/jit/RegisterAllocator.h
@@ -4,28 +4,27 @@
  * 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 jit_RegisterAllocator_h
 #define jit_RegisterAllocator_h
 
 #include "mozilla/Attributes.h"
 
-#include "jit/InlineList.h"
-#include "jit/Ion.h"
 #include "jit/LIR.h"
-#include "jit/Lowering.h"
-#include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 
 // Generic structures and functions for use by register allocators.
 
 namespace js {
 namespace jit {
 
+class LIRGenerator;
+
 // Structure for running a liveness analysis on a finished register allocation.
 // This analysis can be used for two purposes:
 //
 // - Check the integrity of the allocation, i.e. that the reads and writes of
 //   physical values preserve the semantics of the original virtual registers.
 //
 // - Populate safepoints with live registers, GC thing and value data, to
 //   streamline the process of prototyping new allocators.
--- a/js/src/jit/Safepoints.cpp
+++ b/js/src/jit/Safepoints.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/Safepoints.h"
 
 #include "mozilla/MathAlgorithms.h"
 
+#include "jit/BitSet.h"
 #include "jit/IonSpewer.h"
 #include "jit/LIR.h"
 
 using namespace js;
 using namespace jit;
 
 using mozilla::FloorLog2;
 
--- a/js/src/jit/Safepoints.h
+++ b/js/src/jit/Safepoints.h
@@ -2,24 +2,23 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_Safepoints_h
 #define jit_Safepoints_h
 
-#include "jit/BitSet.h"
 #include "jit/CompactBuffer.h"
-#include "jit/Registers.h"
 #include "jit/shared/Assembler-shared.h"
 
 namespace js {
 namespace jit {
 
+class BitSet;
 struct SafepointNunboxEntry;
 class LAllocation;
 class LSafepoint;
 
 static const uint32_t INVALID_SAFEPOINT_OFFSET = uint32_t(-1);
 
 class SafepointWriter
 {
--- a/js/src/jit/Snapshots.cpp
+++ b/js/src/jit/Snapshots.cpp
@@ -1,24 +1,21 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jsscript.h"
 
-#include "jit/IonFrames.h"
-#include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
 #ifdef TRACK_SNAPSHOTS
 #include "jit/LIR.h"
 #include "jit/MIR.h"
 #endif
-#include "jit/MIRGenerator.h"
 #include "jit/SnapshotReader.h"
 #include "jit/SnapshotWriter.h"
 
 using namespace js;
 using namespace js::jit;
 
 // Snapshot header:
 //
--- a/js/src/jit/TypeRepresentationSet.cpp
+++ b/js/src/jit/TypeRepresentationSet.cpp
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/TypeRepresentationSet.h"
 
 #include "mozilla/HashFunctions.h"
 
 #include "jit/IonBuilder.h"
 
-#include "jsinferinlines.h"
-
 using namespace js;
 using namespace jit;
 
 ///////////////////////////////////////////////////////////////////////////
 // TypeRepresentationSet hasher
 
 HashNumber
 TypeRepresentationSetHasher::hash(TypeRepresentationSet key)
--- a/js/src/jit/UnreachableCodeElimination.cpp
+++ b/js/src/jit/UnreachableCodeElimination.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/UnreachableCodeElimination.h"
 
 #include "jit/AliasAnalysis.h"
 #include "jit/IonAnalysis.h"
+#include "jit/MIRGenerator.h"
 #include "jit/ValueNumbering.h"
 
 using namespace js;
 using namespace jit;
 
 bool
 UnreachableCodeElimination::analyze()
 {
--- a/js/src/jit/UnreachableCodeElimination.h
+++ b/js/src/jit/UnreachableCodeElimination.h
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_UnreachableCodeElimination_h
 #define jit_UnreachableCodeElimination_h
 
-#include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 namespace js {
 namespace jit {
 
 class MIRGraph;
 
 class UnreachableCodeElimination
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/VMFunctions.h"
 
 #include "builtin/ParallelArray.h"
 #include "builtin/TypedObject.h"
 #include "frontend/BytecodeCompiler.h"
 #include "jit/BaselineIC.h"
-#include "jit/Ion.h"
 #include "jit/IonCompartment.h"
 #include "jit/IonFrames.h"
 #include "vm/ArrayObject.h"
 #include "vm/Debugger.h"
 #include "vm/Interpreter.h"
 
 #include "jsinferinlines.h"
 
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_VMFunctions_h
 #define jit_VMFunctions_h
 
 #include "jspubtd.h"
 
 #include "jit/CompileInfo.h"
-#include "jit/Ion.h"
 #include "jit/IonFrames.h"
 
 namespace js {
 
 class DeclEnvObject;
 class ForkJoinSlice;
 
 namespace jit {
--- a/js/src/jit/ValueNumbering.cpp
+++ b/js/src/jit/ValueNumbering.cpp
@@ -1,20 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/ValueNumbering.h"
 
-#include "jit/CompileInfo.h"
-#include "jit/Ion.h"
-#include "jit/IonBuilder.h"
 #include "jit/IonSpewer.h"
+#include "jit/MIRGenerator.h"
+#include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace js::jit;
 
 ValueNumberer::ValueNumberer(MIRGenerator *mir, MIRGraph &graph, bool optimistic)
   : mir(mir),
     graph_(graph),
     pessimisticPass_(!optimistic),
--- a/js/src/jit/ValueNumbering.h
+++ b/js/src/jit/ValueNumbering.h
@@ -2,19 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_ValueNumbering_h
 #define jit_ValueNumbering_h
 
-#include "jit/CompileInfo.h"
 #include "jit/MIR.h"
-#include "jit/MIRGraph.h"
 
 namespace js {
 namespace jit {
 
 class ValueNumberer
 {
   protected:
     struct ValueHasher
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -111,16 +111,44 @@ MacroAssemblerARM::convertDoubleToInt32(
         // Move the top word of the double into the output reg, if it is non-zero,
         // then the original value was -0.0
         as_vxfer(dest, InvalidReg, src, FloatToCore, Assembler::Equal, 1);
         ma_cmp(dest, Imm32(0x80000000), Assembler::Equal);
         ma_b(fail, Assembler::Equal);
     }
 }
 
+// Checks whether a float32 is representable as a 32-bit integer. If so, the
+// integer is written to the output register. Otherwise, a bailout is taken to
+// the given snapshot. This function overwrites the scratch float register.
+void
+MacroAssemblerARM::convertFloat32ToInt32(const FloatRegister &src, const Register &dest, Label *fail, bool negativeZeroCheck)
+{
+    // convert the floating point value to an integer, if it did not fit,
+    //     then when we convert it *back* to  a float, it will have a
+    //     different value, which we can test.
+    ma_vcvt_F32_I32(src, ScratchFloatReg);
+    // move the value into the dest register.
+    ma_vxfer(ScratchFloatReg, dest);
+    ma_vcvt_I32_F32(ScratchFloatReg, ScratchFloatReg);
+    ma_vcmp_f32(src, ScratchFloatReg);
+    as_vmrs(pc);
+    ma_b(fail, Assembler::VFP_NotEqualOrUnordered);
+
+    if (negativeZeroCheck) {
+        ma_cmp(dest, Imm32(0));
+        // Test and bail for -0.0, when integer result is 0
+        // Move the top word of the double into the output reg, if it is non-zero,
+        // then the original value was -0.0
+        as_vxfer(dest, InvalidReg, src, FloatToCore, Assembler::Equal, 0);
+        ma_cmp(dest, Imm32(0x80000000), Assembler::Equal);
+        ma_b(fail, Assembler::Equal);
+    }
+}
+
 void
 MacroAssemblerARM::convertFloatToDouble(const FloatRegister &src, const FloatRegister &dest) {
     as_vcvt(VFPRegister(dest), VFPRegister(src).singleOverlay());
 }
 
 void
 MacroAssemblerARM::branchTruncateFloat32(const FloatRegister &src, const Register &dest, Label *fail) {
     ma_vcvt_F32_I32(src, ScratchFloatReg);
@@ -1481,16 +1509,21 @@ MacroAssemblerARM::ma_vimm_f32(float val
 }
 
 void
 MacroAssemblerARM::ma_vcmp(FloatRegister src1, FloatRegister src2, Condition cc)
 {
     as_vcmp(VFPRegister(src1), VFPRegister(src2), cc);
 }
 void
+MacroAssemblerARM::ma_vcmp_f32(FloatRegister src1, FloatRegister src2, Condition cc)
+{
+    as_vcmp(VFPRegister(src1).singleOverlay(), VFPRegister(src2).singleOverlay(), cc);
+}
+void
 MacroAssemblerARM::ma_vcmpz(FloatRegister src1, Condition cc)
 {
     as_vcmpz(VFPRegister(src1), cc);
 }
 
 void
 MacroAssemblerARM::ma_vcvt_F64_I32(FloatRegister src, FloatRegister dest, Condition cc)
 {
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -48,16 +48,18 @@ class MacroAssemblerARM : public Assembl
     void convertBoolToInt32(Register source, Register dest);
     void convertInt32ToDouble(const Register &src, const FloatRegister &dest);
     void convertInt32ToDouble(const Address &src, FloatRegister dest);
     void convertUInt32ToDouble(const Register &src, const FloatRegister &dest);
     void convertDoubleToFloat(const FloatRegister &src, const FloatRegister &dest);
     void branchTruncateDouble(const FloatRegister &src, const Register &dest, Label *fail);
     void convertDoubleToInt32(const FloatRegister &src, const Register &dest, Label *fail,
                               bool negativeZeroCheck = true);
+    void convertFloat32ToInt32(const FloatRegister &src, const Register &dest, Label *fail,
+                               bool negativeZeroCheck = true);
 
     void convertFloatToDouble(const FloatRegister &src, const FloatRegister &dest);
     void branchTruncateFloat32(const FloatRegister &src, const Register &dest, Label *fail);
     void convertInt32ToFloat32(const Register &src, const FloatRegister &dest);
     void convertInt32ToFloat32(const Address &src, FloatRegister dest);
 
     void addDouble(FloatRegister src, FloatRegister dest);
     void subDouble(FloatRegister src, FloatRegister dest);
@@ -317,16 +319,17 @@ class MacroAssemblerARM : public Assembl
     void ma_vabs(FloatRegister src, FloatRegister dest, Condition cc = Always);
 
     void ma_vsqrt(FloatRegister src, FloatRegister dest, Condition cc = Always);
 
     void ma_vimm(double value, FloatRegister dest, Condition cc = Always);
     void ma_vimm_f32(float value, FloatRegister dest, Condition cc = Always);
 
     void ma_vcmp(FloatRegister src1, FloatRegister src2, Condition cc = Always);
+    void ma_vcmp_f32(FloatRegister src1, FloatRegister src2, Condition cc = Always);
     void ma_vcmpz(FloatRegister src1, Condition cc = Always);
 
     void ma_vadd_f32(FloatRegister src1, FloatRegister src2, FloatRegister dst);
     void ma_vsub_f32(FloatRegister src1, FloatRegister src2, FloatRegister dst);
 
     void ma_vmul_f32(FloatRegister src1, FloatRegister src2, FloatRegister dst);
     void ma_vdiv_f32(FloatRegister src1, FloatRegister src2, FloatRegister dst);
 
--- a/js/src/jit/shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/shared/Assembler-x86-shared.cpp
@@ -1,16 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "gc/Marking.h"
-#include "jit/IonMacroAssembler.h"
+#include "jit/IonCompartment.h"
+#if defined(JS_CPU_X86)
+# include "jit/x86/MacroAssembler-x86.h"
+#elif defined(JS_CPU_X64)
+# include "jit/x64/MacroAssembler-x64.h"
+#elif defined(JS_CPU_ARM)
+# include "jit/arm/MacroAssembler-arm.h"
+#endif
 
 using namespace js;
 using namespace js::jit;
 
 void
 AssemblerX86Shared::copyJumpRelocationTable(uint8_t *dest)
 {
     if (jumpRelocations_.length())
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -1298,16 +1298,20 @@ class AssemblerX86Shared
     void cvtsi2sd(const Register &src, const FloatRegister &dest) {
         JS_ASSERT(HasSSE2());
         masm.cvtsi2sd_rr(src.code(), dest.code());
     }
     void movmskpd(const FloatRegister &src, const Register &dest) {
         JS_ASSERT(HasSSE2());
         masm.movmskpd_rr(src.code(), dest.code());
     }
+    void movmskps(const FloatRegister &src, const Register &dest) {
+        JS_ASSERT(HasSSE2());
+        masm.movmskps_rr(src.code(), dest.code());
+    }
     void ptest(const FloatRegister &lhs, const FloatRegister &rhs) {
         JS_ASSERT(HasSSE41());
         masm.ptest_rr(rhs.code(), lhs.code());
     }
     void ucomisd(const FloatRegister &lhs, const FloatRegister &rhs) {
         JS_ASSERT(HasSSE2());
         masm.ucomisd_rr(rhs.code(), lhs.code());
     }
--- a/js/src/jit/shared/BaselineCompiler-shared.h
+++ b/js/src/jit/shared/BaselineCompiler-shared.h
@@ -4,19 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_shared_BaselineCompiler_shared_h
 #define jit_shared_BaselineCompiler_shared_h
 
 #include "jit/BaselineFrameInfo.h"
 #include "jit/BaselineIC.h"
-#include "jit/IonInstrumentation.h"
+#include "jit/BytecodeAnalysis.h"
 #include "jit/IonMacroAssembler.h"
-#include "jit/IonSpewer.h"
 
 namespace js {
 namespace jit {
 
 class BaselineCompilerShared
 {
   protected:
     JSContext *cx;
--- a/js/src/jit/shared/BaselineIC-x86-shared.cpp
+++ b/js/src/jit/shared/BaselineIC-x86-shared.cpp
@@ -1,19 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BaselineCompiler.h"
 #include "jit/BaselineHelpers.h"
 #include "jit/BaselineIC.h"
-#include "jit/BaselineJIT.h"
-#include "jit/IonLinker.h"
 
 using namespace js;
 using namespace js::jit;
 
 bool
 ICCompare_Double::Compiler::generateStubCode(MacroAssembler &masm)
 {
     Label failure, notNaN;
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/shared/CodeGenerator-shared-inl.h"
 
 #include "mozilla/DebugOnly.h"
 
+#include "jit/IonCaches.h"
 #include "jit/IonMacroAssembler.h"
 #include "jit/IonSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGenerator.h"
 #include "jit/ParallelFunctions.h"
 
 #include "jit/IonFrames-inl.h"
 
--- a/js/src/jit/shared/CodeGenerator-shared.h
+++ b/js/src/jit/shared/CodeGenerator-shared.h
@@ -3,27 +3,26 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_shared_CodeGenerator_shared_h
 #define jit_shared_CodeGenerator_shared_h
 
 #include "mozilla/Alignment.h"
-#include "mozilla/Util.h"
 
-#include "jit/IonCaches.h"
 #include "jit/IonFrames.h"
 #include "jit/IonMacroAssembler.h"
 #include "jit/LIR.h"
-#include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 #include "jit/Safepoints.h"
 #include "jit/SnapshotWriter.h"
 #include "jit/VMFunctions.h"
+#include "vm/ForkJoin.h"
 
 namespace js {
 namespace jit {
 
 class OutOfLineCode;
 class CodeGenerator;
 class MacroAssembler;
 class IonCache;
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -6,17 +6,16 @@
 
 #include "jit/shared/CodeGenerator-x86-shared.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include "jit/IonCompartment.h"
 #include "jit/IonFrames.h"
-#include "jit/ParallelFunctions.h"
 #include "jit/RangeAnalysis.h"
 
 #include "jit/shared/CodeGenerator-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DoubleSignificandBits;
--- a/js/src/jit/shared/IonFrames-x86-shared.cpp
+++ b/js/src/jit/shared/IonFrames-x86-shared.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/Ion.h"
 #include "jit/IonFrames.h"
 
 using namespace js;
 using namespace js::jit;
 
 IonJSFrameLayout *
 InvalidationBailoutStack::fp() const
 {
--- a/js/src/jit/shared/Lowering-shared-inl.h
+++ b/js/src/jit/shared/Lowering-shared-inl.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_shared_Lowering_shared_inl_h
 #define jit_shared_Lowering_shared_inl_h
 
 #include "jit/shared/Lowering-shared.h"
 
 #include "jit/MIR.h"
-#include "jit/MIRGraph.h"
+#include "jit/MIRGenerator.h"
 
 namespace js {
 namespace jit {
 
 bool
 LIRGeneratorShared::emitAtUses(MInstruction *mir)
 {
     JS_ASSERT(mir->canEmitAtUses());
--- a/js/src/jit/shared/Lowering-shared.cpp
+++ b/js/src/jit/shared/Lowering-shared.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 "jit/shared/Lowering-shared-inl.h"
 
 #include "jit/LIR.h"
 #include "jit/MIR.h"
-#include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace jit;
 
 bool
 LIRGeneratorShared::visitConstant(MConstant *ins)
 {
     const Value &v = ins->value();
--- a/js/src/jit/shared/Lowering-shared.h
+++ b/js/src/jit/shared/Lowering-shared.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_shared_Lowering_shared_h
 #define jit_shared_Lowering_shared_h
 
 // This file declares the structures that are used for attaching LIR to a
 // MIRGraph.
 
-#include "jit/IonAllocPolicy.h"
 #include "jit/LIR.h"
 
 namespace js {
 namespace jit {
 
 class MBasicBlock;
 class MTableSwitch;
 class MIRGenerator;
--- a/js/src/jit/shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/shared/Lowering-x86-shared.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 "jit/shared/Lowering-x86-shared.h"
 
 #include "mozilla/MathAlgorithms.h"
 
-#include "jit/Lowering.h"
 #include "jit/MIR.h"
 
 #include "jit/shared/Lowering-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::FloorLog2;
--- a/js/src/jit/shared/MacroAssembler-x86-shared.h
+++ b/js/src/jit/shared/MacroAssembler-x86-shared.h
@@ -452,16 +452,48 @@ class MacroAssemblerX86Shared : public A
                 andl(Imm32(1), dest);
                 j(Assembler::NonZero, fail);
             }
 
             bind(&notZero);
         }
     }
 
+    // Checks whether a float32 is representable as a 32-bit integer. If so, the
+    // integer is written to the output register. Otherwise, a bailout is taken to
+    // the given snapshot. This function overwrites the scratch float register.
+    void convertFloat32ToInt32(FloatRegister src, Register dest, Label *fail,
+                               bool negativeZeroCheck = true)
+    {
+        cvttss2si(src, dest);
+        convertInt32ToFloat32(dest, ScratchFloatReg);
+        ucomiss(src, ScratchFloatReg);
+        j(Assembler::Parity, fail);
+        j(Assembler::NotEqual, fail);
+
+        // Check for -0
+        if (negativeZeroCheck) {
+            Label notZero;
+            branchTest32(Assembler::NonZero, dest, dest, &notZero);
+
+            if (Assembler::HasSSE41()) {
+                ptest(src, src);
+                j(Assembler::NonZero, fail);
+            } else {
+                // bit 0 = sign of low float
+                // bits 1 to 3 = signs of higher floats
+                movmskps(src, dest);
+                andl(Imm32(1), dest);
+                j(Assembler::NonZero, fail);
+            }
+
+            bind(&notZero);
+        }
+    }
+
     void clampIntToUint8(Register reg) {
         Label inRange;
         branchTest32(Assembler::Zero, reg, Imm32(0xffffff00), &inRange);
         {
             sarl(Imm32(31), reg);
             notl(reg);
             andl(Imm32(255), reg);
         }
--- a/js/src/jit/shared/MoveEmitter-x86-shared.h
+++ b/js/src/jit/shared/MoveEmitter-x86-shared.h
@@ -2,17 +2,23 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_MoveEmitter_x86_shared_h
 #define jit_MoveEmitter_x86_shared_h
 
-#include "jit/IonMacroAssembler.h"
+#if defined(JS_CPU_X86)
+# include "jit/x86/MacroAssembler-x86.h"
+#elif defined(JS_CPU_X64)
+# include "jit/x64/MacroAssembler-x64.h"
+#elif defined(JS_CPU_ARM)
+# include "jit/arm/MacroAssembler-arm.h"
+#endif
 #include "jit/MoveResolver.h"
 
 namespace js {
 namespace jit {
 
 class CodeGenerator;
 
 class MoveEmitterX86
--- a/js/src/jit/x64/Assembler-x64.cpp
+++ b/js/src/jit/x64/Assembler-x64.cpp
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/x64/Assembler-x64.h"
 
 #include "gc/Marking.h"
-#include "jit/LIR.h"
 
 using namespace js;
 using namespace js::jit;
 
 ABIArgGenerator::ABIArgGenerator()
   :
 #if defined(XP_WIN)
     regIndex_(0),
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_x64_Assembler_x64_h
 #define jit_x64_Assembler_x64_h
 
 #include "mozilla/Util.h"
 
-#include "jit/CompactBuffer.h"
 #include "jit/IonCode.h"
 #include "jit/shared/Assembler-shared.h"
 
 namespace js {
 namespace jit {
 
 static MOZ_CONSTEXPR_VAR Register rax = { JSC::X86Registers::eax };
 static MOZ_CONSTEXPR_VAR Register rbx = { JSC::X86Registers::ebx };
--- a/js/src/jit/x64/Bailouts-x64.cpp
+++ b/js/src/jit/x64/Bailouts-x64.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/Bailouts.h"
-#include "jit/IonCompartment.h"
 
 using namespace js;
 using namespace js::jit;
 
 #if defined(_WIN32)
 # pragma pack(push, 1)
 #endif
 
--- a/js/src/jit/x64/BaselineIC-x64.cpp
+++ b/js/src/jit/x64/BaselineIC-x64.cpp
@@ -1,19 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/BaselineCompiler.h"
 #include "jit/BaselineHelpers.h"
 #include "jit/BaselineIC.h"
-#include "jit/BaselineJIT.h"
-#include "jit/IonLinker.h"
 
 using namespace js;
 using namespace js::jit;
 
 namespace js {
 namespace jit {
 
 // ICCompare_Int32
--- a/js/src/jit/x64/CodeGenerator-x64.cpp
+++ b/js/src/jit/x64/CodeGenerator-x64.cpp
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jit/x64/CodeGenerator-x64.h"
 
+#include "jit/IonCaches.h"
 #include "jit/MIR.h"
-#include "jit/MIRGraph.h"
 
 #include "jsscriptinlines.h"
 
 #include "jit/shared/CodeGenerator-shared-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
--- a/js/src/jit/x64/CodeGenerator-x64.h
+++ b/js/src/jit/x64/CodeGenerator-x64.h
@@ -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/. */
 
 #ifndef jit_x64_CodeGenerator_x64_h
 #define jit_x64_CodeGenerator_x64_h
 
 #include "jit/shared/CodeGenerator-x86-shared.h"
-#include "jit/x64/Assembler-x64.h"
 
 namespace js {
 namespace jit {
 
 class CodeGeneratorX64 : public CodeGeneratorX86Shared
 {
     CodeGeneratorX64 *thisFromCtor() {
         return this;
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/x64/MacroAssembler-x64.h"
 
 #include "jit/Bailouts.h"
 #include "jit/BaselineFrame.h"
+#include "jit/IonCompartment.h"
 #include "jit/IonFrames.h"
 #include "jit/MoveEmitter.h"
 
 using namespace js;
 using namespace js::jit;
 
 void
 MacroAssemblerX64::loadConstantDouble(double d, const FloatRegister &dest)
--- a/js/src/jit/x64/Trampoline-x64.cpp
+++ b/js/src/jit/x64/Trampoline-x64.cpp
@@ -1,22 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "assembler/assembler/MacroAssembler.h"
 #include "jit/Bailouts.h"
-#include "jit/ExecutionModeInlines.h"
 #include "jit/IonCompartment.h"
 #include "jit/IonFrames.h"
 #include "jit/IonLinker.h"
-#include "jit/IonSpewer.h"
-#include "jit/PerfSpewer.h"
 #include "jit/VMFunctions.h"
 #include "jit/x64/BaselineHelpers-x64.h"
 
 using namespace js;
 using namespace js::jit;
 
 // All registers to save and restore. This includes the stack pointer, since we
 // use the ability to reference register values on the stack by index.
--- a/js/src/jit/x86/CodeGenerator-x86.cpp
+++ b/js/src/jit/x86/CodeGenerator-x86.cpp
@@ -6,16 +6,17 @@
 
 #include "jit/x86/CodeGenerator-x86.h"
 
 #include "mozilla/DebugOnly.h"
 
 #include "jsnum.h"
 
 #include "jit/ExecutionModeInlines.h"
+#include "jit/IonCaches.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "vm/Shape.h"
 
 #include "jsscriptinlines.h"
 
 #include "jit/shared/CodeGenerator-shared-inl.h"
 
--- a/js/src/jsapi-tests/testArgumentsObject.cpp
+++ b/js/src/jsapi-tests/testArgumentsObject.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 "jsapi-tests/tests.h"
 
 #include "vm/ArgumentsObject-inl.h"
-#include "vm/Stack-inl.h"
 
 using namespace js;
 
 static const char NORMAL_ZERO[] =
     "function f() { return arguments; }";
 static const char NORMAL_ONE[] =
     "function f(a) { return arguments; }";
 static const char NORMAL_TWO[] =
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -7,17 +7,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 "jsobj.h"
 #include "jswrapper.h"
 
 #include "jsapi-tests/tests.h"
 
-#include "jsobjinlines.h"
+#include "vm/ProxyObject.h"
 
 struct OuterWrapper : js::Wrapper
 {
     OuterWrapper() : Wrapper(0) {}
 
     virtual bool isOuterWindow() {
         return true;
     }
--- a/js/src/jsapi-tests/testConservativeGC.cpp
+++ b/js/src/jsapi-tests/testConservativeGC.cpp
@@ -4,18 +4,16 @@
 
 #if !defined(JSGC_ROOT_ANALYSIS) && !defined(JSGC_USE_EXACT_ROOTING)
 
 #include "jsobj.h"
 
 #include "jsapi-tests/tests.h"
 #include "vm/String.h"
 
-#include "jsobjinlines.h"
-
 BEGIN_TEST(testConservativeGC)
 {
     JS::RootedValue v2(cx);
     EVAL("({foo: 'bar'});", v2.address());
     CHECK(v2.isObject());
     char objCopy[sizeof(JSObject)];
     js_memcpy(&objCopy, JSVAL_TO_OBJECT(v2), sizeof(JSObject));
 
--- a/js/src/jsapi-tests/testErrorCopying.cpp
+++ b/js/src/jsapi-tests/testErrorCopying.cpp
@@ -3,18 +3,16 @@
  *
  * Tests that the column number of error reports is properly copied over from
  * other reports when invoked from the C++ api.
  */
 /* 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 "jscntxt.h"
-
 #include "jsapi-tests/tests.h"
 
 static uint32_t column = 0;
 
 static void
 my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     column = report->column;
--- a/js/src/jsapi-tests/testExternalStrings.cpp
+++ b/js/src/jsapi-tests/testExternalStrings.cpp
@@ -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/. */
 
 #include "mozilla/PodOperations.h"
 #include "mozilla/Util.h"
 
-#include "jsutil.h"
-
 #include "jsapi-tests/tests.h"
 
 using mozilla::ArrayLength;
 using mozilla::PodEqual;
 
 static const jschar arr[] = {
     'h', 'i', ',', 'd', 'o', 'n', '\'', 't', ' ', 'd', 'e', 'l', 'e', 't', 'e', ' ', 'm', 'e', '\0'
 };
--- a/js/src/jsapi-tests/testFindSCCs.cpp
+++ b/js/src/jsapi-tests/testFindSCCs.cpp
@@ -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/. */
 
 #include <stdarg.h>
 #include <string.h>
 
-#include "jscntxt.h"
-#include "jsgc.h"
-
 #include "gc/FindSCCs.h"
 #include "jsapi-tests/tests.h"
 
 static const unsigned MaxVertices = 10;
 
 using js::gc::GraphNodeBase;
 using js::gc::ComponentFinder;
 
--- a/js/src/jsapi-tests/testFuncCallback.cpp
+++ b/js/src/jsapi-tests/testFuncCallback.cpp
@@ -1,15 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "jscntxt.h"
-#include "jsfun.h"
-
 #include "jsapi-tests/tests.h"
 
 #ifdef MOZ_TRACE_JSCALLS
 
 static int depth = 0;
 static int enters = 0;
 static int leaves = 0;
 static int interpreted = 0;
--- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp
+++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp
@@ -1,15 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "jscntxt.h"
-#include "jsfriendapi.h"
-
 #include "jsapi-tests/tests.h"
 
 const unsigned BufferSize = 20;
 static unsigned FinalizeCalls = 0;
 static JSFinalizeStatus StatusBuffer[BufferSize];
 static bool IsCompartmentGCBuffer[BufferSize];
 
 static void
--- a/js/src/jsapi-tests/testGCOutOfMemory.cpp
+++ b/js/src/jsapi-tests/testGCOutOfMemory.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  *
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  * Contributor: Igor Bukanov
  */
 
-#include "jscntxt.h"
-
 #include "jsapi-tests/tests.h"
 
 static unsigned errorCount = 0;
 
 static void
 ErrorCounter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     ++errorCount;
--- a/js/src/jsapi-tests/testIntString.cpp
+++ b/js/src/jsapi-tests/testIntString.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
-#include "vm/String.h"
 
 BEGIN_TEST(testIntString_bug515273)
 {
     JS::RootedValue v(cx);
 
     EVAL("'1';", v.address());
     JSString *str = JSVAL_TO_STRING(v);
     CHECK(JS_StringHasBeenInterned(cx, str));
--- a/js/src/jsapi-tests/testNewObject.cpp
+++ b/js/src/jsapi-tests/testNewObject.cpp
@@ -1,17 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  */
 /* 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 "jsfriendapi.h"
-
 #include "jsapi-tests/tests.h"
 
 const size_t N = 1000;
 static jsval argv[N];
 
 static bool
 constructHook(JSContext *cx, unsigned argc, jsval *vp)
 {
--- a/js/src/jsapi-tests/testParseJSON.cpp
+++ b/js/src/jsapi-tests/testParseJSON.cpp
@@ -1,22 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  */
 /* 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 <limits>
-#include <math.h>
 
 #include "jsstr.h"
 
 #include "jsapi-tests/tests.h"
-#include "vm/String.h"
 
 using namespace js;
 
 class AutoInflatedString {
     JSContext * const cx;
     jschar *chars_;
     size_t length_;
 
--- a/js/src/jsapi-tests/testStructuredClone.cpp
+++ b/js/src/jsapi-tests/testStructuredClone.cpp
@@ -1,13 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "jsfriendapi.h"
 #include "js/StructuredClone.h"
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testStructuredClone_object)
 {
     JS::RootedObject g1(cx, createGlobal());
     JS::RootedObject g2(cx, createGlobal());
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -3,18 +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 "jsapi-tests/tests.h"
 
 #include <stdio.h>
 
-#include "jsobj.h"
-
 #include "js/RootingAPI.h"
 
 JSAPITest *JSAPITest::list;
 
 bool JSAPITest::init()
 {
     rt = createRuntime();
     if (!rt)
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -2,18 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jsapi_tests_tests_h
 #define jsapi_tests_tests_h
 
-#include "mozilla/Util.h"
-
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "jsalloc.h"
 #include "jscntxt.h"
 #include "jsgc.h"
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -546,17 +546,17 @@ class AutoHashSetRooter : protected Auto
     AutoHashSetRooter(const AutoHashSetRooter &hmr) MOZ_DELETE;
     AutoHashSetRooter &operator=(const AutoHashSetRooter &hmr) MOZ_DELETE;
 
     HashSetImpl set;
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
-class AutoValueVector : public AutoVectorRooter<Value>
+class MOZ_STACK_CLASS AutoValueVector : public AutoVectorRooter<Value>
 {
   public:
     explicit AutoValueVector(JSContext *cx
                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
         : AutoVectorRooter<Value>(cx, VALVECTOR)
     {
         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5555,46 +5555,47 @@ js_DumpBacktrace(JSContext *cx)
                         script, i.pc() - script->code);
     }
     fprintf(stdout, "%s", sprinter.string());
 }
 void
 JSObject::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ObjectsExtraSizes *sizes)
 {
     if (hasDynamicSlots())
-        sizes->slots = mallocSizeOf(slots);
+        sizes->mallocHeapSlots = mallocSizeOf(slots);
 
     if (hasDynamicElements()) {
         js::ObjectElements *elements = getElementsHeader();
         if (JS_UNLIKELY(elements->isAsmJSArrayBuffer())) {
 #if defined (JS_CPU_X64)
             // On x64, ArrayBufferObject::prepareForAsmJS switches the
             // ArrayBufferObject to use mmap'd storage.
-            sizes->elementsAsmJSNonHeap = as<ArrayBufferObject>().byteLength();
+            sizes->nonHeapElementsAsmJS = as<ArrayBufferObject>().byteLength();
 #else
-            sizes->elementsAsmJSHeap = mallocSizeOf(elements);
+            sizes->mallocHeapElementsAsmJS = mallocSizeOf(elements);
 #endif
         } else {
-            sizes->elementsNonAsmJS = mallocSizeOf(elements);
+            sizes->mallocHeapElementsNonAsmJS = mallocSizeOf(elements);
         }
     }
 
     // Other things may be measured in the future if DMD indicates it is worthwhile.
     // Note that sizes->private_ is measured elsewhere.
     if (is<ArgumentsObject>()) {
-        sizes->argumentsData = as<ArgumentsObject>().sizeOfMisc(mallocSizeOf);
+        sizes->mallocHeapArgumentsData = as<ArgumentsObject>().sizeOfMisc(mallocSizeOf);
     } else if (is<RegExpStaticsObject>()) {
-        sizes->regExpStatics = as<RegExpStaticsObject>().sizeOfData(mallocSizeOf);
+        sizes->mallocHeapRegExpStatics = as<RegExpStaticsObject>().sizeOfData(mallocSizeOf);
     } else if (is<PropertyIteratorObject>()) {
-        sizes->propertyIteratorData = as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf);
+        sizes->mallocHeapPropertyIteratorData = as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf);
 #ifdef JS_ION
     } else if (is<AsmJSModuleObject>()) {
-        as<AsmJSModuleObject>().sizeOfMisc(mallocSizeOf, &sizes->asmJSModuleCode,
-                                           &sizes->asmJSModuleData);
+        as<AsmJSModuleObject>().sizeOfMisc(mallocSizeOf, &sizes->nonHeapCodeAsmJS,
+                                           &sizes->mallocHeapAsmJSModuleData);
 #endif
 #ifdef JS_HAS_CTYPES
     } else {
         // This must be the last case.
-        sizes->ctypesData = js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
+        sizes->mallocHeapCtypesData =
+            js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
 #endif
     }
 }
 
--- a/js/src/jsweakcache.h
+++ b/js/src/jsweakcache.h
@@ -2,19 +2,20 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jsweakcache_h
 #define jsweakcache_h
 
+#include "jscntxt.h"
 #include "gc/Marking.h"
-
 #include "js/HashTable.h"
+#include "vm/Runtime.h"
 
 namespace js {
 
 // A WeakCache is used to map a key to a value similar to an HashMap except
 // that its entries are garbage collected.  An entry is kept as long as
 // both the key and value are marked.
 //
 // No mark function is provided with this weak container.  However, this weak
--- a/js/src/shell/jsheaptools.cpp
+++ b/js/src/shell/jsheaptools.cpp
@@ -9,20 +9,18 @@
 #include "mozilla/Move.h"
 
 #include <string.h>
 
 #include "jsalloc.h"
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jscompartment.h"
-#include "jsfun.h"
 #include "jsobj.h"
 #include "jsprf.h"
-#include "jsutil.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 
 using mozilla::OldMove;
 using mozilla::MoveRef;
 
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -4,17 +4,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/. */
 
 #ifndef vm_ArgumentsObject_h
 #define vm_ArgumentsObject_h
 
 #include "mozilla/MemoryReporting.h"
 
-#include "jsfun.h"
+#include "jsobj.h"
+
+#include "gc/Barrier.h"
 
 namespace js {
 
 class AbstractFramePtr;
 class ScriptFrameIter;
 
 namespace jit {
 class IonJSFrameLayout;
--- a/js/src/vm/ForkJoin.h
+++ b/js/src/vm/ForkJoin.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_ForkJoin_h
 #define vm_ForkJoin_h
 
 #include "jscntxt.h"
 
 #include "jit/Ion.h"
+#include "jit/MIR.h"
 
 ///////////////////////////////////////////////////////////////////////////
 // Read Me First
 //
 // The ForkJoin abstraction:
 // -------------------------
 //
 // This is the building block for executing multi-threaded JavaScript with
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -10,24 +10,25 @@
 #include "jsdate.h"
 #include "jsexn.h"
 #include "jsfriendapi.h"
 #include "jsmath.h"
 #include "json.h"
 #include "jsweakmap.h"
 
 #include "builtin/Eval.h"
-#include "builtin/Intl.h"
+#if EXPOSE_INTL_API
+# include "builtin/Intl.h"
+#endif
 #include "builtin/MapObject.h"
 #include "builtin/Object.h"
 #include "builtin/RegExp.h"
 #include "vm/RegExpStatics.h"
 
 #include "jscompartmentinlines.h"
-#include "jsfuninlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/ObjectImpl-inl.h"
 
 using namespace js;
 
 JSObject *
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -2,18 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 vm_GlobalObject_h
 #define vm_GlobalObject_h
 
-#include "mozilla/DebugOnly.h"
-
 #include "jsarray.h"
 #include "jsbool.h"
 #include "jsexn.h"
 #include "jsfun.h"
 #include "jsnum.h"
 
 #include "builtin/RegExp.h"
 #include "js/Vector.h"
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -10,17 +10,16 @@
 #include "vm/Interpreter.h"
 
 #include "jscompartment.h"
 #include "jsinfer.h"
 #include "jsnum.h"
 #include "jsstr.h"
 
 #include "jit/Ion.h"
-#include "jit/IonCompartment.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/ForkJoin.h"
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
 #include "vm/Stack-inl.h"
--- a/js/src/vm/MemoryMetrics.cpp
+++ b/js/src/vm/MemoryMetrics.cpp
@@ -192,17 +192,17 @@ StatsCompartmentCallback(JSRuntime *rt, 
     rtStats->initExtraCompartmentStats(compartment, &cStats);
 
     compartment->compartmentStats = &cStats;
 
     // Measure the compartment object itself, and things hanging off it.
     compartment->sizeOfIncludingThis(rtStats->mallocSizeOf_,
                                      &cStats.compartmentObject,
                                      &cStats.typeInference,
-                                     &cStats.shapesCompartmentTables,
+                                     &cStats.shapesMallocHeapCompartmentTables,
                                      &cStats.crossCompartmentWrappersTable,
                                      &cStats.regexpCompartment,
                                      &cStats.debuggeesSet,
                                      &cStats.baselineStubsOptimized);
 }
 
 static void
 StatsZoneCallback(JSRuntime *rt, void *data, Zone *zone)
@@ -230,17 +230,17 @@ StatsArenaCallback(JSRuntime *rt, void *
     // end of the header and the start of the first GC thing.
     size_t allocationSpace = arena->thingsSpan(thingSize);
     rtStats->currZoneStats->gcHeapArenaAdmin += gc::ArenaSize - allocationSpace;
 
     // We don't call the callback on unused things.  So we compute the
     // unused space like this:  arenaUnused = maxArenaUnused - arenaUsed.
     // We do this by setting arenaUnused to maxArenaUnused here, and then
     // subtracting thingSize for every used cell, in StatsCellCallback().
-    rtStats->currZoneStats->gcHeapUnusedGcThings += allocationSpace;
+    rtStats->currZoneStats->unusedGCThings += allocationSpace;
 }
 
 static CompartmentStats *
 GetCompartmentStats(JSCompartment *comp)
 {
     return static_cast<CompartmentStats *>(comp->compartmentStats);
 }
 
@@ -251,23 +251,23 @@ StatsCellCallback(JSRuntime *rt, void *d
     StatsClosure *closure = static_cast<StatsClosure *>(data);
     RuntimeStats *rtStats = closure->rtStats;
     ZoneStats *zStats = rtStats->currZoneStats;
     switch (traceKind) {
       case JSTRACE_OBJECT: {
         JSObject *obj = static_cast<JSObject *>(thing);
         CompartmentStats *cStats = GetCompartmentStats(obj->compartment());
         if (obj->is<JSFunction>())
-            cStats->gcHeapObjectsFunction += thingSize;
+            cStats->objectsGCHeapFunction += thingSize;
         else if (obj->is<ArrayObject>())
-            cStats->gcHeapObjectsDenseArray += thingSize;
+            cStats->objectsGCHeapDenseArray += thingSize;
         else if (obj->is<CrossCompartmentWrapperObject>())
-            cStats->gcHeapObjectsCrossCompartmentWrapper += thingSize;
+            cStats->objectsGCHeapCrossCompartmentWrapper += thingSize;
         else
-            cStats->gcHeapObjectsOrdinary += thingSize;
+            cStats->objectsGCHeapOrdinary += thingSize;
 
         JS::ObjectsExtraSizes objectsExtra;
         obj->sizeOfExcludingThis(rtStats->mallocSizeOf_, &objectsExtra);
         cStats->objectsExtra.add(objectsExtra);
 
         // JSObject::sizeOfExcludingThis() doesn't measure objectsPrivate,
         // so we do it here.
         if (ObjectPrivateVisitor *opv = closure->opv) {
@@ -292,56 +292,56 @@ StatsCellCallback(JSRuntime *rt, void *d
         if (!p) {
             JS::StringInfo info(str->length(), shortStringThingSize,
                                 normalStringThingSize, strCharsSize);
             zStats->strings.add(p, str, info);
         } else {
             p->value.add(shortStringThingSize, normalStringThingSize, strCharsSize);
         }
 
-        zStats->gcHeapStringsShort += shortStringThingSize;
-        zStats->gcHeapStringsNormal += normalStringThingSize;
-        zStats->stringCharsNonNotable += strCharsSize;
+        zStats->stringsShortGCHeap += shortStringThingSize;
+        zStats->stringsNormalGCHeap += normalStringThingSize;
+        zStats->stringsNormalMallocHeap += strCharsSize;
 
         break;
       }
 
       case JSTRACE_SHAPE: {
         Shape *shape = static_cast<Shape *>(thing);
         CompartmentStats *cStats = GetCompartmentStats(shape->compartment());
         size_t propTableSize, kidsSize;
         shape->sizeOfExcludingThis(rtStats->mallocSizeOf_, &propTableSize, &kidsSize);
         if (shape->inDictionary()) {
-            cStats->gcHeapShapesDict += thingSize;
-            cStats->shapesExtraDictTables += propTableSize;
+            cStats->shapesGCHeapDict += thingSize;
+            cStats->shapesMallocHeapDictTables += propTableSize;
             JS_ASSERT(kidsSize == 0);
         } else {
             JSObject *parent = shape->base()->getObjectParent();
             if (parent && parent->is<GlobalObject>())
-                cStats->gcHeapShapesTreeGlobalParented += thingSize;
+                cStats->shapesGCHeapTreeGlobalParented += thingSize;
             else
-                cStats->gcHeapShapesTreeNonGlobalParented += thingSize;
-            cStats->shapesExtraTreeTables += propTableSize;
-            cStats->shapesExtraTreeShapeKids += kidsSize;
+                cStats->shapesGCHeapTreeNonGlobalParented += thingSize;
+            cStats->shapesMallocHeapTreeTables += propTableSize;
+            cStats->shapesMallocHeapTreeShapeKids += kidsSize;
         }
         break;
       }
 
       case JSTRACE_BASE_SHAPE: {
         BaseShape *base = static_cast<BaseShape *>(thing);
         CompartmentStats *cStats = GetCompartmentStats(base->compartment());
-        cStats->gcHeapShapesBase += thingSize;
+        cStats->shapesGCHeapBase += thingSize;
         break;
       }
 
       case JSTRACE_SCRIPT: {
         JSScript *script = static_cast<JSScript *>(thing);
         CompartmentStats *cStats = GetCompartmentStats(script->compartment());
-        cStats->gcHeapScripts += thingSize;
-        cStats->scriptData += script->sizeOfData(rtStats->mallocSizeOf_);
+        cStats->scriptsGCHeap += thingSize;
+        cStats->scriptsMallocHeapData += script->sizeOfData(rtStats->mallocSizeOf_);
 #ifdef JS_ION
         size_t baselineData = 0, baselineStubsFallback = 0;
         jit::SizeOfBaselineData(script, rtStats->mallocSizeOf_, &baselineData,
                                 &baselineStubsFallback);
         cStats->baselineData += baselineData;
         cStats->baselineStubsFallback += baselineStubsFallback;
         cStats->ionData += jit::SizeOfIonData(script, rtStats->mallocSizeOf_);
 #endif
@@ -352,40 +352,40 @@ StatsCellCallback(JSRuntime *rt, void *d
             closure->seenSources.add(entry, ss); // Not much to be done on failure.
             rtStats->runtime.scriptSources += ss->sizeOfIncludingThis(rtStats->mallocSizeOf_);
         }
         break;
       }
 
       case JSTRACE_LAZY_SCRIPT: {
         LazyScript *lazy = static_cast<LazyScript *>(thing);
-        zStats->gcHeapLazyScripts += thingSize;
-        zStats->lazyScripts += lazy->sizeOfExcludingThis(rtStats->mallocSizeOf_);
+        zStats->lazyScriptsGCHeap += thingSize;
+        zStats->lazyScriptsMallocHeap += lazy->sizeOfExcludingThis(rtStats->mallocSizeOf_);
         break;
       }
 
       case JSTRACE_IONCODE: {
 #ifdef JS_ION
-        zStats->gcHeapIonCodes += thingSize;
+        zStats->ionCodesGCHeap += thingSize;
         // The code for a script is counted in ExecutableAllocator::sizeOfCode().
 #endif
         break;
       }
 
       case JSTRACE_TYPE_OBJECT: {
         types::TypeObject *obj = static_cast<types::TypeObject *>(thing);
-        zStats->gcHeapTypeObjects += thingSize;
-        zStats->typeObjects += obj->sizeOfExcludingThis(rtStats->mallocSizeOf_);
+        zStats->typeObjectsGCHeap += thingSize;
+        zStats->typeObjectsMallocHeap += obj->sizeOfExcludingThis(rtStats->mallocSizeOf_);
         break;
       }
 
     }
 
     // Yes, this is a subtraction:  see StatsArenaCallback() for details.
-    zStats->gcHeapUnusedGcThings -= thingSize;
+    zStats->unusedGCThings -= thingSize;
 }
 
 static void
 FindNotableStrings(ZoneStats &zStats)
 {
     using namespace JS;
 
     // You should only run FindNotableStrings once per ZoneStats object
@@ -403,22 +403,22 @@ FindNotableStrings(ZoneStats &zStats)
         if (info.totalSizeOf() < NotableStringInfo::notableSize() ||
             !zStats.notableStrings.growBy(1))
             continue;
 
         zStats.notableStrings.back() = OldMove(NotableStringInfo(str, info));
 
         // We're moving this string from a non-notable to a notable bucket, so
         // subtract it out of the non-notable tallies.
-        MOZ_ASSERT(zStats.gcHeapStringsShort >= info.sizeOfShortStringGCThings);
-        MOZ_ASSERT(zStats.gcHeapStringsNormal >= info.sizeOfNormalStringGCThings);
-        MOZ_ASSERT(zStats.stringCharsNonNotable >= info.sizeOfAllStringChars);
-        zStats.gcHeapStringsShort -= info.sizeOfShortStringGCThings;
-        zStats.gcHeapStringsNormal -= info.sizeOfNormalStringGCThings;
-        zStats.stringCharsNonNotable -= info.sizeOfAllStringChars;
+        MOZ_ASSERT(zStats.stringsShortGCHeap >= info.shortGCHeap);
+        MOZ_ASSERT(zStats.stringsNormalGCHeap >= info.normalGCHeap);
+        MOZ_ASSERT(zStats.stringsNormalMallocHeap >= info.normalMallocHeap);
+        zStats.stringsShortGCHeap -= info.shortGCHeap;
+        zStats.stringsNormalGCHeap -= info.normalGCHeap;
+        zStats.stringsNormalMallocHeap -= info.normalMallocHeap;
     }
 
     // zStats.strings holds unrooted JSString pointers, which we don't want to
     // expose out into the dangerous land where we might GC.
     zStats.strings.clear();
 }
 
 JS_PUBLIC_API(bool)
@@ -445,66 +445,63 @@ JS::CollectRuntimeStats(JSRuntime *rt, R
         return false;
     rtStats->runtime.scriptSources = 0;
     IterateZonesCompartmentsArenasCells(rt, &closure, StatsZoneCallback, StatsCompartmentCallback,
                                         StatsArenaCallback, StatsCellCallback);
 
     // Take the "explicit/js/runtime/" measurements.
     rt->sizeOfIncludingThis(rtStats->mallocSizeOf_, &rtStats->runtime);
 
-    DebugOnly<size_t> totalArenaSize = 0;
-
-    rtStats->gcHeapGcThings = 0;
+    rtStats->gcHeapGCThings = 0;
     for (size_t i = 0; i < rtStats->zoneStatsVector.length(); i++) {
         ZoneStats &zStats = rtStats->zoneStatsVector[i];
 
         rtStats->zTotals.add(zStats);
-        rtStats->gcHeapGcThings += zStats.sizeOfLiveGCThings();
-#ifdef DEBUG
-        totalArenaSize += zStats.gcHeapArenaAdmin + zStats.gcHeapUnusedGcThings;
-#endif
 
         // Move any strings which take up more than the sundries threshold
         // (counting all of their copies together) into notableStrings.
         FindNotableStrings(zStats);
     }
 
     FindNotableStrings(rtStats->zTotals);
 
     for (size_t i = 0; i < rtStats->compartmentStatsVector.length(); i++) {
         CompartmentStats &cStats = rtStats->compartmentStatsVector[i];
-
         rtStats->cTotals.add(cStats);
-        rtStats->gcHeapGcThings += cStats.sizeOfLiveGCThings();
     }
 
+    rtStats->gcHeapGCThings = rtStats->zTotals.sizeOfLiveGCThings() +
+                              rtStats->cTotals.sizeOfLiveGCThings();
+
 #ifdef DEBUG
-    totalArenaSize += rtStats->gcHeapGcThings;
+    // Check that the in-arena measurements look ok.
+    size_t totalArenaSize = rtStats->zTotals.gcHeapArenaAdmin +
+                            rtStats->zTotals.unusedGCThings +
+                            rtStats->gcHeapGCThings;
     JS_ASSERT(totalArenaSize % gc::ArenaSize == 0);
 #endif
 
     for (CompartmentsIter comp(rt); !comp.done(); comp.next())
         comp->compartmentStats = NULL;
 
     size_t numDirtyChunks =
         (rtStats->gcHeapChunkTotal - rtStats->gcHeapUnusedChunks) / gc::ChunkSize;
     size_t perChunkAdmin =
         sizeof(gc::Chunk) - (sizeof(gc::Arena) * gc::ArenasPerChunk);
     rtStats->gcHeapChunkAdmin = numDirtyChunks * perChunkAdmin;
-    rtStats->gcHeapUnusedArenas -= rtStats->gcHeapChunkAdmin;
 
     // |gcHeapUnusedArenas| is the only thing left.  Compute it in terms of
     // all the others.  See the comment in RuntimeStats for explanation.
     rtStats->gcHeapUnusedArenas = rtStats->gcHeapChunkTotal -
                                   rtStats->gcHeapDecommittedArenas -
                                   rtStats->gcHeapUnusedChunks -
-                                  rtStats->zTotals.gcHeapUnusedGcThings -
+                                  rtStats->zTotals.unusedGCThings -
                                   rtStats->gcHeapChunkAdmin -
                                   rtStats->zTotals.gcHeapArenaAdmin -
-                                  rtStats->gcHeapGcThings;
+                                  rtStats->gcHeapGCThings;
     return true;
 }
 
 JS_PUBLIC_API(size_t)
 JS::SystemCompartmentCount(JSRuntime *rt)
 {
     size_t n = 0;
     for (CompartmentsIter comp(rt); !comp.done(); comp.next()) {
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -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/. */
 
 #ifndef vm_ObjectImpl_h
 #define vm_ObjectImpl_h
 
 #include "mozilla/Assertions.h"
-#include "mozilla/GuardObjects.h"
 
 #include <stdint.h>
 
 #include "jsfriendapi.h"
 #include "jsinfer.h"
 #include "NamespaceImports.h"
 
 #include "gc/Barrier.h"
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -22,17 +22,16 @@
 #include "jsscript.h"
 #include "jsstr.h"
 #include "jstypes.h"
 #include "jswatchpoint.h"
 
 #include "frontend/SourceNotes.h"
 #include "jit/AsmJSModule.h"
 #include "vm/Debugger.h"
-#include "vm/Interpreter.h"
 #include "vm/Shape.h"
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/Debugger-inl.h"
 #include "vm/Interpreter-inl.h"
--- a/js/src/vm/Probes.h
+++ b/js/src/vm/Probes.h
@@ -6,19 +6,16 @@
 
 #ifndef vm_Probes_h
 #define vm_Probes_h
 
 #ifdef INCLUDE_MOZILLA_DTRACE
 #include "javascript-trace.h"
 #endif
 
-#include "jsobj.h"
-#include "jspubtd.h"
-
 #include "vm/Stack.h"
 
 namespace js {
 
 namespace Probes {
 
 /*
  * Static probes
--- a/js/src/vm/ProxyObject.cpp
+++ b/js/src/vm/ProxyObject.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "vm/ProxyObject.h"
 
-#include "jscompartment.h"
-
 #include "jsgcinlines.h"
 
 using namespace js;
 
 void
 ProxyObject::initCrossCompartmentPrivate(HandleValue priv)
 {
     initCrossCompartmentSlot(PRIVATE_SLOT, priv);
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -6,16 +6,17 @@
 
 #ifndef vm_RegExpObject_h
 #define vm_RegExpObject_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "jscntxt.h"
+#include "jsproxy.h"
 
 #include "gc/Marking.h"
 #if ENABLE_YARR_JIT
 #include "yarr/YarrJIT.h"
 #else
 #include "yarr/YarrInterpreter.h"
 #endif
 
--- a/js/src/vm/RegExpStatics.h
+++ b/js/src/vm/RegExpStatics.h
@@ -3,22 +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 vm_RegExpStatics_h
 #define vm_RegExpStatics_h
 
 #include "gc/Marking.h"
-#include "vm/GlobalObject.h"
 #include "vm/MatchPairs.h"
+#include "vm/RegExpObject.h"
 #include "vm/Runtime.h"
 
 namespace js {
 
+class GlobalObject;
+
 class RegExpStatics
 {
     /* The latest RegExp output, set after execution. */
     VectorMatchPairs        matches;
     HeapPtr<JSLinearString> matchesInput;
 
     /*
      * The previous RegExp input, used to resolve lazy state.
--- a/js/src/vm/Runtime-inl.h
+++ b/js/src/vm/Runtime-inl.h
@@ -5,19 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_Runtime_inl_h
 #define vm_Runtime_inl_h
 
 #include "vm/Runtime.h"
 
 #include "jscompartment.h"
-#include "jsworkers.h"
 
-#include "jit/IonFrames.h"
 #include "vm/Probes.h"
 
 #include "jsgcinlines.h"
 
 namespace js {
 
 inline bool
 NewObjectCache::lookupProto(const Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -20,16 +20,17 @@
 #include "jsgc.h"
 #include "jsmath.h"
 #include "jsnativestack.h"
 #include "jsobj.h"
 #include "jsscript.h"
 #include "jswatchpoint.h"
 #include "jswrapper.h"
 
+#include "assembler/assembler/MacroAssembler.h"
 #include "jit/AsmJSSignalHandlers.h"
 #include "jit/IonCompartment.h"
 #include "jit/PcScriptCache.h"
 #include "js/MemoryMetrics.h"
 #include "yarr/BumpPointerAllocator.h"
 
 #include "jscntxtinlines.h"
 #include "jsgcinlines.h"
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -14,26 +14,32 @@
 #include "mozilla/Scoped.h"
 #include "mozilla/ThreadLocal.h"
 
 #include <setjmp.h>
 
 #include "jsatom.h"
 #include "jsclist.h"
 #include "jsgc.h"
-#include "jsproxy.h"
+#ifdef DEBUG
+# include "jsproxy.h"
+#endif
 #include "jsscript.h"
 
 #include "ds/FixedSizeHash.h"
 #include "frontend/ParseMaps.h"
-#include "gc/Nursery.h"
+#ifdef JSGC_GENERATIONAL
+# include "gc/Nursery.h"
+#endif
 #include "gc/Statistics.h"
-#include "gc/StoreBuffer.h"
+#ifdef JSGC_GENERATIONAL
+# include "gc/StoreBuffer.h"
+#endif
 #ifdef XP_MACOSX
-#include "jit/AsmJSSignalHandlers.h"
+# include "jit/AsmJSSignalHandlers.h"
 #endif
 #include "js/HashTable.h"
 #include "js/Vector.h"
 #include "vm/CommonPropertyNames.h"
 #include "vm/DateTime.h"
 #include "vm/SPSProfiler.h"
 #include "vm/Stack.h"
 #include "vm/ThreadPool.h"
--- a/js/src/yarr/YarrJIT.h
+++ b/js/src/yarr/YarrJIT.h
@@ -27,21 +27,20 @@
 
 #ifndef yarr_YarrJIT_h
 #define yarr_YarrJIT_h
 
 #include "assembler/wtf/Platform.h"
 
 #if ENABLE_YARR_JIT
 
-#include "assembler/assembler/MacroAssembler.h"
+#include "assembler/assembler/MacroAssemblerCodeRef.h"
 
 #include "yarr/MatchResult.h"
 #include "yarr/Yarr.h"
-#include "yarr/YarrPattern.h"
 
 #if WTF_CPU_X86 && !WTF_COMPILER_MSVC && !WTF_COMPILER_SUNCC
 #define YARR_CALL __attribute__ ((regparm (3)))
 #else
 #define YARR_CALL
 #endif
 
 #if JS_TRACE_LOGGING
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1694,33 +1694,33 @@ private:
         if (amount >= SUNDRIES_THRESHOLD) {                                   \
             nsresult rv;                                                      \
             rv = cb->Callback(EmptyCString(), _path,                          \
                               nsIMemoryReporter::KIND_HEAP,                   \
                               nsIMemoryReporter::UNITS_BYTES, amount,         \
                               _desc, closure);                                \
             NS_ENSURE_SUCCESS(rv, rv);                                        \
         } else {                                                              \
-            otherSundries += amount;                                          \
+            sundriesMallocHeap += amount;                                     \
         }                                                                     \
     } while (0)
 
 #define ZCREPORT_GC_BYTES(_path, _amount, _desc)                              \
     do {                                                                      \
         size_t amount = _amount;  /* evaluate _amount only once */            \
         if (amount >= SUNDRIES_THRESHOLD) {                                   \
             nsresult rv;                                                      \
             rv = cb->Callback(EmptyCString(), _path,                          \
                               nsIMemoryReporter::KIND_NONHEAP,                \
                               nsIMemoryReporter::UNITS_BYTES, amount,         \
                               NS_LITERAL_CSTRING(_desc), closure);            \
             NS_ENSURE_SUCCESS(rv, rv);                                        \
             gcTotal += amount;                                                \
         } else {                                                              \
-            gcHeapSundries += amount;                                         \
+            sundriesGCHeap += amount;                                         \
         }                                                                     \
     } while (0)
 
 #define RREPORT_BYTES(_path, _kind, _amount, _desc)                           \
     do {                                                                      \
         size_t amount = _amount;  /* evaluate _amount only once */            \
         nsresult rv;                                                          \
         rv = cb->Callback(EmptyCString(), _path,                              \
@@ -1737,81 +1737,81 @@ namespace xpc {
 
 static nsresult
 ReportZoneStats(const JS::ZoneStats &zStats,
                 const xpc::ZoneStatsExtras &extras,
                 nsIMemoryReporterCallback *cb,
                 nsISupports *closure, size_t *gcTotalOut = NULL)
 {
     const nsAutoCString& pathPrefix = extras.pathPrefix;
-    size_t gcTotal = 0, gcHeapSundries = 0, otherSundries = 0;
+    size_t gcTotal = 0, sundriesGCHeap = 0, sundriesMallocHeap = 0;
 
     ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap-arena-admin"),
                       zStats.gcHeapArenaAdmin,
                       "Memory on the garbage-collected JavaScript "
                       "heap, within arenas, that is used (a) to hold internal "
                       "bookkeeping information, and (b) to provide padding to "
                       "align GC things.");
 
     ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("unused-gc-things"),
-                      zStats.gcHeapUnusedGcThings,
+                      zStats.unusedGCThings,
                       "Memory on the garbage-collected JavaScript "
                       "heap taken by empty GC thing slots within non-empty "
                       "arenas.");
 
     ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/gc-heap"),
-                      zStats.gcHeapLazyScripts,
+                      zStats.lazyScriptsGCHeap,
                       "Memory on the garbage-collected JavaScript "
                       "heap that represents scripts which haven't executed yet.");
 
-    ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-objects/gc-heap"),
-                      zStats.gcHeapTypeObjects,
-                      "Memory on the garbage-collected JavaScript "
-                      "heap that holds type inference information.");
-
-    ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("ion-codes/gc-heap"),
-                      zStats.gcHeapIonCodes,
+    ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/malloc-heap"),
+                   zStats.lazyScriptsMallocHeap,
+                   "Memory holding miscellaneous additional information associated with lazy "
+                   "scripts.  This memory is allocated on the malloc heap.");
+
+    ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("ion-codes-gc-heap"),
+                      zStats.ionCodesGCHeap,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds references to executable code pools "
                       "used by the IonMonkey JIT.");
 
-    ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/malloc-heap"),
-                   zStats.lazyScripts,
-                   "Memory holding miscellaneous additional information associated with lazy "
-                   "scripts.  This memory is allocated on the malloc heap.");
-
-    ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-objects"),
-                   zStats.typeObjects,
+    ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-objects/gc-heap"),
+                      zStats.typeObjectsGCHeap,
+                      "Memory on the garbage-collected JavaScript "
+                      "heap that holds type inference information.");
+
+    ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-objects/malloc-heap"),
+                   zStats.typeObjectsMallocHeap,
                    "Memory holding miscellaneous additional information associated with type "
                    "objects.");
 
     ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-pool"),
                    zStats.typePool,
                    "Memory holding contents of type sets and related data.");
 
-    size_t gcHeapStringsAboutMemory = 0;
-    size_t stringCharsAboutMemory = 0;
+    size_t stringsNotableAboutMemoryGCHeap = 0;
+    size_t stringsNotableAboutMemoryMallocHeap = 0;
 
     for (size_t i = 0; i < zStats.notableStrings.length(); i++) {
         const JS::NotableStringInfo& info = zStats.notableStrings[i];
 
         nsDependentCString notableString(info.buffer);
 
         // Viewing about:memory generates many notable strings which contain
         // "string(length=".  If we report these as notable, then we'll create
         // even more notable strings the next time we open about:memory (unless
         // there's a GC in the meantime), and so on ad infinitum.
         //
         // To avoid cluttering up about:memory like this, we stick notable
         // strings which contain "strings/notable/string(length=" into their own
         // bucket.
 #       define STRING_LENGTH "string(length="
         if (FindInReadable(NS_LITERAL_CSTRING(STRING_LENGTH), notableString)) {
-            gcHeapStringsAboutMemory += info.totalGCThingSizeOf();
-            stringCharsAboutMemory += info.sizeOfAllStringChars;
+            stringsNotableAboutMemoryGCHeap += info.totalGCHeapSizeOf();
+            stringsNotableAboutMemoryMallocHeap += info.normalMallocHeap;
             continue;
         }
 
         // Escape / to \ before we put notableString into the memory reporter
         // path, because we don't want any forward slashes in the string to
         // count as path separators.
         nsCString escapedString(notableString);
         escapedString.ReplaceSubstring("/", "\\");
@@ -1820,97 +1820,97 @@ ReportZoneStats(const JS::ZoneStats &zSt
 
         nsCString path = pathPrefix +
             nsPrintfCString("strings/notable/" STRING_LENGTH "%d, copies=%d, \"%s\"%s)/",
                             info.length, info.numCopies, escapedString.get(),
                             truncated ? " (truncated)" : "");
 
         REPORT_BYTES2(path + NS_LITERAL_CSTRING("gc-heap"),
             KIND_NONHEAP,
-            info.totalGCThingSizeOf(),
+            info.totalGCHeapSizeOf(),
             nsPrintfCString("Memory allocated to hold headers for copies of "
             "the given notable string.  A string is notable if all of its copies "
             "together use more than %d bytes total of JS GC heap and malloc heap "
             "memory.\n\n"
             "These headers may contain the string data itself, if the string "
             "is short enough.  If so, the string won't have any memory reported "
             "under 'string-chars'.",
             JS::NotableStringInfo::notableSize()));
-        gcTotal += info.totalGCThingSizeOf();
-
-        if (info.sizeOfAllStringChars > 0) {
+        gcTotal += info.totalGCHeapSizeOf();
+
+        if (info.normalMallocHeap > 0) {
             REPORT_BYTES2(path + NS_LITERAL_CSTRING("malloc-heap"),
                 KIND_HEAP,
-                info.sizeOfAllStringChars,
+                info.normalMallocHeap,
                 nsPrintfCString("Memory allocated on the malloc heap to hold "
                 "string data for copies of the given notable string.  A string is "
                 "notable if all of its copies together use more than %d bytes "
                 "total of JS GC heap and malloc heap memory.",
                 JS::NotableStringInfo::notableSize()));
         }
     }
 
-    ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/short/gc-heap"),
-                      zStats.gcHeapStringsShort,
+    ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/short-gc-heap"),
+                      zStats.stringsShortGCHeap,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds headers for strings which are short "
                       "enough to be stored completely within the header.  That "
                       "is, a 'short' string uses no string-chars.");
 
     ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/normal/gc-heap"),
-                      zStats.gcHeapStringsNormal,
+                      zStats.stringsNormalGCHeap,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds string headers for strings which are too "
                       "long to fit entirely within the header.  The character "
                       "data for such strings is counted under "
                       "strings/normal/malloc-heap.");
 
     ZCREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/normal/malloc-heap"),
-                   zStats.stringCharsNonNotable,
+                   zStats.stringsNormalMallocHeap,
                    "Memory allocated to hold characters for strings which are too long "
                    "to fit entirely within their string headers.\n\n"
                    "Sometimes more memory is allocated than necessary, to "
                    "simplify string concatenation.");
 
-    if (gcHeapStringsAboutMemory > 0) {
+    if (stringsNotableAboutMemoryGCHeap > 0) {
         ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("strings/notable/about-memory/gc-heap"),
-                          gcHeapStringsAboutMemory,
+                          stringsNotableAboutMemoryGCHeap,
                           "Memory allocated on the garbage-collected JavaScript "
                           "heap that holds headers for notable strings which "
                           "contain the string '" STRING_LENGTH "'.  These "
                           "strings are likely from about:memory itself.  We "
                           "filter them out rather than display them, because "
                           "displaying them would create even more strings every "
                           "time you refresh about:memory.");
     }
 
-    if (stringCharsAboutMemory > 0) {
+    if (stringsNotableAboutMemoryMallocHeap > 0) {
         ZCREPORT_BYTES(pathPrefix +
                        NS_LITERAL_CSTRING("strings/notable/about-memory/malloc-heap"),
-                       stringCharsAboutMemory,
+                       stringsNotableAboutMemoryMallocHeap,
                        "Memory allocated to hold characters of notable strings "
                        "which contain the string '" STRING_LENGTH "'.  These "
                        "strings are likely from about:memory itself.  We filter "
                        "them out rather than display them, because displaying "
                        "them would create even more strings every time you "
                        "refresh about:memory.");
     }
 
-    if (gcHeapSundries > 0) {
+    if (sundriesGCHeap > 0) {
         // We deliberately don't use ZCREPORT_GC_BYTES here.
         REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("sundries/gc-heap"),
-                        gcHeapSundries,
+                        sundriesGCHeap,
                         "The sum of all the 'gc-heap' measurements that are too "
                         "small to be worth showing individually.");
     }
 
-    if (otherSundries > 0) {
+    if (sundriesMallocHeap > 0) {
         // We deliberately don't use ZCREPORT_BYTES here.
         REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("sundries/malloc-heap"),
-                     KIND_HEAP, otherSundries,
+                     KIND_HEAP, sundriesMallocHeap,
                      "The sum of all the 'malloc-heap' measurements that are too "
                      "small to be worth showing individually.");
     }
 
     if (gcTotalOut)
         *gcTotalOut += gcTotal;
 
     return NS_OK;
@@ -1922,17 +1922,17 @@ static nsresult
 ReportCompartmentStats(const JS::CompartmentStats &cStats,
                        const xpc::CompartmentStatsExtras &extras,
                        amIAddonManager *addonManager,
                        nsIMemoryReporterCallback *cb,
                        nsISupports *closure, size_t *gcTotalOut = NULL)
 {
     static const nsDependentCString addonPrefix("explicit/add-ons/");
 
-    size_t gcTotal = 0, gcHeapSundries = 0, otherSundries = 0;
+    size_t gcTotal = 0, sundriesGCHeap = 0, sundriesMallocHeap = 0;
     nsAutoCString cJSPathPrefix = extras.jsPathPrefix;
     nsAutoCString cDOMPathPrefix = extras.domPathPrefix;
 
     // Only attempt to prefix if we got a location and the path wasn't already
     // prefixed.
     if (extras.location && addonManager &&
         cJSPathPrefix.Find(addonPrefix, false, 0, 0) != 0) {
         nsAutoCString addonId;
@@ -1946,158 +1946,100 @@ ReportCompartmentStats(const JS::Compart
             addonId.Insert(NS_LITERAL_CSTRING("add-ons/"), 0);
             addonId += "/";
             cJSPathPrefix.Insert(addonId, explicitLength);
             cDOMPathPrefix.Insert(addonId, explicitLength);
         }
     }
 
     ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/ordinary"),
-                      cStats.gcHeapObjectsOrdinary,
+                      cStats.objectsGCHeapOrdinary,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds ordinary (i.e. not otherwise distinguished "
                       "my memory reporters) objects.");
 
     ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/function"),
-                      cStats.gcHeapObjectsFunction,
+                      cStats.objectsGCHeapFunction,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds function objects.");
 
     ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/dense-array"),
-                      cStats.gcHeapObjectsDenseArray,
+                      cStats.objectsGCHeapDenseArray,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds dense array objects.");
 
     ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/slow-array"),
-                      cStats.gcHeapObjectsSlowArray,
+                      cStats.objectsGCHeapSlowArray,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds slow array objects.");
 
     ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/gc-heap/cross-compartment-wrapper"),
-                      cStats.gcHeapObjectsCrossCompartmentWrapper,
+                      cStats.objectsGCHeapCrossCompartmentWrapper,
                       "Memory on the garbage-collected JavaScript "
                       "heap that holds cross-compartment wrapper objects.");
 
-    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("scripts/gc-heap"),
-                      cStats.gcHeapScripts,
-                      "Memory on the garbage-collected JavaScript "
-                      "heap that holds JSScript instances. A JSScript is "
-                      "created for each user-defined function in a script. One "
-                      "is also created for the top-level code in a script.");
-
-    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree/global-parented"),
-                      cStats.gcHeapShapesTreeGlobalParented,
-                      "Memory on the garbage-collected JavaScript heap that "
-                      "holds shapes that (a) are in a property tree, and (b) "
-                      "represent an object whose parent is the global object.");
-
-    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree/non-global-parented"),
-                      cStats.gcHeapShapesTreeNonGlobalParented,
-                      "Memory on the garbage-collected JavaScript heap that "
-                      "holds shapes that (a) are in a property tree, and (b) "
-                      "represent an object whose parent is not the global object.");
-
-    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/dict"),
-                      cStats.gcHeapShapesDict,
-                      "Memory on the garbage-collected JavaScript "
-                      "heap that holds shapes that are in dictionary mode.");
-
-    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/base"),
-                      cStats.gcHeapShapesBase,
-                      "Memory on the garbage-collected JavaScript "
-                      "heap that collates data common to many shapes.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/slots"),
-                   cStats.objectsExtra.slots,
-                   "Memory allocated on the malloc heap for the non-fixed object "
-                   "slot arrays, which are used to represent object properties. "
-                   "Some objects also contain a fixed number of slots which are "
-                   "stored on the JavaScript heap; those slots "
-                   "are not counted here, but in 'objects/gc-heap/*' instead.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/elements/non-asm.js"),
-                   cStats.objectsExtra.elementsNonAsmJS,
-                   "Memory allocated on the malloc heap for non-asm.js object element arrays, "
-                   "which are used to represent indexed object properties.");
-
-    // asm.js arrays are heap-allocated on some platforms and
-    // non-heap-allocated on others.  We never put them under sundries,
-    // because (a) in practice they're almost always larger than the sundries
-    // threshold, and (b) we'd need a third category of non-heap, non-GC
-    // sundries, which would be a pain.
-    size_t asmJSHeap    = cStats.objectsExtra.elementsAsmJSHeap;
-    size_t asmJSNonHeap = cStats.objectsExtra.elementsAsmJSNonHeap;
-    MOZ_ASSERT(asmJSHeap == 0 || asmJSNonHeap == 0);
-    if (asmJSHeap > 0) {
-        REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/elements/asm.js"),
-                     KIND_HEAP, asmJSHeap,
-                     "Memory allocated on the malloc heap for object element arrays used as asm.js "
-                     "array buffers.");
-    }
-    if (asmJSNonHeap > 0) {
-        REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/non-heap/elements/asm.js"),
-                     KIND_NONHEAP, asmJSNonHeap,
-                     "Memory allocated for object element arrays used as asm.js array buffers. "
-                     "This memory lives outside both the malloc heap and the JS heap.");
-    }
-
-    REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/non-heap/code/asm.js"),
-                 KIND_NONHEAP, cStats.objectsExtra.asmJSModuleCode,
-                 "Memory allocated for AOT-compiled asm.js code.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/asm.js-module-data"),
-                   cStats.objectsExtra.asmJSModuleData,
-                   "Memory allocated for asm.js module data.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/arguments-data"),
-                   cStats.objectsExtra.argumentsData,
-                   "Memory allocated on the malloc heap for data belonging to arguments objects.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/regexp-statics"),
-                   cStats.objectsExtra.regExpStatics,
-                   "Memory allocated for data belonging to the RegExpStatics object.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/property-iterator-data"),
-                   cStats.objectsExtra.propertyIteratorData,
-                   "Memory allocated on the malloc heap for data belonging to property iterator objects.");
-
-    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/ctypes-data"),
-                   cStats.objectsExtra.ctypesData,
-                   "Memory allocated on the malloc heap for data belonging to ctypes objects.");
-
     // Note that we use cDOMPathPrefix here.  This is because we measure orphan
     // DOM nodes in the JS reporter, but we want to report them in a "dom"
     // sub-tree rather than a "js" sub-tree.
     ZCREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),
                    cStats.objectsPrivate,
                    "Memory used by orphan DOM nodes that are only reachable "
                    "from JavaScript objects.");
 
+    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree/global-parented"),
+                      cStats.shapesGCHeapTreeGlobalParented,
+                      "Memory on the garbage-collected JavaScript heap that "
+                      "holds shapes that (a) are in a property tree, and (b) "
+                      "represent an object whose parent is the global object.");
+
+    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree/non-global-parented"),
+                      cStats.shapesGCHeapTreeNonGlobalParented,
+                      "Memory on the garbage-collected JavaScript heap that "
+                      "holds shapes that (a) are in a property tree, and (b) "
+                      "represent an object whose parent is not the global object.");
+
+    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/dict"),
+                      cStats.shapesGCHeapDict,
+                      "Memory on the garbage-collected JavaScript "
+                      "heap that holds shapes that are in dictionary mode.");
+
+    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/base"),
+                      cStats.shapesGCHeapBase,
+                      "Memory on the garbage-collected JavaScript "
+                      "heap that collates data common to many shapes.");
+
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/tree-tables"),
-                   cStats.shapesExtraTreeTables,
+                   cStats.shapesMallocHeapTreeTables,
                    "Memory allocated on the malloc heap for the property tables "
                    "that belong to shapes that are in a property tree.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/dict-tables"),
-                   cStats.shapesExtraDictTables,
+                   cStats.shapesMallocHeapDictTables,
                    "Memory allocated on the malloc heap for the property tables "
                    "that belong to shapes that are in dictionary mode.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/tree-shape-kids"),
-                   cStats.shapesExtraTreeShapeKids,
+                   cStats.shapesMallocHeapTreeShapeKids,
                    "Memory allocated on the malloc heap for the kid hashes that "
                    "belong to shapes that are in a property tree.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/compartment-tables"),
-                   cStats.shapesCompartmentTables,
+                   cStats.shapesMallocHeapCompartmentTables,
                    "Memory on the malloc heap used by compartment-wide tables storing shape "
                    "information for use during object construction.");
 
+    ZCREPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("scripts/gc-heap"),
+                      cStats.scriptsGCHeap,
+                      "Memory on the garbage-collected JavaScript "
+                      "heap that holds JSScript instances. A JSScript is "
+                      "created for each user-defined function in a script. One "
+                      "is also created for the top-level code in a script.");
+
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("scripts/malloc-heap/data"),
-                   cStats.scriptData,
+                   cStats.scriptsMallocHeapData,
                    "Memory on the malloc heap allocated for various variable-length tables in "
                    "JSScript.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("baseline/data"),
                    cStats.baselineData,
                    "Memory used by the Baseline JIT for compilation data: "
                    "BaselineScripts.");
 
@@ -2127,16 +2069,74 @@ ReportCompartmentStats(const JS::Compart
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("regexp-compartment"),
                    cStats.regexpCompartment,
                    "Memory used by the regexp compartment.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("debuggees-set"),
                    cStats.debuggeesSet,
                    "Memory used by the debuggees set.");
 
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/slots"),
+                   cStats.objectsExtra.mallocHeapSlots,
+                   "Memory allocated on the malloc heap for the non-fixed object "
+                   "slot arrays, which are used to represent object properties. "
+                   "Some objects also contain a fixed number of slots which are "
+                   "stored on the JavaScript heap; those slots "
+                   "are not counted here, but in 'objects/gc-heap/*' instead.");
+
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/elements/non-asm.js"),
+                   cStats.objectsExtra.mallocHeapElementsNonAsmJS,
+                   "Memory allocated on the malloc heap for non-asm.js object element arrays, "
+                   "which are used to represent indexed object properties.");
+
+    // asm.js arrays are heap-allocated on some platforms and
+    // non-heap-allocated on others.  We never put them under sundries,
+    // because (a) in practice they're almost always larger than the sundries
+    // threshold, and (b) we'd need a third category of sundries ("non-heap"),
+    // which would be a pain.
+    size_t mallocHeapElementsAsmJS = cStats.objectsExtra.mallocHeapElementsAsmJS;
+    size_t nonHeapElementsAsmJS    = cStats.objectsExtra.nonHeapElementsAsmJS;
+    MOZ_ASSERT(mallocHeapElementsAsmJS == 0 || nonHeapElementsAsmJS == 0);
+    if (mallocHeapElementsAsmJS > 0) {
+        REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/elements/asm.js"),
+                     KIND_HEAP, mallocHeapElementsAsmJS,
+                     "Memory allocated on the malloc heap for object element arrays used as asm.js "
+                     "array buffers.");
+    }
+    if (nonHeapElementsAsmJS > 0) {
+        REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/non-heap/elements/asm.js"),
+                     KIND_NONHEAP, nonHeapElementsAsmJS,
+                     "Memory allocated for object element arrays used as asm.js array buffers. "
+                     "This memory lives outside both the malloc heap and the JS heap.");
+    }
+
+    REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/non-heap/code/asm.js"),
+                 KIND_NONHEAP, cStats.objectsExtra.nonHeapCodeAsmJS,
+                 "Memory allocated for AOT-compiled asm.js code.");
+
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/asm.js-module-data"),
+                   cStats.objectsExtra.mallocHeapAsmJSModuleData,
+                   "Memory allocated for asm.js module data.");
+
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/arguments-data"),
+                   cStats.objectsExtra.mallocHeapArgumentsData,
+                   "Memory allocated on the malloc heap for data belonging to arguments objects.");
+
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/regexp-statics"),
+                   cStats.objectsExtra.mallocHeapRegExpStatics,
+                   "Memory allocated for data belonging to the RegExpStatics object.");
+
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/property-iterator-data"),
+                   cStats.objectsExtra.mallocHeapPropertyIteratorData,
+                   "Memory allocated on the malloc heap for data belonging to property iterator objects.");
+
+    ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/ctypes-data"),
+                   cStats.objectsExtra.mallocHeapCtypesData,
+                   "Memory allocated on the malloc heap for data belonging to ctypes objects.");
+
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/type-scripts"),
                    cStats.typeInference.typeScripts,
                    "Memory used by type sets associated with scripts.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/type-results"),
                    cStats.typeInference.typeResults,
                    "Memory used by dynamic type results produced by scripts.");
 
@@ -2151,28 +2151,28 @@ ReportCompartmentStats(const JS::Compart
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/array-type-tables"),
                    cStats.typeInference.arrayTypeTables,
                    "Memory indexing type objects associated with array literals.");
 
     ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("type-inference/object-type-tables"),
                    cStats.typeInference.objectTypeTables,
                    "Memory indexing type objects associated with object literals.");
 
-    if (gcHeapSundries > 0) {
+    if (sundriesGCHeap > 0) {
         // We deliberately don't use ZCREPORT_GC_BYTES here.
         REPORT_GC_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("sundries/gc-heap"),
-                        gcHeapSundries,
+                        sundriesGCHeap,
                         "The sum of all the 'gc-heap' measurements that are too "
                         "small to be worth showing individually.");
     }
 
-    if (otherSundries > 0) {
+    if (sundriesMallocHeap > 0) {
         // We deliberately don't use ZCREPORT_BYTES here.
         REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("sundries/malloc-heap"),
-                     KIND_HEAP, otherSundries,
+                     KIND_HEAP, sundriesMallocHeap,
                      "The sum of all the 'malloc-heap' measurements that are too "
                      "small to be worth showing individually.");
     }
 
     if (gcTotalOut)
         *gcTotalOut += gcTotal;
 
     return NS_OK;
@@ -2229,38 +2229,16 @@ ReportJSRuntimeExplicitTreeStats(const J
                   "Memory used by DtoaState, which is used for converting "
                   "strings to numbers and vice versa.");
 
     RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/temporary"),
                   KIND_HEAP, rtStats.runtime.temporary,
                   "Memory held transiently in JSRuntime and used during "
                   "compilation.  It mostly holds parse nodes.");
 
-    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/ion"),
-                  KIND_NONHEAP, rtStats.runtime.code.ion,
-                  "Memory used by the IonMonkey JIT to hold generated code.");
-
-    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/baseline"),
-                  KIND_NONHEAP, rtStats.runtime.code.baseline,
-                  "Memory used by the Baseline JIT to hold generated code.");
-
-    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/regexp"),
-                  KIND_NONHEAP, rtStats.runtime.code.regexp,
-                  "Memory used by the regexp JIT to hold generated code.");
-
-    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/other"),
-                  KIND_NONHEAP, rtStats.runtime.code.other,
-                  "Memory used by the JITs to hold generated code for "
-                  "wrappers and trampolines.");
-
-    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/unused"),
-                  KIND_NONHEAP, rtStats.runtime.code.unused,
-                  "Memory allocated by one of the JITs to hold code, "
-                  "but which is currently unused.");
-
     RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/regexp-data"),
                   KIND_NONHEAP, rtStats.runtime.regexpData,
                   "Memory used by the regexp JIT to hold data.");
 
     RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/interpreter-stack"),
                   KIND_HEAP, rtStats.runtime.interpreterStack,
                   "Memory used for JS interpreter frames.");
 
@@ -2276,16 +2254,38 @@ ReportJSRuntimeExplicitTreeStats(const J
                   KIND_HEAP, rtStats.runtime.scriptData,
                   "Memory used for the table holding script data shared in "
                   "the runtime.");
 
     RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/script-sources"),
                   KIND_HEAP, rtStats.runtime.scriptSources,
                   "Memory use for storing JavaScript source code and filenames.");
 
+    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/ion"),
+                  KIND_NONHEAP, rtStats.runtime.code.ion,
+                  "Memory used by the IonMonkey JIT to hold generated code.");
+
+    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/baseline"),
+                  KIND_NONHEAP, rtStats.runtime.code.baseline,
+                  "Memory used by the Baseline JIT to hold generated code.");
+
+    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/regexp"),
+                  KIND_NONHEAP, rtStats.runtime.code.regexp,
+                  "Memory used by the regexp JIT to hold generated code.");
+
+    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/other"),
+                  KIND_NONHEAP, rtStats.runtime.code.other,
+                  "Memory used by the JITs to hold generated code for "
+                  "wrappers and trampolines.");
+
+    RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/unused"),
+                  KIND_NONHEAP, rtStats.runtime.code.unused,
+                  "Memory allocated by one of the JITs to hold code, "
+                  "but which is currently unused.");
+
     if (rtTotalOut)
         *rtTotalOut = rtTotal;
 
     // Report GC numbers that don't belong to a compartment.
 
     // We don't want to report decommitted memory in "explicit", so we just
     // change the leading "explicit/" to "decommitted/".
     nsCString rtPath2(rtPath);
@@ -2632,32 +2632,32 @@ JSReporter::CollectReports(WindowPaths *
 
     REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/arenas"),
                  KIND_OTHER,
                  rtStats.gcHeapUnusedArenas,
                  "The same as 'explicit/js-non-window/gc-heap/unused-arenas'.");
 
     REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things"),
                  KIND_OTHER,
-                 rtStats.zTotals.gcHeapUnusedGcThings,
-                 "The same as 'js-main-runtime/compartments/gc-heap/unused-gc-things'.");
+                 rtStats.zTotals.unusedGCThings,
+                 "The same as 'js-main-runtime/zones/unused-gc-things'.");
 
     REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/chunk-admin"),
                  KIND_OTHER,
                  rtStats.gcHeapChunkAdmin,
                  "The same as 'explicit/js-non-window/gc-heap/chunk-admin'.");
 
     REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/arena-admin"),
                  KIND_OTHER,
                  rtStats.zTotals.gcHeapArenaAdmin,
-                 "The same as 'js-main-runtime/compartments/gc-heap/arena-admin'.");
+                 "The same as 'js-main-runtime/zones/gc-heap-arena-admin'.");
 
     REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things"),
                  KIND_OTHER,
-                 rtStats.gcHeapGcThings,
+                 rtStats.gcHeapGCThings,
                  "Memory on the garbage-collected JavaScript heap that holds GC things such "
                  "as objects, strings, scripts, etc.")
 
     // Report xpconnect.
 
     REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect"),
                  KIND_HEAP, xpconnect,
                  "Memory used by XPConnect.");
--- a/js/xpconnect/src/XPCRuntimeService.cpp
+++ b/js/xpconnect/src/XPCRuntimeService.cpp
@@ -1,22 +1,25 @@
 /* -*- Mode: C++; tab-width: 8; 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 "mozilla/dom/workers/Workers.h"
 #include "nsContentUtils.h"
 #include "BackstagePass.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsDOMClassInfo.h"
 #include "nsIPrincipal.h"
 
+#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
+#include "mozilla/dom/workers/Workers.h"
+
 using mozilla::dom::workers::ResolveWorkerClasses;
+namespace indexedDB = mozilla::dom::indexedDB;
 
 NS_INTERFACE_MAP_BEGIN(BackstagePass)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCScriptable)
@@ -47,31 +50,44 @@ BackstagePass::NewResolve(nsIXPConnectWr
                           JSContext * cx, JSObject * objArg,
                           jsid idArg, uint32_t flags,
                           JSObject * *objpArg, bool *_retval)
 {
     JS::RootedObject obj(cx, objArg);
     JS::RootedId id(cx, idArg);
 
     bool resolved;
+    *objpArg = nullptr;
 
     *_retval = !!JS_ResolveStandardClass(cx, obj, id, &resolved);
-    if (!*_retval) {
-        *objpArg = nullptr;
-        return NS_OK;
-    }
+    NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
 
     if (resolved) {
         *objpArg = obj;
         return NS_OK;
     }
 
     JS::RootedObject objp(cx, *objpArg);
-    *_retval = !!ResolveWorkerClasses(cx, obj, id, flags, &objp);
-    *objpArg = objp;
+
+    *_retval = ResolveWorkerClasses(cx, obj, id, flags, &objp);
+    NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
+
+    if (objp) {
+        *objpArg = objp;
+        return NS_OK;
+    }
+
+    *_retval = indexedDB::ResolveConstructors(cx, obj, id, &objp);
+    NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE);
+
+    if (objp) {
+        *objpArg = objp;
+        return NS_OK;
+    }
+
     return NS_OK;
 }
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 BackstagePass::GetInterfaces(uint32_t *aCount, nsIID * **aArray)
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -25,22 +25,16 @@
 #ifdef MOZ_JSDEBUGGER
 #include "jsdIDebuggerService.h"
 #endif
 
 #include "XPCQuickStubs.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Exceptions.h"
-#include "mozilla/dom/IDBIndexBinding.h"
-#include "mozilla/dom/IDBObjectStoreBinding.h"
-#include "mozilla/dom/IDBOpenDBRequestBinding.h"
-#include "mozilla/dom/IDBRequestBinding.h"
-#include "mozilla/dom/IDBTransactionBinding.h"
-#include "mozilla/dom/IDBVersionChangeEventBinding.h"
 #include "mozilla/dom/TextDecoderBinding.h"
 #include "mozilla/dom/TextEncoderBinding.h"
 #include "mozilla/dom/DOMErrorBinding.h"
 
 #include "nsDOMMutationObserver.h"
 #include "nsICycleCollectorListener.h"
 #include "nsThread.h"
 #include "mozilla/XPTInterfaceInfoManager.h"
@@ -525,23 +519,21 @@ nsXPConnect::InitClassesWithNewWrappedGl
     }
 
     // Stuff coming through this path always ends up as a DOM global.
     // XXX Someone who knows why we can assert this should re-check
     //     (after bug 720580).
     MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
 
     // Init WebIDL binding constructors wanted on all XPConnect globals.
-    if (!IDBIndexBinding::GetConstructorObject(aJSContext, global) ||
-        !IDBObjectStoreBinding::GetConstructorObject(aJSContext, global) ||
-        !IDBOpenDBRequestBinding::GetConstructorObject(aJSContext, global) ||
-        !IDBRequestBinding::GetConstructorObject(aJSContext, global) ||
-        !IDBTransactionBinding::GetConstructorObject(aJSContext, global) ||
-        !IDBVersionChangeEventBinding::GetConstructorObject(aJSContext, global) ||
-        !TextDecoderBinding::GetConstructorObject(aJSContext, global) ||
+    // Additional bindings may be created lazily, see BackstagePass::NewResolve.
+    //
+    // XXX Please do not add any additional classes here without the approval of
+    //     the XPConnect module owner.
+    if (!TextDecoderBinding::GetConstructorObject(aJSContext, global) ||
         !TextEncoderBinding::GetConstructorObject(aJSContext, global) ||
         !DOMErrorBinding::GetConstructorObject(aJSContext, global)) {
         return UnexpectedFailure(NS_ERROR_FAILURE);
     }
 
     wrappedGlobal.forget(_retval);
     return NS_OK;
 }
--- a/mozglue/linker/Mappable.cpp
+++ b/mozglue/linker/Mappable.cpp
@@ -180,44 +180,52 @@ public:
     strlcpy(str, name, sizeof(str));
     ioctl(fd, ASHMEM_SET_NAME, str);
     if (ioctl(fd, ASHMEM_SET_SIZE, length))
       return NULL;
 
     /* The Gecko crash reporter is confused by adjacent memory mappings of
      * the same file and chances are we're going to map from the same file
      * descriptor right away. To avoid problems with the crash reporter,
-     * create an empty anonymous page before and after the ashmem mapping.
-     * We create two anonymous pages because on some platforms, subsequent
-     * mappings are placed at adjacent, increasing memory addresses (ARM)
-     * and on others, such mappings are placed at adjacent, decreasing
-     * memory addresses (x86). It is more convenient to just do two pages
-     * everywhere than to twiddle with platform-specific #defines.
+     * create an empty anonymous page before or after the ashmem mapping,
+     * depending on how mappings grow in the address space.
      */
-    size_t anon_mapping_length = length + 2 * PAGE_SIZE;
+#if defined(__arm__)
+    void *buf = ::mmap(NULL, length + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    if (buf != MAP_FAILED) {
+      ::mmap(AlignedEndPtr(reinterpret_cast<char *>(buf) + length, PAGE_SIZE),
+             PAGE_SIZE, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+      DEBUG_LOG("Decompression buffer of size 0x%x in ashmem \"%s\", mapped @%p",
+                length, str, buf);
+      return new _MappableBuffer(fd.forget(), buf, length);
+    }
+#elif defined(__i386__)
+    size_t anon_mapping_length = length + PAGE_SIZE;
     void *buf = ::mmap(NULL, anon_mapping_length, PROT_NONE,
                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     if (buf != MAP_FAILED) {
       char *first_page = reinterpret_cast<char *>(buf);
       char *map_page = first_page + PAGE_SIZE;
-      char *last_page = map_page + ((length + PAGE_SIZE - 1) & PAGE_MASK);
 
-      void *actual_buf = ::mmap(map_page, last_page - map_page, PROT_READ | PROT_WRITE,
+      void *actual_buf = ::mmap(map_page, length, PROT_READ | PROT_WRITE,
                                 MAP_FIXED | MAP_SHARED, fd, 0);
       if (actual_buf == MAP_FAILED) {
         ::munmap(buf, anon_mapping_length);
         DEBUG_LOG("Fixed allocation of decompression buffer at %p failed", map_page);
         return NULL;
       }
 
       DEBUG_LOG("Decompression buffer of size 0x%x in ashmem \"%s\", mapped @%p",
                 length, str, actual_buf);
       return new _MappableBuffer(fd.forget(), actual_buf, length);
     }
 #else
+#error need to add a case for your CPU
+#endif
+#else
     /* On Linux, use /dev/shm as base directory for temporary files, assuming
      * it's on tmpfs */
     /* TODO: check that /dev/shm is tmpfs */
     char path[256];
     sprintf(path, "/dev/shm/%s.XXXXXX", name);
     fd = mkstemp(path);
     if (fd == -1)
       return NULL;
@@ -245,18 +253,24 @@ public:
       flags |= MAP_SHARED;
     }
 #endif
     return ::mmap(const_cast<void *>(addr), length, prot, flags, fd, offset);
   }
 
 #ifdef ANDROID
   ~_MappableBuffer() {
-    /* Free the additional pages we allocated. See _MappableBuffer::Create */
-    ::munmap(*this - PAGE_SIZE, GetLength() + 2 * PAGE_SIZE);
+    /* Free the additional page we allocated. See _MappableBuffer::Create */
+#if defined(__arm__)
+    ::munmap(AlignedEndPtr(*this + GetLength(), PAGE_SIZE), PAGE_SIZE);
+#elif defined(__i386__)
+    ::munmap(*this - PAGE_SIZE, GetLength() + PAGE_SIZE);
+#else
+#error need to add a case for your CPU
+#endif
   }
 #endif
 
 private:
   _MappableBuffer(int fd, void *buf, size_t length)
   : MappedPtr(buf, length), fd(fd) { }
 
   /* File descriptor for the temporary file or ashmem */
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -106,19 +106,19 @@ class BackendMakeFile(object):
         if self.xpt_name:
             self.fh.write('XPT_NAME := %s\n' % self.xpt_name)
 
             # We just recompile all xpidls because it's easier and less error
             # prone.
             self.fh.write('NONRECURSIVE_TARGETS += export\n')
             self.fh.write('NONRECURSIVE_TARGETS_export += xpidl\n')
             self.fh.write('NONRECURSIVE_TARGETS_export_xpidl_DIRECTORY = '
-                '$(DEPTH)/config/makefiles/precompile\n')
+                '$(DEPTH)/xpcom/xpidl\n')
             self.fh.write('NONRECURSIVE_TARGETS_export_xpidl_TARGETS += '
-                'xpidl\n')
+                'export\n')
 
         return self.fh.close()
 
 
 class RecursiveMakeTraversal(object):
     """
     Helper class to keep track of how the "traditional" recursive make backend
     recurses subdirectories. This is useful until all adhoc rules are removed
@@ -422,35 +422,27 @@ class RecursiveMakeBackend(CommonBackend
         # Skip static dirs during export traversal, or build everything in
         # parallel when enabled.
         def export_filter(current, subdirs):
             if self._parallel_export:
                 return parallel_filter(current, subdirs)
             return current, subdirs.parallel, \
                 subdirs.dirs + subdirs.tests + subdirs.tools
 
-        # compile and tools build everything in parallel, but skip precompile.
-        def other_filter(current, subdirs):
-            if current == 'subtiers/precompile':
-                return None, [], []
-            return parallel_filter(current, subdirs)
-
         # Skip tools dirs during libs traversal
         def libs_filter(current, subdirs):
-            if current == 'subtiers/precompile':
-                return None, [], []
             return current, subdirs.parallel, \
                 subdirs.static + subdirs.dirs + subdirs.tests
 
         # compile and tools tiers use the same traversal as export
         filters = {
             'export': export_filter,
-            'compile': other_filter,
+            'compile': parallel_filter,
             'libs': libs_filter,
-            'tools': other_filter,
+            'tools': parallel_filter,
         }
 
         root_deps_mk = Makefile()
 
         # Fill the dependencies for traversal of each tier.
         for tier, filter in filters.items():
             main, all_deps = \
                 self._traversal.compute_dependencies(filter)
--- a/testing/specialpowers/content/MockFilePicker.jsm
+++ b/testing/specialpowers/content/MockFilePicker.jsm
@@ -17,17 +17,17 @@ Cu.import("resource://gre/modules/XPCOMU
 
 var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
 var oldClassID, oldFactory;
 var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
 var newFactory = function (window) {
   return {
     createInstance: function(aOuter, aIID) {
       if (aOuter)
-	throw Components.results.NS_ERROR_NO_AGGREGATION;
+        throw Components.results.NS_ERROR_NO_AGGREGATION;
       return new MockFilePickerInstance(window).QueryInterface(aIID);
     },
     lockFactory: function(aLock) {
       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
     },
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
   };
 }
@@ -53,30 +53,30 @@ this.MockFilePicker = {
     this.factory = newFactory(window);
     if (!registrar.isCIDRegistered(newClassID)) {
       oldClassID = registrar.contractIDToCID(CONTRACT_ID);
       oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
       registrar.unregisterFactory(oldClassID, oldFactory);
       registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
     }
   },
-  
+
   reset: function() {
     this.appendFilterCallback = null;
     this.appendFiltersCallback = null;
     this.displayDirectory = null;
     this.filterIndex = 0;
     this.mode = null;
     this.returnFiles = [];
     this.returnValue = null;
     this.showCallback = null;
     this.shown = false;
     this.showing = false;
   },
-  
+
   cleanup: function() {
     var previousFactory = this.factory;
     this.reset();
     this.factory = null;
     if (oldFactory) {
       registrar.unregisterFactory(newClassID, previousFactory);
       registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
     }
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
@@ -4,17 +4,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 if CONFIG['LIBXUL_SDK']:
     error('toolkit.mozbuild is not compatible with --enable-libxul-sdk=')
 
 if not CONFIG['MOZ_NATIVE_NSPR']:
     add_tier_dir('nspr', 'config/nspr')
 
-add_tier_dir('precompile', 'config/makefiles/precompile')
 add_tier_dir('external', 'config/external')
 
 if not CONFIG['MOZ_NATIVE_NSS']:
     add_tier_dir('nss', 'security/build')
 
 include('/config/js/js.mozbuild')
 
 if CONFIG['MOZ_CONTENT_SANDBOX']:
--- a/xpcom/moz.build
+++ b/xpcom/moz.build
@@ -1,16 +1,20 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
+PARALLEL_DIRS += [
+    'idl-parser',
+    'xpidl',
+]
+
 DIRS += [
-    'idl-parser',
     'typelib',
     'string',
     'glue',
     'base',
     'ds',
     'io',
     'components',
     'threads',
new file mode 100644
--- /dev/null
+++ b/xpcom/xpidl/Makefile.in
@@ -0,0 +1,8 @@
+# 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/.
+
+export::
+	$(call SUBMAKE,xpidl-parser,$(DEPTH)/xpcom/idl-parser)
+	$(call py_action,process_install_manifest,$(DIST)/idl $(DEPTH)/_build_manifests/install/dist_idl)
+	$(call SUBMAKE,xpidl,$(DEPTH)/config/makefiles/xpidl)
new file mode 100644
--- /dev/null
+++ b/xpcom/xpidl/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.