Merge m-c to inbound.
authorMs2ger <ms2ger@gmail.com>
Fri, 06 Sep 2013 12:31:58 +0200
changeset 158749 7884c58c28a873d2bcd009247c4b82387e959b6d
parent 158678 ab5f2982323626fc77caae739c1c1533c7f4d55b (current diff)
parent 158748 96472e9e9373fa16d842afd598d86f17df1268c5 (diff)
child 158751 0fa38163e3bf0b70c6cc571b5fd805dd482d334e
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to inbound.
config/makefiles/tiers.mk
config/rules.mk
content/media/EncodedBufferCache.h
image/src/EndianMacros.h
js/src/config/makefiles/tiers.mk
js/src/config/rules.mk
js/src/jit/BaselineIC.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/x86/MacroAssembler-x86.h
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 908977 - Generate XPIDL headers directly into dist/include
+Bug 912832 - Inverse tiers and subtiers for build traversal
--- a/Makefile.in
+++ b/Makefile.in
@@ -47,20 +47,20 @@ ifndef MOZ_PROFILE_USE
 # a common directory. Each manifest is responsible for defining files in
 # a specific subdirectory of the object directory. The invoked Python
 # script simply iterates over all the manifests, purging files as
 # necessary. To manage new directories or add files to the manifests,
 # modify the backend generator.
 #
 # We need to explicitly put backend.RecursiveMakeBackend.built here
 # otherwise the rule in rules.mk doesn't run early enough.
-default all export libs tools:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built
+libs export tools:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built
 	$(call SUBMAKE,backend.RecursiveMakeBackend.built,js/src,1)
 
-default all export::
+export::
 	$(call py_action,purge_manifests,-d _build_manifests/purge .)
 endif
 
 CLOBBER: $(topsrcdir)/CLOBBER
 	@echo "STOP!  The CLOBBER file has changed."
 	@echo "Please run the build through a sanctioned build wrapper, such as"
 	@echo "'mach build' or client.mk."
 	@exit 1
@@ -74,39 +74,32 @@ CLOBBER: $(topsrcdir)/CLOBBER
 
 config.status: $(topsrcdir)/configure
 	@echo "STOP!  configure has changed and needs to be run in this build directory."
 	@echo "Please rerun configure."
 	@echo "To ignore this message, touch 'config.status' in the build directory,"
 	@echo "but your build might not succeed."
 	@exit 1
 
-default all export::
+export::
 	$(RM) -r $(DIST)/sdk
 
 ifdef ENABLE_TESTS
 # Additional makefile targets to call automated test suites
 include $(topsrcdir)/testing/testsuite-targets.mk
 endif
 
-# Hacky way for precompile tier to bypass default tier traversal mechanism.
-TIER_precompile_CUSTOM := 1
+export::
+	$(call py_action,process_install_manifest,$(DIST)/include _build_manifests/install/dist_include js/src/_build_manifests/install/dist_include)
 
-default all export::
-	$(call py_action,process_install_manifest,$(DIST)/include _build_manifests/install/dist_include js/src/_build_manifests/install/dist_include)
+default all::
+	$(call BUILDSTATUS,TIERS export compile libs tools)
 
 include $(topsrcdir)/config/rules.mk
 
-default all::
-	$(call BUILDSTATUS,TIERS $(TIERS))
-	$(foreach tier,$(TIERS),$(call SUBMAKE,tier_$(tier)))
-
-include $(topsrcdir)/config/makefiles/tiers.mk
-$(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier))))
-
 distclean::
 	$(RM) $(DIST_GARBAGE)
 
 ifeq ($(OS_ARCH),WINNT)
 # we want to copy PDB files on Windows
 MAKE_SYM_STORE_ARGS := -c --vcs-info
 ifdef PDBSTR_PATH
 MAKE_SYM_STORE_ARGS += -i
--- a/accessible/src/jsat/moz.build
+++ b/accessible/src/jsat/moz.build
@@ -1,12 +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/.
-
-MODULE = 'alerts'
-
-CPP_SOURCES += [
-    'nsAccessibilityFactory.cpp',
-]
-
--- a/accessible/tests/mochitest/actions/moz.build
+++ b/accessible/tests/mochitest/actions/moz.build
@@ -1,8 +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/.
-
-MODULE = 'alerts'
-
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6601,16 +6601,21 @@ var gIdentityHandler = {
       accessKey: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.accesskey"),
       callback: function() { /* NOP */ }
     };
     let secondaryActions = [
       {
         label: gNavigatorBundle.getString("mixedContentBlocked.unblock.label"),
         accessKey: gNavigatorBundle.getString("mixedContentBlocked.unblock.accesskey"),
         callback: function() {
+          // Use telemetry to measure how often unblocking happens
+          const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
+          let histogram =
+            Services.telemetry.getHistogramById("MIXED_CONTENT_UNBLOCK_COUNTER");
+          histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
           // Reload the page with the content unblocked
           BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
         }
       }
     ];
     let options = {
       dismissed: true,
     };
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -4696,16 +4696,17 @@ let TabStateCacheTelemetry = {
   /**
    * Initialize the telemetry.
    */
   _init: function() {
     if (this._initialized) {
       // Avoid double initialization
       return;
     }
+    this._initialized = true;
     Services.obs.addObserver(this, "profile-before-change", false);
   },
 
   observe: function() {
     Services.obs.removeObserver(this, "profile-before-change");
 
     // Record hit/miss rate
     let accesses = this._hits + this._misses;
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -223,29 +223,26 @@ if test "$OS_TARGET" = "Android" -a -z "
     esac
 
     AC_SUBST(ANDROID_CPU_ARCH)
 
     if test -z "$STLPORT_CPPFLAGS$STLPORT_LDFLAGS$STLPORT_LIBS"; then
         if test -n "$MOZ_ANDROID_LIBSTDCXX" ; then
             if test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/libgnustl_static.a"; then
                 # android-ndk-r8b
-                STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/"
-                STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/include"
-                STLPORT_LIBS="-lgnustl_static"
+                STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/ -lgnustl_static"
+                STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/include/backward"
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libgnustl_static.a"; then
                 # android-ndk-r7, android-ndk-r7b, android-ndk-r8
-                STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/"
+                STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/ -lgnustl_static"
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
-                STLPORT_LIBS="-lgnustl_static"
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a"; then
                 # android-ndk-r5c, android-ndk-r6, android-ndk-r6b
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
-                STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/"
-                STLPORT_LIBS="-lstdc++"
+                STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/ -lstdc++"
             else
                 AC_MSG_ERROR([Couldn't find path to gnu-libstdc++ in the android ndk])
             fi
         else
             STLPORT_CPPFLAGS="-I$_topsrcdir/build/stlport/stlport -I$android_ndk/sources/cxx-stl/system/include"
             STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
         fi
     fi
--- a/build/clang-plugin/Makefile.in
+++ b/build/clang-plugin/Makefile.in
@@ -35,8 +35,17 @@ all: $(PLUGIN) $(TESTS)
 	$(CXX) -shared -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS) -lclangASTMatchers
 
 TESTFLAGS := -fsyntax-only -Xclang -verify \
 	-Xclang -load -Xclang $(CURDIR)/$(PLUGIN) \
 	-Xclang -add-plugin -Xclang moz-check
 
 $(TESTS): test-%: tests/%.cpp $(PLUGIN)
 	$(CXX) $(TESTFLAGS) $<
+
+compile libs export tools: all
+
+distclean clean:
+	rm -f $(OBJS) $(TESTS) $(PLUGIN)
+
+check:
+
+.PHONY: compile libs export tools distclean clean check
--- a/build/pymake/pymake/parserdata.py
+++ b/build/pymake/pymake/parserdata.py
@@ -88,17 +88,17 @@ def parsecommandlineargs(args):
             vname = vname.strip()
             vnameexp = data.Expansion.fromstring(vname, "Command-line argument")
 
             stmts.append(ExportDirective(vnameexp, concurrent_set=True))
             stmts.append(SetVariable(vnameexp, token=t,
                                      value=val, valueloc=Location('<command-line>', i, len(vname) + len(t)),
                                      targetexp=None, source=data.Variables.SOURCE_COMMANDLINE))
         else:
-            r.append(a)
+            r.append(data.stripdotslash(a))
 
     return stmts, r, ' '.join(overrides)
 
 class Statement(object):
     """
     Represents parsed make file syntax.
 
     This is an abstract base class. Child classes are expected to implement
new file mode 100644
--- /dev/null
+++ b/build/pymake/tests/cmd-stripdotslash.mk
@@ -0,0 +1,5 @@
+all:
+	$(MAKE) -f $(TESTPATH)/cmd-stripdotslash.mk ./foo
+
+./foo:
+	@echo TEST-PASS
--- a/build/virtualenv/populate_virtualenv.py
+++ b/build/virtualenv/populate_virtualenv.py
@@ -8,20 +8,36 @@
 from __future__ import print_function, unicode_literals
 
 import distutils.sysconfig
 import os
 import shutil
 import subprocess
 import sys
 
+from distutils.version import StrictVersion
+
 
 # Minimum version of Python required to build.
+MINIMUM_PYTHON_VERSION = StrictVersion('2.7.3')
 MINIMUM_PYTHON_MAJOR = 2
-MINIMUM_PYTHON_MINOR = 7
+
+
+UPGRADE_WINDOWS = '''
+Please upgrade to the latest MozillaBuild development environments. See
+https://developer.mozilla.org/en-US/docs/Developer_Guide/Build_Instructions/Windows_Prerequisites
+'''.lstrip()
+
+UPGRADE_OTHER = '''
+Run |mach bootstrap| to ensure your system is up to date.
+
+If you still receive this error, your shell environment is likely detecting
+another Python version. Ensure a modern Python can be found in the paths
+defined by the $PATH environment variable and try again.
+'''.lstrip()
 
 
 class VirtualenvManager(object):
     """Contains logic for managing virtualenvs for building the tree."""
 
     def __init__(self, topsrcdir, topobjdir, virtualenv_path, log_handle,
         manifest_path):
         """Create a new manager.
@@ -338,23 +354,30 @@ class VirtualenvManager(object):
         and call .ensure() and .activate() to make the virtualenv active.
         """
 
         execfile(self.activate_path, dict(__file__=self.activate_path))
 
 
 def verify_python_version(log_handle):
     """Ensure the current version of Python is sufficient."""
-    major, minor = sys.version_info[:2]
+    major, minor, micro = sys.version_info[:3]
+
+    our = StrictVersion('%d.%d.%d' % (major, minor, micro))
 
-    if major != MINIMUM_PYTHON_MAJOR or minor < MINIMUM_PYTHON_MINOR:
-        log_handle.write('Python %d.%d or greater (but not Python 3) is '
-            'required to build. ' %
-            (MINIMUM_PYTHON_MAJOR, MINIMUM_PYTHON_MINOR))
-        log_handle.write('You are running Python %d.%d.\n' % (major, minor))
+    if major != MINIMUM_PYTHON_MAJOR or our < MINIMUM_PYTHON_VERSION:
+        log_handle.write('Python %s or greater (but not Python 3) is '
+            'required to build. ' % MINIMUM_PYTHON_VERSION)
+        log_handle.write('You are running Python %s.\n' % our)
+
+        if os.name in ('nt', 'ce'):
+            log_handle.write(UPGRADE_WINDOWS)
+        else:
+            log_handle.write(UPGRADE_OTHER)
+
         sys.exit(1)
 
 
 if __name__ == '__main__':
     if len(sys.argv) < 4:
         print('Usage: populate_virtualenv.py /path/to/topsrcdir /path/to/topobjdir /path/to/virtualenv')
         sys.exit(1)
 
--- a/client.mk
+++ b/client.mk
@@ -115,16 +115,18 @@ endef
 # As $(shell) doesn't preserve newlines, use sed to replace them with an
 # unlikely sequence (||), which is then replaced back to newlines by make
 # before evaluation. $(shell) replacing newlines with spaces, || is always
 # followed by a space (since sed doesn't remove newlines), except on the
 # last line, so replace both '|| ' and '||'.
 MOZCONFIG_CONTENT := $(subst ||,$(CR),$(subst || ,$(CR),$(shell _PYMAKE=$(.PYMAKE) $(TOPSRCDIR)/$(MOZCONFIG_LOADER) $(TOPSRCDIR) | sed 's/$$/||/')))
 $(eval $(MOZCONFIG_CONTENT))
 
+export FOUND_MOZCONFIG
+
 # As '||' was used as a newline separator, it means it's not occurring in
 # lines themselves. It can thus safely be used to replaces normal spaces,
 # to then replace newlines with normal spaces. This allows to get a list
 # of mozconfig output lines.
 MOZCONFIG_OUT_LINES := $(subst $(CR), ,$(subst $(NULL) $(NULL),||,$(MOZCONFIG_CONTENT)))
 # Filter-out comments from those lines.
 START_COMMENT = \#
 MOZCONFIG_OUT_FILTERED := $(filter-out $(START_COMMENT)%,$(MOZCONFIG_OUT_LINES))
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -108,17 +108,17 @@ endif
 endif
 endif
 
 ifdef stl_compiler
 STL_WRAPPERS_SENTINEL = $(DIST)/stl_wrappers/sentinel
 
 $(STL_WRAPPERS_SENTINEL): $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
 	$(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers
-	$(PYTHON) $(srcdir)/nsinstall.py stl_wrappers $(DIST)
+	$(PYTHON) $(srcdir)/nsinstall.py -t stl_wrappers $(DIST)
 	touch $(STL_WRAPPERS_SENTINEL)
 
 export:: $(STL_WRAPPERS_SENTINEL)
 
 GARBAGE += $(STL_WRAPPERS_SENTINEL)
 GARBAGE_DIRS += stl_wrappers
 endif
 
--- a/config/make-stl-wrappers.py
+++ b/config/make-stl-wrappers.py
@@ -1,13 +1,14 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 from __future__ import print_function
 import os, re, string, sys
+from mozbuild.util import FileAvoidWrite
 
 def find_in_path(file, searchpath):
     for dir in searchpath.split(os.pathsep):
         f = os.path.join(dir, file)
         if os.path.exists(f):
             return f
     return ''
 
@@ -32,23 +33,20 @@ def main(outdir, compiler, template_file
     path_to_new = header_path('new', compiler)
 
     for header in open(header_list_file, 'r'):
         header = header.rstrip()
         if 0 == len(header) or is_comment(header):
             continue
 
         path = header_path(header, compiler)
-        try:
-            f = open(os.path.join(outdir, header), 'w')
+        with FileAvoidWrite(os.path.join(outdir, header)) as f:
             f.write(string.Template(template).substitute(HEADER=header,
                                                          HEADER_PATH=path,
                                                          NEW_HEADER_PATH=path_to_new))
-        finally:
-            f.close()
 
 
 if __name__ == '__main__':
     if 5 != len(sys.argv):
         print("""Usage:
   python {0} OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE
 """.format(sys.argv[0]), file=sys.stderr)
         sys.exit(1)
--- a/config/makefiles/precompile/Makefile.in
+++ b/config/makefiles/precompile/Makefile.in
@@ -2,38 +2,23 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # This make file defines the precompile tier. This tier effectively fans out
 # to other make files and specialized targets.
 
 SUPPRESS_DEFAULT_RULES := 1
 
-include $(topsrcdir)/config/rules.mk
-
-# We don't print the build status messages unless we're in a top level build
-# otherwise the output is unexpected and it confuses downstream parsers.
-define make_subtier_dir
-$(call BUILDSTATUS,SUBTIER_START precompile $(1))
-+$(MAKE) -C $(2) $(3)
-$(call BUILDSTATUS,SUBTIER_FINISH precompile $(1))
-
-endef
-
 default::
-	$(call BUILDSTATUS,TIER_START  precompile IPDL WebIDL XPIDL)
 	+$(MAKE) export
-	$(call BUILDSTATUS,TIER_FINISH precompile)
 
 export:: ipdl webidl xpidl
 
 ipdl:
-	$(call make_subtier_dir,IPDL,$(DEPTH)/ipc/ipdl,ipdl)
+	$(call SUBMAKE,ipdl,$(DEPTH)/ipc/ipdl)
 
 webidl:
-	$(call make_subtier_dir,WebIDL,$(DEPTH)/dom/bindings,webidl)
+	$(call SUBMAKE,webidl,$(DEPTH)/dom/bindings)
 
 xpidl:
-	$(call BUILDSTATUS,SUBTIER_START  precompile XPIDL)
-	+$(MAKE) -C $(DEPTH)/xpcom/idl-parser xpidl-parser
+	$(call SUBMAKE,xpidl-parser,$(DEPTH)/xpcom/idl-parser)
 	$(call py_action,process_install_manifest,$(DIST)/idl $(DEPTH)/_build_manifests/install/dist_idl)
-	+$(MAKE) -C $(DEPTH)/config/makefiles/xpidl xpidl
-	$(call BUILDSTATUS,SUBTIER_FINISH precompile XPIDL)
+	$(call SUBMAKE,xpidl,$(DEPTH)/config/makefiles/xpidl)
deleted file mode 100644
--- a/config/makefiles/tiers.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- makefile -*-
-# vim:set ts=8 sw=8 sts=8 noet:
-#
-# 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 file contains logic for tier traversal.
-
-define CREATE_SUBTIER_RULE
-$(2)_tier_$(1):
-	$$(call BUILDSTATUS,SUBTIER_START  $(1) $(2) $$(tier_$(1)_dirs))
-	$$(foreach dir,$$(tier_$(1)_dirs),$$(call TIER_DIR_SUBMAKE,$(1),$(2),$$(dir),$(2)))
-	$$(call BUILDSTATUS,SUBTIER_FINISH $(1) $(2))
-
-endef
-
-# This function is called and evaluated to produce the rule to build the
-# specified tier.
-#
-# Tiers are traditionally composed of directories that are invoked either
-# once (so-called "static" directories) or 3 times with the export, libs, and
-# tools sub-tiers.
-#
-# If the TIER_$(tier)_CUSTOM variable is defined, then these traditional
-# tier rules are ignored and each directory in the tier is executed via a
-# sub-make invocation (make -C).
-define CREATE_TIER_RULE
-tier_$(1)::
-ifdef TIER_$(1)_CUSTOM
-	$$(foreach dir,$$($$@_dirs),$$(call SUBMAKE,,$$(dir)))
-else
-	$(call BUILDSTATUS,TIER_START $(1) $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
-ifneq (,$(tier_$(1)_staticdirs))
-	$(call BUILDSTATUS,SUBTIER_START  $(1) static $$($$@_staticdirs))
-	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,$(1),static,$$(dir),,1))
-	$(call BUILDSTATUS,SUBTIER_FINISH $(1) static)
-endif
-ifneq (,$(tier_$(1)_dirs))
-	$$(MAKE) export_$$@
-	$$(MAKE) libs_$$@
-	$$(MAKE) tools_$$@
-endif
-	$(call BUILDSTATUS,TIER_FINISH $(1))
-endif
-
-$(foreach subtier,export libs tools,$(call CREATE_SUBTIER_RULE,$(1),$(subtier)))
-
-endef
--- a/config/recurse.mk
+++ b/config/recurse.mk
@@ -5,16 +5,29 @@
 ifndef INCLUDED_RULES_MK
 include $(topsrcdir)/config/rules.mk
 endif
 
 #########################
 # Tier traversal handling
 #########################
 
+ifdef TIERS
+
+compile libs export tools::
+	$(call BUILDSTATUS,TIER_START $@ $(filter-out $(if $(filter export,$@),,precompile),$(TIERS)))
+	$(foreach tier,$(TIERS), $(if $(filter-out compile_precompile libs_precompile tools_precompile,$@_$(tier)), \
+		$(call BUILDSTATUS,SUBTIER_START $@ $(tier) $(if $(filter libs,$@),$(tier_$(tier)_staticdirs)) $(tier_$(tier)_dirs)) \
+		$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
+		$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@)) \
+		$(call BUILDSTATUS,SUBTIER_FINISH $@ $(tier))))
+	$(call BUILDSTATUS,TIER_FINISH $@)
+
+else
+
 define CREATE_SUBTIER_TRAVERSAL_RULE
 PARALLEL_DIRS_$(1) = $$(addsuffix _$(1),$$(PARALLEL_DIRS))
 
 .PHONY: $(1) $$(PARALLEL_DIRS_$(1))
 
 ifdef PARALLEL_DIRS
 $$(PARALLEL_DIRS_$(1)): %_$(1): %/Makefile
 	+@$$(call SUBMAKE,$(1),$$*)
@@ -23,15 +36,17 @@ endif
 $(1):: $$(SUBMAKEFILES)
 ifdef PARALLEL_DIRS
 	+@$(MAKE) $$(PARALLEL_DIRS_$(1))
 endif
 	$$(LOOP_OVER_DIRS)
 
 endef
 
-$(foreach subtier,export libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
+$(foreach subtier,export compile libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
 
-export:: $(SUBMAKEFILES)
+compile export:: $(SUBMAKEFILES)
 	$(LOOP_OVER_TOOL_DIRS)
 
 tools:: $(SUBMAKEFILES)
 	$(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,libs,$(dir)))
+
+endif
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -431,17 +431,20 @@ ifdef MOZ_UPDATE_XTERM
 # Its good not to have a newline at the end of the titlebar string because it
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick printf into doing it.
 UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ;
 endif
 
 ifdef MACH
 ifndef NO_BUILDSTATUS_MESSAGES
-BUILDSTATUS=@echo "BUILDSTATUS $1"
+define BUILDSTATUS
+@echo "BUILDSTATUS $1"
+
+endef
 endif
 endif
 
 # Static directories are largely independent of our build system. But, they
 # could share the same build mechanism (like moz.build files). We need to
 # prevent leaking of our backend state to these independent build systems. This
 # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static
 # directories.
@@ -453,17 +456,16 @@ endef # The extra line is important here
 
 define TIER_DIR_SUBMAKE
 $(call BUILDSTATUS,TIERDIR_START  $(1) $(2) $(3))
 $(call SUBMAKE,$(4),$(3),$(5))
 $(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3))
 
 endef # Ths empty line is important.
 
-
 ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
   $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
 
 # we only use this for the makefiles target and other stuff that doesn't matter
 ifneq (,$(strip $(PARALLEL_DIRS)))
 LOOP_OVER_PARALLEL_DIRS = \
@@ -683,22 +685,21 @@ endif
 #   This is used to update or create the Makefiles before invoking them.
 SUBMAKEFILES += $(addsuffix /Makefile, $(DIRS) $(TOOL_DIRS) $(PARALLEL_DIRS))
 
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
-ifndef TIERS
 default all::
 	$(MAKE) export
+	$(MAKE) compile
 	$(MAKE) libs
 	$(MAKE) tools
-endif # TIERS
 endif # SUPPRESS_DEFAULT_RULES
 
 ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),)
 ECHO := echo
 QUIET :=
 else
 ECHO := true
 QUIET := -q
@@ -725,16 +726,18 @@ HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 ifndef NO_MAKEFILE_RULE
 GLOBAL_DEPS += Makefile.in
 endif
 
 ##############################################
+compile:: $(OBJS) $(HOST_OBJS)
+
 include $(topsrcdir)/config/makefiles/target_libs.mk
 
 ##############################################
 ifndef NO_PROFILE_GUIDED_OPTIMIZE
 ifdef MOZ_PROFILE_USE
 ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
 # When building with PGO, we have to make sure to re-link
 # in the MOZ_PROFILE_USE phase if we linked in the
--- a/content/base/public/nsIObjectLoadingContent.idl
+++ b/content/base/public/nsIObjectLoadingContent.idl
@@ -9,17 +9,17 @@ interface nsIRequest;
 interface nsIFrame;
 interface nsIObjectFrame;
 interface nsIPluginTag;
 interface nsIDOMElement;
 interface nsIDOMClientRect;
 interface nsIURI;
 
 %{C++
-#include "nsNPAPIPluginInstance.h"
+class nsNPAPIPluginInstance;
 %}
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 /**
  * This interface represents a content node that loads objects.
  *
  * Please make sure to update the MozObjectLoadingContent WebIDL
  * interface to mirror this interface when changing it.
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -20,16 +20,18 @@
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/OldDebugAPI.h"
 #include "js/Value.h"
 #include "Layers.h"
 #include "MediaDecoder.h"
+// nsNPAPIPluginInstance must be included before nsIDocument.h, which is included in mozAutoDocUpdate.h.
+#include "nsNPAPIPluginInstance.h"
 #include "mozAutoDocUpdate.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/Base64.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLMediaElement.h"
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1426,16 +1426,19 @@ nsDocument::~nsDocument()
     nsCOMPtr<nsIURI> uri;
     principal->GetURI(getter_AddRefs(uri));
     bool isAboutScheme = true;
     if (uri) {
       uri->SchemeIs("about", &isAboutScheme);
     }
 
     if (!isAboutScheme) {
+      // Record the page load
+      uint32_t pageLoaded = 1;
+      Accumulate(Telemetry::MIXED_CONTENT_UNBLOCK_COUNTER, pageLoaded);
       // Record the mixed content status of the docshell in Telemetry
       enum {
         NO_MIXED_CONTENT = 0, // There is no Mixed Content on the page
         MIXED_DISPLAY_CONTENT = 1, // The page attempted to load Mixed Display Content
         MIXED_ACTIVE_CONTENT = 2, // The page attempted to load Mixed Active Content
         MIXED_DISPLAY_AND_ACTIVE_CONTENT = 3 // The page attempted to load Mixed Display & Mixed Active Content
       };
 
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -20,16 +20,17 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIExternalProtocolHandler.h"
 #include "nsEventStates.h"
 #include "nsIObjectFrame.h"
 #include "nsIPermissionManager.h"
 #include "nsPluginHost.h"
+#include "nsPluginInstanceOwner.h"
 #include "nsJSNPRuntime.h"
 #include "nsIPresShell.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsScriptSecurityManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIStreamConverterService.h"
 #include "nsIURILoader.h"
 #include "nsIURL.h"
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -14,27 +14,27 @@
 #define NSOBJECTLOADINGCONTENT_H_
 
 #include "mozilla/Attributes.h"
 #include "nsImageLoadingContent.h"
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsIRunnable.h"
-#include "nsPluginInstanceOwner.h"
 #include "nsIThreadInternal.h"
 #include "nsIFrame.h"
 #include "nsIFrameLoader.h"
 
 class nsAsyncInstantiateEvent;
 class nsStopPluginRunnable;
 class AutoSetInstantiatingToFalse;
 class nsObjectFrame;
 class nsFrameLoader;
 class nsXULElement;
+class nsPluginInstanceOwner;
 
 class nsObjectLoadingContent : public nsImageLoadingContent
                              , public nsIStreamListener
                              , public nsIFrameLoaderOwner
                              , public nsIObjectLoadingContent
                              , public nsIChannelEventSink
 {
   friend class AutoSetInstantiatingToFalse;
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -12,17 +12,16 @@
 #include "nsISupportsUtils.h"
 #include "nsString.h"
 #include "nsIURI.h"
 #include "nsIHttpChannel.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIStreamListener.h"
 #include "nsWeakReference.h"
-#include "jsapi.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsIProgressEventSink.h"
 #include "nsJSUtils.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -172,22 +172,18 @@ nsDOMEventTargetHelper::AddEventListener
                                          uint8_t aOptionalArgc)
 {
   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
                "Won't check if this is chrome, you want to set "
                "aWantsUntrusted to false or make the aWantsUntrusted "
                "explicit by making aOptionalArgc non-zero.");
 
   if (aOptionalArgc < 2) {
-    nsresult rv;
-    nsIScriptContext* context = GetContextForEventHandlers(&rv);
+    nsresult rv = WantsUntrusted(&aWantsUntrusted);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIDocument> doc =
-      nsContentUtils::GetDocumentFromScriptContext(context);
-    aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
   }
 
   nsEventListenerManager* elm = GetListenerManager(true);
   NS_ENSURE_STATE(elm);
   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
@@ -195,25 +191,21 @@ void
 nsDOMEventTargetHelper::AddEventListener(const nsAString& aType,
                                          nsIDOMEventListener* aListener,
                                          bool aUseCapture,
                                          const Nullable<bool>& aWantsUntrusted,
                                          ErrorResult& aRv)
 {
   bool wantsUntrusted;
   if (aWantsUntrusted.IsNull()) {
-    nsresult rv;
-    nsIScriptContext* context = GetContextForEventHandlers(&rv);
+    nsresult rv = WantsUntrusted(&wantsUntrusted);
     if (NS_FAILED(rv)) {
       aRv.Throw(rv);
       return;
     }
-    nsCOMPtr<nsIDocument> doc =
-      nsContentUtils::GetDocumentFromScriptContext(context);
-    wantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
   } else {
     wantsUntrusted = aWantsUntrusted.Value();
   }
 
   nsEventListenerManager* elm = GetListenerManager(true);
   if (!elm) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return;
@@ -229,22 +221,18 @@ nsDOMEventTargetHelper::AddSystemEventLi
                                                uint8_t aOptionalArgc)
 {
   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
                "Won't check if this is chrome, you want to set "
                "aWantsUntrusted to false or make the aWantsUntrusted "
                "explicit by making aOptionalArgc non-zero.");
 
   if (aOptionalArgc < 2) {
-    nsresult rv;
-    nsIScriptContext* context = GetContextForEventHandlers(&rv);
+    nsresult rv = WantsUntrusted(&aWantsUntrusted);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIDocument> doc =
-      nsContentUtils::GetDocumentFromScriptContext(context);
-    aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
   }
 
   return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
                                    aWantsUntrusted);
 }
 
 NS_IMETHODIMP
 nsDOMEventTargetHelper::DispatchEvent(nsIDOMEvent* aEvent, bool* aRetVal)
@@ -348,8 +336,20 @@ nsDOMEventTargetHelper::GetContextForEve
   if (NS_FAILED(*aRv)) {
     return nullptr;
   }
   nsPIDOMWindow* owner = GetOwner();
   return owner ? static_cast<nsGlobalWindow*>(owner)->GetContextInternal()
                : nullptr;
 }
 
+nsresult
+nsDOMEventTargetHelper::WantsUntrusted(bool* aRetVal)
+{
+  nsresult rv;
+  nsIScriptContext* context = GetContextForEventHandlers(&rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIDocument> doc =
+    nsContentUtils::GetDocumentFromScriptContext(context);
+  // We can let listeners on workers to always handle all the events.
+  *aRetVal = (doc && !nsContentUtils::IsChromeDoc(doc)) || !NS_IsMainThread();
+  return rv;
+}
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -115,16 +115,18 @@ public:
   nsPIDOMWindow* GetOwner() const { return mOwnerWindow; }
   void BindToOwner(nsIGlobalObject* aOwner);
   void BindToOwner(nsPIDOMWindow* aOwner);
   void BindToOwner(nsDOMEventTargetHelper* aOther);
   virtual void DisconnectFromOwner();                   
   nsIGlobalObject* GetParentObject() const { return mParentObject; }
   bool HasOrHasHadOwner() { return mHasOrHasHadOwnerWindow; }
 protected:
+  nsresult WantsUntrusted(bool* aRetVal);
+
   nsRefPtr<nsEventListenerManager> mListenerManager;
   // Dispatch a trusted, non-cancellable and non-bubbling event to |this|.
   nsresult DispatchTrustedEvent(const nsAString& aEventName);
   // Make |event| trusted and dispatch |aEvent| to |this|.
   nsresult DispatchTrustedEvent(nsIDOMEvent* aEvent);
 
   virtual void LastRelease() {}
 private:
--- a/content/media/AudioAvailableEventManager.cpp
+++ b/content/media/AudioAvailableEventManager.cpp
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsTArray.h"
 #include "AudioAvailableEventManager.h"
 #include "VideoUtils.h"
-
+#include "MediaDecoder.h"
+#include "nsIRunnable.h"
 
 namespace mozilla {
 
 static const nsTArray< nsCOMPtr<nsIRunnable> >::size_type MAX_PENDING_EVENTS = 100;
 
 class nsAudioAvailableEventRunner : public nsRunnable
 {
 private:
--- a/content/media/AudioAvailableEventManager.h
+++ b/content/media/AudioAvailableEventManager.h
@@ -2,23 +2,28 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AudioAvailableEventManager_h__
 #define AudioAvailableEventManager_h__
 
-#include "nsCOMPtr.h"
-#include "nsIRunnable.h"
-#include "MediaDecoder.h"
-#include "MediaDecoderReader.h"
+#include "nsAutoPtr.h"
+#include "nsTArray.h"
+#include "AudioSampleFormat.h"
+#include "mozilla/ReentrantMonitor.h"
+
+class nsIRunnable;
+template <class T> class nsCOMPtr;
 
 namespace mozilla {
 
+class MediaDecoder;
+
 class AudioAvailableEventManager
 {
 public:
   AudioAvailableEventManager(MediaDecoder* aDecoder);
   ~AudioAvailableEventManager();
 
   // Initialize the event manager with audio metadata.  Called before
   // audio begins to get queued or events are dispatched.
--- a/content/media/AudioChannelFormat.cpp
+++ b/content/media/AudioChannelFormat.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AudioChannelFormat.h"
+#include "nsTArray.h"
 
 #include <algorithm>
 
 namespace mozilla {
 
 enum {
   SURROUND_L,
   SURROUND_R,
--- a/content/media/AudioChannelFormat.h
+++ b/content/media/AudioChannelFormat.h
@@ -1,17 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef MOZILLA_AUDIOCHANNELFORMAT_H_
 #define MOZILLA_AUDIOCHANNELFORMAT_H_
 
-#include "nsTArray.h"
+#include <stdint.h>
+
+template <class T>
+class nsTArray;
 
 namespace mozilla {
 
 /*
  * This file provides utilities for upmixing and downmixing channels.
  *
  * The channel layouts, upmixing and downmixing are consistent with the
  * Web Audio spec.
--- a/content/media/AudioNodeEngine.cpp
+++ b/content/media/AudioNodeEngine.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/arm.h"
 #include "AudioNodeEngine.h"
 #ifdef BUILD_ARM_NEON
+#include "mozilla/arm.h"
 #include "AudioNodeEngineNEON.h"
 #endif
 
 namespace mozilla {
 
 void
 AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk)
 {
--- a/content/media/AudioNodeEngine.h
+++ b/content/media/AudioNodeEngine.h
@@ -3,23 +3,23 @@
 /* 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_AUDIONODEENGINE_H_
 #define MOZILLA_AUDIONODEENGINE_H_
 
 #include "AudioSegment.h"
 #include "mozilla/dom/AudioNode.h"
-#include "mozilla/dom/AudioParam.h"
 #include "mozilla/Mutex.h"
 
 namespace mozilla {
 
 namespace dom {
 struct ThreeDPoint;
+class AudioParamTimeline;
 }
 
 class AudioNodeStream;
 
 /**
  * This class holds onto a set of immutable channel buffers. The storage
  * for the buffers must be malloced, but the buffer pointers and the malloc
  * pointers can be different (e.g. if the buffers are contained inside
--- a/content/media/AudioNodeExternalInputStream.cpp
+++ b/content/media/AudioNodeExternalInputStream.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "MediaStreamGraphImpl.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeExternalInputStream.h"
+#include "AudioChannelFormat.h"
 #include "speex/speex_resampler.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 AudioNodeExternalInputStream::AudioNodeExternalInputStream(AudioNodeEngine* aEngine, TrackRate aSampleRate)
   : AudioNodeStream(aEngine, MediaStreamGraph::INTERNAL_STREAM, aSampleRate)
--- a/content/media/AudioNodeExternalInputStream.h
+++ b/content/media/AudioNodeExternalInputStream.h
@@ -2,21 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_AUDIONODEEXTERNALINPUTSTREAM_H_
 #define MOZILLA_AUDIONODEEXTERNALINPUTSTREAM_H_
 
 #include "MediaStreamGraph.h"
-#include "AudioChannelFormat.h"
-#include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
-#include "mozilla/dom/AudioParam.h"
-#include <deque>
 
 #ifdef PR_LOGGING
 #define LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
 #else
 #define LOG(type, msg)
 #endif
 
 // Forward declaration for mResamplerMap
--- a/content/media/AudioNodeStream.cpp
+++ b/content/media/AudioNodeStream.cpp
@@ -3,16 +3,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AudioNodeStream.h"
 
 #include "MediaStreamGraphImpl.h"
 #include "AudioNodeEngine.h"
 #include "ThreeDPoint.h"
+#include "AudioChannelFormat.h"
+#include "AudioParamTimeline.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 /**
  * An AudioNodeStream produces a single audio track with ID
  * AUDIO_NODE_STREAM_TRACK_ID. This track has rate AudioContext::sIdealAudioRate
--- a/content/media/AudioNodeStream.h
+++ b/content/media/AudioNodeStream.h
@@ -2,35 +2,34 @@
 /* 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_AUDIONODESTREAM_H_
 #define MOZILLA_AUDIONODESTREAM_H_
 
 #include "MediaStreamGraph.h"
-#include "AudioChannelFormat.h"
-#include "AudioNodeEngine.h"
 #include "mozilla/dom/AudioNodeBinding.h"
-#include "mozilla/dom/AudioParam.h"
+#include "AudioSegment.h"
 
 #ifdef PR_LOGGING
 #define LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
 #else
 #define LOG(type, msg)
 #endif
 
 namespace mozilla {
 
 namespace dom {
 struct ThreeDPoint;
 class AudioParamTimeline;
 }
 
 class ThreadSharedFloatArrayBufferList;
+class AudioNodeEngine;
 
 /**
  * An AudioNodeStream produces one audio track with ID AUDIO_TRACK.
  * The start time of the AudioTrack is aligned to the start time of the
  * AudioContext's destination node stream, plus some multiple of BLOCK_SIZE
  * samples.
  *
  * An AudioNodeStream has an AudioNodeEngine plugged into it that does the
--- a/content/media/AudioSegment.h
+++ b/content/media/AudioSegment.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_AUDIOSEGMENT_H_
 #define MOZILLA_AUDIOSEGMENT_H_
 
 #include "MediaSegment.h"
-#include "nsISupportsImpl.h"
 #include "AudioSampleFormat.h"
 #include "SharedBuffer.h"
 
 namespace mozilla {
 
 class AudioStream;
 
 /**
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -3,22 +3,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/. */
 #include <stdio.h>
 #include <math.h>
 #include "prlog.h"
 #include "prdtoa.h"
 #include "AudioStream.h"
-#include "nsAlgorithm.h"
 #include "VideoUtils.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Mutex.h"
 #include <algorithm>
 #include "mozilla/Preferences.h"
+#include "soundtouch/SoundTouch.h"
 
 #if defined(MOZ_CUBEB)
 #include "nsAutoRef.h"
 #include "cubeb/cubeb.h"
 
 template <>
 class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
 {
--- a/content/media/AudioStream.h
+++ b/content/media/AudioStream.h
@@ -1,22 +1,24 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(AudioStream_h_)
 #define AudioStream_h_
 
-#include "nscore.h"
 #include "AudioSampleFormat.h"
 #include "AudioChannelCommon.h"
-#include "soundtouch/SoundTouch.h"
 #include "nsAutoPtr.h"
 
+namespace soundtouch {
+class SoundTouch;
+}
+
 namespace mozilla {
 
 class AudioStream;
 
 class AudioClock
 {
   public:
     AudioClock(mozilla::AudioStream* aStream);
--- a/content/media/AudioStreamTrack.h
+++ b/content/media/AudioStreamTrack.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AUDIOSTREAMTRACK_H_
 #define AUDIOSTREAMTRACK_H_
 
 #include "MediaStreamTrack.h"
+#include "DOMMediaStream.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioStreamTrack : public MediaStreamTrack {
 public:
   AudioStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
     : MediaStreamTrack(aStream, aTrackID) {}
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DOMMediaStream.h"
-#include "nsDOMClassInfoID.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/MediaStreamBinding.h"
 #include "mozilla/dom/LocalMediaStreamBinding.h"
 #include "mozilla/dom/AudioNode.h"
 #include "MediaStreamGraph.h"
 #include "AudioStreamTrack.h"
 #include "VideoStreamTrack.h"
 
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -3,23 +3,22 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NSDOMMEDIASTREAM_H_
 #define NSDOMMEDIASTREAM_H_
 
 #include "nsIDOMMediaStream.h"
 #include "nsCycleCollectionParticipant.h"
-#include "nsIPrincipal.h"
 #include "nsWrapperCache.h"
+#include "StreamBuffer.h"
 #include "nsIDOMWindow.h"
-#include "StreamBuffer.h"
-#include "nsIRunnable.h"
 
 class nsXPCClassInfo;
+class nsIPrincipal;
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
 // currentTime getter.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 // X11 has a #define for CurrentTime. Unbelievable :-(.
--- a/content/media/DecoderTraits.h
+++ b/content/media/DecoderTraits.h
@@ -3,17 +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/. */
 
 #ifndef DecoderTraits_h_
 #define DecoderTraits_h_
 
 #include "nsCOMPtr.h"
-#include "nsAString.h"
+
+class nsAString;
+class nsACString;
 
 namespace mozilla {
 
 class AbstractMediaDecoder;
 class MediaDecoder;
 class MediaDecoderOwner;
 class MediaDecoderReader;
 
--- a/content/media/EncodedBufferCache.cpp
+++ b/content/media/EncodedBufferCache.cpp
@@ -1,17 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "EncodedBufferCache.h"
 #include "nsAnonymousTemporaryFile.h"
-#include "nsLocalFile.h"
+#include "nsDOMFile.h"
+#include "prio.h"
 
 namespace mozilla {
 
 void
 EncodedBufferCache::AppendBuffer(nsTArray<uint8_t> & aBuf)
 {
   MutexAutoLock lock(mMutex);
   mDataSize += aBuf.Length();
--- a/content/media/EncodedBufferCache.h
+++ b/content/media/EncodedBufferCache.h
@@ -2,20 +2,22 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef EncodedBufferCache_h_
 #define EncodedBufferCache_h_
 
+#include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "mozilla/Mutex.h"
-#include "prio.h"
-#include "nsDOMFile.h"
+
+struct PRFileDesc;
+class nsIDOMBlob;
 
 namespace mozilla {
 
 class ReentrantMonitor;
 /**
  * Data is moved into a temporary file when it grows beyond
  * the maximal size passed in the Init function.
  * The AppendBuffer and ExtractBlob methods are thread-safe and can be called on
--- a/content/media/FileBlockCache.cpp
+++ b/content/media/FileBlockCache.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/XPCOM.h"
 #include "FileBlockCache.h"
 #include "VideoUtils.h"
+#include "prio.h"
 #include <algorithm>
 
 namespace mozilla {
 
 nsresult FileBlockCache::Open(PRFileDesc* aFD)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
   NS_ENSURE_TRUE(aFD != nullptr, NS_ERROR_FAILURE);
--- a/content/media/FileBlockCache.h
+++ b/content/media/FileBlockCache.h
@@ -4,20 +4,22 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef FILE_BLOCK_CACHE_H_
 #define FILE_BLOCK_CACHE_H_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Monitor.h"
-#include "prio.h"
 #include "nsTArray.h"
 #include "MediaCache.h"
 #include "nsDeque.h"
+#include "nsThreadUtils.h"
+
+struct PRFileDesc;
 
 namespace mozilla {
 
 // Manages file I/O for the media cache. Data comes in over the network
 // via callbacks on the main thread, however we don't want to write the
 // incoming data to the media cache on the main thread, as this could block
 // causing UI jank. 
 //
--- a/content/media/MediaCache.cpp
+++ b/content/media/MediaCache.cpp
@@ -1,29 +1,30 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ReentrantMonitor.h"
-#include "mozilla/XPCOM.h"
 
 #include "MediaCache.h"
-#include "nsNetUtil.h"
 #include "prio.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "MediaResource.h"
-#include "nsMathUtils.h"
 #include "prlog.h"
 #include "mozilla/Preferences.h"
 #include "FileBlockCache.h"
+#include "nsAnonymousTemporaryFile.h"
+#include "nsIObserverService.h"
+#include "nsISeekableStream.h"
+#include "nsIPrincipal.h"
 #include "mozilla/Attributes.h"
-#include "nsAnonymousTemporaryFile.h"
+#include "mozilla/Services.h"
 #include <algorithm>
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMediaCacheLog;
 #define LOG(type, msg) PR_LOG(gMediaCacheLog, type, msg)
 #else
@@ -359,16 +360,36 @@ MediaCacheFlusher::Observe(nsISupports *
     MediaCache::Flush();
   }
   if (strcmp(aTopic, "network-clear-cache-stored-anywhere") == 0) {
     MediaCache::Flush();
   }
   return NS_OK;
 }
 
+MediaCacheStream::MediaCacheStream(ChannelMediaResource* aClient)
+  : mClient(aClient),
+    mInitialized(false),
+    mHasHadUpdate(false),
+    mClosed(false),
+    mDidNotifyDataEnded(false),
+    mResourceID(0),
+    mIsTransportSeekable(false),
+    mCacheSuspended(false),
+    mChannelEnded(false),
+    mChannelOffset(0),
+    mStreamLength(-1),
+    mStreamOffset(0),
+    mPlaybackBytesPerSecond(10000),
+    mPinCount(0),
+    mCurrentMode(MODE_PLAYBACK),
+    mMetadataInPartialBlockBuffer(false)
+{
+}
+
 void MediaCacheStream::BlockList::AddFirstBlock(int32_t aBlock)
 {
   NS_ASSERTION(!mEntries.GetEntry(aBlock), "Block already in list");
   Entry* entry = mEntries.PutEntry(aBlock);
 
   if (mFirstBlock < 0) {
     entry->mNextBlock = entry->mPrevBlock = aBlock;
   } else {
--- a/content/media/MediaCache.h
+++ b/content/media/MediaCache.h
@@ -3,18 +3,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MediaCache_h_
 #define MediaCache_h_
 
 #include "nsTArray.h"
-#include "nsIPrincipal.h"
 #include "nsCOMPtr.h"
+#include "nsHashKeys.h"
+#include "nsTHashtable.h"
+
+class nsIPrincipal;
 
 namespace mozilla {
 // defined in MediaResource.h
 class ChannelMediaResource;
 class MediaByteRange;
 class MediaResource;
 class ReentrantMonitorAutoEnter;
 
@@ -186,27 +189,17 @@ public:
   };
   enum ReadMode {
     MODE_METADATA,
     MODE_PLAYBACK
   };
 
   // aClient provides the underlying transport that cache will use to read
   // data for this stream.
-  MediaCacheStream(ChannelMediaResource* aClient)
-    : mClient(aClient), mInitialized(false),
-      mHasHadUpdate(false),
-      mClosed(false),
-      mDidNotifyDataEnded(false), mResourceID(0),
-      mIsTransportSeekable(false), mCacheSuspended(false),
-      mChannelEnded(false),
-      mChannelOffset(0), mStreamLength(-1),  
-      mStreamOffset(0), mPlaybackBytesPerSecond(10000),
-      mPinCount(0), mCurrentMode(MODE_PLAYBACK),
-      mMetadataInPartialBlockBuffer(false) {}
+  MediaCacheStream(ChannelMediaResource* aClient);
   ~MediaCacheStream();
 
   // Set up this stream with the cache. Can fail on OOM. One
   // of InitAsClone or Init must be called before any other method on
   // this class. Does nothing if already initialized.
   nsresult Init();
 
   // Set up this stream with the cache, assuming it's for the same data
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -3,30 +3,29 @@
 /* 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 "MediaDecoder.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 #include <limits>
-#include "nsNetUtil.h"
-#include "AudioStream.h"
-#include "mozilla/dom/HTMLVideoElement.h"
 #include "nsIObserver.h"
-#include "nsIObserverService.h"
 #include "nsTArray.h"
 #include "VideoUtils.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsContentUtils.h"
 #include "ImageContainer.h"
 #include "MediaResource.h"
 #include "nsError.h"
 #include "mozilla/Preferences.h"
+#include "nsIMemoryReporter.h"
+#include "nsComponentManagerUtils.h"
+#include "nsITimer.h"
 #include <algorithm>
 
 #ifdef MOZ_WMF
 #include "WMFDecoder.h"
 #endif
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -175,29 +175,22 @@ The owning object of a MediaDecoder obje
 destroying the MediaDecoder object.
 
 */
 #if !defined(MediaDecoder_h_)
 #define MediaDecoder_h_
 
 #include "nsISupports.h"
 #include "nsCOMPtr.h"
-#include "nsIThread.h"
-#include "nsIChannel.h"
 #include "nsIObserver.h"
 #include "nsAutoPtr.h"
-#include "nsSize.h"
-#include "prlog.h"
-#include "gfxContext.h"
-#include "gfxRect.h"
 #include "MediaResource.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/TimeStamp.h"
 #include "MediaStreamGraph.h"
-#include "MediaDecoderOwner.h"
 #include "AudioChannelCommon.h"
 #include "AbstractMediaDecoder.h"
 
 class nsIStreamListener;
 class nsIMemoryReporter;
 class nsIPrincipal;
 class nsITimer;
 
@@ -209,19 +202,17 @@ class TimeRanges;
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 namespace layers {
 class Image;
 } //namespace layers
 
-class MediaByteRange;
 class VideoFrameContainer;
-class AudioStream;
 class MediaDecoderStateMachine;
 class MediaDecoderOwner;
 
 // The size to use for audio data frames in MozAudioAvailable events.
 // This value is per channel, and is chosen to give ~43 fps of events,
 // for example, 44100 with 2 channels, 2*1024 = 2048.
 static const uint32_t FRAMEBUFFER_LENGTH_PER_CHANNEL = 1024;
 
--- a/content/media/MediaDecoderReader.cpp
+++ b/content/media/MediaDecoderReader.cpp
@@ -1,18 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "MediaDecoderReader.h"
+#ifdef MOZ_OMX_DECODER
 #include "GrallocImages.h"
-#include "MediaDecoderReader.h"
+#endif
 #include "AbstractMediaDecoder.h"
-#include "MediaDecoderStateMachine.h"
 #include "VideoUtils.h"
 #include "ImageContainer.h"
 
 #include "mozilla/mozalloc.h"
 #include <stdint.h>
 #include <algorithm>
 
 namespace mozilla {
--- a/content/media/MediaDecoderReader.h
+++ b/content/media/MediaDecoderReader.h
@@ -4,25 +4,33 @@
  * 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/. */
 #if !defined(MediaDecoderReader_h_)
 #define MediaDecoderReader_h_
 
 #include <nsDeque.h>
 #include "nsSize.h"
 #include "mozilla/ReentrantMonitor.h"
-#include "MediaStreamGraph.h"
 #include "SharedBuffer.h"
 #include "AudioSampleFormat.h"
-#include "MediaResource.h"
-#include "mozilla/dom/HTMLMediaElement.h"
+#include "AbstractMediaDecoder.h"
+#include "ImageTypes.h"
+
+struct nsIntRect;
 
 namespace mozilla {
 
-class AbstractMediaDecoder;
+namespace layers {
+class Image;
+class ImageContainer;
+}
+
+namespace dom {
+class TimeRanges;
+}
 
 // Stores info relevant to presenting media frames.
 class VideoInfo {
 public:
   VideoInfo()
     : mAudioRate(44100),
       mAudioChannels(2),
       mDisplay(0,0),
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -6,31 +6,31 @@
 #ifdef XP_WIN
 // Include Windows headers required for enabling high precision timers.
 #include "windows.h"
 #include "mmsystem.h"
 #endif
  
 #include "mozilla/DebugOnly.h"
 #include <stdint.h>
-#include "mozilla/Util.h"
 
 #include "MediaDecoderStateMachine.h"
-#include <limits>
 #include "AudioStream.h"
 #include "nsTArray.h"
 #include "MediaDecoder.h"
 #include "MediaDecoderReader.h"
 #include "mozilla/mozalloc.h"
 #include "VideoUtils.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsDeque.h"
 #include "AudioSegment.h"
 #include "VideoSegment.h"
 #include "ImageContainer.h"
+#include "nsComponentManagerUtils.h"
+#include "nsITimer.h"
 
 #include "prenv.h"
 #include "mozilla/Preferences.h"
 #include <algorithm>
 
 namespace mozilla {
 
 using namespace mozilla::layers;
@@ -721,29 +721,27 @@ void MediaDecoderStateMachine::SendStrea
       (!mInfo.mHasVideo || mReader->VideoQueue().IsFinished());
   if (finished && !stream->mHaveSentFinish) {
     stream->mHaveSentFinish = true;
     stream->mStream->Finish();
   }
 
   if (mAudioCaptured) {
     // Discard audio packets that are no longer needed.
-    int64_t audioPacketTimeToDiscard =
-        std::min(minLastAudioPacketTime, mStartTime + mCurrentFrameTime);
     while (true) {
       nsAutoPtr<AudioData> a(mReader->AudioQueue().PopFront());
       if (!a)
         break;
       // Packet times are not 100% reliable so this may discard packets that
       // actually contain data for mCurrentFrameTime. This means if someone might
       // create a new output stream and we actually don't have the audio for the
       // very start. That's OK, we'll play silence instead for a brief moment.
       // That's OK. Seeking to this time would have a similar issue for such
       // badly muxed resources.
-      if (a->GetEnd() >= audioPacketTimeToDiscard) {
+      if (a->GetEnd() >= minLastAudioPacketTime) {
         mReader->AudioQueue().PushFront(a.forget());
         break;
       }
     }
 
     if (finished) {
       mAudioCompleted = true;
       UpdateReadyState();
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -76,23 +76,26 @@ hardware (via AudioStream).
 #if !defined(MediaDecoderStateMachine_h__)
 #define MediaDecoderStateMachine_h__
 
 #include "mozilla/Attributes.h"
 #include "nsThreadUtils.h"
 #include "MediaDecoder.h"
 #include "AudioAvailableEventManager.h"
 #include "mozilla/ReentrantMonitor.h"
-#include "nsITimer.h"
-#include "AudioSegment.h"
-#include "VideoSegment.h"
+#include "MediaDecoderReader.h"
+#include "MediaDecoderOwner.h"
+#include "MediaMetadataManager.h"
+
+class nsITimer;
 
 namespace mozilla {
 
-class MediaDecoderReader;
+class AudioSegment;
+class VideoSegment;
 
 /*
   The state machine class. This manages the decoding and seeking in the
   MediaDecoderReader on the decode thread, and A/V sync on the shared
   state machine thread, and controls the audio "push" thread.
 
   All internal state is synchronised via the decoder monitor. State changes
   are either propagated by NotifyAll on the monitor (typically when state
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -2,27 +2,25 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaRecorder.h"
 #include "GeneratedEvents.h"
 #include "MediaEncoder.h"
-#include "mozilla/Util.h"
 #include "nsDOMEventTargetHelper.h"
-#include "nsDOMFile.h"
 #include "nsError.h"
 #include "nsIDocument.h"
 #include "nsIDOMBlobEvent.h"
 #include "nsIDOMRecordErrorEvent.h"
-#include "nsIScriptObjectPrincipal.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsAString.h"
 #include "nsTArray.h"
+#include "DOMMediaStream.h"
+#include "EncodedBufferCache.h"
+#include "nsIDOMFile.h"
 
 namespace mozilla {
 
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(MediaRecorder, nsDOMEventTargetHelper,
                                      mStream)
 
@@ -145,17 +143,17 @@ MediaRecorder::MediaRecorder(DOMMediaStr
 
 void
 MediaRecorder::ExtractEncodedData()
 {
   TimeStamp lastBlobTimeStamp = TimeStamp::Now();
   do {
     nsTArray<nsTArray<uint8_t> > outputBufs;
     mEncoder->GetEncodedData(&outputBufs, mMimeType);
-    for (uint i = 0; i < outputBufs.Length(); i++) {
+    for (uint32_t i = 0; i < outputBufs.Length(); i++) {
       mEncodedBufferCache->AppendBuffer(outputBufs[i]);
     }
 
     if (mTimeSlice > 0 && (TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) {
       NS_DispatchToMainThread(new PushBlobTask(this));
       lastBlobTimeStamp = TimeStamp::Now();
     }
   } while (!mEncoder->IsShutdown());
--- a/content/media/MediaRecorder.h
+++ b/content/media/MediaRecorder.h
@@ -2,28 +2,29 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MediaRecorder_h
 #define MediaRecorder_h
 
-#include "DOMMediaStream.h"
-#include "MediaEncoder.h"
 #include "mozilla/dom/MediaRecorderBinding.h"
 #include "nsDOMEventTargetHelper.h"
-#include "EncodedBufferCache.h"
-#include "TrackUnionStream.h"
 
 // Max size for allowing queue encoded data in memory
 #define MAX_ALLOW_MEMORY_BUFFER 1024000
 namespace mozilla {
 
 class ErrorResult;
+class DOMMediaStream;
+class EncodedBufferCache;
+class MediaEncoder;
+class ProcessedMediaStream;
+class MediaInputPort;
 
 namespace dom {
 
 /**
  * Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html
  * The MediaRecorder accepts a mediaStream as input source passed from UA. When recorder starts,
  * a MediaEncoder will be created and accept the mediaStream as input source.
  * Encoder will get the raw data by track data changes, encode it by selected MIME Type, then store the encoded in EncodedBufferCache object.
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -13,25 +13,23 @@
 #include "MediaDecoder.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 #include "nsIFile.h"
 #include "nsIFileChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsISeekableStream.h"
 #include "nsIInputStream.h"
-#include "nsIOutputStream.h"
 #include "nsIRequestObserver.h"
 #include "nsIStreamListener.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "nsError.h"
 #include "nsICachingChannel.h"
-#include "nsURILoader.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsContentUtils.h"
 #include "nsHostObjectProtocolHandler.h"
 #include <algorithm>
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMediaResourceLog;
 #define LOG(msg, ...) PR_LOG(gMediaResourceLog, PR_LOG_DEBUG, \
--- a/content/media/MediaResource.h
+++ b/content/media/MediaResource.h
@@ -2,41 +2,44 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #if !defined(MediaResource_h_)
 #define MediaResource_h_
 
 #include "mozilla/Mutex.h"
-#include "mozilla/XPCOM.h"
+#ifdef MOZ_DASH
 #include "mozilla/ReentrantMonitor.h"
+#endif
 #include "nsIChannel.h"
-#include "nsIHttpChannel.h"
-#include "nsIPrincipal.h"
 #include "nsIURI.h"
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "MediaCache.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/TimeStamp.h"
+#include "nsThreadUtils.h"
 
 // For HTTP seeking, if number of bytes needing to be
 // seeked forward is less than this value then a read is
 // done rather than a byte range request.
 static const int64_t SEEK_VS_READ_THRESHOLD = 32*1024;
 
 static const uint32_t HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE = 416;
 
 // Number of bytes we have accumulated before we assume the connection download
 // rate can be reliably calculated. 57 Segments at IW=3 allows slow start to
 // reach a CWND of 30 (See bug 831998)
 static const int64_t RELIABLE_DATA_THRESHOLD = 57 * 1460;
 
+class nsIHttpChannel;
+class nsIPrincipal;
+
 namespace mozilla {
 
 class MediaDecoder;
 
 /**
  * This class is useful for estimating rates of data passing through
  * some channel. The idea is that activity on the channel "starts"
  * and "stops" over time. At certain times data passes through the
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -8,19 +8,17 @@
 
 #include "AudioSegment.h"
 #include "VideoSegment.h"
 #include "nsContentUtils.h"
 #include "nsIAppShell.h"
 #include "nsIObserver.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWidgetsCID.h"
-#include "nsXPCOMCIDInternal.h"
 #include "prlog.h"
-#include "VideoUtils.h"
 #include "mozilla/Attributes.h"
 #include "TrackUnionStream.h"
 #include "ImageContainer.h"
 #include "AudioChannelCommon.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioNodeExternalInputStream.h"
 #include <algorithm>
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -6,17 +6,16 @@
 #ifndef MOZILLA_MEDIASTREAMGRAPH_H_
 #define MOZILLA_MEDIASTREAMGRAPH_H_
 
 #include "mozilla/Mutex.h"
 #include "mozilla/LinkedList.h"
 #include "AudioStream.h"
 #include "nsTArray.h"
 #include "nsIRunnable.h"
-#include "nsISupportsImpl.h"
 #include "StreamBuffer.h"
 #include "TimeVarying.h"
 #include "VideoFrameContainer.h"
 #include "VideoSegment.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 
--- a/content/media/MediaStreamTrack.cpp
+++ b/content/media/MediaStreamTrack.cpp
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaStreamTrack.h"
 
 #include "DOMMediaStream.h"
 #include "nsIUUIDGenerator.h"
 #include "nsServiceManagerUtils.h"
-#include "MediaStreamGraph.h"
 
 namespace mozilla {
 namespace dom {
 
 MediaStreamTrack::MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
   : mStream(aStream), mTrackID(aTrackID), mEnded(false), mEnabled(true)
 {
   SetIsDOMBinding();
--- a/content/media/MediaStreamTrack.h
+++ b/content/media/MediaStreamTrack.h
@@ -2,21 +2,23 @@
 /* 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 MEDIASTREAMTRACK_H_
 #define MEDIASTREAMTRACK_H_
 
 #include "nsDOMEventTargetHelper.h"
-#include "DOMMediaStream.h"
 #include "nsID.h"
 #include "StreamBuffer.h"
 
 namespace mozilla {
+
+class DOMMediaStream;
+
 namespace dom {
 
 class AudioStreamTrack;
 class VideoStreamTrack;
 
 /**
  * Class representing a track in a DOMMediaStream.
  */
--- a/content/media/StreamBuffer.h
+++ b/content/media/StreamBuffer.h
@@ -1,21 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_STREAMBUFFER_H_
 #define MOZILLA_STREAMBUFFER_H_
 
-#include "mozilla/DebugOnly.h"
-
 #include "MediaSegment.h"
 #include "nsAutoPtr.h"
-#include <algorithm>
 
 namespace mozilla {
 
 /**
  * Media time relative to the start of a StreamBuffer.
  */
 typedef MediaTime StreamTime;
 const StreamTime STREAM_TIME_MAX = MEDIA_TIME_MAX;
--- a/content/media/TextTrack.cpp
+++ b/content/media/TextTrack.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 et tw=78: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/TextTrack.h"
 #include "mozilla/dom/TextTrackBinding.h"
+#include "mozilla/dom/TextTrackCueList.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_3(TextTrack,
                                      nsDOMEventTargetHelper,
                                      mParent,
                                      mCueList,
--- a/content/media/TextTrack.h
+++ b/content/media/TextTrack.h
@@ -3,23 +3,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_TextTrack_h
 #define mozilla_dom_TextTrack_h
 
 #include "mozilla/dom/TextTrackBinding.h"
-#include "mozilla/dom/TextTrackCue.h"
-#include "mozilla/dom/TextTrackCueList.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsString.h"
-#include "nsWrapperCache.h"
 
 namespace mozilla {
 namespace dom {
 
 class TextTrackCue;
 class TextTrackCueList;
 
 class TextTrack MOZ_FINAL : public nsDOMEventTargetHelper
--- a/content/media/TextTrackCue.cpp
+++ b/content/media/TextTrackCue.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLTrackElement.h"
 #include "mozilla/dom/TextTrackCue.h"
-#include "mozilla/dom/ProcessingInstruction.h"
 #include "nsIFrame.h"
-#include "nsTextNode.h"
 #include "nsVideoFrame.h"
 
 // Alternate value for the 'auto' keyword.
 #define WEBVTT_AUTO -1
 
 namespace mozilla {
 namespace dom {
 
--- a/content/media/TextTrackCueList.h
+++ b/content/media/TextTrackCueList.h
@@ -2,17 +2,17 @@
 /* vim:set ts=2 sw=2 et tw=78: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_TextTrackCueList_h
 #define mozilla_dom_TextTrackCueList_h
 
-#include "mozilla/dom/TextTrackCue.h"
+#include "nsTArray.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 
 namespace mozilla {
 namespace dom {
 
 class TextTrackCue;
--- a/content/media/TextTrackList.h
+++ b/content/media/TextTrackList.h
@@ -9,18 +9,16 @@
 
 #include "mozilla/dom/TextTrack.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDOMEventTargetHelper.h"
 
 namespace mozilla {
 namespace dom {
 
-class TextTrack;
-
 class TextTrackList MOZ_FINAL : public nsDOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackList, nsDOMEventTargetHelper)
 
   TextTrackList(nsISupports* aGlobal);
 
--- a/content/media/VideoFrameContainer.h
+++ b/content/media/VideoFrameContainer.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 VIDEOFRAMECONTAINER_H_
 #define VIDEOFRAMECONTAINER_H_
 
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
-#include "nsISupportsImpl.h"
 #include "gfxPoint.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 
 namespace mozilla {
 
 namespace dom {
 class HTMLMediaElement;
--- a/content/media/VideoPlaybackQuality.cpp
+++ b/content/media/VideoPlaybackQuality.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VideoPlaybackQuality.h"
 
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/VideoPlaybackQualityBinding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
-#include "MediaDecoder.h"
 
 namespace mozilla {
 namespace dom {
 
 VideoPlaybackQuality::VideoPlaybackQuality(HTMLMediaElement* aElement,
                                            DOMHighResTimeStamp aCreationTime,
                                            uint64_t aTotalFrames,
                                            uint64_t aDroppedFrames,
--- a/content/media/VideoStreamTrack.h
+++ b/content/media/VideoStreamTrack.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef VIDEOSTREAMTRACK_H_
 #define VIDEOSTREAMTRACK_H_
 
 #include "MediaStreamTrack.h"
+#include "DOMMediaStream.h"
 
 namespace mozilla {
 namespace dom {
 
 class VideoStreamTrack : public MediaStreamTrack {
 public:
   VideoStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
     : MediaStreamTrack(aStream, aTrackID) {}
--- a/content/media/VideoUtils.cpp
+++ b/content/media/VideoUtils.cpp
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VideoUtils.h"
 #include "MediaResource.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsMathUtils.h"
+#include "nsSize.h"
 
 #include <stdint.h>
 
 // Converts from number of audio frames to microseconds, given the specified
 // audio rate.
 CheckedInt64 FramesToUsecs(int64_t aFrames, uint32_t aRate) {
   return (CheckedInt64(aFrames) * USECS_PER_S) / aRate;
 }
--- a/content/media/VideoUtils.h
+++ b/content/media/VideoUtils.h
@@ -6,26 +6,31 @@
 
 #ifndef VideoUtils_h
 #define VideoUtils_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/CheckedInt.h"
 
-#include "nsRect.h"
+#if !(defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) || \
+    defined(MOZ_ASAN)
+// For MEDIA_THREAD_STACK_SIZE
 #include "nsIThreadManager.h"
+#endif
 #include "nsThreadUtils.h"
 #include "prtime.h"
 
 using mozilla::CheckedInt64;
 using mozilla::CheckedUint64;
 using mozilla::CheckedInt32;
 using mozilla::CheckedUint32;
 
+struct nsIntSize;
+
 // This file contains stuff we'd rather put elsewhere, but which is
 // dependent on other changes which we don't want to wait for. We plan to
 // remove this file in the near future.
 
 
 // This belongs in xpcom/monitor/Monitor.h, once we've made
 // mozilla::Monitor non-reentrant.
 namespace mozilla {
--- a/content/media/WebVTTLoadListener.cpp
+++ b/content/media/WebVTTLoadListener.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebVTTLoadListener.h"
 #include "mozilla/dom/TextTrackCue.h"
-#include "nsIAsyncVerifyRedirectCallback.h"
-#include "VideoUtils.h"
+#include "mozilla/dom/HTMLTrackElement.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_1(WebVTTLoadListener, mElement)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebVTTLoadListener)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
--- a/content/media/WebVTTLoadListener.h
+++ b/content/media/WebVTTLoadListener.h
@@ -4,37 +4,38 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_WebVTTLoadListener_h
 #define mozilla_dom_WebVTTLoadListener_h
 
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
-#include "nsIObserver.h"
 #include "nsAutoPtr.h"
 #include "nsAutoRef.h"
 #include "nsCycleCollectionParticipant.h"
-#include "mozilla/dom/HTMLTrackElement.h"
 
 struct webvtt_parser_t;
 struct webvtt_cue;
 typedef int webvtt_error;
 
 template <>
 class nsAutoRefTraits<webvtt_parser_t> : public nsPointerRefTraits<webvtt_parser_t>
 {
 public:
   static void Release(webvtt_parser_t* aParser) {
     // Call parser dtor here.
   }
 };
 
 namespace mozilla {
 namespace dom {
+
+class HTMLTrackElement;
+
 /**
  * Class that manages the libwebvtt parsing library and functions as an
  * interface between Gecko and libwebvtt.
  *
  * Currently it's only designed to work with an HTMLTrackElement. The
  * HTMLTrackElement controls the lifetime of the WebVTTLoadListener.
  *
  * The workflow of this class is as follows:
--- a/content/media/directshow/DirectShowReader.cpp
+++ b/content/media/directshow/DirectShowReader.cpp
@@ -6,16 +6,18 @@
 #include "DirectShowReader.h"
 #include "MediaDecoderReader.h"
 #include "mozilla/RefPtr.h"
 #include "dshow.h"
 #include "AudioSinkFilter.h"
 #include "SourceFilter.h"
 #include "DirectShowUtils.h"
 #include "SampleSink.h"
+#include "MediaResource.h"
+#include "VideoUtils.h"
 
 namespace mozilla {
 
 
 #ifdef PR_LOGGING
 
 PRLogModuleInfo*
 GetDirectShowLog() {
--- a/content/media/encoder/MediaEncoder.cpp
+++ b/content/media/encoder/MediaEncoder.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "MediaEncoder.h"
 #include "MediaDecoder.h"
+#include "nsIPrincipal.h"
 #ifdef MOZ_OGG
 #include "OggWriter.h"
 #endif
 #ifdef MOZ_OPUS
 #include "OpusTrackEncoder.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
--- a/content/media/gstreamer/GStreamerMozVideoBuffer.cpp
+++ b/content/media/gstreamer/GStreamerMozVideoBuffer.cpp
@@ -2,16 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <string.h>
 #include "GStreamerReader.h"
 #include "GStreamerMozVideoBuffer.h"
+#include "ImageContainer.h"
 
 namespace mozilla {
 
 static GstMozVideoBuffer *gst_moz_video_buffer_copy(GstMozVideoBuffer* self);
 static void gst_moz_video_buffer_finalize(GstMozVideoBuffer* self);
 
 G_DEFINE_TYPE(GstMozVideoBuffer, gst_moz_video_buffer, GST_TYPE_BUFFER);
 
--- a/content/media/gstreamer/GStreamerReader.cpp
+++ b/content/media/gstreamer/GStreamerReader.cpp
@@ -139,24 +139,24 @@ nsresult GStreamerReader::Init(MediaDeco
   gst_pad_add_event_probe(sinkpad,
       G_CALLBACK(&GStreamerReader::EventProbeCb), this);
   gst_object_unref(sinkpad);
   gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb);
   gst_pad_set_element_private(sinkpad, this);
 
   mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
-        "appsink name=audiosink max-buffers=2 sync=true caps=audio/x-raw-float,"
+        "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-float,"
 #ifdef IS_LITTLE_ENDIAN
         "channels={1,2},width=32,endianness=1234", TRUE, nullptr);
 #else
         "channels={1,2},width=32,endianness=4321", TRUE, nullptr);
 #endif
 #else
-        "appsink name=audiosink max-buffers=2 sync=true caps=audio/x-raw-int,"
+        "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-int,"
 #ifdef IS_LITTLE_ENDIAN
         "channels={1,2},width=16,endianness=1234", TRUE, nullptr);
 #else
         "channels={1,2},width=16,endianness=4321", TRUE, nullptr);
 #endif
 #endif
   mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink),
                                                    "audiosink"));
--- a/content/media/gstreamer/GStreamerReader.h
+++ b/content/media/gstreamer/GStreamerReader.h
@@ -14,23 +14,28 @@
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
 #pragma GCC diagnostic ignored "-Wpragmas"
 #pragma GCC diagnostic ignored "-Wreserved-user-defined-literal"
 #include <gst/video/video.h>
 #pragma GCC diagnostic pop
 #include <map>
 #include "MediaDecoderReader.h"
+#include "nsRect.h"
 
 namespace mozilla {
 
 namespace dom {
 class TimeRanges;
 }
 
+namespace layers {
+class PlanarYCbCrImage;
+}
+
 class AbstractMediaDecoder;
 
 class GStreamerReader : public MediaDecoderReader
 {
 public:
   GStreamerReader(AbstractMediaDecoder* aDecoder);
   virtual ~GStreamerReader();
 
--- a/content/media/ogg/OggCodecState.cpp
+++ b/content/media/ogg/OggCodecState.cpp
@@ -12,16 +12,28 @@
 #include "nsDebug.h"
 #include "MediaDecoderReader.h"
 #include "OggCodecState.h"
 #include "OggDecoder.h"
 #include "nsTraceRefcnt.h"
 #include "VideoUtils.h"
 #include <algorithm>
 
+// On Android JellyBean, the hardware.h header redefines version_major and
+// version_minor, which breaks our build.  See:
+// https://bugzilla.mozilla.org/show_bug.cgi?id=912702#c6
+#ifdef MOZ_WIDGET_GONK
+#ifdef version_major
+#undef version_major
+#endif
+#ifdef version_minor
+#undef version_minor
+#endif
+#endif
+
 namespace mozilla {
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gMediaDecoderLog;
 #define LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
 #else
 #define LOG(type, msg)
 #endif
--- a/content/media/ogg/OggReader.cpp
+++ b/content/media/ogg/OggReader.cpp
@@ -18,16 +18,17 @@
 extern "C" {
 #include "opus/opus_multistream.h"
 }
 #endif
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/TimeStamp.h"
 #include "VorbisUtils.h"
 #include "MediaMetadataManager.h"
+#include "nsISeekableStream.h"
 
 namespace mozilla {
 
 // On B2G estimate the buffered ranges rather than calculating them explicitly.
 // This prevents us doing I/O on the main thread, which is prohibited in B2G.
 #ifdef MOZ_WIDGET_GONK
 #define OGG_ESTIMATE_BUFFERED 1
 #endif
--- a/content/media/omx/MediaOmxReader.h
+++ b/content/media/omx/MediaOmxReader.h
@@ -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/. */
 #if !defined(MediaOmxReader_h_)
 #define MediaOmxReader_h_
 
 #include "MediaResource.h"
 #include "MediaDecoderReader.h"
+#include "nsRect.h"
 #include <ui/GraphicBuffer.h>
 
 namespace android {
 class OmxDecoder;
 }
 
 namespace mozilla {
 
--- a/content/media/omx/OmxDecoder.cpp
+++ b/content/media/omx/OmxDecoder.cpp
@@ -22,16 +22,17 @@
 #include "nsMimeTypes.h"
 #include "MPAPI.h"
 #include "prlog.h"
 
 #include "GonkNativeWindow.h"
 #include "GonkNativeWindowClient.h"
 #include "OMXCodecProxy.h"
 #include "OmxDecoder.h"
+#include "nsISeekableStream.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo *gOmxDecoderLog;
 #define LOG(type, msg...) PR_LOG(gOmxDecoderLog, type, (msg))
 #else
 #define LOG(x...)
 #endif
 
--- a/content/media/plugins/MediaPluginHost.cpp
+++ b/content/media/plugins/MediaPluginHost.cpp
@@ -9,20 +9,26 @@
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "MediaPluginHost.h"
 #include "nsXPCOMStrings.h"
 #include "nsISeekableStream.h"
 #include "MediaPluginReader.h"
 #include "nsIGfxInfo.h"
 #include "gfxCrashReporterUtils.h"
 #include "prmem.h"
+#include "prlink.h"
 #include "MediaResourceServer.h"
+#include "nsServiceManagerUtils.h"
 
 #include "MPAPI.h"
 
+#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
+#include "nsIPropertyBag2.h"
+#endif
+
 #if defined(ANDROID) || defined(MOZ_WIDGET_GONK)
 #include "android/log.h"
 #define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "MediaPluginHost" , ## args)
 #else
 #define ALOG(args...) /* do nothing */
 #endif
 
 using namespace MPAPI;
--- a/content/media/raw/RawReader.cpp
+++ b/content/media/raw/RawReader.cpp
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaDecoderStateMachine.h"
 #include "AbstractMediaDecoder.h"
 #include "RawReader.h"
 #include "RawDecoder.h"
 #include "VideoUtils.h"
+#include "nsISeekableStream.h"
 
 using namespace mozilla;
 
 RawReader::RawReader(AbstractMediaDecoder* aDecoder)
   : MediaDecoderReader(aDecoder),
     mCurrentFrame(0), mFrameSize(0)
 {
   MOZ_COUNT_CTOR(RawReader);
@@ -271,12 +272,12 @@ nsresult RawReader::Seek(int64_t aTime, 
     } else {
       video.forget();
     }
   }
 
   return NS_OK;
 }
 
-nsresult RawReader::GetBuffered(TimeRanges* aBuffered, int64_t aStartTime)
+nsresult RawReader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
 {
   return NS_OK;
 }
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -124,42 +124,33 @@ MOCHITEST_FILES = \
 		test_media_selection.html \
 		test_playback.html \
 		test_seekLies.html \
 		test_media_sniffer.html \
 		contentType.sjs \
 		test_streams_srcObject.html \
 		test_reset_src.html \
 		test_streams_autoplay.html \
+		test_streams_element_capture.html \
+		test_streams_element_capture_reset.html \
+		test_streams_element_capture_createObjectURL.html \
 		test_streams_gc.html \
 		test_streams_tracks.html \
 		$(filter disabled-for-intermittent-failures--bug-608634, test_error_in_video_document.html) \
 		test_texttrack.html \
 		test_texttrackcue.html \
 		test_timeupdate_small_files.html \
 		test_unseekable.html \
 		test_VideoPlaybackQuality.html \
 		test_VideoPlaybackQuality_disabled.html \
 		test_webvtt_disabled.html \
 		test_playback_rate_playpause.html \
 		test_bug895305.html \
 		$(NULL)
 
-# Disabled on Windows for frequent intermittent failures
-ifneq ($(OS_ARCH), WINNT)
-MOCHITEST_FILES += \
-		test_streams_element_capture.html \
-		test_streams_element_capture_reset.html \
-		test_streams_element_capture_createObjectURL.html \
-		$(NULL)
-else
-$(filter disabled-on-windows-for-timeouts--bug-752796, test_streams_element_capture.html)
-$(filter disabled-on-windows-for-timeouts--bug-752796, test_streams_element_capture_reset.html)
-endif
-
 # Don't run in suite
 ifndef MOZ_SUITE
 MOCHITEST_FILES += test_play_twice.html
 else
 $(filter disabled-pending-investigation--bug-598252, test_play_twice.html)
 endif
 
 # These tests are disabled until we figure out random failures.
--- a/content/media/wave/WaveReader.cpp
+++ b/content/media/wave/WaveReader.cpp
@@ -5,20 +5,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsError.h"
 #include "AbstractMediaDecoder.h"
 #include "MediaResource.h"
 #include "WaveReader.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "MediaDecoderStateMachine.h"
 #include "VideoUtils.h"
+#include "nsISeekableStream.h"
 
 #include <stdint.h>
 #include "mozilla/Util.h"
 #include "mozilla/CheckedInt.h"
+#include "mozilla/Endian.h"
 #include <algorithm>
 
 namespace mozilla {
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
 
 #ifdef PR_LOGGING
@@ -64,51 +66,43 @@ static const uint16_t WAVE_FORMAT_ENCODI
 // We reject files with more than this number of channels if we're decoding for
 // playback.
 static const uint8_t MAX_CHANNELS = 2;
 
 namespace {
   uint32_t
   ReadUint32BE(const char** aBuffer)
   {
-    uint32_t result =
-      uint8_t((*aBuffer)[0]) << 24 |
-      uint8_t((*aBuffer)[1]) << 16 |
-      uint8_t((*aBuffer)[2]) << 8 |
-      uint8_t((*aBuffer)[3]);
+    uint32_t result = BigEndian::readUint32(*aBuffer);
     *aBuffer += sizeof(uint32_t);
     return result;
   }
 
   uint32_t
   ReadUint32LE(const char** aBuffer)
   {
-    uint32_t result =
-      uint8_t((*aBuffer)[3]) << 24 |
-      uint8_t((*aBuffer)[2]) << 16 |
-      uint8_t((*aBuffer)[1]) << 8 |
-      uint8_t((*aBuffer)[0]);
+    uint32_t result = LittleEndian::readUint32(*aBuffer);
     *aBuffer += sizeof(uint32_t);
     return result;
   }
 
   uint16_t
   ReadUint16LE(const char** aBuffer)
   {
-    uint16_t result =
-      uint8_t((*aBuffer)[1]) << 8 |
-      uint8_t((*aBuffer)[0]) << 0;
+    uint16_t result = LittleEndian::readUint16(*aBuffer);
     *aBuffer += sizeof(uint16_t);
     return result;
   }
 
   int16_t
   ReadInt16LE(const char** aBuffer)
   {
-    return static_cast<int16_t>(ReadUint16LE(aBuffer));
+    uint16_t result = LittleEndian::readInt16(*aBuffer);
+    *aBuffer += sizeof(int16_t);
+    return result;
   }
 
   uint8_t
   ReadUint8(const char** aBuffer)
   {
     uint8_t result = uint8_t((*aBuffer)[0]);
     *aBuffer += sizeof(uint8_t);
     return result;
@@ -136,17 +130,17 @@ nsresult WaveReader::ReadMetadata(VideoI
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   bool loaded = LoadRIFFChunk();
   if (!loaded) {
     return NS_ERROR_FAILURE;
   }
 
-  nsAutoPtr<HTMLMediaElement::MetadataTags> tags;
+  nsAutoPtr<dom::HTMLMediaElement::MetadataTags> tags;
 
   bool loadAllChunks = LoadAllChunks(tags);
   if (!loadAllChunks) {
     return NS_ERROR_FAILURE;
   }
 
   mInfo.mHasAudio = true;
   mInfo.mHasVideo = false;
@@ -273,17 +267,17 @@ nsresult WaveReader::Seek(int64_t aTarge
   position += mWavePCMOffset;
   return mDecoder->GetResource()->Seek(nsISeekableStream::NS_SEEK_SET, position);
 }
 
 static double RoundToUsecs(double aSeconds) {
   return floor(aSeconds * USECS_PER_S) / USECS_PER_S;
 }
 
-nsresult WaveReader::GetBuffered(TimeRanges* aBuffered, int64_t aStartTime)
+nsresult WaveReader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
 {
   if (!mInfo.mHasAudio) {
     return NS_OK;
   }
   int64_t startOffset = mDecoder->GetResource()->GetNextCachedData(mWavePCMOffset);
   while (startOffset >= 0) {
     int64_t endOffset = mDecoder->GetResource()->GetCachedDataEnd(startOffset);
     // Bytes [startOffset..endOffset] are cached.
@@ -537,17 +531,17 @@ WaveReader::GetNextChunk(uint32_t* aChun
   *aChunk = ReadUint32BE(&p);
   *aChunkSize = ReadUint32LE(&p);
 
   return true;
 }
 
 bool
 WaveReader::LoadListChunk(uint32_t aChunkSize,
-    nsAutoPtr<HTMLMediaElement::MetadataTags> &aTags)
+                          nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags)
 {
   // List chunks are always word (two byte) aligned.
   NS_ABORT_IF_FALSE(mDecoder->GetResource()->Tell() % 2 == 0,
                     "LoadListChunk called with unaligned resource");
 
   static const unsigned int MAX_CHUNK_SIZE = 1 << 16;
   static_assert(uint64_t(MAX_CHUNK_SIZE) < UINT_MAX / sizeof(char),
                 "MAX_CHUNK_SIZE too large for enumerator.");
@@ -571,17 +565,17 @@ WaveReader::LoadListChunk(uint32_t aChun
     { 0x49415254, NS_LITERAL_CSTRING("artist") },   // IART
     { 0x49434d54, NS_LITERAL_CSTRING("comments") }, // ICMT
     { 0x49474e52, NS_LITERAL_CSTRING("genre") },    // IGNR
     { 0x494e414d, NS_LITERAL_CSTRING("name") },     // INAM
   };
 
   const char* const end = chunk.get() + aChunkSize;
 
-  aTags = new HTMLMediaElement::MetadataTags;
+  aTags = new dom::HTMLMediaElement::MetadataTags;
 
   while (p + 8 < end) {
     uint32_t id = ReadUint32BE(&p);
     // Uppercase tag id, inspired by GStreamer's Wave parser.
     id &= 0xDFDFDFDF;
 
     uint32_t length = ReadUint32LE(&p);
 
@@ -613,17 +607,17 @@ WaveReader::LoadListChunk(uint32_t aChun
       }
     }
   }
 
   return true;
 }
 
 bool
-WaveReader::LoadAllChunks(nsAutoPtr<HTMLMediaElement::MetadataTags> &aTags)
+WaveReader::LoadAllChunks(nsAutoPtr<dom::HTMLMediaElement::MetadataTags> &aTags)
 {
   // Chunks are always word (two byte) aligned.
   NS_ABORT_IF_FALSE(mDecoder->GetResource()->Tell() % 2 == 0,
                     "LoadAllChunks called with unaligned resource");
 
   bool loadFormatChunk = false;
   bool findDataOffset = false;
 
--- a/content/media/wave/WaveReader.h
+++ b/content/media/wave/WaveReader.h
@@ -2,16 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(WaveReader_h_)
 #define WaveReader_h_
 
 #include "MediaDecoderReader.h"
+#include "mozilla/dom/HTMLMediaElement.h"
 
 namespace mozilla {
 namespace dom {
 class TimeRanges;
 }
 }
 
 namespace mozilla {
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AudioBufferSourceNode.h"
 #include "mozilla/dom/AudioBufferSourceNodeBinding.h"
+#include "mozilla/dom/AudioParam.h"
 #include "nsMathUtils.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioDestinationNode.h"
 #include "AudioParamTimeline.h"
 #include "speex/speex_resampler.h"
 #include <limits>
 
--- a/content/media/webaudio/AudioNode.cpp
+++ b/content/media/webaudio/AudioNode.cpp
@@ -2,16 +2,18 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AudioNode.h"
 #include "mozilla/ErrorResult.h"
 #include "AudioNodeStream.h"
+#include "AudioNodeEngine.h"
+#include "mozilla/dom/AudioParam.h"
 
 namespace mozilla {
 namespace dom {
 
 static const uint32_t INVALID_PORT = 0xffffffff;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioNode)
 
--- a/content/media/webm/WebMReader.h
+++ b/content/media/webm/WebMReader.h
@@ -131,17 +131,17 @@ public:
   {
     NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
     return mHasVideo;
   }
 
   virtual nsresult ReadMetadata(VideoInfo* aInfo,
                                 MetadataTags** aTags);
   virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
-  virtual nsresult GetBuffered(TimeRanges* aBuffered, int64_t aStartTime);
+  virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
 
 #ifdef MOZ_DASH
   virtual void SetMainReader(DASHReader *aMainReader) MOZ_OVERRIDE {
     NS_ASSERTION(aMainReader, "aMainReader is null.");
     mMainReader = aMainReader;
   }
 
--- a/content/media/webspeech/recognition/Makefile.in
+++ b/content/media/webspeech/recognition/Makefile.in
@@ -1,14 +1,7 @@
 # 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 $(topsrcdir)/dom/dom-config.mk
-
-VPATH += \
-  $(srcdir)/test \
-  $(NULL)
-
-LOCAL_INCLUDES += $(VPATH:%=-I%)
-
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/content/media/webspeech/recognition/moz.build
+++ b/content/media/webspeech/recognition/moz.build
@@ -22,25 +22,25 @@ EXPORTS.mozilla.dom += [
     'SpeechRecognitionResult.h',
     'SpeechRecognitionResultList.h',
     'SpeechStreamListener.h',
     'test/FakeSpeechRecognitionService.h',
 ]
 
 CPP_SOURCES += [
     'EnableWebSpeechRecognitionCheck.cpp',
-    'FakeSpeechRecognitionService.cpp',
     'SpeechGrammar.cpp',
     'SpeechGrammarList.cpp',
     'SpeechRecognition.cpp',
     'SpeechRecognitionAlternative.cpp',
     'SpeechRecognitionResult.cpp',
     'SpeechRecognitionResultList.cpp',
     'SpeechStreamListener.cpp',
     'endpointer.cc',
     'energy_endpointer.cc',
     'energy_endpointer_params.cc',
+    'test/FakeSpeechRecognitionService.cpp',
 ]
 
 LIBXUL_LIBRARY = True
 
 LIBRARY_NAME = 'gkconwebspeechrecognition_s'
 
--- a/content/media/webspeech/recognition/test/moz.build
+++ b/content/media/webspeech/recognition/test/moz.build
@@ -1,9 +1,4 @@
 # 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/.
-
-CPP_SOURCES += [
-    'FakeSpeechRecognitionService.cpp',
-]
-
--- a/content/media/wmf/WMFByteStream.cpp
+++ b/content/media/wmf/WMFByteStream.cpp
@@ -12,17 +12,20 @@
 #include "WMFByteStream.h"
 #include "WMFSourceReaderCallback.h"
 #include "WMFUtils.h"
 #include "MediaResource.h"
 #include "nsISeekableStream.h"
 #include "mozilla/RefPtr.h"
 #include "nsIThreadPool.h"
 #include "nsXPCOMCIDInternal.h"
+#include "nsComponentManagerUtils.h"
+#include "mozilla/DebugOnly.h"
 #include <algorithm>
+#include <cassert>
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gWMFByteStreamLog = nullptr;
 #define LOG(...) PR_LOG(gWMFByteStreamLog, PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define LOG(...)
--- a/content/media/wmf/WMFReader.h
+++ b/content/media/wmf/WMFReader.h
@@ -4,16 +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/. */
 #if !defined(WMFReader_h_)
 #define WMFReader_h_
 
 #include "WMF.h"
 #include "MediaDecoderReader.h"
 #include "nsAutoPtr.h"
+#include "mozilla/RefPtr.h"
+#include "nsRect.h"
 
 namespace mozilla {
 
 class WMFByteStream;
 class WMFSourceReaderCallback;
 class DXVA2Manager;
 
 namespace dom {
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -7,17 +7,17 @@
 
 #ifndef nsXBLService_h_
 #define nsXBLService_h_
 
 #include "mozilla/LinkedList.h"
 #include "nsString.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
-#include "jsapi.h"              // nsXBLJSClass derives from JSClass
+#include "js/Class.h"           // nsXBLJSClass derives from JSClass
 #include "nsTArray.h"
 
 class nsXBLBinding;
 class nsXBLDocumentInfo;
 class nsXBLJSClass;
 class nsIContent;
 class nsIDocument;
 class nsString;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -758,16 +758,17 @@ nsDocShell::nsDocShell():
     mIsBeingDestroyed(false),
     mIsExecutingOnLoadHandler(false),
     mIsPrintingOrPP(false),
     mSavingOldViewer(false),
 #ifdef DEBUG
     mInEnsureScriptEnv(false),
 #endif
     mAffectPrivateSessionLifetime(true),
+    mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
     mFrameType(eFrameTypeRegular),
     mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
     mParentCharsetSource(0)
 {
     mHistoryID = ++gDocshellIDCounter;
     if (gDocShellCount++ == 0) {
         NS_ASSERTION(sURIFixup == nullptr,
                      "Huh, sURIFixup not null in first nsDocShell ctor!");
@@ -2871,16 +2872,22 @@ nsDocShell::SetDocLoaderParent(nsDocLoad
             SetIsActive(value);
         }
         if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
             value = false;
         }
         SetAllowDNSPrefetch(value);
         value = parentAsDocShell->GetAffectPrivateSessionLifetime();
         SetAffectPrivateSessionLifetime(value);
+        uint32_t flags;
+        if (NS_SUCCEEDED(parentAsDocShell->GetDefaultLoadFlags(&flags)))
+        {
+            SetDefaultLoadFlags(flags);
+        }
+
     }
 
     nsCOMPtr<nsILoadContext> parentAsLoadContext(do_QueryInterface(parent));
     if (parentAsLoadContext &&
         NS_SUCCEEDED(parentAsLoadContext->GetUsePrivateBrowsing(&value)))
     {
         SetPrivateBrowsing(value);
     }
@@ -5364,16 +5371,50 @@ nsDocShell::SetSandboxFlags(uint32_t aSa
 NS_IMETHODIMP
 nsDocShell::GetSandboxFlags(uint32_t  *aSandboxFlags)
 {
     *aSandboxFlags = mSandboxFlags;
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDocShell::SetDefaultLoadFlags(uint32_t aDefaultLoadFlags)
+{
+    mDefaultLoadFlags = aDefaultLoadFlags;
+
+    // Tell the load group to set these flags all requests in the group
+    if (mLoadGroup) {
+        mLoadGroup->SetDefaultLoadFlags(aDefaultLoadFlags);
+    } else {
+        NS_WARNING("nsDocShell::SetDefaultLoadFlags has no loadGroup to propagate the flags to");
+    }
+
+    // Recursively tell all of our children.  We *do not* skip
+    // <iframe mozbrowser> children - if someone sticks custom flags in this
+    // docShell then they too get the same flags.
+    nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
+    while (iter.HasMore()) {
+        nsCOMPtr<nsIDocShell> docshell = do_QueryObject(iter.GetNext());
+        if (!docshell) {
+            continue;
+        }
+        docshell->SetDefaultLoadFlags(aDefaultLoadFlags);
+    }
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetDefaultLoadFlags(uint32_t *aDefaultLoadFlags)
+{
+    *aDefaultLoadFlags = mDefaultLoadFlags;
+    return NS_OK;
+}
+
+
+NS_IMETHODIMP
 nsDocShell::SetMixedContentChannel(nsIChannel* aMixedContentChannel)
 {
 #ifdef DEBUG
      // if the channel is non-null
      if (aMixedContentChannel) {
        // Get the root docshell.
        nsCOMPtr<nsIDocShellTreeItem> root;
        GetSameTypeRootTreeItem(getter_AddRefs(root));
@@ -7786,30 +7827,34 @@ nsDocShell::RestoreFromHistory()
 
         bool allowMedia = childShell->GetAllowMedia();
 
         bool allowDNSPrefetch;
         childShell->GetAllowDNSPrefetch(&allowDNSPrefetch);
 
         bool allowContentRetargeting = childShell->GetAllowContentRetargeting();
 
+        uint32_t defaultLoadFlags;
+        childShell->GetDefaultLoadFlags(&defaultLoadFlags);
+
         // this.AddChild(child) calls child.SetDocLoaderParent(this), meaning
         // that the child inherits our state. Among other things, this means
         // that the child inherits our mIsActive and mInPrivateBrowsing, which
         // is what we want.
         AddChild(childItem);
 
         childShell->SetAllowPlugins(allowPlugins);
         childShell->SetAllowJavascript(allowJavascript);
         childShell->SetAllowMetaRedirects(allowRedirects);
         childShell->SetAllowSubframes(allowSubframes);
         childShell->SetAllowImages(allowImages);
         childShell->SetAllowMedia(allowMedia);
         childShell->SetAllowDNSPrefetch(allowDNSPrefetch);
         childShell->SetAllowContentRetargeting(allowContentRetargeting);
+        childShell->SetDefaultLoadFlags(defaultLoadFlags);
 
         rv = childShell->BeginRestore(nullptr, false);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     nsCOMPtr<nsIPresShell> shell = GetPresShell();
 
     // We may be displayed on a different monitor (or in a different
@@ -9427,17 +9472,17 @@ nsDocShell::DoURILoad(nsIURI * aURI,
 #endif
 
     nsresult rv;
     nsCOMPtr<nsIURILoader> uriLoader;
 
     uriLoader = do_GetService(NS_URI_LOADER_CONTRACTID, &rv);
     if (NS_FAILED(rv)) return rv;
 
-    nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
+    nsLoadFlags loadFlags = mDefaultLoadFlags;
     if (aFirstParty) {
         // tag first party URL loads
         loadFlags |= nsIChannel::LOAD_INITIAL_DOCUMENT_URI;
     }
 
     if (mLoadType == LOAD_ERROR_PAGE) {
         // Error pages are LOAD_BACKGROUND
         loadFlags |= nsIChannel::LOAD_BACKGROUND;
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -836,16 +836,17 @@ protected:
     
     // @see nsIDocShellHistory::createdDynamically
     bool                       mDynamicallyCreated;
 #ifdef DEBUG
     bool                       mInEnsureScriptEnv;
 #endif
     bool                       mAffectPrivateSessionLifetime;
     uint64_t                   mHistoryID;
+    uint32_t                   mDefaultLoadFlags;
 
     static nsIURIFixup *sURIFixup;
 
     nsRefPtr<nsDOMNavigationTiming> mTiming;
 
     // Are we a regular frame, a browser frame, or an app frame?
     FrameType mFrameType;
 
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -37,17 +37,19 @@ interface nsILayoutHistoryState;
 interface nsISecureBrowserUI;
 interface nsIDOMStorage;
 interface nsIPrincipal;
 interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 
-[scriptable, builtinclass, uuid(62f1b40d-1d15-4640-95dc-20caae775bd1)]
+typedef unsigned long nsLoadFlags;
+
+[scriptable, builtinclass, uuid(5f4d82fc-3220-4f7e-9b00-626f1033318a)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -348,16 +350,26 @@ interface nsIDocShell : nsIDocShellTreeI
   readonly attribute unsigned long busyFlags;
 
   /* 
    * attribute to access the loadtype  for the document
    */
   attribute unsigned long  loadType;
 
   /*
+   * Default load flags (as defined in nsIRequest) that will be set on all
+   * requests made by this docShell and propagated to all child docShells and
+   * to nsILoadGroup::defaultLoadFlags for the docShell's loadGroup.
+   * Default is no flags.  Once set, only future requests initiated by the
+   * docShell are affected, so in general, these flags should be set before
+   * the docShell loads any content.
+   */
+  attribute nsLoadFlags defaultLoadFlags;
+
+  /*
    * returns true if the docshell is being destroyed, false otherwise
    */
   boolean isBeingDestroyed();
 
   /*
    * Returns true if the docshell is currently executing the onLoad Handler
    */
   readonly attribute boolean isExecutingOnLoadHandler;
--- a/docshell/test/chrome/Makefile.in
+++ b/docshell/test/chrome/Makefile.in
@@ -84,16 +84,19 @@ MOCHITEST_CHROME_FILES =	\
 		bug690056_window.xul \
 		test_bug311007.xul \
 		bug311007_window.xul \
 		test_principalInherit.xul \
 		test_mozFrameType.xul \
 		mozFrameType_window.xul \
 		test_bug789773.xul \
 		test_private_hidden_window.html \
+		test_bug909218.html \
+		bug909218.html \
+		bug909218.js \
     docshell_helpers.js \
     generic.html \
     test_bug846906.xul \
     bug846906.html \
     test_allowContentRetargeting.html \
     $(NULL)
 
 ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2)
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug909218.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+  <link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css">
+  <script src="bug909218.js"></script>
+</head>
+<body>
+    <img src="http://mochi.test:8888/tests/docshell/test/chrome/red.png">
+    <!-- an iframe so we can check these too get the correct flags -->
+    <iframe src="generic.html"/>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug909218.js
@@ -0,0 +1,2 @@
+// This file exists just to ensure that we load it with the correct flags.
+dump("bug909218.js loaded\n");
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/test_bug909218.html
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(test);
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+// The default flags we will stick on the docShell - every request made by the
+// docShell should include those flags.
+const TEST_FLAGS = Ci.nsIRequest.LOAD_ANONYMOUS |
+                   Ci.nsIRequest.LOAD_BYPASS_CACHE |
+                   Ci.nsIRequest.INHIBIT_CACHING |
+                   Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY;
+
+var TEST_URL = "http://mochi.test:8888/chrome/docshell/test/chrome/bug909218.html";
+
+// These are the requests we expect to see loading TEST_URL into our iframe.
+
+// The test entry-point.  The basic outline is:
+// * Create an iframe and set defaultLoadFlags on its docShell.
+// * Add a web progress listener to observe each request as the iframe is
+//   loaded, and check that each request has the flags we specified.
+// * Load our test URL into the iframe and wait for the load to complete.
+function test() {
+  var iframe = document.createElement("iframe");
+  document.body.appendChild(iframe);
+  var docShell = docshellForWindow(iframe.contentWindow);
+  // Add our progress listener - when it notices the top-level document is
+  // complete, the test will end.
+  RequestWatcher.init(docShell, SimpleTest.finish);
+  // Set the flags we care about, then load our test URL.
+  docShell.defaultLoadFlags = TEST_FLAGS;
+  iframe.setAttribute("src", TEST_URL);
+}
+
+// an nsIWebProgressListener that checks all requests made by the docShell
+// have the flags we expect.
+RequestWatcher = {
+  init: function(docShell, callback) {
+    this.callback = callback;
+    this.docShell = docShell;
+    docShell.
+          QueryInterface(Ci.nsIInterfaceRequestor).
+          getInterface(Ci.nsIWebProgress).
+          addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST |
+                                    Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
+    // These are the requests we expect to see - initialize each to have a
+    // count of zero.
+    this.requestCounts = {};
+    for (var url of [
+        TEST_URL,
+        // content loaded by the above test html.
+        "http://mochi.test:8888/chrome/docshell/test/chrome/bug909218.js",
+        "http://mochi.test:8888/tests/SimpleTest/test.css",
+        "http://mochi.test:8888/tests/docshell/test/chrome/red.png",
+        // the content of an iframe in the test html.
+        "http://mochi.test:8888/chrome/docshell/test/chrome/generic.html"
+      ]) {
+      this.requestCounts[url] = 0;
+    }
+  },
+
+  // Finalize the test after we detect a completed load.  We check we saw the
+  // correct requests and make a callback to exit.
+  finalize: function() {
+    ok(Object.keys(this.requestCounts).length, "we expected some requests");
+    for (var url in this.requestCounts) {
+      var count = this.requestCounts[url];
+      // As we are looking at all request states, we expect more than 1 for
+      // each URL - 0 or 1 would imply something went wrong - >1 just means
+      // multiple states for each request were recorded, which we don't care
+      // about (we do care they all have the correct flags though - but we
+      // do that in onStateChange)
+      ok(count > 1, url + " saw " + count + " requests");
+    }
+    this.docShell.
+          QueryInterface(Ci.nsIInterfaceRequestor).
+          getInterface(Ci.nsIWebProgress).
+          removeProgressListener(this);
+    this.callback();
+  },
+
+  onStateChange: function (webProgress, req, flags, status) {
+    // We are checking requests - if there isn't one, ignore it.
+    if (!req) {
+      return;
+    }
+    // We will usually see requests for 'about:document-onload-blocker' not
+    // have the flag, so we just ignore them.
+    // We also see, eg, resource://gre-resources/loading-image.png, so
+    // skip resource:// URLs too.
+    if (req.name.startsWith("about:") || req.name.startsWith("resource:")) {
+      return;
+    }
+    is(req.loadFlags & TEST_FLAGS, TEST_FLAGS, "request " + req.name + " has the expected flags");
+    this.requestCounts[req.name] += 1;
+    var stopFlags = Ci.nsIWebProgressListener.STATE_STOP |
+                    Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
+    if (req.name == TEST_URL && (flags & stopFlags) == stopFlags) {
+      this.finalize();
+    }
+  },
+  QueryInterface: XPCOMUtils.generateQI([
+    Ci.nsIWebProgressListener,
+    Ci.nsISupportsWeakReference,
+  ])
+}
+
+function docshellForWindow(win) {
+  return win.
+         QueryInterface(Ci.nsIInterfaceRequestor).
+         getInterface(Ci.nsIWebNavigation).
+         QueryInterface(Ci.nsIDocShell);
+}
+
+</script>
+</head>
+</html>
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -7,18 +7,18 @@
 #ifndef nsPluginArray_h___
 #define nsPluginArray_h___
 
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "nsIObserver.h"
 #include "nsWrapperCache.h"
 #include "nsPluginTags.h"
+#include "nsPIDOMWindow.h"
 
-class nsPIDOMWindow;
 class nsPluginElement;
 class nsMimeType;
 
 class nsPluginArray MOZ_FINAL : public nsIObserver,
                                 public nsSupportsWeakReference,
                                 public nsWrapperCache
 {
 public:
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -219,17 +219,17 @@ class Descriptor(DescriptorProvider):
             else:
                 nativeTypeDefault = "mozilla::dom::" + ifaceName
 
         self.nativeType = desc.get('nativeType', nativeTypeDefault)
         self.jsImplParent = desc.get('jsImplParent', self.nativeType)
 
         # Do something sane for JSObject
         if self.nativeType == "JSObject":
-            headerDefault = "jsapi.h"
+            headerDefault = "js/TypeDecls.h"
         elif self.interface.isCallback() or self.interface.isJSImplemented():
             # A copy of CGHeaders.getDeclarationFilename; we can't
             # import it here, sadly.
             # Use our local version of the header, not the exported one, so that
             # test bindings, which don't export, will work correctly.
             basename = os.path.basename(self.interface.filename())
             headerDefault = basename.replace('.webidl', 'Binding.h')
         else:
--- a/dom/plugins/base/PluginPRLibrary.cpp
+++ b/dom/plugins/base/PluginPRLibrary.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=8 et :
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/PluginPRLibrary.h"
+#include "nsNPAPIPluginInstance.h"
 
 // Some plugins on Windows, notably Quake Live, implement NP_Initialize using
 // cdecl instead of the documented stdcall. In order to work around this,
 // we force the caller to use a frame pointer.
 #if defined(XP_WIN) && defined(_M_IX86)
 #include <malloc.h>
 
 // gNotOptimized exists so that the compiler will not optimize the alloca
--- a/dom/plugins/base/nsIPluginInstanceOwner.idl
+++ b/dom/plugins/base/nsIPluginInstanceOwner.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 #include "nspluginroot.idl"
 #include "nsIInputStream.idl"
 
 interface nsIDocument;
 
 %{C++
 #include "npapi.h"
-#include "nsNPAPIPluginInstance.h"
+class nsNPAPIPluginInstance;
 class nsPluginEvent;
 %}
 
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 // Do not make this interface scriptable, because the virtual functions in C++
 // blocks will make script call the wrong functions.
 [uuid(59BE4CA5-3CB0-40E6-A111-9A88C8477610)]
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.h
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.h
@@ -10,24 +10,25 @@
 #include "nsIHTTPHeaderListener.h"
 #include "nsIRequest.h"
 #include "nsITimer.h"
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 #include "nsIOutputStream.h"
 #include "nsIPluginInstanceOwner.h"
 #include "nsString.h"
-#include "nsNPAPIPluginInstance.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "mozilla/PluginLibrary.h"
 
 #define MAX_PLUGIN_NECKO_BUFFER 16384
 
 class nsPluginStreamListenerPeer;
 class nsNPAPIPluginStreamListener;
+class nsNPAPIPluginInstance;
+class nsIChannel;
 
 class nsNPAPIStreamWrapper
 {
 public:
   nsNPAPIStreamWrapper(nsIOutputStream *outputStream,
                        nsNPAPIPluginStreamListener *streamListener);
   ~nsNPAPIStreamWrapper();
 
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -3646,16 +3646,28 @@ protected:
 };
 
 PRCList nsPluginDestroyRunnable::sRunnableListHead =
   PR_INIT_STATIC_CLIST(&nsPluginDestroyRunnable::sRunnableListHead);
 
 PRCList PluginDestructionGuard::sListHead =
   PR_INIT_STATIC_CLIST(&PluginDestructionGuard::sListHead);
 
+PluginDestructionGuard::PluginDestructionGuard(nsNPAPIPluginInstance *aInstance)
+  : mInstance(aInstance)
+{
+  Init();
+}
+
+PluginDestructionGuard::PluginDestructionGuard(NPP npp)
+  : mInstance(npp ? static_cast<nsNPAPIPluginInstance*>(npp->ndata) : nullptr)
+{
+  Init();
+}
+
 PluginDestructionGuard::~PluginDestructionGuard()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
 
   PR_REMOVE_LINK(this);
 
   if (mDelayedDestroy) {
     // We've attempted to destroy the plugin instance we're holding on
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -7,17 +7,16 @@
 #define nsPluginHost_h_
 
 #include "nsIPluginHost.h"
 #include "nsIObserver.h"
 #include "nsCOMPtr.h"
 #include "prlink.h"
 #include "prclist.h"
 #include "npapi.h"
-#include "nsNPAPIPluginInstance.h"
 #include "nsIPluginTag.h"
 #include "nsPluginsDir.h"
 #include "nsPluginDirServiceProvider.h"
 #include "nsAutoPtr.h"
 #include "nsWeakPtr.h"
 #include "nsIPrompt.h"
 #include "nsWeakReference.h"
 #include "nsThreadUtils.h"
@@ -32,16 +31,21 @@
 
 class nsNPAPIPlugin;
 class nsIComponentManager;
 class nsIFile;
 class nsIChannel;
 class nsPluginNativeWindow;
 class nsObjectLoadingContent;
 class nsPluginInstanceOwner;
+class nsNPAPIPluginInstance;
+class nsNPAPIPluginStreamListener;
+class nsIPluginInstanceOwner;
+class nsIInputStream;
+class nsIStreamListener;
 
 class nsInvalidPluginTag : public nsISupports
 {
 public:
   nsInvalidPluginTag(const char* aFullPath, int64_t aLastModifiedTime = 0);
   virtual ~nsInvalidPluginTag();
   
   NS_DECL_ISUPPORTS
@@ -298,27 +302,19 @@ private:
   // We need to hold a global ptr to ourselves because we register for
   // two different CIDs for some reason...
   static nsPluginHost* sInst;
 };
 
 class MOZ_STACK_CLASS PluginDestructionGuard : protected PRCList
 {
 public:
-  PluginDestructionGuard(nsNPAPIPluginInstance *aInstance)
-    : mInstance(aInstance)
-  {
-    Init();
-  }
+  PluginDestructionGuard(nsNPAPIPluginInstance *aInstance);
 
-  PluginDestructionGuard(NPP npp)
-    : mInstance(npp ? static_cast<nsNPAPIPluginInstance*>(npp->ndata) : nullptr)
-  {
-    Init();
-  }
+  PluginDestructionGuard(NPP npp);
 
   ~PluginDestructionGuard();
 
   static bool DelayDestroy(nsNPAPIPluginInstance *aInstance);
 
 protected:
   void Init()
   {
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -7,22 +7,23 @@
 #define nsPluginTags_h_
 
 #include "mozilla/Attributes.h"
 #include "nscore.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIPluginTag.h"
-#include "nsNPAPIPluginInstance.h"
 #include "nsITimer.h"
+#include "nsStringGlue.h"
 
 class nsPluginHost;
 struct PRLibrary;
 struct nsPluginInfo;
+class nsNPAPIPlugin;
 
 // A linked-list of plugin information that is used for instantiating plugins
 // and reflecting plugin information into JavaScript.
 class nsPluginTag : public nsIPluginTag
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGINTAG
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -21,17 +21,16 @@
 #include "gfxSharedImageSurface.h"
 #include "nsNPAPIPluginInstance.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #include "gfxContext.h"
 #include "gfxColor.h"
 #include "gfxUtils.h"
-#include "nsNPAPIPluginInstance.h"
 #include "Layers.h"
 #include "SharedTextureImage.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 #if defined(OS_WIN)
 #include <windowsx.h>
 #include "gfxWindowsPlatform.h"
--- a/gfx/2d/SourceSurfaceCairo.h
+++ b/gfx/2d/SourceSurfaceCairo.h
@@ -1,14 +1,14 @@
 /* -*- 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_OP_SOURCESURFACE_CAIRO_H_
+#ifndef _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H
 #define _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H
 
 #include "2D.h"
 
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetCairo;
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -163,17 +163,17 @@ struct LayerPropertiesBase : public Laye
       }
     }
 
     nsIntRegion visible;
     visible.Xor(mVisibleRegion, mLayer->GetVisibleRegion());
     AddTransformedRegion(result, visible, mTransform);
 
     AddRegion(result, ComputeChangeInternal(aCallback));
-    AddTransformedRegion(result, mLayer->GetInvalidRegion().GetBounds(), mTransform);
+    AddTransformedRegion(result, mLayer->GetInvalidRegion(), mTransform);
 
     if (mMaskLayer && otherMask) {
       AddTransformedRegion(result, mMaskLayer->ComputeChange(aCallback), mTransform);
     }
 
     if (mUseClipRect && otherClip) {
       if (!mClipRect.IsEqualInterior(*otherClip)) {
         nsIntRegion tmp; 
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -5,17 +5,17 @@
 /* I got the format description from http://www.daubnet.com/formats/BMP.html */
 
 /* This is a Cross-Platform BMP Decoder, which should work everywhere, including
  * Big-Endian machines like the PowerPC. */
 
 #include <stdlib.h>
 
 #include "ImageLogging.h"
-#include "EndianMacros.h"
+#include "mozilla/Endian.h"
 #include "nsBMPDecoder.h"
 
 #include "nsIInputStream.h"
 #include "RasterImage.h"
 #include <algorithm>
 
 namespace mozilla {
 namespace image {
@@ -383,19 +383,19 @@ nsBMPDecoder::WriteInternal(const char* 
             toCopy = aCount;
         memcpy(mRawBuf + (mPos - WIN_V3_HEADER_LENGTH), aBuffer, toCopy);
         mPos += toCopy;
         aBuffer += toCopy;
         aCount -= toCopy;
     }
     if (mPos == WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH && 
         mBIH.compression == BI_BITFIELDS) {
-        mBitFields.red = LITTLE_TO_NATIVE32(*(uint32_t*)mRawBuf);
-        mBitFields.green = LITTLE_TO_NATIVE32(*(uint32_t*)(mRawBuf + 4));
-        mBitFields.blue = LITTLE_TO_NATIVE32(*(uint32_t*)(mRawBuf + 8));
+        mBitFields.red = LittleEndian::readUint32(reinterpret_cast<uint32_t*>(mRawBuf));
+        mBitFields.green = LittleEndian::readUint32(reinterpret_cast<uint32_t*>(mRawBuf + 4));
+        mBitFields.blue = LittleEndian::readUint32(reinterpret_cast<uint32_t*>(mRawBuf + 8));
         CalcBitShift();
     }
     while (aCount && (mPos < mBFH.dataoffset)) { // Skip whatever is between header and data
         mPos++; aBuffer++; aCount--;
     }
     if (aCount && ++mPos >= mBFH.dataoffset) {
         // Need to increment mPos, else we might get to mPos==mLOH again
         // From now on, mPos is irrelevant
@@ -443,17 +443,17 @@ nsBMPDecoder::WriteInternal(const char* 
                         while (lpos > 0) {
                           SetPixel(d, *p, mColors);
                           --lpos;
                           ++p;
                         }
                         break;
                       case 16:
                         while (lpos > 0) {
-                          uint16_t val = LITTLE_TO_NATIVE16(*(uint16_t*)p);
+                          uint16_t val = LittleEndian::readUint16(reinterpret_cast<uint16_t*>(p));
                           SetPixel(d,
                                   (val & mBitFields.red) >> mBitFields.redRightShift << mBitFields.redLeftShift,
                                   (val & mBitFields.green) >> mBitFields.greenRightShift << mBitFields.greenLeftShift,
                                   (val & mBitFields.blue) >> mBitFields.blueRightShift << mBitFields.blueLeftShift);
                           --lpos;
                           p+=2;
                         }
                         break;
@@ -693,19 +693,19 @@ void nsBMPDecoder::ProcessFileHeader()
     memset(&mBFH, 0, sizeof(mBFH));
     memcpy(&mBFH.signature, mRawBuf, sizeof(mBFH.signature));
     memcpy(&mBFH.filesize, mRawBuf + 2, sizeof(mBFH.filesize));
     memcpy(&mBFH.reserved, mRawBuf + 6, sizeof(mBFH.reserved));
     memcpy(&mBFH.dataoffset, mRawBuf + 10, sizeof(mBFH.dataoffset));
     memcpy(&mBFH.bihsize, mRawBuf + 14, sizeof(mBFH.bihsize));
 
     // Now correct the endianness of the header
-    mBFH.filesize = LITTLE_TO_NATIVE32(mBFH.filesize);
-    mBFH.dataoffset = LITTLE_TO_NATIVE32(mBFH.dataoffset);
-    mBFH.bihsize = LITTLE_TO_NATIVE32(mBFH.bihsize);
+    mBFH.filesize = LittleEndian::readUint32(&mBFH.filesize);
+    mBFH.dataoffset = LittleEndian::readUint32(&mBFH.dataoffset);
+    mBFH.bihsize = LittleEndian::readUint32(&mBFH.bihsize);
 }
 
 void nsBMPDecoder::ProcessInfoHeader()
 {
     memset(&mBIH, 0, sizeof(mBIH));
     if (mBFH.bihsize == 12) { // OS/2 Bitmap
         memcpy(&mBIH.width, mRawBuf, 2);
         memcpy(&mBIH.height, mRawBuf + 2, 2);
@@ -721,23 +721,23 @@ void nsBMPDecoder::ProcessInfoHeader()
         memcpy(&mBIH.image_size, mRawBuf + 16, sizeof(mBIH.image_size));
         memcpy(&mBIH.xppm, mRawBuf + 20, sizeof(mBIH.xppm));
         memcpy(&mBIH.yppm, mRawBuf + 24, sizeof(mBIH.yppm));
         memcpy(&mBIH.colors, mRawBuf + 28, sizeof(mBIH.colors));
         memcpy(&mBIH.important_colors, mRawBuf + 32, sizeof(mBIH.important_colors));
     }
 
     // Convert endianness
-    mBIH.width = LITTLE_TO_NATIVE32(mBIH.width);
-    mBIH.height = LITTLE_TO_NATIVE32(mBIH.height);
-    mBIH.planes = LITTLE_TO_NATIVE16(mBIH.planes);
-    mBIH.bpp = LITTLE_TO_NATIVE16(mBIH.bpp);
+    mBIH.width = LittleEndian::readUint32(&mBIH.width);
+    mBIH.height = LittleEndian::readUint32(&mBIH.height);
+    mBIH.planes = LittleEndian::readUint16(&mBIH.planes);
+    mBIH.bpp = LittleEndian::readUint16(&mBIH.bpp);
 
-    mBIH.compression = LITTLE_TO_NATIVE32(mBIH.compression);
-    mBIH.image_size = LITTLE_TO_NATIVE32(mBIH.image_size);
-    mBIH.xppm = LITTLE_TO_NATIVE32(mBIH.xppm);
-    mBIH.yppm = LITTLE_TO_NATIVE32(mBIH.yppm);
-    mBIH.colors = LITTLE_TO_NATIVE32(mBIH.colors);
-    mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors);
+    mBIH.compression = LittleEndian::readUint32(&mBIH.compression);
+    mBIH.image_size = LittleEndian::readUint32(&mBIH.image_size);
+    mBIH.xppm = LittleEndian::readUint32(&mBIH.xppm);
+    mBIH.yppm = LittleEndian::readUint32(&mBIH.yppm);
+    mBIH.colors = LittleEndian::readUint32(&mBIH.colors);
+    mBIH.important_colors = LittleEndian::readUint32(&mBIH.important_colors);
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* This is a Cross-Platform ICO Decoder, which should work everywhere, including
  * Big-Endian machines like the PowerPC. */
 
 #include <stdlib.h>
 
-#include "EndianMacros.h"
+#include "mozilla/Endian.h"
 #include "nsICODecoder.h"
 
 #include "RasterImage.h"
 
 namespace mozilla {
 namespace image {
 
 #define ICONCOUNTOFFSET 4
@@ -109,33 +109,33 @@ bool nsICODecoder::FillBitmapFileHeaderB
     }
     dataOffset += 4 * numColors;
     fileSize = dataOffset + GetRealWidth() * GetRealHeight();
   } else {
     fileSize = dataOffset + (mDirEntry.mBitCount * GetRealWidth() * 
                              GetRealHeight()) / 8;
   }
 
-  fileSize = NATIVE32_TO_LITTLE(fileSize);
+  NativeEndian::swapToLittleEndianInPlace(&fileSize, 1);
   memcpy(bfh + 2, &fileSize, sizeof(fileSize));
-  dataOffset = NATIVE32_TO_LITTLE(dataOffset);
+  NativeEndian::swapToLittleEndianInPlace(&dataOffset, 1);
   memcpy(bfh + 10, &dataOffset, sizeof(dataOffset));
   return true;
 }
 
 // A BMP inside of an ICO has *2 height because of the AND mask
 // that follows the actual bitmap.  The BMP shouldn't know about
 // this difference though.
 bool
 nsICODecoder::FixBitmapHeight(int8_t *bih) 
 {
   // Get the height from the BMP file information header
   int32_t height;
   memcpy(&height, bih + 8, sizeof(height));
-  height = LITTLE_TO_NATIVE32(height);
+  NativeEndian::swapFromLittleEndianInPlace(&height, 1);
   // BMPs can be stored inverted by having a negative height
   height = abs(height);
 
   // The bitmap height is by definition * 2 what it should be to account for
   // the 'AND mask'. It is * 2 even if the `AND mask` is not present.
   height /= 2;
 
   if (height > 256) {
@@ -146,30 +146,30 @@ nsICODecoder::FixBitmapHeight(int8_t *bi
   // the ICO height.  So fix the ICO height.
   if (height == 256) {
     mDirEntry.mHeight = 0;
   } else {
     mDirEntry.mHeight = (int8_t)height;
   }
 
   // Fix the BMP height in the BIH so that the BMP decoder can work properly
-  height = NATIVE32_TO_LITTLE(height);
+  NativeEndian::swapToLittleEndianInPlace(&height, 1);
   memcpy(bih + 8, &height, sizeof(height));
   return true;
 }
 
 // We should always trust the contained resource for the width
 // information over our own information.
 bool
 nsICODecoder::FixBitmapWidth(int8_t *bih) 
 {
   // Get the width from the BMP file information header
   int32_t width;
   memcpy(&width, bih + 4, sizeof(width));
-  width = LITTLE_TO_NATIVE32(width);
+  NativeEndian::swapFromLittleEndianInPlace(&width, 1);
   if (width > 256) {
     return false;
   }
 
   // We should always trust the width  from the bitmap itself instead of 
   // the ICO width.
   if (width == 256) {
     mDirEntry.mWidth = 0;
@@ -181,26 +181,26 @@ nsICODecoder::FixBitmapWidth(int8_t *bih
 
 // The BMP information header's bits per pixel should be trusted
 // more than what we have.  Usually the ICO's BPP is set to 0
 int32_t 
 nsICODecoder::ExtractBPPFromBitmap(int8_t *bih)
 {
   int32_t bitsPerPixel;
   memcpy(&bitsPerPixel, bih + 14, sizeof(bitsPerPixel));
-  bitsPerPixel = LITTLE_TO_NATIVE32(bitsPerPixel);
+  NativeEndian::swapFromLittleEndianInPlace(&bitsPerPixel, 1);
   return bitsPerPixel;
 }
 
 int32_t 
 nsICODecoder::ExtractBIHSizeFromBitmap(int8_t *bih)
 {
   int32_t headerSize;
   memcpy(&headerSize, bih, sizeof(headerSize));
-  headerSize = LITTLE_TO_NATIVE32(headerSize);
+  NativeEndian::swapFromLittleEndianInPlace(&headerSize, 1);
   return headerSize;
 }
 
 void
 nsICODecoder::SetHotSpotIfCursor() {
   if (!mIsCursor) {
     return;
   }
@@ -227,17 +227,17 @@ nsICODecoder::WriteInternal(const char* 
         return;
       }
       mIsCursor = (*aBuffer == 2);
     }
     mPos++; aBuffer++; aCount--;
   }
 
   if (mPos == ICONCOUNTOFFSET && aCount >= 2) {
-    mNumIcons = LITTLE_TO_NATIVE16(((uint16_t*)aBuffer)[0]);
+    mNumIcons = LittleEndian::readUint16(reinterpret_cast<const uint16_t*>(aBuffer));
     aBuffer += 2;
     mPos += 2;
     aCount -= 2;
   }
 
   if (mNumIcons == 0)
     return; // Nothing to do.
 
@@ -584,24 +584,24 @@ void
 nsICODecoder::ProcessDirEntry(IconDirEntry& aTarget)
 {
   memset(&aTarget, 0, sizeof(aTarget));
   memcpy(&aTarget.mWidth, mDirEntryArray, sizeof(aTarget.mWidth));
   memcpy(&aTarget.mHeight, mDirEntryArray + 1, sizeof(aTarget.mHeight));
   memcpy(&aTarget.mColorCount, mDirEntryArray + 2, sizeof(aTarget.mColorCount));
   memcpy(&aTarget.mReserved, mDirEntryArray + 3, sizeof(aTarget.mReserved));
   memcpy(&aTarget.mPlanes, mDirEntryArray + 4, sizeof(aTarget.mPlanes));
-  aTarget.mPlanes = LITTLE_TO_NATIVE16(aTarget.mPlanes);
+  aTarget.mPlanes = LittleEndian::readUint16(&aTarget.mPlanes);
   memcpy(&aTarget.mBitCount, mDirEntryArray + 6, sizeof(aTarget.mBitCount));
-  aTarget.mBitCount = LITTLE_TO_NATIVE16(aTarget.mBitCount);
+  aTarget.mBitCount = LittleEndian::readUint16(&aTarget.mBitCount);
   memcpy(&aTarget.mBytesInRes, mDirEntryArray + 8, sizeof(aTarget.mBytesInRes));
-  aTarget.mBytesInRes = LITTLE_TO_NATIVE32(aTarget.mBytesInRes);
+  aTarget.mBytesInRes = LittleEndian::readUint32(&aTarget.mBytesInRes);
   memcpy(&aTarget.mImageOffset, mDirEntryArray + 12, 
          sizeof(aTarget.mImageOffset));
-  aTarget.mImageOffset = LITTLE_TO_NATIVE32(aTarget.mImageOffset);
+  aTarget.mImageOffset = LittleEndian::readUint32(&aTarget.mImageOffset);
 }
 
 bool
 nsICODecoder::NeedsNewFrame() const
 {
   if (mContainedDecoder) {
     return mContainedDecoder->NeedsNewFrame();
   }
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -545,17 +545,17 @@ nsPNGDecoder::info_callback(png_structp 
       }
     else
       png_set_expand(png_ptr);
   }
 
   if (bit_depth == 16)
     png_set_scale_16(png_ptr);
 
-  qcms_data_type inType;
+  qcms_data_type inType = QCMS_DATA_RGBA_8;
   uint32_t intent = -1;
   uint32_t pIntent;
   if (decoder->mCMSMode != eCMSMode_Off) {
     intent = gfxPlatform::GetRenderingIntent();
     decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr,
                                              color_type, &inType, &pIntent);
     /* If we're not mandating an intent, use the one from the image. */
     if (intent == uint32_t(-1))
--- a/image/encoders/bmp/nsBMPEncoder.cpp
+++ b/image/encoders/bmp/nsBMPEncoder.cpp
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCRT.h"
-#include "EndianMacros.h"
+#include "mozilla/Endian.h"
 #include "nsBMPEncoder.h"
 #include "prprf.h"
 #include "nsString.h"
 #include "nsStreamUtils.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 
 using namespace mozilla;
@@ -545,75 +545,68 @@ nsBMPEncoder::InitInfoHeader(Version aVe
       mBMPInfoHeader.gamma_blue = 0;
       mBMPInfoHeader.intent = 0;
       mBMPInfoHeader.profile_offset = 0;
       mBMPInfoHeader.profile_size = 0;
       mBMPInfoHeader.reserved = 0;
   }
 }
 
-template<typename T>
-static inline void
-ConvertToLittle(T& value)
-{
-    value = NATIVE32_TO_LITTLE(value);
-}
-
 // Encodes the BMP file header mBMPFileHeader
 void 
 nsBMPEncoder::EncodeFileHeader() 
 {  
   mozilla::image::BMPFILEHEADER littleEndianBFH = mBMPFileHeader;
-  ConvertToLittle(littleEndianBFH.filesize);
-  ConvertToLittle(littleEndianBFH.reserved);
-  ConvertToLittle(littleEndianBFH.dataoffset);
-  ConvertToLittle(littleEndianBFH.bihsize);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.filesize, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.reserved, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.dataoffset, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianBFH.bihsize, 1);
 
   ENCODE(&mImageBufferCurr, littleEndianBFH.signature);
   ENCODE(&mImageBufferCurr, littleEndianBFH.filesize);
   ENCODE(&mImageBufferCurr, littleEndianBFH.reserved);
   ENCODE(&mImageBufferCurr, littleEndianBFH.dataoffset);
   ENCODE(&mImageBufferCurr, littleEndianBFH.bihsize);
 }
 
 // Encodes the BMP infor header mBMPInfoHeader
 void 
 nsBMPEncoder::EncodeInfoHeader()
 {
   mozilla::image::BITMAPV5HEADER littleEndianmBIH = mBMPInfoHeader;
-  ConvertToLittle(littleEndianmBIH.width);
-  ConvertToLittle(littleEndianmBIH.height);
-  ConvertToLittle(littleEndianmBIH.planes);
-  ConvertToLittle(littleEndianmBIH.bpp);
-  ConvertToLittle(littleEndianmBIH.compression);
-  ConvertToLittle(littleEndianmBIH.image_size);
-  ConvertToLittle(littleEndianmBIH.xppm);
-  ConvertToLittle(littleEndianmBIH.yppm);
-  ConvertToLittle(littleEndianmBIH.colors);
-  ConvertToLittle(littleEndianmBIH.important_colors);
-  ConvertToLittle(littleEndianmBIH.red_mask);
-  ConvertToLittle(littleEndianmBIH.green_mask);
-  ConvertToLittle(littleEndianmBIH.blue_mask);
-  ConvertToLittle(littleEndianmBIH.alpha_mask);
-  ConvertToLittle(littleEndianmBIH.color_space);
-  ConvertToLittle(littleEndianmBIH.white_point.r.x);
-  ConvertToLittle(littleEndianmBIH.white_point.r.y);
-  ConvertToLittle(littleEndianmBIH.white_point.r.z);
-  ConvertToLittle(littleEndianmBIH.white_point.g.x);
-  ConvertToLittle(littleEndianmBIH.white_point.g.y);
-  ConvertToLittle(littleEndianmBIH.white_point.g.z);
-  ConvertToLittle(littleEndianmBIH.white_point.b.x);
-  ConvertToLittle(littleEndianmBIH.white_point.b.y);
-  ConvertToLittle(littleEndianmBIH.white_point.b.z);
-  ConvertToLittle(littleEndianmBIH.gamma_red);
-  ConvertToLittle(littleEndianmBIH.gamma_green);
-  ConvertToLittle(littleEndianmBIH.gamma_blue);
-  ConvertToLittle(littleEndianmBIH.intent);
-  ConvertToLittle(littleEndianmBIH.profile_offset);
-  ConvertToLittle(littleEndianmBIH.profile_size);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.width, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.height, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.planes, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.bpp, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.compression, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.image_size, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.xppm, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.yppm, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.colors, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.important_colors, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.red_mask, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.green_mask, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.blue_mask, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.alpha_mask, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.color_space, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.r.x, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.r.y, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.r.z, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.g.x, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.g.y, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.g.z, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.b.x, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.b.y, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.white_point.b.z, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.gamma_red, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.gamma_green, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.gamma_blue, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.intent, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.profile_offset, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.profile_size, 1);
   
   if (mBMPFileHeader.bihsize == OS2_BIH_LENGTH) {
       uint16_t width = (uint16_t) littleEndianmBIH.width;
       ENCODE(&mImageBufferCurr, width);
       uint16_t height = (uint16_t) littleEndianmBIH.width;
       ENCODE(&mImageBufferCurr, height);
   } else {
       ENCODE(&mImageBufferCurr, littleEndianmBIH.width);
--- a/image/encoders/ico/nsICOEncoder.cpp
+++ b/image/encoders/ico/nsICOEncoder.cpp
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCRT.h"
-#include "EndianMacros.h"
+#include "mozilla/Endian.h"
 #include "nsBMPEncoder.h"
 #include "nsPNGEncoder.h"
 #include "nsICOEncoder.h"
 #include "prprf.h"
 #include "nsString.h"
 #include "nsStreamUtils.h"
 #include "nsTArray.h"
 
@@ -166,17 +166,17 @@ nsICOEncoder::AddImageFrame(const uint8_
 
     char *imageBuffer;
     rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
     NS_ENSURE_SUCCESS(rv, rv);
     memcpy(mImageBufferCurr, imageBuffer + BFH_LENGTH, 
            BMPImageBufferSize - BFH_LENGTH);
     // We need to fix the BMP height to be *2 for the AND mask
     uint32_t fixedHeight = GetRealHeight() * 2;
-    fixedHeight = NATIVE32_TO_LITTLE(fixedHeight);
+    NativeEndian::swapToLittleEndianInPlace(&fixedHeight, 1);
     // The height is stored at an offset of 8 from the DIB header
     memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
     mImageBufferCurr += BMPImageBufferSize - BFH_LENGTH;
 
     // Calculate rowsize in DWORD's
     uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
     int32_t currentLine = GetRealHeight();
     
@@ -471,19 +471,19 @@ nsICOEncoder::InitInfoHeader(uint32_t aB
   mICODirEntry.mReserved = 0;
 }
 
 // Encodes the icon file header mICOFileHeader
 void 
 nsICOEncoder::EncodeFileHeader() 
 {  
   IconFileHeader littleEndianIFH = mICOFileHeader;
-  littleEndianIFH.mReserved = NATIVE16_TO_LITTLE(littleEndianIFH.mReserved);
-  littleEndianIFH.mType = NATIVE16_TO_LITTLE(littleEndianIFH.mType);
-  littleEndianIFH.mCount = NATIVE16_TO_LITTLE(littleEndianIFH.mCount);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mReserved, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mType, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianIFH.mCount, 1);
 
   memcpy(mImageBufferCurr, &littleEndianIFH.mReserved, 
          sizeof(littleEndianIFH.mReserved));
   mImageBufferCurr += sizeof(littleEndianIFH.mReserved);
   memcpy(mImageBufferCurr, &littleEndianIFH.mType, 
          sizeof(littleEndianIFH.mType));
   mImageBufferCurr += sizeof(littleEndianIFH.mType);
   memcpy(mImageBufferCurr, &littleEndianIFH.mCount, 
@@ -492,22 +492,20 @@ nsICOEncoder::EncodeFileHeader()
 }
 
 // Encodes the icon directory info header mICODirEntry
 void 
 nsICOEncoder::EncodeInfoHeader()
 {
   IconDirEntry littleEndianmIDE = mICODirEntry;
 
-  littleEndianmIDE.mPlanes = NATIVE16_TO_LITTLE(littleEndianmIDE.mPlanes);
-  littleEndianmIDE.mBitCount = NATIVE16_TO_LITTLE(littleEndianmIDE.mBitCount);
-  littleEndianmIDE.mBytesInRes = 
-    NATIVE32_TO_LITTLE(littleEndianmIDE.mBytesInRes);
-  littleEndianmIDE.mImageOffset  = 
-    NATIVE32_TO_LITTLE(littleEndianmIDE.mImageOffset);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mPlanes, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mBitCount, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mBytesInRes, 1);
+  NativeEndian::swapToLittleEndianInPlace(&littleEndianmIDE.mImageOffset, 1);
 
   memcpy(mImageBufferCurr, &littleEndianmIDE.mWidth, 
          sizeof(littleEndianmIDE.mWidth));
   mImageBufferCurr += sizeof(littleEndianmIDE.mWidth);
   memcpy(mImageBufferCurr, &littleEndianmIDE.mHeight, 
          sizeof(littleEndianmIDE.mHeight));
   mImageBufferCurr += sizeof(littleEndianmIDE.mHeight);
   memcpy(mImageBufferCurr, &littleEndianmIDE.mColorCount, 
deleted file mode 100644
--- a/image/src/EndianMacros.h
+++ /dev/null
@@ -1,28 +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/. */
-
-#ifndef MOZILLA_IMAGELIB_ENDIAN_H_
-#define MOZILLA_IMAGELIB_ENDIAN_H_
-
-
-#if defined WORDS_BIGENDIAN || defined IS_BIG_ENDIAN || defined __BIG_ENDIAN__
-// We must ensure that the entity is unsigned
-// otherwise, if it is signed/negative, the MSB will be
-// propagated when we shift
-#define LITTLE_TO_NATIVE16(x) (((((uint16_t) x) & 0xFF) << 8) | \
-                               (((uint16_t) x) >> 8))
-#define LITTLE_TO_NATIVE32(x) (((((uint32_t) x) & 0xFF) << 24) | \
-                               (((((uint32_t) x) >> 8) & 0xFF) << 16) | \
-                               (((((uint32_t) x) >> 16) & 0xFF) << 8) | \
-                               (((uint32_t) x) >> 24))
-#define NATIVE32_TO_LITTLE LITTLE_TO_NATIVE32
-#define NATIVE16_TO_LITTLE LITTLE_TO_NATIVE16
-#else
-#define LITTLE_TO_NATIVE16(x) x
-#define LITTLE_TO_NATIVE32(x) x
-#define NATIVE32_TO_LITTLE(x) x
-#define NATIVE16_TO_LITTLE(x) x
-#endif
-
-#endif
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -24,16 +24,17 @@
 * in other embeddings.
 */
 #ifdef MOZILLA_CLIENT
 #define JSD_THREADSAFE 1
 /* define JSD_HAS_DANGEROUS_THREAD 1 */
 #define JSD_USE_NSPR_LOCKS 1
 #endif /* MOZILLA_CLIENT */
 
+#include "jsapi.h"
 #include "jshash.h"
 #include "jsclist.h"
 #include "jsdebug.h"
 #include "js/OldDebugAPI.h"
 #include "jsd_lock.h"
 
 #include <stdio.h>
 #include <stdlib.h>
--- a/js/jsd/jsdebug.h
+++ b/js/jsd/jsdebug.h
@@ -6,17 +6,18 @@
 
 /*
  * Header for JavaScript Debugging support - All public functions
  */
 
 #ifndef jsdebug_h___
 #define jsdebug_h___
 
-#include "jsapi.h"
+#include "jstypes.h"
+#include "js/TypeDecls.h"
 
 extern "C" {
 
 /*
  * The linkage of JSD API functions differs depending on whether the file is
  * used within the JSD library or not.  Any source file within the JSD
  * libraray should define EXPORT_JSD_API whereas any client of the library
  * should not.
@@ -709,19 +710,19 @@ JSD_AddFullSourceText(JSDContext* jsdc,
 #define JSD_HOOK_RETURN_CONTINUE_THROW  5
 
 /*
 * Implement a callback of this form in order to hook execution.
 */
 typedef unsigned
 (* JSD_ExecutionHookProc)(JSDContext*     jsdc,
                           JSDThreadState* jsdthreadstate,
-                          unsigned           type,
+                          unsigned        type,
                           void*           callerdata,
-                          jsval*          rval);
+                          JS::Value*      rval);
 
 /* possible 'type' params for JSD_CallHookProc */
 #define JSD_HOOK_TOPLEVEL_START  0   /* about to evaluate top level script */
 #define JSD_HOOK_TOPLEVEL_END    1   /* done evaluting top level script    */
 #define JSD_HOOK_FUNCTION_CALL   2   /* about to call a function           */
 #define JSD_HOOK_FUNCTION_RETURN 3   /* done calling function              */
 
 /*
@@ -1000,24 +1001,24 @@ JSD_EvaluateScriptInStackFrame(JSDContex
 extern JSD_PUBLIC_API(bool)
 JSD_AttemptScriptInStackFrame(JSDContext* jsdc,
                               JSDThreadState* jsdthreadstate,
                               JSDStackFrameInfo* jsdframe,
                               const char *bytes, unsigned length,
                               const char *filename, unsigned lineno, JS::MutableHandleValue rval);
 
 /*
-* Convert the given jsval to a string
+* Convert the given JS::Value to a string
 * NOTE: The ErrorReporter hook might be called if this fails.
 */
 extern JSD_PUBLIC_API(JSString*)
 JSD_ValToStringInStackFrame(JSDContext* jsdc,
                             JSDThreadState* jsdthreadstate,
                             JSDStackFrameInfo* jsdframe,
-                            jsval val);
+                            JS::Value val);
 
 /*
 * Get the JSDValue currently being thrown as an exception (may be NULL).
 * NOTE: must eventually release by calling JSD_DropValue (if not NULL)
 * *** new for version 1.1 ****
 */
 extern JSD_PUBLIC_API(JSDValue*)
 JSD_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate);
@@ -1116,41 +1117,41 @@ JSD_IsUnlocked(JSDStaticLock* lock);
 extern JSD_PUBLIC_API(void*)
 JSD_CurrentThread();
 
 /***************************************************************************/
 /* Value and Property Functions  --- All NEW for 1.1 --- */
 
 /*
 * NOTE: JSDValue and JSDProperty objects are reference counted. This allows
-* for rooting these objects AND any underlying garbage collected jsvals.
+* for rooting these objects AND any underlying garbage collected JS::Values.
 * ALL JSDValue and JSDProperty objects returned by the functions below
 * MUST eventually be released using the appropriate JSD_Dropxxx function.
 */
 
 /*
-* Create a new JSDValue to wrap the given jsval
+* Create a new JSDValue to wrap the given JS::Value
 * NOTE: must eventually release by calling JSD_DropValue (if not NULL)
 * *** new for version 1.1 ****
 */
 extern JSD_PUBLIC_API(JSDValue*)
-JSD_NewValue(JSDContext* jsdc, jsval val);
+JSD_NewValue(JSDContext* jsdc, JS::Value val);
 
 /*
 * Release the JSDValue. After this call the object MUST not be referenced again!
 * *** new for version 1.1 ****
 */
 extern JSD_PUBLIC_API(void)
 JSD_DropValue(JSDContext* jsdc, JSDValue* jsdval);
 
 /*
-* Get the jsval wrapped by this JSDValue
+* Get the JS::Value wrapped by this JSDValue
 * *** new for version 1.1 ****
 */
-extern JSD_PUBLIC_API(jsval)
+extern JSD_PUBLIC_API(JS::Value)
 JSD_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval);
 
 /*
 * Clear all property and association information about the given JSDValue.
 * Such information will be lazily regenerated when later accessed. This
 * function must be called to make changes to the properties of an object
 * visible to the accessor functions below (if the properties et.al. have
 * changed since a previous call to those accessors).
--- a/js/public/Id.h
+++ b/js/public/Id.h
@@ -152,9 +152,12 @@ JSID_IS_EMPTY(const jsid id)
 #ifdef JS_USE_JSID_STRUCT_TYPES
 extern JS_PUBLIC_DATA(const jsid) JSID_VOID;
 extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY;
 #else
 # define JSID_VOID ((jsid)JSID_TYPE_VOID)
 # define JSID_EMPTY ((jsid)JSID_TYPE_OBJECT)
 #endif
 
+extern JS_PUBLIC_DATA(const JS::Handle<jsid>) JSID_VOIDHANDLE;
+extern JS_PUBLIC_DATA(const JS::Handle<jsid>) JSID_EMPTYHANDLE;
+
 #endif /* js_Id_h */
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -201,23 +201,25 @@ ifdef HAVE_DTRACE
 export_files += $(CURDIR)/javascript-trace.h
 endif
 
 INSTALL_TARGETS += jsconfig
 jsconfig_FILES = $(export_files)
 jsconfig_DEST = $(DIST)/include
 jsconfig_TARGET := export
 
+.PHONY: buildffi buildicu
+buildffi buildicu:
+compile:: buildffi buildicu
+
 include $(topsrcdir)/config/rules.mk
 
 ifdef JS_HAS_CTYPES
 ifndef MOZ_NATIVE_FFI
-# Build libffi proper as part of the 'exports' target, so things get built
-# in the right order.
-export::
+buildffi:
 		$(call SUBMAKE,,ctypes/libffi)
 
 distclean clean::
 		$(call SUBMAKE,$@,ctypes/libffi)
 endif
 endif
 
 
@@ -247,24 +249,22 @@ ifeq ($(OS_ARCH),WINNT)
   # and debug libraries.
   ifdef MOZ_DEBUG
     ICU_LIB_SUFFIX=d
   endif
   ICU_LIB_RENAME = $(foreach libname,$(ICU_LIB_NAMES),\
                      cp -p intl/icu/lib/s$(libname)$(ICU_LIB_SUFFIX).lib intl/icu/lib/$(libname).lib;)
 endif
 
-# - Build ICU as part of the "export" target, so things get built
-#   in the right order.
 # - ICU requires GNU make according to its readme.html. pymake can't be used
 #   because it doesn't support order only dependencies.
 # - Force ICU to use the standard suffix for object files because expandlibs
 #   will discard all files with a non-standard suffix (bug 857450).
 # - Options for genrb: -k strict parsing; -R omit collation tailoring rules.
-export::
+buildicu:
 	$(GMAKE) $(ICU_GMAKE_OPTIONS) -C intl/icu STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-k -R'
 	$(ICU_LIB_RENAME)
 
 distclean clean::
 	$(call SUBMAKE,$@,intl/icu)
 
 endif
 endif
--- a/js/src/build/autoconf/android.m4
+++ b/js/src/build/autoconf/android.m4
@@ -223,29 +223,26 @@ if test "$OS_TARGET" = "Android" -a -z "
     esac
 
     AC_SUBST(ANDROID_CPU_ARCH)
 
     if test -z "$STLPORT_CPPFLAGS$STLPORT_LDFLAGS$STLPORT_LIBS"; then
         if test -n "$MOZ_ANDROID_LIBSTDCXX" ; then
             if test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/libgnustl_static.a"; then
                 # android-ndk-r8b
-                STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/"
-                STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/include"
-                STLPORT_LIBS="-lgnustl_static"
+                STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/ -lgnustl_static"
+                STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/libs/$ANDROID_CPU_ARCH/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/$android_gnu_compiler_version/include/backward"
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libgnustl_static.a"; then
                 # android-ndk-r7, android-ndk-r7b, android-ndk-r8
-                STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/"
+                STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/ -lgnustl_static"
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
-                STLPORT_LIBS="-lgnustl_static"
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a"; then
                 # android-ndk-r5c, android-ndk-r6, android-ndk-r6b
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
-                STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/"
-                STLPORT_LIBS="-lstdc++"
+                STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/ -lstdc++"
             else
                 AC_MSG_ERROR([Couldn't find path to gnu-libstdc++ in the android ndk])
             fi
         else
             STLPORT_CPPFLAGS="-I$_topsrcdir/build/stlport/stlport -I$android_ndk/sources/cxx-stl/system/include"
             STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
         fi
     fi
--- a/js/src/builtin/MapObject.h
+++ b/js/src/builtin/MapObject.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 builtin_MapObject_h
 #define builtin_MapObject_h
 
-#include "jsapi.h"
 #include "jsobj.h"
 
 #include "vm/Runtime.h"
 
 namespace js {
 
 /*
  * Comparing two ropes for equality can fail. The js::HashTable template
--- a/js/src/builtin/ParallelArray.h
+++ b/js/src/builtin/ParallelArray.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 builtin_ParallelArray_h
 #define builtin_ParallelArray_h
 
-#include "jsapi.h"
 #include "jsobj.h"
 
 #include "jit/Ion.h"
 
 namespace js {
 
 class ParallelArrayObject : public JSObject
 {
deleted file mode 100644
--- a/js/src/config/makefiles/tiers.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- makefile -*-
-# vim:set ts=8 sw=8 sts=8 noet:
-#
-# 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 file contains logic for tier traversal.
-
-define CREATE_SUBTIER_RULE
-$(2)_tier_$(1):
-	$$(call BUILDSTATUS,SUBTIER_START  $(1) $(2) $$(tier_$(1)_dirs))
-	$$(foreach dir,$$(tier_$(1)_dirs),$$(call TIER_DIR_SUBMAKE,$(1),$(2),$$(dir),$(2)))
-	$$(call BUILDSTATUS,SUBTIER_FINISH $(1) $(2))
-
-endef
-
-# This function is called and evaluated to produce the rule to build the
-# specified tier.
-#
-# Tiers are traditionally composed of directories that are invoked either
-# once (so-called "static" directories) or 3 times with the export, libs, and
-# tools sub-tiers.
-#
-# If the TIER_$(tier)_CUSTOM variable is defined, then these traditional
-# tier rules are ignored and each directory in the tier is executed via a
-# sub-make invocation (make -C).
-define CREATE_TIER_RULE
-tier_$(1)::
-ifdef TIER_$(1)_CUSTOM
-	$$(foreach dir,$$($$@_dirs),$$(call SUBMAKE,,$$(dir)))
-else
-	$(call BUILDSTATUS,TIER_START $(1) $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
-ifneq (,$(tier_$(1)_staticdirs))
-	$(call BUILDSTATUS,SUBTIER_START  $(1) static $$($$@_staticdirs))
-	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,$(1),static,$$(dir),,1))
-	$(call BUILDSTATUS,SUBTIER_FINISH $(1) static)
-endif
-ifneq (,$(tier_$(1)_dirs))
-	$$(MAKE) export_$$@
-	$$(MAKE) libs_$$@
-	$$(MAKE) tools_$$@
-endif
-	$(call BUILDSTATUS,TIER_FINISH $(1))
-endif
-
-$(foreach subtier,export libs tools,$(call CREATE_SUBTIER_RULE,$(1),$(subtier)))
-
-endef
--- a/js/src/config/recurse.mk
+++ b/js/src/config/recurse.mk
@@ -5,16 +5,29 @@
 ifndef INCLUDED_RULES_MK
 include $(topsrcdir)/config/rules.mk
 endif
 
 #########################
 # Tier traversal handling
 #########################
 
+ifdef TIERS
+
+compile libs export tools::
+	$(call BUILDSTATUS,TIER_START $@ $(filter-out $(if $(filter export,$@),,precompile),$(TIERS)))
+	$(foreach tier,$(TIERS), $(if $(filter-out compile_precompile libs_precompile tools_precompile,$@_$(tier)), \
+		$(call BUILDSTATUS,SUBTIER_START $@ $(tier) $(if $(filter libs,$@),$(tier_$(tier)_staticdirs)) $(tier_$(tier)_dirs)) \
+		$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
+		$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@)) \
+		$(call BUILDSTATUS,SUBTIER_FINISH $@ $(tier))))
+	$(call BUILDSTATUS,TIER_FINISH $@)
+
+else
+
 define CREATE_SUBTIER_TRAVERSAL_RULE
 PARALLEL_DIRS_$(1) = $$(addsuffix _$(1),$$(PARALLEL_DIRS))
 
 .PHONY: $(1) $$(PARALLEL_DIRS_$(1))
 
 ifdef PARALLEL_DIRS
 $$(PARALLEL_DIRS_$(1)): %_$(1): %/Makefile
 	+@$$(call SUBMAKE,$(1),$$*)
@@ -23,15 +36,17 @@ endif
 $(1):: $$(SUBMAKEFILES)
 ifdef PARALLEL_DIRS
 	+@$(MAKE) $$(PARALLEL_DIRS_$(1))
 endif
 	$$(LOOP_OVER_DIRS)
 
 endef
 
-$(foreach subtier,export libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
+$(foreach subtier,export compile libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier))))
 
-export:: $(SUBMAKEFILES)
+compile export:: $(SUBMAKEFILES)
 	$(LOOP_OVER_TOOL_DIRS)
 
 tools:: $(SUBMAKEFILES)
 	$(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,libs,$(dir)))
+
+endif
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -431,17 +431,20 @@ ifdef MOZ_UPDATE_XTERM
 # Its good not to have a newline at the end of the titlebar string because it
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick printf into doing it.
 UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ;
 endif
 
 ifdef MACH
 ifndef NO_BUILDSTATUS_MESSAGES
-BUILDSTATUS=@echo "BUILDSTATUS $1"
+define BUILDSTATUS
+@echo "BUILDSTATUS $1"
+
+endef
 endif
 endif
 
 # Static directories are largely independent of our build system. But, they
 # could share the same build mechanism (like moz.build files). We need to
 # prevent leaking of our backend state to these independent build systems. This
 # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static
 # directories.
@@ -453,17 +456,16 @@ endef # The extra line is important here
 
 define TIER_DIR_SUBMAKE
 $(call BUILDSTATUS,TIERDIR_START  $(1) $(2) $(3))
 $(call SUBMAKE,$(4),$(3),$(5))
 $(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3))
 
 endef # Ths empty line is important.
 
-
 ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
   $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
 
 # we only use this for the makefiles target and other stuff that doesn't matter
 ifneq (,$(strip $(PARALLEL_DIRS)))
 LOOP_OVER_PARALLEL_DIRS = \
@@ -683,22 +685,21 @@ endif
 #   This is used to update or create the Makefiles before invoking them.
 SUBMAKEFILES += $(addsuffix /Makefile, $(DIRS) $(TOOL_DIRS) $(PARALLEL_DIRS))
 
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
-ifndef TIERS
 default all::
 	$(MAKE) export
+	$(MAKE) compile
 	$(MAKE) libs
 	$(MAKE) tools
-endif # TIERS
 endif # SUPPRESS_DEFAULT_RULES
 
 ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),)
 ECHO := echo
 QUIET :=
 else
 ECHO := true
 QUIET := -q
@@ -725,16 +726,18 @@ HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 ifndef NO_MAKEFILE_RULE
 GLOBAL_DEPS += Makefile.in
 endif
 
 ##############################################
+compile:: $(OBJS) $(HOST_OBJS)
+
 include $(topsrcdir)/config/makefiles/target_libs.mk
 
 ##############################################
 ifndef NO_PROFILE_GUIDED_OPTIMIZE
 ifdef MOZ_PROFILE_USE
 ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
 # When building with PGO, we have to make sure to re-link
 # in the MOZ_PROFILE_USE phase if we linked in the
--- a/js/src/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.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 ctypes_CTypes_h
 #define ctypes_CTypes_h
 
 #include "ffi.h"
-#include "jsapi.h"
 #include "jscntxt.h"
 #include "prlink.h"
 
 #include "js/HashTable.h"
 
 namespace js {
 namespace ctypes {
 
--- a/js/src/ctypes/Library.h
+++ b/js/src/ctypes/Library.h
@@ -1,36 +1,37 @@
 /* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ctypes_Library_h
 #define ctypes_Library_h
 
-#include "jsapi.h"
+#include "js/TypeDecls.h"
 
+struct JSCTypesCallbacks;
 struct PRLibrary;
 
 namespace js {
 namespace ctypes {
 
 enum LibrarySlot {
   SLOT_LIBRARY = 0,
   LIBRARY_SLOTS
 };
 
 namespace Library
 {
-  bool Name(JSContext* cx, unsigned argc, jsval *vp);
+  bool Name(JSContext* cx, unsigned argc, JS::Value *vp);
 
-  JSObject* Create(JSContext* cx, jsval path, JSCTypesCallbacks* callbacks);
+  JSObject* Create(JSContext* cx, JS::Value path, JSCTypesCallbacks* callbacks);
 
   bool IsLibrary(JSObject* obj);
   PRLibrary* GetLibrary(JSObject* obj);
 
-  bool Open(JSContext* cx, unsigned argc, jsval* vp);
+  bool Open(JSContext* cx, unsigned argc, JS::Value* vp);
 }
 
 }
 }
 
 #endif /* ctypes_Library_h */
--- a/js/src/ds/IdValuePair.h
+++ b/js/src/ds/IdValuePair.h
@@ -4,16 +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 ds_IdValuePair_h
 #define ds_IdValuePair_h
 
 #include "NamespaceImports.h"
 
+#include "js/Id.h"
+
 namespace js {
 
 struct IdValuePair
 {
     jsid id;
     Value value;
 
     IdValuePair() {}
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -2,21 +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 gc_Barrier_h
 #define gc_Barrier_h
 
-#include "jsapi.h"
 #include "NamespaceImports.h"
 
 #include "gc/Heap.h"
 #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
  * traced through by the GC to change. This includes:
  *   - writes to object properties
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.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 gc_GCInternals_h
 #define gc_GCInternals_h
 
-#include "jsapi.h"
 #include "jsworkers.h"
 
 #include "vm/Runtime.h"
 
 namespace js {
 namespace gc {
 
 void
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.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/. */
 
 #ifdef MOZ_VALGRIND
 # include <valgrind/memcheck.h>
 #endif
 
-#include "jsapi.h"
 #include "jscntxt.h"
 #include "jsgc.h"
 #include "jsprf.h"
 
 #include "gc/GCInternals.h"
 #include "gc/Zone.h"
 #include "js/HashTable.h"
 
--- a/js/src/gdb/gdb-tests.cpp
+++ b/js/src/gdb/gdb-tests.cpp
@@ -2,16 +2,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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "gdb-tests.h"
+#include "jsapi.h"
 #include "jsfriendapi.h"
 
 using namespace JS;
 
 /* The class of the global object. */
 JSClass global_class = {
     "global", JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,  JS_DeletePropertyStub, JS_PropertyStub,  JS_StrictPropertyStub,
--- a/js/src/gdb/gdb-tests.h
+++ b/js/src/gdb/gdb-tests.h
@@ -15,17 +15,16 @@
 // - js/src/gdb/mozilla holds the actual GDB SpiderMonkey support code.
 // - Each '.py' file in js/src/gdb/tests is a unit test for the above.
 // - Each '.cpp' file in js/src/gdb/tests is C++ code for one of the unit tests
 //   to run.
 //
 // (So the .cpp files are two steps removed from being anything one would
 // actually run.)
 
-#include "jsapi.h"
 #include "NamespaceImports.h"
 
 void breakpoint();
 
 struct GDBFragment {
     GDBFragment() {
         next = allFragments;
         allFragments = this;
--- a/js/src/gdb/tests/test-JSObject.cpp
+++ b/js/src/gdb/tests/test-JSObject.cpp
@@ -1,9 +1,10 @@
 #include "gdb-tests.h"
+#include "jsapi.h"
 
 FRAGMENT(JSObject, simple) {
   JS::Rooted<JSObject *> glob(cx, JS::CurrentGlobalOrNull(cx));
   JS::Rooted<JSObject *> plain(cx, JS_NewObject(cx, 0, 0, 0));
   JS::Rooted<JSObject *> func(cx, (JSObject *) JS_NewFunction(cx, (JSNative) 1, 0, 0,
                                                               JS::CurrentGlobalOrNull(cx), "dys"));
   JS::Rooted<JSObject *> anon(cx, (JSObject *) JS_NewFunction(cx, (JSNative) 1, 0, 0,
                                                               JS::CurrentGlobalOrNull(cx), 0));
--- a/js/src/gdb/tests/test-Root.cpp
+++ b/js/src/gdb/tests/test-Root.cpp
@@ -1,9 +1,10 @@
 #include "gdb-tests.h"
+#include "jsapi.h"
 
 FRAGMENT(Root, null) {
   JS::Rooted<JSObject *> null(cx, NULL);
 
   breakpoint();
 
   (void) null;
 }
--- a/js/src/gdb/tests/test-jsid.cpp
+++ b/js/src/gdb/tests/test-jsid.cpp
@@ -1,9 +1,10 @@
 #include "gdb-tests.h"
+#include "jsapi.h"
 
 FRAGMENT(jsid, simple) {
   JS::Rooted<JSString *> string(cx, JS_NewStringCopyZ(cx, "moon"));
   JS::Rooted<JSString *> interned(cx, JS_InternJSString(cx, string));
   JS::Rooted<jsid> string_id(cx, INTERNED_STRING_TO_JSID(cx, interned));
   jsid int_id = INT_TO_JSID(1729);
   jsid void_id = JSID_VOID;
   JS::Rooted<jsid> object_id(cx, OBJECT_TO_JSID(JS::CurrentGlobalOrNull(cx)));
--- a/js/src/gdb/tests/test-jsval.cpp
+++ b/js/src/gdb/tests/test-jsval.cpp
@@ -1,9 +1,10 @@
 #include "gdb-tests.h"
+#include "jsapi.h"
 
 FRAGMENT(jsval, simple) {
   JS::Rooted<jsval> fortytwo(cx, INT_TO_JSVAL(42));
   JS::Rooted<jsval> negone(cx, INT_TO_JSVAL(-1));
   JS::Rooted<jsval> undefined(cx, JSVAL_VOID);
   JS::Rooted<jsval> null(cx, JSVAL_NULL);
   JS::Rooted<jsval> js_true(cx, JSVAL_TRUE);
   JS::Rooted<jsval> js_false(cx, JSVAL_FALSE);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug911368.js
@@ -0,0 +1,10 @@
+// |jit-test|
+(function (stdlib, heap) {
+    "use asm";
+    function f(i0) {
+        i0 = i0 | 0;
+        switch (0xc << (0xa % 1)) {
+            case -2:
+        };
+    }
+})()
--- a/js/src/jit-test/tests/ion/bug756235.js
+++ b/js/src/jit-test/tests/ion/bug756235.js
@@ -1,8 +1,10 @@
+// |jit-test| slow;
+
 gczeal(2);
 try {
     function complex(aReal, aImag) {
         let Z = new complex(0.0, 0.0);
     }
     function f(trace) {
         const width = 60;
         const height = 60;
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -28,21 +28,22 @@ AsmJSModule::patchHeapAccesses(ArrayBuff
 #if defined(JS_CPU_X86)
     void *heapOffset = (void*)heap->dataPointer();
     void *heapLength = (void*)heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         JSC::X86Assembler::setPointer(heapAccesses_[i].patchLengthAt(code_), heapLength);
         JSC::X86Assembler::setPointer(heapAccesses_[i].patchOffsetAt(code_), heapOffset);
     }
 #elif defined(JS_CPU_ARM)
-    jit::IonContext ic(cx, NULL);
-    jit::AutoFlushCache afc("patchBoundsCheck");
     uint32_t bits = mozilla::CeilingLog2(heap->byteLength());
     for (unsigned i = 0; i < heapAccesses_.length(); i++)
         jit::Assembler::updateBoundsCheck(bits, (jit::Instruction*)(heapAccesses_[i].offset() + code_));
+    // We already know the exact extent of areas that need to be patched, just make sure we
+    // flush all of them at once.
+    jit::AutoFlushCache::updateTop(uintptr_t(code_), pod.codeBytes_);
 #endif
 }
 
 static uint8_t *
 AllocateExecutableMemory(ExclusiveContext *cx, size_t totalBytes)
 {
     JS_ASSERT(totalBytes % AsmJSPageSize == 0);
 
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4713,31 +4713,31 @@ DoSetElemFallback(JSContext *cx, Baselin
                 IonSpew(IonSpew_BaselineIC,
                         "  Generating SetElem_DenseAdd stub "
                         "(shape=%p, type=%p, protoDepth=%u)",
                         obj->lastProperty(), type.get(), protoDepth);
                 ICSetElemDenseAddCompiler compiler(cx, obj, protoDepth);
                 ICUpdatedStub *denseStub = compiler.getStub(compiler.getStubSpace(script));
                 if (!denseStub)
                     return false;
-                if (!denseStub->addUpdateStubForValue(cx, script, obj, JS::JSID_VOIDHANDLE, rhs))
+                if (!denseStub->addUpdateStubForValue(cx, script, obj, JSID_VOIDHANDLE, rhs))
                     return false;
 
                 stub->addNewStub(denseStub);
             } else if (!addingCase &&
                        !DenseSetElemStubExists(cx, ICStub::SetElem_Dense, stub, obj))
             {
                 IonSpew(IonSpew_BaselineIC,
                         "  Generating SetElem_Dense stub (shape=%p, type=%p)",
                         obj->lastProperty(), type.get());
                 ICSetElem_Dense::Compiler compiler(cx, shape, type);
                 ICUpdatedStub *denseStub = compiler.getStub(compiler.getStubSpace(script));
                 if (!denseStub)
                     return false;
-                if (!denseStub->addUpdateStubForValue(cx, script, obj, JS::JSID_VOIDHANDLE, rhs))
+                if (!denseStub->addUpdateStubForValue(cx, script, obj, JSID_VOIDHANDLE, rhs))
                     return false;
 
                 stub->addNewStub(denseStub);
             }
         }
 
         return true;
     }
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -95,17 +95,17 @@ EnterBaseline(JSContext *cx, EnterJitDat
     JS_ASSERT_IF(data.constructing, data.maxArgv[0].isObject());
 
     data.result.setInt32(data.numActualArgs);
     {
         AssertCompartmentUnchanged pcc(cx);
         IonContext ictx(cx, NULL);
         JitActivation activation(cx, data.constructing);
         JSAutoResolveFlags rf(cx, RESOLVE_INFER);
-        AutoFlushInhibitor afi(cx->compartment()->ionCompartment());
+        AutoFlushInhibitor afi(cx->runtime()->ionRuntime());
 
         if (data.osrFrame)
             data.osrFrame->setRunningInJit();
 
         JS_ASSERT_IF(data.osrFrame, !IsJSDEnabled(cx));
 
         // Single transition point from Interpreter to Baseline.
         enter(data.jitcode, data.maxArgc, data.maxArgv, data.osrFrame, data.calleeToken,
@@ -718,18 +718,19 @@ BaselineScript::pcForReturnAddress(JSScr
 
 void
 BaselineScript::toggleDebugTraps(JSScript *script, jsbytecode *pc)
 {
     JS_ASSERT(script->baselineScript() == this);
 
     SrcNoteLineScanner scanner(script->notes(), script->lineno);
 
-    IonContext ictx(script->runtimeFromMainThread(), script->compartment(), NULL);
-    AutoFlushCache afc("DebugTraps");
+    JSRuntime *rt = script->runtimeFromMainThread();
+    IonContext ictx(rt, script->compartment(), NULL);
+    AutoFlushCache afc("DebugTraps", rt->ionRuntime());
 
     for (uint32_t i = 0; i < numPCMappingIndexEntries(); i++) {
         PCMappingIndexEntry &entry = pcMappingIndexEntry(i);
 
         CompactBufferReader reader(pcMappingReader(i));
         jsbytecode *curPC = script->code + entry.pcOffset;
         uint32_t nativeOffset = entry.nativeOffset;
 
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -212,17 +212,17 @@ bool
 IonRuntime::initialize(JSContext *cx)
 {
     JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
 
     AutoLockForExclusiveAccess lock(cx);
     AutoCompartment ac(cx, cx->atomsCompartment());
 
     IonContext ictx(cx, NULL);
-    AutoFlushCache afc("IonRuntime::initialize");
+    AutoFlushCache afc("IonRuntime::initialize", this);
 
     execAlloc_ = cx->runtime()->getExecAlloc(cx);
     if (!execAlloc_)
         return false;
 
     if (!cx->compartment()->ensureIonCompartmentExists(cx))
         return false;
 
@@ -1144,20 +1144,20 @@ IonScript::destroyBackedges(JSRuntime *r
     // script is invalidated.
     backedgeEntries_ = 0;
 }
 
 void
 jit::ToggleBarriers(JS::Zone *zone, bool needs)
 {
     JSRuntime *rt = zone->runtimeFromMainThread();
-    IonContext ictx(rt);
     if (!rt->hasIonRuntime())
         return;
 
+    IonContext ictx(rt);
     AutoFlushCache afc("ToggleBarriers", rt->ionRuntime());
     for (gc::CellIterUnderGC i(zone, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
         if (script->hasIonScript())
             script->ionScript()->toggleBarriers(needs);
         if (script->hasBaselineScript())
             script->baselineScript()->toggleBarriers(needs);
     }
@@ -1539,17 +1539,17 @@ AttachFinishedCompilations(JSContext *cx
             types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
             enterCompiler.initExisting(builder->recompileInfo);
 
             bool success;
             {
                 // Release the worker thread lock and root the compiler for GC.
                 AutoTempAllocatorRooter root(cx, &builder->temp());
                 AutoUnlockWorkerThreadState unlock(cx->runtime());
-                AutoFlushCache afc("AttachFinishedCompilations");
+                AutoFlushCache afc("AttachFinishedCompilations", cx->runtime()->ionRuntime());
                 success = codegen->link();
             }
 
             if (!success) {
                 // Silently ignore OOM during code generation, we're at an
                 // operation callback and can't propagate failures.
                 cx->clearPendingException();
             }
@@ -1628,17 +1628,17 @@ IonCompile(JSContext *cx, JSScript *scri
     MIRGraph *graph = alloc->new_<MIRGraph>(temp);
     CompileInfo *info = alloc->new_<CompileInfo>(script, script->function(), osrPc, constructing,
                                                  executionMode);
     if (!info)
         return AbortReason_Alloc;
 
     BaselineInspector inspector(cx, script);
 
-    AutoFlushCache afc("IonCompile");
+    AutoFlushCache afc("IonCompile", cx->runtime()->ionRuntime());
 
     types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
     if (!enterCompiler.init(script))
         return AbortReason_Disable;
 
     AutoTempAllocatorRooter root(cx, temp);
 
     IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, &inspector, info, baselineFrame);
@@ -2076,17 +2076,17 @@ EnterIon(JSContext *cx, EnterJitData &da
     JS_ASSERT_IF(data.constructing, data.maxArgv[0].isObject());
 
     data.result.setInt32(data.numActualArgs);
     {
         AssertCompartmentUnchanged pcc(cx);
         IonContext ictx(cx, NULL);
         JitActivation activation(cx, data.constructing);
         JSAutoResolveFlags rf(cx, RESOLVE_INFER);
-        AutoFlushInhibitor afi(cx->compartment()->ionCompartment());
+        AutoFlushInhibitor afi(cx->runtime()->ionRuntime());
 
         // Single transition point from Interpreter to Baseline.
         enter(data.jitcode, data.maxArgc, data.maxArgv, /* osrFrame = */NULL, data.calleeToken,
               /* scopeChain = */ NULL, 0, data.result.address());
     }
 
     JS_ASSERT(!cx->runtime()->hasIonReturnOverride());
 
@@ -2357,17 +2357,17 @@ jit::InvalidateAll(FreeOp *fop, Zone *zo
 }
 
 
 void
 jit::Invalidate(types::TypeCompartment &types, FreeOp *fop,
                 const Vector<types::RecompileInfo> &invalid, bool resetUses)
 {
     IonSpew(IonSpew_Invalidate, "Start invalidation.");
-    AutoFlushCache afc ("Invalidate");
+    AutoFlushCache afc ("Invalidate", fop->runtime()->ionRuntime());
 
     // Add an invalidation reference to all invalidated IonScripts to indicate
     // to the traversal which frames have been invalidated.
     bool anyInvalidation = false;
     for (size_t i = 0; i < invalid.length(); i++) {
         const types::CompilerOutput &co = *invalid[i].compilerOutput(types);
         switch (co.kind()) {
           case types::CompilerOutput::Ion:
@@ -2584,67 +2584,60 @@ jit::UsesBeforeIonRecompile(JSScript *sc
     JS_ASSERT(loopDepth > 0);
     return minUses + loopDepth * 100;
 }
 
 void
 AutoFlushCache::updateTop(uintptr_t p, size_t len)
 {
     IonContext *ictx = GetIonContext();
-    IonRuntime *irt = ictx->runtime->ionRuntime();
+    IonRuntime *irt = (ictx != NULL) ? ictx->runtime->ionRuntime() : NULL;
     if (!irt || !irt->flusher())
         JSC::ExecutableAllocator::cacheFlush((void*)p, len);
     else
         irt->flusher()->update(p, len);
 }
 
 AutoFlushCache::AutoFlushCache(const char *nonce, IonRuntime *rt)
   : start_(0),
     stop_(0),
     name_(nonce),
+    runtime_(rt),
     used_(false)
 {
-    if (CurrentIonContext() != NULL)
-        rt = GetIonContext()->runtime->ionRuntime();
-
-    // If a compartment isn't available, then be a nop, nobody will ever see this flusher
-    if (rt) {
-        if (rt->flusher())
-            IonSpew(IonSpew_CacheFlush, "<%s ", nonce);
-        else
-            IonSpewCont(IonSpew_CacheFlush, "<%s ", nonce);
-        rt->setFlusher(this);
-    } else {
-        IonSpew(IonSpew_CacheFlush, "<%s DEAD>\n", nonce);
-    }
-    runtime_ = rt;
+    if (rt->flusher())
+        IonSpew(IonSpew_CacheFlush, "<%s ", nonce);
+    else
+        IonSpewCont(IonSpew_CacheFlush, "<%s ", nonce);
+
+    rt->setFlusher(this);
 }
 
-AutoFlushInhibitor::AutoFlushInhibitor(IonCompartment *ic)
-  : ic_(ic),
+AutoFlushInhibitor::AutoFlushInhibitor(IonRuntime *rt)
+  : runtime_(rt),
     afc(NULL)
 {
-    if (!ic)
-        return;
-    afc = ic->flusher();
-    // Ensure that called functions get a fresh flusher
-    ic->setFlusher(NULL);
-    // Ensure the current flusher has been flushed
+    afc = rt->flusher();
+
+    // Ensure that called functions get a fresh flusher.
+    rt->setFlusher(NULL);
+
+    // Ensure the current flusher has been flushed.
     if (afc) {
         afc->flushAnyway();
         IonSpewCont(IonSpew_CacheFlush, "}");
     }
 }
 AutoFlushInhibitor::~AutoFlushInhibitor()
 {
-    if (!ic_)
-        return;
-    JS_ASSERT(ic_->flusher() == NULL);
-    // Ensure any future modifications are recorded
-    ic_->setFlusher(afc);
+    JS_ASSERT(runtime_->flusher() == NULL);
+
+    // Ensure any future modifications are recorded.
+    runtime_->setFlusher(afc);
+
     if (afc)
         IonSpewCont(IonSpew_CacheFlush, "{");
 }
 
 void
 jit::PurgeCaches(JSScript *script, Zone *zone)
 {
     if (script->hasIonScript())
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1694,17 +1694,17 @@ GetPropertyIC::update(JSContext *cx, siz
 {
     void *returnAddr;
     RootedScript topScript(cx, GetTopIonJSScript(cx, &returnAddr));
     IonScript *ion = topScript->ionScript();
 
     GetPropertyIC &cache = ion->getCache(cacheIndex).toGetProperty();
     RootedPropertyName name(cx, cache.name());
 
-    AutoFlushCache afc ("GetPropertyCache");
+    AutoFlushCache afc ("GetPropertyCache", cx->runtime()->ionRuntime());
 
     // Override the return value if we are invalidated (bug 728188).
     AutoDetectInvalidation adi(cx, vp.address(), ion);
 
     // If the cache is idempotent, we will redo the op in the interpreter.
     if (cache.idempotent())
         adi.disable();
 
@@ -1856,17 +1856,17 @@ GetPropertyParIC::attachTypedArrayLength
     hasTypedArrayLengthStub_ = true;
     return linkAndAttachStub(cx, masm, attacher, ion, "parallel typed array length");
 }
 
 ParallelResult
 GetPropertyParIC::update(ForkJoinSlice *slice, size_t cacheIndex,
                          HandleObject obj, MutableHandleValue vp)
 {
-    AutoFlushCache afc("GetPropertyParCache");
+    AutoFlushCache afc("GetPropertyParCache", slice->runtime()->ionRuntime());
 
     IonScript *ion = GetTopIonJSScript(slice)->parallelIonScript();
     GetPropertyParIC &cache = ion->getCache(cacheIndex).toGetPropertyPar();
 
     // Grab the property early, as the pure path is fast anyways and doesn't
     // need a lock. If we can't do it purely, bail out of parallel execution.
     if (!GetPropertyPure(slice, obj, NameToId(cache.name()), vp.address()))
         return TP_RETRY_SEQUENTIALLY;
@@ -2690,17 +2690,17 @@ IsPropertyAddInlineable(JSContext *cx, H
     pShape.set(shape);
     return true;
 }
 
 bool
 SetPropertyIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
                       HandleValue value)
 {
-    AutoFlushCache afc ("SetPropertyCache");
+    AutoFlushCache afc ("SetPropertyCache", cx->runtime()->ionRuntime());
 
     void *returnAddr;
     RootedScript script(cx, GetTopIonJSScript(cx, &returnAddr));
     IonScript *ion = script->ionScript();
     SetPropertyIC &cache = ion->getCache(cacheIndex).toSetProperty();
     RootedPropertyName name(cx, cache.name());
     RootedId id(cx, AtomToId(name));
     RootedShape shape(cx);
@@ -3163,17 +3163,17 @@ GetElementIC::update(JSContext *cx, size
     if (cache.isDisabled()) {
         if (!GetElementOperation(cx, JSOp(*pc), &lval, idval, res))
             return false;
         types::TypeScript::Monitor(cx, script, pc, res);
         return true;
     }
 
     // Override the return value if we are invalidated (bug 728188).
-    AutoFlushCache afc ("GetElementCache");
+    AutoFlushCache afc ("GetElementCache", cx->runtime()->ionRuntime());
     AutoDetectInvalidation adi(cx, res.address(), ion);
 
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, idval, &id))
         return false;
 
     bool attachedStub = false;
     if (cache.canAttachStub()) {
@@ -3414,17 +3414,17 @@ GetElementParIC::attachTypedArrayElement
     GenerateTypedArrayElement(cx, masm, attacher, tarr, idval, object(), index(), output());
     return linkAndAttachStub(cx, masm, attacher, ion, "parallel typed array");
 }
 
 ParallelResult
 GetElementParIC::update(ForkJoinSlice *slice, size_t cacheIndex, HandleObject obj,
                         HandleValue idval, MutableHandleValue vp)
 {
-    AutoFlushCache afc("GetElementParCache");
+    AutoFlushCache afc("GetElementParCache", slice->runtime()->ionRuntime());
 
     IonScript *ion = GetTopIonJSScript(slice)->parallelIonScript();
     GetElementParIC &cache = ion->getCache(cacheIndex).toGetElementPar();
 
     // Try to get the element early, as the pure path doesn't need a lock. If
     // we can't do it purely, bail out of parallel execution.
     if (!GetObjectElementOperationPure(slice, obj, idval, vp.address()))
         return TP_RETRY_SEQUENTIALLY;
@@ -3610,17 +3610,17 @@ IsCacheableScopeChain(JSObject *scopeCha
     }
 
     MOZ_ASSUME_UNREACHABLE("Invalid scope chain");
 }
 
 JSObject *
 BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
 {
-    AutoFlushCache afc ("BindNameCache");
+    AutoFlushCache afc ("BindNameCache", cx->runtime()->ionRuntime());
 
     IonScript *ion = GetTopIonJSScript(cx)->ionScript();
     BindNameIC &cache = ion->getCache(cacheIndex).toBindName();
     HandlePropertyName name = cache.name();
 
     RootedObject holder(cx);
     if (scopeChain->is<GlobalObject>()) {
         holder = scopeChain;
@@ -3753,17 +3753,17 @@ IsCacheableNameCallGetter(JSObject *scop
     return IsCacheableGetPropCallNative(obj, holder, shape) ||
         IsCacheableGetPropCallPropertyOp(obj, holder, shape);
 }
 
 bool
 NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
                MutableHandleValue vp)
 {
-    AutoFlushCache afc ("GetNameCache");
+    AutoFlushCache afc ("GetNameCache", cx->runtime()->ionRuntime());
 
     void *returnAddr;
     IonScript *ion = GetTopIonJSScript(cx, &returnAddr)->ionScript();
 
     NameIC &cache = ion->getCache(cacheIndex).toName();
     RootedPropertyName name(cx, cache.name());
 
     RootedScript script(cx);
@@ -3816,17 +3816,17 @@ CallsiteCloneIC::attach(JSContext *cx, I
     attacher.jumpRejoin(masm);
 
     return linkAndAttachStub(cx, masm, attacher, ion, "generic");
 }
 
 JSObject *
 CallsiteCloneIC::update(JSContext *cx, size_t cacheIndex, HandleObject callee)
 {
-    AutoFlushCache afc ("CallsiteCloneCache");
+    AutoFlushCache afc ("CallsiteCloneCache", cx->runtime()->ionRuntime());
 
     // Act as the identity for functions that are not clone-at-callsite, as we
     // generate this cache as long as some callees are clone-at-callsite.
     RootedFunction fun(cx, &callee->as<JSFunction>());
     if (!fun->hasScript() || !fun->nonLazyScript()->shouldCloneAtCallsite)
         return fun;
 
     IonScript *ion = GetTopIonJSScript(cx)->ionScript();
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -709,34 +709,35 @@ struct AutoFlushCache
     const char *name_;
     IonRuntime *runtime_;
     bool used_;
 
   public:
     void update(uintptr_t p, size_t len);
     static void updateTop(uintptr_t p, size_t len);
     ~AutoFlushCache();
-    AutoFlushCache(const char *nonce, IonRuntime *rt = NULL);
+    AutoFlushCache(const char *nonce, IonRuntime *rt);
     void flushAnyway();
 };
 
 // If you are currently in the middle of modifing Ion-compiled code, which
 // is going to be flushed at *some* point, but determine that you *must*
 // call a function *right* *now*, two things can go wrong:
 //   1)  The flusher that you were using is still active, but you are about to
 //       enter jitted code, so it needs to be flushed
 //   2) the called function can re-enter a compilation/modification path which
 //       will use your AFC, and thus not flush when his compilation is done
 
-struct AutoFlushInhibitor {
+struct AutoFlushInhibitor
+{
   private:
-    IonCompartment *ic_;
+    IonRuntime *runtime_;
     AutoFlushCache *afc;
   public:
-    AutoFlushInhibitor(IonCompartment *ic);
+    AutoFlushInhibitor(IonRuntime *rt);
     ~AutoFlushInhibitor();
 };
 } // namespace jit
 
 namespace gc {
 
 inline bool
 IsMarked(const jit::VMFunction *)
--- a/js/src/jit/IonCompartment.h
+++ b/js/src/jit/IonCompartment.h
@@ -427,22 +427,16 @@ class IonCompartment
     IonCode *stringConcatStub(ExecutionMode mode) {
         switch (mode) {
           case SequentialExecution: return stringConcatStub_;
           case ParallelExecution:   return parallelStringConcatStub_;
           default:                  MOZ_ASSUME_UNREACHABLE("No such execution mode");
         }
     }
 
-    AutoFlushCache *flusher() {
-        return rt->flusher();
-    }
-    void setFlusher(AutoFlushCache *fl) {
-        rt->setFlusher(fl);
-    }
     OptimizedICStubSpace *optimizedStubSpace() {
         return &optimizedStubSpace_;
     }
 };
 
 // Called from JSCompartment::discardJitCode().
 void InvalidateAll(FreeOp *fop, JS::Zone *zone);
 void FinishInvalidation(FreeOp *fop, JSScript *script);
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -2736,17 +2736,18 @@ void Assembler::updateBoundsCheck(uint32
 
     Op2Reg reg = op.toOp2Reg();
     Register index;
     reg.getRM(&index);
     JS_ASSERT(reg.isO2RegImmShift());
     // O2RegImmShift shift = reg.toO2RegImmShift();
 
     *inst = InstALU(ScratchRegister, InvalidReg, lsr(index, logHeapSize), op_mov, SetCond, Always);
-    AutoFlushCache::updateTop(uintptr_t(inst), 4);
+    // NOTE: we don't update the Auto Flush Cache!  this function is currently only called from
+    // within AsmJSModule::patchHeapAccesses, which does that for us.  Don't call this!
 }
 
 void
 AutoFlushCache::update(uintptr_t newStart, size_t len)
 {
     uintptr_t newStop = newStart + len;
     used_ = true;
     if (!start_) {
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -1904,19 +1904,19 @@ CodeGeneratorARM::visitSoftUDivOrMod(LSo
 {
     Register lhs = ToRegister(ins->lhs());
     Register rhs = ToRegister(ins->rhs());
     Register output = ToRegister(ins->output());
 
     JS_ASSERT(lhs == r0);
     JS_ASSERT(rhs == r1);
     JS_ASSERT(ins->mirRaw()->isDiv() || ins->mirRaw()->isAsmJSUDiv() ||
-              ins->mirRaw()->isAsmJSUMod());
+              ins->mirRaw()->isMod() || ins->mirRaw()->isAsmJSUMod());
     JS_ASSERT_IF(ins->mirRaw()->isDiv() || ins->mirRaw()->isAsmJSUDiv(), output == r0);
-    JS_ASSERT_IF(ins->mirRaw()->isAsmJSUMod(), output == r1);
+    JS_ASSERT_IF(ins->mirRaw()->isMod() || ins->mirRaw()->isAsmJSUMod(), output == r1);
 
     Label afterDiv;
 
     masm.ma_cmp(rhs, Imm32(0));
     Label notzero;
     masm.ma_b(&notzero, Assembler::NonZero);
     masm.ma_mov(Imm32(0), output);
     masm.ma_b(&afterDiv);
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -10,17 +10,16 @@
 #include "mozilla/Util.h"
 
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "jsalloc.h"
-#include "jsapi.h"
 #include "jscntxt.h"
 #include "jsgc.h"
 
 #include "js/Vector.h"
 
 /* Note: Aborts on OOM. */
 class JSAPITestString {
     js::Vector<char, 0, js::SystemAllocPolicy> chars;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -102,21 +102,16 @@ using mozilla::PodZero;
 using js::frontend::Parser;
 
 #ifdef HAVE_VA_LIST_AS_ARRAY
 #define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
 #else
 #define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
 #endif
 
-const jsid voidIdValue = JSID_VOID;
-const jsid emptyIdValue = JSID_EMPTY;
-const HandleId JS::JSID_VOIDHANDLE = HandleId::fromMarkedLocation(&voidIdValue);
-const HandleId JS::JSID_EMPTYHANDLE = HandleId::fromMarkedLocation(&emptyIdValue);
-
 /* Make sure that jschar is two bytes unsigned integer */
 JS_STATIC_ASSERT((jschar)-1 > 0);
 JS_STATIC_ASSERT(sizeof(jschar) == 2);
 
 JS_PUBLIC_API(int64_t)
 JS_Now()
 {
     return PRMJ_Now();
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4575,16 +4575,9 @@ JS_EncodeInterpretedFunction(JSContext *
 extern JS_PUBLIC_API(JSScript *)
 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length,
                 JSPrincipals *principals, JSPrincipals *originPrincipals);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
                              JSPrincipals *principals, JSPrincipals *originPrincipals);
 
-namespace JS {
-
-extern JS_PUBLIC_DATA(const Handle<jsid>) JSID_VOIDHANDLE;
-extern JS_PUBLIC_DATA(const Handle<jsid>) JSID_EMPTYHANDLE;
-
-} /* namespace JS */
-
 #endif /* jsapi_h */
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -10,17 +10,16 @@
 
 #include "jsatominlines.h"
 
 #include "mozilla/RangedPtr.h"
 #include "mozilla/Util.h"
 
 #include <string.h>
 
-#include "jsapi.h"
 #include "jscntxt.h"
 #include "jsstr.h"
 #include "jstypes.h"
 
 #include "gc/Marking.h"
 #include "vm/Xdr.h"
 
 #include "jscntxtinlines.h"
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -4,21 +4,24 @@
  * 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 jsatom_h
 #define jsatom_h
 
 #include "mozilla/HashFunctions.h"
 
+#include "jsalloc.h"
+
 #include "gc/Barrier.h"
 #include "gc/Rooting.h"
 #include "vm/CommonPropertyNames.h"
 
 class JSAtom;
+class JSAutoByteString;
 
 struct JSIdArray {
     int length;
     js::HeapId vector[1];    /* actually, length jsid words */
 };
 
 namespace js {
 
--- a/js/src/jsbool.h
+++ b/js/src/jsbool.h
@@ -6,17 +6,16 @@
 
 #ifndef jsbool_h
 #define jsbool_h
 
 /*
  * JS boolean interface.
  */
 
-#include "jsapi.h"
 #include "NamespaceImports.h"
 
 extern JSObject *
 js_InitBooleanClass(JSContext *cx, js::HandleObject obj);
 
 extern JSString *
 js_BooleanToString(js::ExclusiveContext *cx, bool b);
 
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -7,17 +7,16 @@
 /* JS Garbage Collector. */
 
 #ifndef jsgc_h
 #define jsgc_h
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/MemoryReporting.h"
 
-#include "jsapi.h"
 #include "jslock.h"
 #include "jsobj.h"
 
 #include "js/GCAPI.h"
 #include "js/Vector.h"
 
 class JSAtom;
 struct JSCompartment;
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -6,22 +6,24 @@
 
 /* Definitions related to javascript type inference. */
 
 #ifndef jsinfer_h
 #define jsinfer_h
 
 #include "mozilla/MemoryReporting.h"
 
+#include "jsalloc.h"
 #include "jsfriendapi.h"
 
 #include "ds/IdValuePair.h"
 #include "ds/LifoAlloc.h"
 #include "gc/Barrier.h"
 #include "js/Utility.h"
+#include "js/Vector.h"
 
 namespace js {
 
 class TypeRepresentation;
 
 class TaggedProto
 {
   public:
--- a/js/src/json.h
+++ b/js/src/json.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 json_h
 #define json_h
 
-#include "jsapi.h"
 #include "NamespaceImports.h"
 
 #include "js/RootingAPI.h"
 
 namespace js {
 class StringBuffer;
 }
 
--- a/js/src/jsonparser.h
+++ b/js/src/jsonparser.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 jsonparser_h
 #define jsonparser_h
 
 #include "mozilla/Attributes.h"
 
-#include "jsapi.h"
-
 #include "ds/IdValuePair.h"
 #include "vm/String.h"
 
 namespace js {
 
 class MOZ_STACK_CLASS JSONParser : private AutoGCRooter
 {
   public:
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -6,17 +6,16 @@
 
 #ifndef jsopcode_h
 #define jsopcode_h
 
 /*
  * JS bytecode definitions.
  */
 
-#include "jsapi.h"
 #include "jsbytecode.h"
 #include "NamespaceImports.h"
 
 #include "frontend/SourceNotes.h"
 
 /*
  * JS operation bytecodes.
  */
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -2357,17 +2357,17 @@ Proxy::defineProperty(JSContext *cx, Han
            Proxy::defineProperty(cx, proxy, id, &desc);
 }
 
 bool
 Proxy::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return proxy->as<ProxyObject>().handler()->getOwnPropertyNames(cx, proxy, props);
 }
 
 bool
 Proxy::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
 {
@@ -2400,17 +2400,17 @@ js::AppendUnique(JSContext *cx, AutoIdVe
     return base.appendAll(uniqueOthers);
 }
 
 bool
 Proxy::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     if (!handler->hasPrototype())
         return proxy->as<ProxyObject>().handler()->enumerate(cx, proxy, props);
     if (!handler->keys(cx, proxy, props))
         return false;
     AutoIdVector protoProps(cx);
     INVOKE_ON_PROTOTYPE(cx, handler, proxy,
@@ -2538,30 +2538,30 @@ Proxy::set(JSContext *cx, HandleObject p
     return handler->set(cx, proxy, receiver, id, strict, vp);
 }
 
 bool
 Proxy::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return handler->keys(cx, proxy, props);
 }
 
 bool
 Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
     vp.setUndefined(); // default result if we refuse to perform this action
     if (!handler->hasPrototype()) {
-        AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
+        AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                                BaseProxyHandler::GET, true);
         // If the policy denies access but wants us to return true, we need
         // to hand a valid (empty) iterator object to the caller.
         if (!policy.allowed()) {
             AutoIdVector props(cx);
             return policy.returnValue() &&
                    EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp);
         }
@@ -2596,17 +2596,17 @@ bool
 Proxy::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
 
     // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
     // can only set our default value once we're sure that we're not calling the
     // trap.
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                            BaseProxyHandler::CALL, true);
     if (!policy.allowed()) {
         args.rval().setUndefined();
         return policy.returnValue();
     }
 
     return handler->call(cx, proxy, args);
 }
@@ -2615,17 +2615,17 @@ bool
 Proxy::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
 
     // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
     // can only set our default value once we're sure that we're not calling the
     // trap.
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                            BaseProxyHandler::CALL, true);
     if (!policy.allowed()) {
         args.rval().setUndefined();
         return policy.returnValue();
     }
 
     return handler->construct(cx, proxy, args);
 }
@@ -2642,17 +2642,17 @@ Proxy::nativeCall(JSContext *cx, IsAccep
 }
 
 bool
 Proxy::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
     *bp = false; // default result if we refuse to perform this action
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return proxy->as<ProxyObject>().handler()->hasInstance(cx, proxy, v, bp);
 }
 
 bool
 Proxy::objectClassIs(HandleObject proxy, ESClassValue classValue, JSContext *cx)
 {
@@ -2665,31 +2665,31 @@ Proxy::className(JSContext *cx, HandleOb
 {
     // Check for unbounded recursion, but don't signal an error; className
     // needs to be infallible.
     int stackDummy;
     if (!JS_CHECK_STACK_SIZE(GetNativeStackLimit(cx), &stackDummy))
         return "too much recursion";
 
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                            BaseProxyHandler::GET, /* mayThrow = */ false);
     // Do the safe thing if the policy rejects.
     if (!policy.allowed()) {
         return handler->BaseProxyHandler::className(cx, proxy);
     }
     return handler->className(cx, proxy);
 }
 
 JSString *
 Proxy::fun_toString(JSContext *cx, HandleObject proxy, unsigned indent)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
-    AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
+    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                            BaseProxyHandler::GET, /* mayThrow = */ false);
     // Do the safe thing if the policy rejects.
     if (!policy.allowed()) {
         if (proxy->isCallable())
             return JS_NewStringCopyZ(cx, "function () {\n    [native code]\n}");
         ReportIsNotFunction(cx, ObjectValue(*proxy));
         return NULL;
     }
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -1470,16 +1470,18 @@ NodeBuilder::function(ASTType type, Toke
                    "defaults", defarray,
                    "body", body,
                    "rest", rest,
                    "generator", isGeneratorVal,
                    "expression", isExpressionVal,
                    dst);
 }
 
+namespace {
+
 /*
  * Serialization of parse nodes to JavaScript objects.
  *
  * All serialization methods take a non-nullable ParseNode pointer.
  */
 class ASTSerializer
 {
     JSContext           *cx;
@@ -1581,16 +1583,18 @@ class ASTSerializer
     void setParser(Parser<FullParseHandler> *p) {
         parser = p;
         builder.setTokenStream(&p->tokenStream);
     }
 
     bool program(ParseNode *pn, MutableHandleValue dst);
 };
 
+} /* anonymous namespace */
+
 AssignmentOperator
 ASTSerializer::aop(JSOp op)
 {
     switch (op) {
       case JSOP_NOP:
         return AOP_ASSIGN;
       case JSOP_ADD:
         return AOP_PLUS;
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.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 jsweakmap_h
 #define jsweakmap_h
 
-#include "jsapi.h"
 #include "jscompartment.h"
 #include "jsfriendapi.h"
 #include "jsobj.h"
 
 #include "gc/Marking.h"
 #include "js/HashTable.h"
 
 namespace js {
--- a/js/src/shell/jsheaptools.h
+++ b/js/src/shell/jsheaptools.h
@@ -4,15 +4,15 @@
  * 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 shell_jsheaptools_h
 #define shell_jsheaptools_h
 
 #ifdef DEBUG
 
-#include "jsapi.h"
+#include "js/TypeDecls.h"
 
-bool FindReferences(JSContext *cx, unsigned argc, jsval *vp);
+bool FindReferences(JSContext *cx, unsigned argc, JS::Value *vp);
 
 #endif /* DEBUG */
 
 #endif /* shell_jsheaptools_h */
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.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 vm_Debugger_h
 #define vm_Debugger_h
 
 #include "mozilla/LinkedList.h"
 
-#include "jsapi.h"
 #include "jsclist.h"
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsweakmap.h"
 
 #include "gc/Barrier.h"
 #include "js/HashTable.h"
 #include "vm/GlobalObject.h"
--- a/js/src/vm/Id.cpp
+++ b/js/src/vm/Id.cpp
@@ -1,13 +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 "js/Id.h"
+#include "js/RootingAPI.h"
 
 #ifdef JS_USE_JSID_STRUCT_TYPES
 const jsid JSID_VOID  = { size_t(JSID_TYPE_VOID) };
 const jsid JSID_EMPTY = { size_t(JSID_TYPE_OBJECT) };
 #endif
 
+static const jsid voidIdValue = JSID_VOID;
+static const jsid emptyIdValue = JSID_EMPTY;
+const JS::HandleId JSID_VOIDHANDLE = JS::HandleId::fromMarkedLocation(&voidIdValue);
+const JS::HandleId JSID_EMPTYHANDLE = JS::HandleId::fromMarkedLocation(&emptyIdValue);
+
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.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 vm_Interpreter_inl_h
 #define vm_Interpreter_inl_h
 
 #include "vm/Interpreter.h"
 
-#include "jsapi.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"
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.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 vm_TypedArrayObject_h
 #define vm_TypedArrayObject_h
 
-#include "jsapi.h"
 #include "jsobj.h"
 
 #include "builtin/TypeRepresentation.h"
 #include "gc/Barrier.h"
 #include "js/Class.h"
 
 typedef struct JSProperty JSProperty;
 
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1019,17 +1019,17 @@ public:
     enum {NO_ARGS = (unsigned) -1};
 
     static JSContext* GetDefaultJSContext();
 
     XPCCallContext(XPCContext::LangType callerLanguage,
                    JSContext* cx           = GetDefaultJSContext(),
                    JS::HandleObject obj    = JS::NullPtr(),
                    JS::HandleObject funobj = JS::NullPtr(),
-                   JS::HandleId id         = JS::JSID_VOIDHANDLE,
+                   JS::HandleId id         = JSID_VOIDHANDLE,
                    unsigned argc           = NO_ARGS,
                    jsval *argv             = nullptr,
                    jsval *rval             = nullptr);
 
     virtual ~XPCCallContext();
 
     inline bool                         IsValid() const ;
 
--- a/js/xpconnect/wrappers/AccessCheck.h
+++ b/js/xpconnect/wrappers/AccessCheck.h
@@ -3,18 +3,18 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __AccessCheck_h__
 #define __AccessCheck_h__
 
-#include "jsapi.h"
 #include "jswrapper.h"
+#include "js/Id.h"
 
 class nsIPrincipal;
 
 namespace xpc {
 
 class AccessCheck {
   public:
     static bool subsumes(JSCompartment *a, JSCompartment *b);
@@ -71,17 +71,17 @@ struct GentlyOpaque : public Policy {
 // This policy only permits access to properties that are safe to be used
 // across origins.
 struct CrossOriginAccessiblePropertiesOnly : public Policy {
     static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
         return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act);
     }
     static bool deny(js::Wrapper::Action act, JS::HandleId id) {
         // Silently fail for enumerate-like operations.
-        if (act == js::Wrapper::GET && id == JS::JSID_VOIDHANDLE)
+        if (act == js::Wrapper::GET && id == JSID_VOIDHANDLE)
             return true;
         return false;
     }
     static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl)
     {
         return false;
     }
 };
--- a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp
+++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp
@@ -1,9 +1,10 @@
 #include "ChromeObjectWrapper.h"
+#include "jsapi.h"
 
 using namespace JS;
 
 namespace xpc {
 
 // When creating wrappers for chrome objects in content, we detect if the
 // prototype of the wrapped chrome object is a prototype for a standard class
 // (like Array.prototype). If it is, we use the corresponding standard prototype
--- a/js/xpconnect/wrappers/FilteringWrapper.h
+++ b/js/xpconnect/wrappers/FilteringWrapper.h
@@ -3,18 +3,25 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __FilteringWrapper_h__
 #define __FilteringWrapper_h__
 
-#include <jsapi.h>
-#include <jswrapper.h>
+#include "mozilla/Attributes.h"
+#include "jswrapper.h"
+#include "js/CallNonGenericMethod.h"
+
+struct JSPropertyDescriptor;
+
+namespace JS {
+class AutoIdVector;
+}
 
 namespace xpc {
 
 template <typename Base, typename Policy>
 class FilteringWrapper : public Base {
   public:
     FilteringWrapper(unsigned flags);
     virtual ~FilteringWrapper();
@@ -23,21 +30,21 @@ class FilteringWrapper : public Base {
                                        JS::Handle<jsid> id,
                                        JS::MutableHandle<JSPropertyDescriptor> desc,
                                        unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
                                           JS::Handle<jsid> id,
                                           JS::MutableHandle<JSPropertyDescriptor> desc,
                                           unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JS::Handle<JSObject*> wrapper,
-                                     js::AutoIdVector &props) MOZ_OVERRIDE;
+                                     JS::AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper,
-                           js::AutoIdVector &props) MOZ_OVERRIDE;
+                           JS::AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool keys(JSContext *cx, JS::Handle<JSObject*> wrapper,
-                      js::AutoIdVector &props) MOZ_OVERRIDE;
+                      JS::AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned flags,
                          JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl,
                             JS::CallArgs args) MOZ_OVERRIDE;
 
     virtual bool defaultValue(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint, JS::MutableHandleValue vp) MOZ_OVERRIDE;
 
     virtual bool enter(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2656,31 +2656,31 @@ ChooseScaleAndSetTransform(FrameLayerBui
     transform = (*aTransform)*transform;
     // Set any matrix entries close to integers to be those exact integers.
     // This protects against floating-point inaccuracies causing problems
     // in the checks below.
     transform.NudgeToIntegers();
   }
   gfxMatrix transform2d;
   if (aContainerFrame &&
-      aState == LAYER_INACTIVE &&
+      (aState == LAYER_INACTIVE || aState == LAYER_SVG_EFFECTS) &&
       (!aTransform || (aTransform->Is2D(&transform2d) &&
                        !transform2d.HasNonTranslation()))) {
     // When we have an inactive ContainerLayer, translate the container by the offset to the
     // reference frame (and offset all child layers by the reverse) so that the coordinate
     // space of the child layers isn't affected by scrolling.
     // This gets confusing for complicated transform (since we'd have to compute the scale
     // factors for the matrix), so we don't bother. Any frames that are building an nsDisplayTransform
     // for a css transform would have 0,0 as their offset to the reference frame, so this doesn't
     // matter.
     nsPoint appUnitOffset = aDisplayListBuilder->ToReferenceFrame(aContainerFrame);
     nscoord appUnitsPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
     offset = nsIntPoint(
-        int32_t(NSAppUnitsToDoublePixels(appUnitOffset.x, appUnitsPerDevPixel)*aIncomingScale.mXScale),
-        int32_t(NSAppUnitsToDoublePixels(appUnitOffset.y, appUnitsPerDevPixel)*aIncomingScale.mYScale));
+        NS_lround(NSAppUnitsToDoublePixels(appUnitOffset.x, appUnitsPerDevPixel)*aIncomingScale.mXScale),
+        NS_lround(NSAppUnitsToDoublePixels(appUnitOffset.y, appUnitsPerDevPixel)*aIncomingScale.mYScale));
   }
   transform = transform * gfx3DMatrix::Translation(offset.x + aIncomingScale.mOffset.x, offset.y + aIncomingScale.mOffset.y, 0);
 
   if (transform.IsSingular()) {
     return false;
   }
 
   bool canDraw2D = transform.CanDraw2D(&transform2d);
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1152,17 +1152,28 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
    * for refresh events.
    */
 
   ImageRequestParameters parms = {aNowTime, previousRefresh, &mRequests};
 
   mStartTable.EnumerateRead(nsRefreshDriver::StartTableRefresh, &parms);
 
   if (mRequests.Count()) {
-    mRequests.EnumerateEntries(nsRefreshDriver::ImageRequestEnumerator, &parms);
+    // RequestRefresh may run scripts, so it's not safe to directly call it
+    // while using a hashtable enumerator to enumerate mRequests in case
+    // script modifies the hashtable. Instead, we build a (local) array of
+    // images to refresh, and then we refresh each image in that array.
+    nsCOMArray<imgIContainer> imagesToRefresh(mRequests.Count());
+    mRequests.EnumerateEntries(nsRefreshDriver::ImageRequestEnumerator,
+                               &imagesToRefresh);
+
+    for (uint32_t i = 0; i < imagesToRefresh.Length(); i++) {
+      imagesToRefresh[i]->RequestRefresh(aNowTime);
+    }
+    imagesToRefresh.Clear();
   }
 
   for (uint32_t i = 0; i < mPresShellsToInvalidateIfHidden.Length(); i++) {
     mPresShellsToInvalidateIfHidden[i]->InvalidatePresShellIfHidden();
   }
   mPresShellsToInvalidateIfHidden.Clear();
 
   if (mViewManagerFlushIsPending) {
@@ -1189,24 +1200,23 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
 #endif
   }
 }
 
 /* static */ PLDHashOperator
 nsRefreshDriver::ImageRequestEnumerator(nsISupportsHashKey* aEntry,
                                         void* aUserArg)
 {
-  ImageRequestParameters* parms =
-    static_cast<ImageRequestParameters*> (aUserArg);
-  mozilla::TimeStamp mostRecentRefresh = parms->mCurrent;
+  nsCOMArray<imgIContainer>* imagesToRefresh =
+    static_cast<nsCOMArray<imgIContainer>*> (aUserArg);
   imgIRequest* req = static_cast<imgIRequest*>(aEntry->GetKey());
   NS_ABORT_IF_FALSE(req, "Unable to retrieve the image request");
   nsCOMPtr<imgIContainer> image;
   if (NS_SUCCEEDED(req->GetImage(getter_AddRefs(image)))) {
-    image->RequestRefresh(mostRecentRefresh);
+    imagesToRefresh->AppendElement(image);
   }
 
   return PL_DHASH_NEXT;
 }
 
 /* static */ PLDHashOperator
 nsRefreshDriver::BeginRefreshingImages(nsISupportsHashKey* aEntry,
                                        void* aUserArg)
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1041,18 +1041,16 @@ nsBlockFrame::Reflow(nsPresContext*     
       state.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
     }
 
 #ifdef DEBUG_kipp
     ListTag(stdout); printf(": block is not fully complete\n");
 #endif
   }
 
-  CheckFloats(state);
-
   // Place the "marker" (bullet) frame if it is placed next to a block
   // child.
   //
   // According to the CSS2 spec, section 12.6.1, the "marker" box
   // participates in the height calculation of the list-item box's
   // first line box.
   //
   // There are exactly two places a bullet can be placed: near the
@@ -1086,16 +1084,18 @@ nsBlockFrame::Reflow(nsPresContext*     
       // Tall bullets won't look particularly nice here...
       nsRect bbox = bullet->GetRect();
       bbox.y = position.mBaseline - metrics.ascent;
       bullet->SetRect(bbox);
     }
     // Otherwise just leave the bullet where it is, up against our top padding.
   }
 
+  CheckFloats(state);
+
   // Compute our final size
   nscoord bottomEdgeOfChildren;
   ComputeFinalSize(*reflowState, state, aMetrics, &bottomEdgeOfChildren);
   nsRect areaBounds = nsRect(0, 0, aMetrics.width, aMetrics.height);
   ComputeOverflowAreas(areaBounds, reflowState->mStyleDisplay,
                        bottomEdgeOfChildren, aMetrics.mOverflowAreas);
   // Factor overflow container child bounds into the overflow area
   aMetrics.mOverflowAreas.UnionWith(ocBounds);
--- a/layout/reftests/line-breaking/reftest.list
+++ b/layout/reftests/line-breaking/reftest.list
@@ -26,9 +26,9 @@ random-if(cocoaWidget) == ja-3.html ja-3
 # representations on the test boxes. See bug #450088 for discussion.
 skip-if(B2G) skip-if(gtk2Widget) == quotationmarks-cjk-1.html quotationmarks-cjk-1-ref.html # bug 773482
 == smileys-1.html smileys-1-ref.html
 == smileys-2.html smileys-2-ref.html
 == url-1.html url-1-ref.html
 == url-2.html url-2-ref.html
 == url-3.html url-3-ref.html
 == winpath-1.html winpath-1-ref.html
-fuzzy-if(cocoaWidget,238,58) == zwnbsp-1.html zwnbsp-1-ref.html
+== zwnbsp-1.html zwnbsp-1-ref.html
--- a/layout/reftests/line-breaking/zwnbsp-1-ref.html
+++ b/layout/reftests/line-breaking/zwnbsp-1-ref.html
@@ -12,33 +12,33 @@ p { margin: 5px 1em; line-height: 1.5; }
 <!-- U+FEFF is (deprecated) ZERO-WIDTH NO-BREAK SPACE -->
 <p>abcdefabcdef</p>
 <p>abcdef)(abcdef</p>
 <p>abcdef<br>abcdef</p>
 <p>abcdef<br>abcdef</p>
 <p>abcdefabcdef</p>
 
 <p>コ<br>ミュ<br>ニ</p>
-<p>コミュニ</p>
+<p>コ&#xfeff;ミ&#xfeff;ュ&#xfeff;ニ</p>
 
 <p>你<br>好<br>吗?</p>
 <p>你好<br>吗?</p>
 <p>你好吗?</p>
 </div>
 
 <div style="float:left; width: 15em;">
 <!-- U+2060 is WORD JOINER -->
 <p>abcdefabcdef</p>
 <p>abcdef)(abcdef</p>
 <p>abcdef<br>abcdef</p>
 <p>abcdef<br>abcdef</p>
 <p>abcdefabcdef</p>
 
 <p>コ<br>ミュ<br>ニ</p>
-<p>コミュニ</p>
+<p>コ&#x2060;ミ&#x2060;ュ&#x2060;ニ</p>
 
 <p>你<br>好<br>吗?</p>
 <p>你好<br>吗?</p>
 <p>你好吗?</p>
 </div>
 
 </body>
 </html>
--- a/layout/svg/nsSVGFilterFrame.cpp
+++ b/layout/svg/nsSVGFilterFrame.cpp
@@ -40,16 +40,19 @@ NS_IMPL_FRAMEARENA_HELPERS(nsSVGFilterFr
 static nsIntRect
 MapFrameRectToFilterSpace(const nsRect* aRect,
                           int32_t aAppUnitsPerCSSPx,
                           const gfxMatrix& aFrameSpaceInCSSPxToFilterSpace,
                           const gfxIntSize& aFilterRes)
 {
   nsIntRect rect(0, 0, aFilterRes.width, aFilterRes.height);
   if (aRect) {
+    if (aRect->IsEmpty()) {
+      return nsIntRect();
+    }
     gfxRect rectInCSSPx =
       nsLayoutUtils::RectToGfxRect(*aRect, aAppUnitsPerCSSPx);
     gfxRect rectInFilterSpace =
       aFrameSpaceInCSSPxToFilterSpace.TransformBounds(rectInCSSPx);
     rectInFilterSpace.RoundOut();
     nsIntRect intRect;
     if (gfxUtils::GfxRectToIntRect(rectInFilterSpace, &intRect)) {
       rect = intRect;
@@ -451,26 +454,33 @@ nsSVGFilterFrame::PaintFilteredFrame(nsR
   }
   return rv;
 }
 
 static nsRect
 TransformFilterSpaceToFrameSpace(nsSVGFilterInstance *aInstance,
                                  nsIntRect *aRect)
 {
+  if (aRect->IsEmpty()) {
+    return nsRect();
+  }
   gfxMatrix m = aInstance->GetFilterSpaceToFrameSpaceInCSSPxTransform();
   gfxRect r(aRect->x, aRect->y, aRect->width, aRect->height);
   r = m.TransformBounds(r);
   return nsLayoutUtils::RoundGfxRectToAppRect(r, aInstance->AppUnitsPerCSSPixel());
 }
 
 nsRect
 nsSVGFilterFrame::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
                                          const nsRect& aPreFilterDirtyRect)
 {
+  if (aPreFilterDirtyRect.IsEmpty()) {
+    return nsRect();
+  }
+
   nsAutoFilterInstance instance(aFilteredFrame, this, nullptr, nullptr,
                                 &aPreFilterDirtyRect, nullptr);
   if (!instance.get()) {
     return nsRect();
   }
   // We've passed in the source's dirty area so the instance knows about it.
   // Now we can ask the instance to compute the area of the filter output
   // that's dirty.
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -281,16 +281,20 @@ nsRect
   return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToUserSpace);
 }
 
 nsIntRect
 nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame,
                                                       const nsPoint& aToReferenceFrame,
                                                       const nsIntRect& aInvalidRect)
 {
+  if (aInvalidRect.IsEmpty()) {
+    return nsIntRect();
+  }
+
   // Don't bother calling GetEffectProperties; the filter property should
   // already have been set up during reflow/ComputeFrameEffectsRect
   nsIFrame* firstFrame =
     nsLayoutUtils::GetFirstContinuationOrSpecialSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
   if (!effectProperties.mFilter)
     return aInvalidRect;
--- a/media/mtransport/nricemediastream.cpp
+++ b/media/mtransport/nricemediastream.cpp
@@ -192,27 +192,32 @@ nsresult NrIceMediaStream::ParseTrickleC
                 << name_ << "'");
       return NS_ERROR_FAILURE;
     }
   }
 
   return NS_OK;
 }
 
+// Returns NS_ERROR_NOT_AVAILABLE if component is unpaired or disabled.
 nsresult NrIceMediaStream::GetActivePair(int component,
                                          NrIceCandidate **localp,
                                          NrIceCandidate **remotep) {
   int r;
   nr_ice_candidate *local_int;
   nr_ice_candidate *remote_int;
 
   r = nr_ice_media_stream_get_active(ctx_->peer(),
                                      stream_,
                                      component,
                                      &local_int, &remote_int);
+  // If result is R_REJECTED then component is unpaired or disabled.
+  if (r == R_REJECTED)
+    return NS_ERROR_NOT_AVAILABLE;
+
   if (r)
     return NS_ERROR_FAILURE;
 
   ScopedDeletePtr<NrIceCandidate> local(
       MakeNrIceCandidate(*local_int));
   if (!local)
     return NS_ERROR_FAILURE;
 
@@ -299,16 +304,31 @@ std::vector<std::string> NrIceMediaStrea
     RFREE(attrs[i]);
   }
 
   RFREE(attrs);
 
   return ret;
 }
 
+nsresult NrIceMediaStream::DisableComponent(int component_id) {
+  if (!stream_)
+    return NS_ERROR_FAILURE;
+
+  int r = nr_ice_media_stream_disable_component(stream_,
+                                                component_id);
+  if (r) {
+    MOZ_MTLOG(ML_ERROR, "Couldn't disable '" << name_ << "':" <<
+              component_id);
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
 nsresult NrIceMediaStream::SendPacket(int component_id,
                                       const unsigned char *data,
                                       size_t len) {
   if (!stream_)
     return NS_ERROR_FAILURE;
 
   int r = nr_ice_media_stream_send(ctx_->peer(), stream_,
                                    component_id,
--- a/media/mtransport/nricemediastream.h
+++ b/media/mtransport/nricemediastream.h
@@ -99,16 +99,19 @@ class NrIceMediaStream {
   nsresult GetDefaultCandidate(int component, std::string *host, int *port);
 
   // Parse remote attributes
   nsresult ParseAttributes(std::vector<std::string>& candidates);
 
   // Parse trickle ICE candidate
   nsresult ParseTrickleCandidate(const std::string& candidate);
 
+  // Disable a component
+  nsresult DisableComponent(int component);
+
   // Get the candidate pair currently active. It's the
   // caller's responsibility to free these.
   nsresult GetActivePair(int component,
                          NrIceCandidate** local, NrIceCandidate** remote);
 
   // The number of components
   int components() const { return components_; }
 
--- a/media/mtransport/test/gtest_utils.h
+++ b/media/mtransport/test/gtest_utils.h
@@ -48,27 +48,27 @@
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 
 // Wait up to timeout seconds for expression to be true
 #define WAIT(expression, timeout) \
   do { \
   for (PRIntervalTime start = PR_IntervalNow(); !(expression) &&        \
            ! ((PR_IntervalNow() - start) > PR_MillisecondsToInterval(timeout));) \
-    PR_Sleep(200); \
+    PR_Sleep(10); \
   } while(0)
 
 // Same as GTEST_WAIT, but stores the result in res. Used when
 // you also want the result of expression but wish to avoid
 // double evaluation.
 #define WAIT_(expression, timeout, res)                      \
   do { \
   for (PRIntervalTime start = PR_IntervalNow(); !(res = (expression)) && \
            ! ((PR_IntervalNow() - start) > PR_MillisecondsToInterval(timeout));) \
-    PR_Sleep(200); \
+    PR_Sleep(10); \
   } while(0)
 
 #define ASSERT_TRUE_WAIT(expression, timeout) \
   do { \
   bool res; \
   WAIT_(expression, timeout, res); \
   ASSERT_TRUE(res); \
   } while(0);
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -163,20 +163,26 @@ class IceTestPeer : public sigslot::has_
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   // Get various pieces of state
   std::vector<std::string> GetGlobalAttributes() {
     return ice_ctx_->GetGlobalAttributes();
   }
 
-  std::vector<std::string> GetCandidates(const std::string &name) {
-    std::vector<std::string> candidates_in = candidates_[name];
+  std::vector<std::string> GetCandidates(size_t stream) {
     std::vector<std::string> candidates;
 
+    if (stream >= streams_.size())
+      return candidates;
+
+    std::vector<std::string> candidates_in =
+      streams_[stream]->GetCandidates();
+
+
     for (size_t i=0; i < candidates_in.size(); i++) {
       if ((!candidate_filter_) || candidate_filter_(candidates_in[i])) {
         std::cerr << "Returning candidate: " << candidates_in[i] << std::endl;
         candidates.push_back(candidates_in[i]);
       }
     }
 
     return candidates;
@@ -208,17 +214,17 @@ class IceTestPeer : public sigslot::has_
         &NrIceCtx::ParseGlobalAttributes, remote->GetGlobalAttributes(), &res),
       NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
 
     if (trickle_mode == TRICKLE_NONE) {
       for (size_t i=0; i<streams_.size(); ++i) {
         test_utils->sts_target()->Dispatch(
             WrapRunnableRet(streams_[i], &NrIceMediaStream::ParseAttributes,
-                            remote->GetCandidates(remote->streams_[i]->name()),
+                            remote->GetCandidates(i),
                             &res), NS_DISPATCH_SYNC);
 
         ASSERT_TRUE(NS_SUCCEEDED(res));
       }
     } else {
       // Parse empty attributes and then trickle them out later
       for (size_t i=0; i<streams_.size(); ++i) {
         std::vector<std::string> empty_attrs;
@@ -244,17 +250,17 @@ class IceTestPeer : public sigslot::has_
     std::cerr << "Doing trickle for stream " << stream << std::endl;
     // If we are in trickle deferred mode, now trickle in the candidates
     // for |stream}
     nsresult res;
 
     ASSERT_GT(remote_->streams_.size(), stream);
 
     std::vector<std::string> candidates =
-      remote_->GetCandidates(remote_->streams_[stream]->name());
+      remote_->GetCandidates(stream);
 
     for (size_t j=0; j<candidates.size(); j++) {
       test_utils->sts_target()->Dispatch(
         WrapRunnableRet(streams_[stream],
                         &NrIceMediaStream::ParseTrickleCandidate,
                         candidates[j],
                         &res), NS_DISPATCH_SYNC);
 
@@ -297,23 +303,27 @@ class IceTestPeer : public sigslot::has_
     for (size_t i=0; i < streams_.size(); ++i) {
       for (int j=0; j < streams_[i]->components(); ++j) {
         std::cerr << "Stream " << i << " component " << j+1 << std::endl;
 
         NrIceCandidate *local;
         NrIceCandidate *remote;
 
         nsresult res = streams_[i]->GetActivePair(j+1, &local, &remote);
-        ASSERT_TRUE(NS_SUCCEEDED(res));
-        DumpCandidate("Local  ", *local);
-        ASSERT_EQ(expected_local_type_, local->type);
-        DumpCandidate("Remote ", *remote);
-        ASSERT_EQ(expected_remote_type_, remote->type);
-        delete local;
-        delete remote;
+        if (res == NS_ERROR_NOT_AVAILABLE) {
+          std::cerr << "Component unpaired or disabled." << std::endl;
+        } else {
+          ASSERT_TRUE(NS_SUCCEEDED(res));
+          DumpCandidate("Local  ", *local);
+          ASSERT_EQ(expected_local_type_, local->type);
+          DumpCandidate("Remote ", *remote);
+          ASSERT_EQ(expected_remote_type_, remote->type);
+          delete local;
+          delete remote;
+        }
       }
     }
   }
 
   void Close() {
     test_utils->sts_target()->Dispatch(
       WrapRunnable(ice_ctx_, &NrIceCtx::destroy_peer_ctx),
       NS_DISPATCH_SYNC);
@@ -374,16 +384,22 @@ class IceTestPeer : public sigslot::has_
   // Allow us to parse candidates directly on the current thread.
   void ParseCandidate(size_t i, const std::string& candidate) {
     std::vector<std::string> attributes;
 
     attributes.push_back(candidate);
     streams_[i]->ParseAttributes(attributes);
   }
 
+  void DisableComponent(size_t stream, int component_id) {
+    ASSERT_LT(stream, streams_.size());
+    nsresult res = streams_[stream]->DisableComponent(component_id);
+    ASSERT_TRUE(NS_SUCCEEDED(res));
+  }
+
  private:
   std::string name_;
   nsRefPtr<NrIceCtx> ice_ctx_;
   std::vector<mozilla::RefPtr<NrIceMediaStream> > streams_;
   std::map<std::string, std::vector<std::string> > candidates_;
   bool gathering_complete_;
   int ready_ct_;
   bool ice_complete_;
@@ -656,16 +672,31 @@ TEST_F(IceGatherTest, TestGatherDNSStunB
 TEST_F(IceGatherTest, TestGatherTurn) {
   if (g_turn_server.empty())
     return;
   peer_->SetTurnServer(g_turn_server, kDefaultStunServerPort,
                        g_turn_user, g_turn_password);
   Gather();
 }
 
+TEST_F(IceGatherTest, TestGatherDisableComponent) {
+  peer_->SetStunServer(kDefaultStunServerHostname, kDefaultStunServerPort);
+  peer_->AddStream(2);
+  peer_->DisableComponent(1, 2);
+  Gather();
+  std::vector<std::string> candidates =
+    peer_->GetCandidates(1);
+
+  for (size_t i=0; i<candidates.size(); ++i) {
+    size_t sp1 = candidates[i].find(' ');
+    ASSERT_EQ(0, candidates[i].compare(sp1+1, 1, "1", 1));
+  }
+}
+
+
 // Verify that a bogus candidate doesn't cause crashes on the
 // main thread. See bug 856433.
 TEST_F(IceGatherTest, TestBogusCandidate) {
   Gather();
   peer_->ParseCandidate(0, kBogusIceCandidate);
 }
 
 TEST_F(IceConnectTest, TestGather) {
@@ -681,16 +712,31 @@ TEST_F(IceConnectTest, TestGatherAutoPri
 
 
 TEST_F(IceConnectTest, TestConnect) {
   AddStream("first", 1);
   ASSERT_TRUE(Gather(true));
   Connect();
 }
 
+TEST_F(IceConnectTest, TestConnectTwoComponents) {
+  AddStream("first", 2);
+  ASSERT_TRUE(Gather(true));
+  Connect();
+}
+
+TEST_F(IceConnectTest, TestConnectTwoComponentsDisableSecond) {
+  AddStream("first", 2);
+  ASSERT_TRUE(Gather(true));
+  p1_->DisableComponent(0, 2);
+  p2_->DisableComponent(0, 2);
+  Connect();
+}
+
+
 TEST_F(IceConnectTest, TestConnectP2ThenP1) {
   AddStream("first", 1);
   ASSERT_TRUE(Gather(true));
   ConnectP2();
   PR_Sleep(1000);
   ConnectP1();
   WaitForComplete();
 }
--- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c
@@ -410,16 +410,19 @@ static int nr_ice_component_process_inco
     int component_id_matched;
     int local_addr_matched;
     int remote_addr_matched;
     nr_ice_cand_pair *found_invalid=0;
     int r=0,_status;
 
     r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)(%d): received request from %s",comp->stream->pctx->label,comp->stream->label,comp->component_id,req->src_addr.as_string);
 
+    if (comp->state == NR_ICE_COMPONENT_DISABLED)
+      ABORT(R_REJECTED);
+
     /* Check for role conficts (7.2.1.1) */
     if(comp->stream->pctx->controlling){
       if(nr_stun_message_has_attribute(sreq,NR_STUN_ATTR_ICE_CONTROLLING,&attr)){
         /* OK, there is a conflict. Who's right? */
         r_log(LOG_ICE,LOG_ERR,"ICE-PEER(%s): role conflict, both controlling",comp->stream->pctx->label);
 
         if(attr->u.ice_controlling > comp->stream->pctx->tiebreaker){
           /* They are: switch */
--- a/media/mtransport/third_party/nICEr/src/ice/ice_component.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.h
@@ -50,16 +50,17 @@ typedef struct nr_ice_pre_answer_request
 typedef STAILQ_HEAD(nr_ice_pre_answer_request_head_, nr_ice_pre_answer_request_) nr_ice_pre_answer_request_head;
 
 struct nr_ice_component_ {
   int state;
 #define NR_ICE_COMPONENT_UNPAIRED           0
 #define NR_ICE_COMPONENT_RUNNING            1
 #define NR_ICE_COMPONENT_NOMINATED          2
 #define NR_ICE_COMPONENT_FAILED             3
+#define NR_ICE_COMPONENT_DISABLED           4
   struct nr_ice_ctx_ *ctx;
   struct nr_ice_media_stream_ *stream;
   nr_ice_component *local_component;
 
   int component_id;
   nr_ice_socket_head sockets;
   nr_ice_candidate_head candidates;
   int candidate_ct;
--- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c
@@ -150,20 +150,22 @@ int nr_ice_media_stream_get_attributes(n
     int index=0;
     int r,_status;
 
     *attrctp=0;
 
     /* First find out how many attributes we need */
     comp=STAILQ_FIRST(&stream->components);
     while(comp){
-      if(r=nr_ice_component_prune_candidates(stream->ctx,comp))
-        ABORT(r);
+      if (comp->state != NR_ICE_COMPONENT_DISABLED) {
+        if(r=nr_ice_component_prune_candidates(stream->ctx,comp))
+          ABORT(r);
 
-      attrct+=comp->candidate_ct;
+        attrct+=comp->candidate_ct;
+      }
 
       comp=STAILQ_NEXT(comp,entry);
     }
 
     if(attrct < 1){
       r_log(LOG_ICE,LOG_WARNING,"ICE-STREAM(%s): Failed to find any components for stream",stream->label);
       ABORT(R_FAILED);
     }
@@ -175,28 +177,30 @@ int nr_ice_media_stream_get_attributes(n
       if(!(attrs[index]=RMALLOC(MAX_ATTRIBUTE_SIZE)))
         ABORT(R_NO_MEMORY);
     }
 
     index=0;
     /* Now format the attributes */
     comp=STAILQ_FIRST(&stream->components);
     while(comp){
-      nr_ice_candidate *cand;
+      if (comp->state != NR_ICE_COMPONENT_DISABLED) {
+        nr_ice_candidate *cand;
 
-      cand=TAILQ_FIRST(&comp->candidates);
-      while(cand){
-        assert(index < attrct);
+        cand=TAILQ_FIRST(&comp->candidates);
+        while(cand){
+          assert(index < attrct);
 
-        if(r=nr_ice_format_candidate_attribute(cand, attrs[index],MAX_ATTRIBUTE_SIZE))
-          ABORT(r);
+          if(r=nr_ice_format_candidate_attribute(cand, attrs[index],MAX_ATTRIBUTE_SIZE))
+            ABORT(r);
 
-        index++;
+          index++;
 
-        cand=TAILQ_NEXT(cand,entry_comp);
+          cand=TAILQ_NEXT(cand,entry_comp);
+        }
       }
       comp=STAILQ_NEXT(comp,entry);
     }
 
     *attrsp=attrs;
     *attrctp=attrct;
 
     _status=0;
@@ -269,18 +273,21 @@ int nr_ice_media_stream_get_default_cand
 int nr_ice_media_stream_pair_candidates(nr_ice_peer_ctx *pctx,nr_ice_media_stream *lstream,nr_ice_media_stream *pstream)
   {
     int r,_status;
     nr_ice_component *pcomp,*lcomp;
 
     pcomp=STAILQ_FIRST(&pstream->components);
     lcomp=STAILQ_FIRST(&lstream->components);
     while(pcomp){
-      if(r=nr_ice_component_pair_candidates(pctx,lcomp,pcomp))
-        ABORT(r);
+      if ((lcomp->state != NR_ICE_COMPONENT_DISABLED) &&
+          (pcomp->state != NR_ICE_COMPONENT_DISABLED)) {
+        if(r=nr_ice_component_pair_candidates(pctx,lcomp,pcomp))
+          ABORT(r);
+      }
 
       lcomp=STAILQ_NEXT(lcomp,entry);
       pcomp=STAILQ_NEXT(pcomp,entry);
     };
 
     if (pstream->ice_state == NR_ICE_MEDIA_STREAM_UNPAIRED) {
       nr_ice_media_stream_set_state(pstream, NR_ICE_MEDIA_STREAM_CHECKS_FROZEN);
     }
@@ -562,28 +569,30 @@ int nr_ice_media_stream_set_state(nr_ice
    the stream is ready */
 int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component)
   {
     int r,_status;
     nr_ice_component *comp;
 
     comp=STAILQ_FIRST(&stream->components);
     while(comp){
-      if(!comp->nominated)
+      if((comp->state != NR_ICE_COMPONENT_DISABLED) &&
+         (comp->local_component->state != NR_ICE_COMPONENT_DISABLED) &&
+         !comp->nominated)
         break;
 
       comp=STAILQ_NEXT(comp,entry);
     }
 
     /* At least one un-nominated component */
     if(comp)
       goto done;
 
     /* All done... */
-    r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all components have nominated candidate pairs",stream->pctx->label,stream->label);
+    r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all active components have nominated candidate pairs",stream->pctx->label,stream->label);
     nr_ice_media_stream_set_state(stream,NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED);
 
     /* Cancel our timer */
     if(stream->timer){
       NR_async_timer_cancel(stream->timer);
       stream->timer=0;
     }
 
@@ -719,25 +728,30 @@ int nr_ice_media_stream_send(nr_ice_peer
                           &comp->active->remote->addr))
       ABORT(r);
 
     _status=0;
   abort:
     return(_status);
   }
 
+/* Returns R_REJECTED if the component is unpaired or has been disabled. */
 int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote)
   {
     int r,_status;
     nr_ice_component *comp;
 
     /* First find the peer component */
     if(r=nr_ice_peer_ctx_find_component(pctx, str, component, &comp))
       ABORT(r);
 
+    if (comp->state == NR_ICE_COMPONENT_UNPAIRED ||
+        comp->state == NR_ICE_COMPONENT_DISABLED)
+      ABORT(R_REJECTED);
+
     if(!comp->active)
       ABORT(R_NOT_FOUND);
 
     if (local) *local = comp->active->local;
     if (remote) *remote = comp->active->remote;
 
     _status=0;
   abort:
@@ -792,8 +806,31 @@ int nr_ice_media_stream_finalize(nr_ice_
       if(rcomp){
         rcomp=STAILQ_NEXT(rcomp,entry);
       }
     }
 
     return(0);
   }
 
+
+int nr_ice_media_stream_disable_component(nr_ice_media_stream *stream, int component_id)
+  {
+    int r,_status;
+    nr_ice_component *comp;
+
+    if (stream->ice_state != NR_ICE_MEDIA_STREAM_UNPAIRED)
+      ABORT(R_FAILED);
+
+    if ((r=nr_ice_media_stream_find_component(stream, component_id, &comp)))
+      ABORT(r);
+
+    /* Can only disable before pairing */
+    if (comp->state != NR_ICE_COMPONENT_UNPAIRED)
+      ABORT(R_FAILED);
+
+    comp->state = NR_ICE_COMPONENT_DISABLED;
+
+    _status=0;
+ abort:
+    return(_status);
+  }
+
--- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h
@@ -89,15 +89,16 @@ int nr_ice_media_stream_component_failed
 int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
 int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp);
 int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len);
 int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote);
 int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr_ice_component **compp);
 int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote);
 int
 nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr);
+int nr_ice_media_stream_disable_component(nr_ice_media_stream *stream, int component_id);
 
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 #endif
 
--- a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c
@@ -203,29 +203,62 @@ static int nr_ice_ctx_parse_candidate(nr
       j++;
     }
 
     if(!comp){
       r_log(LOG_ICE,LOG_ERR,"Peer answered with more components than we offered");
       ABORT(R_BAD_DATA);
     }
 
+    if (comp->state == NR_ICE_COMPONENT_DISABLED) {
+      r_log(LOG_ICE,LOG_ERR,"Peer offered candidates for disabled remote component");
+      ABORT(R_BAD_DATA);
+    }
+    if (comp->local_component->state == NR_ICE_COMPONENT_DISABLED) {
+      r_log(LOG_ICE,LOG_ERR,"Peer offered candidates for disabled local component");
+      ABORT(R_BAD_DATA);
+    }
+
     cand->component=comp;
 
     TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp);
 
     _status=0;
  abort:
     if (_status) {
       nr_ice_candidate_destroy(&cand);
     }
     return(_status);
   }
 
+static int nr_ice_peer_ctx_find_pstream(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream **pstreamp)
+  {
+    int _status;
+    nr_ice_media_stream *pstream;
 
+    /* Because we don't have forward pointers, iterate through all the
+       peer streams to find one that matches us */
+     pstream=STAILQ_FIRST(&pctx->peer_streams);
+     while(pstream) {
+       if (pstream->local_stream == stream)
+         break;
+
+       pstream = STAILQ_NEXT(pstream, entry);
+     }
+     if (!pstream) {
+       r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) has no stream matching stream %s",pctx->ctx->label,pctx->label,stream->label);
+       ABORT(R_NOT_FOUND);
+     }
+
+    *pstreamp = pstream;
+
+    _status=0;
+ abort:
+    return(_status);
+  }
 
 int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *candidate)
   {
     /* First need to find the stream. Because we don't have forward pointers,
        iterate through all the peer streams to find one that matches us */
     nr_ice_media_stream *pstream;
     int r,_status;
     int needs_pairing = 0;
@@ -321,16 +354,41 @@ int nr_ice_peer_ctx_pair_candidates(nr_i
       stream=STAILQ_NEXT(stream,entry);
     }
 
     _status=0;
   abort:
     return(_status);
   }
 
+int nr_ice_peer_ctx_disable_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *lstream, int component_id)
+  {
+    int r, _status;
+    nr_ice_media_stream *pstream;
+    nr_ice_component *component;
+    int j;
+
+    if ((r=nr_ice_peer_ctx_find_pstream(pctx, lstream, &pstream)))
+      ABORT(r);
+
+    /* We shouldn't be calling this after we have started pairing */
+    if (pstream->ice_state != NR_ICE_MEDIA_STREAM_UNPAIRED)
+      ABORT(R_FAILED);
+
+    if ((r=nr_ice_media_stream_find_component(pstream, component_id,
+                                              &component)))
+      ABORT(r);
+
+    component->state = NR_ICE_COMPONENT_DISABLED;
+
+    _status=0;
+ abort:
+    return(_status);
+  }
+
 static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
   {
     nr_ice_peer_ctx *pctx=cb_arg;
     nr_ice_media_stream *str1,*str2;
 
     NR_async_timer_cancel(pctx->done_cb_timer);
     RFREE(pctx->label);
     RFREE(pctx->peer_ufrag);
--- a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.h
@@ -73,13 +73,15 @@ int nr_ice_peer_ctx_pair_candidates(nr_i
 int nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct);
 int nr_ice_peer_ctx_start_checks(nr_ice_peer_ctx *pctx);
 int nr_ice_peer_ctx_start_checks2(nr_ice_peer_ctx *pctx, int allow_non_first);
 int nr_ice_peer_ctx_dump_state(nr_ice_peer_ctx *pctx,FILE *out);
 int nr_ice_peer_ctx_log_state(nr_ice_peer_ctx *pctx);
 int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream);
 int nr_ice_peer_ctx_find_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component_id, nr_ice_component **compp);
 int nr_ice_peer_ctx_deliver_packet_maybe(nr_ice_peer_ctx *pctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len);
+int nr_ice_peer_ctx_disable_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *lstream, int component_id);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 #endif
 
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -366,17 +366,16 @@ TestObserver::OnStateChange(uint32_t sta
     }
     std::cout << ")" << std::endl;
     break;
   default:
     // Unknown State
     break;
   }
 
-  state = stateSuccess;
   lastStateType = state_type;
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 TestObserver::OnAddStream(nsIDOMMediaStream *stream)
 {
@@ -976,19 +975,25 @@ void CreateAnswer(sipcc::MediaConstraint
   void CheckMediaPipeline(int stream, int track, uint32_t flags) {
     mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
       GetMediaPipeline((flags & PIPELINE_LOCAL), stream, track);
     ASSERT_TRUE(pipeline);
     ASSERT_EQ(pipeline->IsDoingRtcpMux(), !!(flags & PIPELINE_RTCP_MUX));
     // We cannot yet test send/recv with video.
     if (!(flags & PIPELINE_VIDEO)) {
       if (flags & PIPELINE_SEND) {
+        ASSERT_TRUE_WAIT(pipeline->rtp_packets_sent() >= 40 &&
+                         pipeline->rtcp_packets_received() >= 1,
+                         kDefaultTimeout);
         ASSERT_GE(pipeline->rtp_packets_sent(), 40);
         ASSERT_GE(pipeline->rtcp_packets_received(), 1);
       } else {
+        ASSERT_TRUE_WAIT(pipeline->rtp_packets_received() >= 40 &&
+                         pipeline->rtcp_packets_sent() >= 1,
+                         kDefaultTimeout);
         ASSERT_GE(pipeline->rtp_packets_received(), 40);
         ASSERT_GE(pipeline->rtcp_packets_sent(), 1);
       }
     }
   }
 
 
 public:
@@ -1666,17 +1671,19 @@ TEST_F(SignalingTest, OfferAnswerDontAdd
 }
 
 TEST_F(SignalingTest, FullCall)
 {
   sipcc::MediaConstraints constraints;
   OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
   // Check that we wrote a bunch of data
   ASSERT_GE(a1_.GetPacketsSent(0), 40);
   //ASSERT_GE(a2_.GetPacketsSent(0), 40);
   //ASSERT_GE(a1_.GetPacketsReceived(0), 40);
   ASSERT_GE(a2_.GetPacketsReceived(0), 40);
@@ -1695,34 +1702,39 @@ TEST_F(SignalingTest, FullCall)
 }
 
 TEST_F(SignalingTest, FullCallAudioOnly)
 {
   sipcc::MediaConstraints constraints;
   OfferAnswer(constraints, constraints, OFFER_AUDIO | ANSWER_AUDIO,
               true, SHOULD_SENDRECV_AUDIO, SHOULD_SENDRECV_AUDIO);
 
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
   // Check that we wrote a bunch of data
   ASSERT_GE(a1_.GetPacketsSent(0), 40);
   //ASSERT_GE(a2_.GetPacketsSent(0), 40);
   //ASSERT_GE(a1_.GetPacketsReceived(0), 40);
   ASSERT_GE(a2_.GetPacketsReceived(0), 40);
 }
 
 TEST_F(SignalingTest, FullCallVideoOnly)
 {
   sipcc::MediaConstraints constraints;
   OfferAnswer(constraints, constraints, OFFER_VIDEO | ANSWER_VIDEO,
               true, SHOULD_SENDRECV_VIDEO, SHOULD_SENDRECV_VIDEO);
 
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+  // If we could check for video packets, we would wait for some to be written
+  // here. Since we can't, we don't.
+  // ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+  //                 a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
 
   // FIXME -- Ideally we would check that packets were sent
   // and received; however, the test driver setup does not
   // currently support sending/receiving with Fake_VideoStreamSource.
   //
@@ -1733,45 +1745,50 @@ TEST_F(SignalingTest, FullCallVideoOnly)
   // ASSERT_GE(a2_.GetPacketsReceived(0), 40);
 }
 
 TEST_F(SignalingTest, OfferModifiedAnswer)
 {
   sipcc::MediaConstraints constraints;
   OfferModifiedAnswer(constraints, constraints, SHOULD_SENDRECV_AV,
                       SHOULD_SENDRECV_AV);
-  PR_Sleep(kDefaultTimeout * 2); // Wait for completion
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
 }
 
 TEST_F(SignalingTest, FullCallTrickle)
 {
   sipcc::MediaConstraints constraints;
   OfferAnswerTrickle(constraints, constraints,
                      SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   std::cerr << "ICE handshake completed" << std::endl;
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
   ASSERT_GE(a1_.GetPacketsSent(0), 40);
   ASSERT_GE(a2_.GetPacketsReceived(0), 40);
 }
 
 // Offer answer with trickle but with chrome-style candidates
 TEST_F(SignalingTest, FullCallTrickleChrome)
 {
   sipcc::MediaConstraints constraints;
   OfferAnswerTrickleChrome(constraints, constraints,
                            SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   std::cerr << "ICE handshake completed" << std::endl;
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
   ASSERT_GE(a1_.GetPacketsSent(0), 40);
   ASSERT_GE(a2_.GetPacketsReceived(0), 40);
 }
 
 // This test comes from Bug 810220
@@ -2044,17 +2061,16 @@ TEST_F(SignalingTest, OfferAnswerCheckDe
 
 TEST_F(SignalingTest, CheckTrickleSdpChange)
 {
   sipcc::MediaConstraints constraints;
   OfferAnswerTrickle(constraints, constraints,
                      SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
   std::cerr << "ICE handshake completed" << std::endl;
 
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
 
   std::cout << "Caller's Local Description: " << std::endl
             << indent(a1_.getLocalDescription()) << std::endl << std::endl;
 
   std::cout << "Caller's Remote Description: " << std::endl
             << indent(a1_.getRemoteDescription()) << std::endl << std::endl;
@@ -2377,17 +2393,19 @@ TEST_F(SignalingTest, AudioOnlyCalleeNoR
 
   // Answer should not have a=rtcp-mux
   ASSERT_EQ(a2_.getLocalDescription().find("\r\na=rtcp-mux"),
             std::string::npos);
 
   ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
   ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
 
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
 
   ASSERT_GE(a1_.GetPacketsSent(0), 40);
   ASSERT_GE(a2_.GetPacketsReceived(0), 40);
 
   // Check the low-level media pipeline
@@ -2420,17 +2438,19 @@ TEST_F(SignalingTest, FullCallAudioNoMux
     ASSERT_NE(match, std::string::npos);
     match = a2_.getLocalDescription().find("\r\na=rtcp-mux", match + 1);
   }
   ASSERT_EQ(match, std::string::npos);
 
   ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
   ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
 
-  PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
+  // Wait for some data to get written
+  ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
+                   a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_.CloseSendStreams();
   a2_.CloseReceiveStreams();
 
   ASSERT_GE(a1_.GetPacketsSent(0), 40);
   ASSERT_GE(a2_.GetPacketsReceived(0), 40);
 
   // Check the low-level media pipeline
--- a/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.c
+++ b/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.c
@@ -21,17 +21,17 @@
 
 
 /* Encoder with int16_t Output */
 int16_t WebRtcPcm16b_EncodeW16(int16_t *speechIn16b,
                                int16_t len,
                                int16_t *speechOut16b)
 {
 #ifdef WEBRTC_BIG_ENDIAN
-    memcpy(speechOut16b, speechIn16b, len * sizeof(WebRtc_Word16));
+    memcpy(speechOut16b, speechIn16b, len * sizeof(int16_t));
 #else
     int i;
     for (i=0;i<len;i++) {
         speechOut16b[i]=(((uint16_t)speechIn16b[i])>>8)|((((uint16_t)speechIn16b[i])<<8)&0xFF00);
     }
 #endif
     return(len<<1);
 }
@@ -60,17 +60,17 @@ int16_t WebRtcPcm16b_Encode(int16_t *spe
 /* Decoder with int16_t Input instead of char when the int16_t Encoder is used */
 int16_t WebRtcPcm16b_DecodeW16(void *inst,
                                int16_t *speechIn16b,
                                int16_t len,
                                int16_t *speechOut16b,
                                int16_t* speechType)
 {
 #ifdef WEBRTC_BIG_ENDIAN
-    memcpy(speechOut16b, speechIn16b, ((len*sizeof(WebRtc_Word16)+1)>>1));
+    memcpy(speechOut16b, speechIn16b, ((len*sizeof(int16_t)+1)>>1));
 #else
     int i;
     int samples=len>>1;
 
     for (i=0;i<samples;i++) {
         speechOut16b[i]=(((uint16_t)speechIn16b[i])>>8)|(((uint16_t)(speechIn16b[i]&0xFF))<<8);
     }
 #endif
--- a/media/webrtc/trunk/webrtc/modules/audio_device/audio_device_opensles.cc
+++ b/media/webrtc/trunk/webrtc/modules/audio_device/audio_device_opensles.cc
@@ -62,26 +62,27 @@ AudioDeviceAndroidOpenSLES::AudioDeviceA
       is_play_initialized_(false),
       is_mic_initialized_(false),
       is_speaker_initialized_(false),
       playout_delay_(0),
       recording_delay_(0),
       agc_enabled_(false),
       rec_thread_(NULL),
       rec_timer_(*EventWrapper::Create()),
-      mic_sampling_rate_(N_REC_SAMPLES_PER_SEC * 1000),
-      speaker_sampling_rate_(N_PLAY_SAMPLES_PER_SEC * 1000),
+      mic_sampling_rate_(N_REC_SAMPLES_PER_SEC),
+      speaker_sampling_rate_(N_PLAY_SAMPLES_PER_SEC),
       max_speaker_vol_(0),
       min_speaker_vol_(0),
       loundspeaker_on_(false),
       opensles_lib_(0) {
   WEBRTC_OPENSL_TRACE(kTraceMemory, kTraceAudioDevice, id, "%s created",
                       __FUNCTION__);
   memset(rec_buf_, 0, sizeof(rec_buf_));
   memset(play_buf_, 0, sizeof(play_buf_));
+  UpdateRecordingDelay();
 }
 
 AudioDeviceAndroidOpenSLES::~AudioDeviceAndroidOpenSLES() {
   WEBRTC_OPENSL_TRACE(kTraceMemory, kTraceAudioDevice, id_, "%s destroyed",
                       __FUNCTION__);
 
   Terminate();
 
@@ -1247,44 +1248,50 @@ int32_t AudioDeviceAndroidOpenSLES::Play
 int32_t AudioDeviceAndroidOpenSLES::CPULoad(
     uint16_t& load) const {
   WEBRTC_OPENSL_TRACE(kTraceWarning, kTraceAudioDevice, id_,
                       "  API call not supported on this platform");
   return -1;
 }
 
 bool AudioDeviceAndroidOpenSLES::PlayoutWarning() const {
+  CriticalSectionScoped lock(&crit_sect_);
   return (play_warning_ > 0);
 }
 
 bool AudioDeviceAndroidOpenSLES::PlayoutError() const {
+  CriticalSectionScoped lock(&crit_sect_);
   return (play_error_ > 0);
 }
 
 bool AudioDeviceAndroidOpenSLES::RecordingWarning() const {
+  CriticalSectionScoped lock(&crit_sect_);
   return (rec_warning_ > 0);
 }
 
 bool AudioDeviceAndroidOpenSLES::RecordingError() const {
+  CriticalSectionScoped lock(&crit_sect_);
   return (rec_error_ > 0);
 }
 
 void AudioDeviceAndroidOpenSLES::ClearPlayoutWarning() {
   play_warning_ = 0;
 }
 
 void AudioDeviceAndroidOpenSLES::ClearPlayoutError() {
   play_error_ = 0;
 }
 
 void AudioDeviceAndroidOpenSLES::ClearRecordingWarning() {
+  CriticalSectionScoped lock(&crit_sect_);
   rec_warning_ = 0;
 }
 
 void AudioDeviceAndroidOpenSLES::ClearRecordingError() {
+  CriticalSectionScoped lock(&crit_sect_);
   rec_error_ = 0;
 }
 
 int32_t AudioDeviceAndroidOpenSLES::SetLoudspeakerStatus(bool enable) {
   loundspeaker_on_ = enable;
   return 0;
 }
 
@@ -1346,89 +1353,117 @@ void AudioDeviceAndroidOpenSLES::Recorde
     SLAndroidSimpleBufferQueueItf queue_itf,
     void* p_context) {
   AudioDeviceAndroidOpenSLES* audio_device =
       static_cast<AudioDeviceAndroidOpenSLES*>(p_context);
   audio_device->RecorderSimpleBufferQueueCallbackHandler(queue_itf);
 }
 
 bool AudioDeviceAndroidOpenSLES::RecThreadFuncImpl() {
-  if (is_recording_) {
-    // TODO(leozwang): Add seting correct scheduling and thread priority.
+  // TODO(leozwang): Add seting correct scheduling and thread priority.
+
+  const unsigned int num_samples = mic_sampling_rate_ / 100;
+  const unsigned int num_bytes =
+    N_REC_CHANNELS * num_samples * sizeof(int16_t);
+  const unsigned int total_bytes = num_bytes;
+  int8_t buf[REC_MAX_TEMP_BUF_SIZE_PER_10ms];
 
-    const unsigned int num_samples = mic_sampling_rate_ / 100;
-    const unsigned int num_bytes =
-        N_REC_CHANNELS * num_samples * sizeof(int16_t);
-    const unsigned int total_bytes = num_bytes;
-    int8_t buf[REC_MAX_TEMP_BUF_SIZE_PER_10ms];
-
-    {
-      CriticalSectionScoped lock(&crit_sect_);
+  crit_sect_.Enter();
+  while (is_recording_) {
+    if (rec_voe_audio_queue_.size() <= 0) {
+      crit_sect_.Leave();
+      // Wait for max 40ms for incoming audio data before looping the
+      // poll and checking for ::Stop() being called (which waits for us
+      // to return).  Actual time between audio callbacks will vary, but
+      // is based on AudioRecord min buffer sizes, which may be 15-80ms
+      // or more, depending on sampling frequency, but typically will be
+      // 25ish ms at 44100Hz.  We also don't want to take "too long" to
+      // exit after ::Stop().  This value of 40ms is arbitrary.
+      rec_timer_.Wait(40);
+      crit_sect_.Enter();
       if (rec_voe_audio_queue_.size() <= 0) {
-        rec_timer_.Wait(1);
+        // still no audio data; check for ::Stop()
+        crit_sect_.Leave();
         return true;
       }
-
-      int8_t* audio = rec_voe_audio_queue_.front();
-      rec_voe_audio_queue_.pop();
-      memcpy(buf, audio, total_bytes);
-      memset(audio, 0, total_bytes);
-      rec_voe_ready_queue_.push(audio);
     }
 
-    UpdateRecordingDelay();
+    int8_t* audio = rec_voe_audio_queue_.front();
+    rec_voe_audio_queue_.pop();
+    memcpy(buf, audio, total_bytes);
+    memset(audio, 0, total_bytes);
+    rec_voe_ready_queue_.push(audio);
+
     voe_audio_buffer_->SetRecordedBuffer(buf, num_samples);
     voe_audio_buffer_->SetVQEData(playout_delay_, recording_delay_, 0);
+
+    // All other implementations UnLock around DeliverRecordedData() only
+    crit_sect_.Leave();
     voe_audio_buffer_->DeliverRecordedData();
+    crit_sect_.Enter();
   }
+  crit_sect_.Leave();
+
+  // if is_recording is false, we either *just* were started, or for some reason
+  // Stop() failed to get us to return for 10 seconds - and when we return here,
+  // Stop will kill us anyways.
+  rec_timer_.Wait(1);
 
   return true;
 }
 
 void AudioDeviceAndroidOpenSLES::RecorderSimpleBufferQueueCallbackHandler(
     SLAndroidSimpleBufferQueueItf queue_itf) {
-  if (is_recording_) {
-    const unsigned int num_samples = mic_sampling_rate_ / 100;
-    const unsigned int num_bytes =
-        N_REC_CHANNELS * num_samples * sizeof(int16_t);
-    const unsigned int total_bytes = num_bytes;
-    int8_t* audio;
 
-    {
-      CriticalSectionScoped lock(&crit_sect_);
-      audio = rec_queue_.front();
-      rec_queue_.pop();
-      rec_voe_audio_queue_.push(audio);
+  const unsigned int num_samples = mic_sampling_rate_ / 100;
+  const unsigned int num_bytes =
+    N_REC_CHANNELS * num_samples * sizeof(int16_t);
+  const unsigned int total_bytes = num_bytes;
+  int8_t* audio;
 
-      if (rec_voe_ready_queue_.size() <= 0) {
-        // Log Error.
-        rec_error_ = 1;
-        WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_,
-                            "  Audio Rec thread buffers underrun");
-      } else {
-        audio = rec_voe_ready_queue_.front();
-        rec_voe_ready_queue_.pop();
-      }
+  {
+    CriticalSectionScoped lock(&crit_sect_);
+    if (!is_recording_) {
+      return;
     }
+    audio = rec_queue_.front();
+    rec_queue_.pop();
+    rec_voe_audio_queue_.push(audio);
+    rec_timer_.Set(); // wake up record thread to process it
 
-    int32_t res = (*queue_itf)->Enqueue(queue_itf,
-                                              audio,
-                                              total_bytes);
-    if (res != SL_RESULT_SUCCESS) {
-      WEBRTC_OPENSL_TRACE(kTraceWarning, kTraceAudioDevice, id_,
-                          "  recorder callback Enqueue failed, %d", res);
-      rec_warning_ = 1;
+    if (rec_voe_ready_queue_.size() <= 0) {
+      // Log Error.
+      rec_error_ = 1;
+      WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_,
+                          "  Audio Rec thread buffers underrun");
+      // This isn't good, but continuing (as it used to) is even worse.
+      // Worst case we end up with buffers building up at the other end or
+      // starved.  To be fixed in full rewrite from upstream.
       return;
     } else {
-      rec_queue_.push(audio);
+      audio = rec_voe_ready_queue_.front();
+      rec_voe_ready_queue_.pop();
     }
+  }
 
-    // TODO(leozwang): OpenSL ES doesn't support AudioRecorder
-    // volume control now, add it when it's ready.
+  int32_t res = (*queue_itf)->Enqueue(queue_itf,
+                                      audio,
+                                      total_bytes);
+  if (res != SL_RESULT_SUCCESS) {
+    WEBRTC_OPENSL_TRACE(kTraceWarning, kTraceAudioDevice, id_,
+                        "  recorder callback Enqueue failed, %d", res);
+    CriticalSectionScoped lock(&crit_sect_);
+    rec_warning_ = 1;
+    return;
+  } else {
+    rec_queue_.push(audio);
   }
+
+  // TODO(leozwang): OpenSL ES doesn't support AudioRecorder
+  // volume control now, add it when it's ready.
 }
 
 void AudioDeviceAndroidOpenSLES::CheckErr(SLresult res) {
   if (res != SL_RESULT_SUCCESS) {
     WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_,
                         "  AudioDeviceAndroidOpenSLES::CheckErr(%lu)", res);
     exit(-1);
   }
@@ -1453,16 +1488,17 @@ int32_t AudioDeviceAndroidOpenSLES::Init
   if (sles_engine_ == NULL) {
     WEBRTC_OPENSL_TRACE(kTraceError, kTraceAudioDevice, id_,
                         "  SL Object is NULL");
     return -1;
   }
 
   mic_sampling_rate_ = N_REC_SAMPLES_PER_SEC;
   speaker_sampling_rate_ = N_PLAY_SAMPLES_PER_SEC;
+  UpdateRecordingDelay();
 
   WEBRTC_OPENSL_TRACE(kTraceStateInfo, kTraceAudioDevice, id_,
                       "  mic sample rate (%d), speaker sample rate (%d)",
                       mic_sampling_rate_, speaker_sampling_rate_);
   return 0;
 }
 
 }  // namespace webrtc
--- a/media/webrtc/trunk/webrtc/video_engine/vie_receiver.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_receiver.cc
@@ -107,28 +107,22 @@ bool ViEReceiver::SetReceiveAbsoluteSend
   } else {
     return rtp_header_parser_->DeregisterRtpHeaderExtension(
         kRtpExtensionAbsoluteSendTime);
   }
 }
 
 int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
                                    int rtp_packet_length) {
-  if (!receiving_) {
-    return -1;
-  }
   return InsertRTPPacket(static_cast<const int8_t*>(rtp_packet),
                          rtp_packet_length);
 }
 
 int ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet,
                                     int rtcp_packet_length) {
-  if (!receiving_rtcp_) {
-    return -1;
-  }
   return InsertRTCPPacket(static_cast<const int8_t*>(rtcp_packet),
                           rtcp_packet_length);
 }
 
 int32_t ViEReceiver::OnReceivedPayloadData(
     const uint8_t* payload_data, const uint16_t payload_size,
     const WebRtcRTPHeader* rtp_header) {
   if (rtp_header == NULL) {
@@ -154,16 +148,19 @@ int ViEReceiver::InsertRTPPacket(const i
                                  int rtp_packet_length) {
   // TODO(mflodman) Change decrypt to get rid of this cast.
   int8_t* tmp_ptr = const_cast<int8_t*>(rtp_packet);
   unsigned char* received_packet = reinterpret_cast<unsigned char*>(tmp_ptr);
   int received_packet_length = rtp_packet_length;
 
   {
     CriticalSectionScoped cs(receive_cs_.get());
+    if (!receiving_) {
+      return -1;
+    }
 
     if (external_decryption_) {
       int decrypted_length = kViEMaxMtu;
       external_decryption_->decrypt(channel_id_, received_packet,
                                     decryption_buffer_, received_packet_length,
                                     &decrypted_length);
       if (decrypted_length <= 0) {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, channel_id_,
@@ -203,16 +200,19 @@ int ViEReceiver::InsertRTPPacket(const i
 int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet,
                                   int rtcp_packet_length) {
   // TODO(mflodman) Change decrypt to get rid of this cast.
   int8_t* tmp_ptr = const_cast<int8_t*>(rtcp_packet);
   unsigned char* received_packet = reinterpret_cast<unsigned char*>(tmp_ptr);
   int received_packet_length = rtcp_packet_length;
   {
     CriticalSectionScoped cs(receive_cs_.get());
+    if (!receiving_rtcp_) {
+      return -1;
+    }
 
     if (external_decryption_) {
       int decrypted_length = kViEMaxMtu;
       external_decryption_->decrypt_rtcp(channel_id_, received_packet,
                                          decryption_buffer_,
                                          received_packet_length,
                                          &decrypted_length);
       if (decrypted_length <= 0) {
@@ -244,28 +244,32 @@ int ViEReceiver::InsertRTCPPacket(const 
       rtp_rtcp->IncomingRtcpPacket(received_packet, received_packet_length);
     }
   }
   assert(rtp_rtcp_);  // Should be set by owner at construction time.
   return rtp_rtcp_->IncomingRtcpPacket(received_packet, received_packet_length);
 }
 
 void ViEReceiver::StartReceive() {
+  CriticalSectionScoped cs(receive_cs_.get());
   receiving_ = true;
 }
 
 void ViEReceiver::StopReceive() {
+  CriticalSectionScoped cs(receive_cs_.get());
   receiving_ = false;
 }
 
 void ViEReceiver::StartRTCPReceive() {
+  CriticalSectionScoped cs(receive_cs_.get());
   receiving_rtcp_ = true;
 }
 
 void ViEReceiver::StopRTCPReceive() {
+  CriticalSectionScoped cs(receive_cs_.get());
   receiving_rtcp_ = false;
 }
 
 int ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) {
   CriticalSectionScoped cs(receive_cs_.get());
   if (rtp_dump_) {
     // Restart it if it already exists and is started
     rtp_dump_->Stop();
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -1370,17 +1370,17 @@ res/drawable-xxhdpi/icon.png: $(ICON_PAT
 $(RES_DIRS): $(subst res/,$(srcdir)/resources/,$(RESOURCES))
 	$(RM) -r $@
 	$(NSINSTALL) -D $@
 
 $(RESOURCES): $(RES_DIRS) $(subst res/,$(srcdir)/resources/,$(RESOURCES))
 	@echo "creating $@"
 	$(NSINSTALL) $(subst res/,$(srcdir)/resources/,$@) $(dir $@)
 
-res/values/strings.xml:
+res/values/strings.xml: $(RES_DIRS)
 	$(MAKE) -C locales
 
 # With multilocale builds, there will be multiple strings.xml files. We need to
 # rebuild gecko.ap_ if any of them change.
 MULTILOCALE_STRINGS_XML_FILES := $(wildcard res/values-*/strings.xml)
 all_resources = \
   res/drawable-mdpi/icon.png \
   res/drawable-hdpi/icon.png \
--- a/moz.build
+++ b/moz.build
@@ -2,17 +2,17 @@
 # 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/.
 
 CONFIGURE_SUBST_FILES += ['tools/update-packaging/Makefile']
 
 if CONFIG['ENABLE_CLANG_PLUGIN']:
-  add_tier_dir('base', 'build/clang-plugin', static=True)
+  add_tier_dir('base', 'build/clang-plugin', external=True)
 
 add_tier_dir('base', ['config', 'build', 'probes', 'mfbt', 'python'])
 
 if not CONFIG['LIBXUL_SDK']:
     if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
         add_tier_dir('base', ['other-licenses/android'])
 
     if CONFIG['MOZ_MEMORY']:
--- a/netwerk/base/public/nsILoadGroup.idl
+++ b/netwerk/base/public/nsILoadGroup.idl
@@ -5,20 +5,22 @@
 
 #include "nsIRequest.idl"
 
 interface nsISimpleEnumerator;
 interface nsIRequestObserver;
 interface nsIInterfaceRequestor;
 interface nsILoadGroupConnectionInfo;
 
+typedef unsigned long nsLoadFlags;
+
 /**
  * A load group maintains a collection of nsIRequest objects. 
  */
-[scriptable, uuid(19501006-46e3-4634-b97d-26eff894b4d3)]
+[scriptable, uuid(afb57ac2-bce5-4ee3-bb34-385089a9ba5c)]
 interface nsILoadGroup : nsIRequest
 {
     /**
      * The group observer is notified when requests are added to and removed
      * from this load group.  The groupObserver is weak referenced.
      */
     attribute nsIRequestObserver groupObserver;
 
@@ -73,16 +75,29 @@ interface nsILoadGroup : nsIRequest
      */
     attribute nsIInterfaceRequestor notificationCallbacks;
 
     /**
      * Connection information for managing things like js/css
      * connection blocking, and per-tab connection grouping
      */
     readonly attribute nsILoadGroupConnectionInfo connectionInfo;
+
+    /**
+     * The set of load flags that will be added to all new requests added to
+     * this group. Any existing requests in the load group are not modified,
+     * so it is expected these flags will be added before requests are added
+     * to the group - typically via nsIDocShell::defaultLoadFlags on a new
+     * docShell.
+     * Note that these flags are *not* added to the default request for the
+     * load group; it is expected the default request will already have these
+     * flags (again, courtesy of setting nsIDocShell::defaultLoadFlags before
+     * the docShell has created the default request.)
+     */
+    attribute nsLoadFlags defaultLoadFlags;
 };
 
 %{C++
 // Forward-declare mozilla::net::SpdyPushCache3
 namespace mozilla {
 namespace net {
 class SpdyPushCache3;
 }
--- a/netwerk/base/src/nsInputStreamPump.cpp
+++ b/netwerk/base/src/nsInputStreamPump.cpp
@@ -574,53 +574,54 @@ nsInputStreamPump::OnStateTransfer()
             if (rv != NS_BASE_STREAM_CLOSED)
                 mStatus = rv;
         }
     }
     return STATE_STOP;
 }
 
 nsresult
-nsInputStreamPump::OnStateStopForFailure()
+nsInputStreamPump::CallOnStateStop()
 {
-    MOZ_ASSERT(NS_FAILED(mStatus), "OnStateStopForFailure should be called "
-                                   "in a failed state");
-    MOZ_ASSERT(NS_IsMainThread(), "OnStateStopForFailure should be on the "
-                                  "main thread");
+    MOZ_ASSERT(NS_IsMainThread(),
+               "CallOnStateStop should only be called on the main thread.");
 
     mState = OnStateStop();
     return NS_OK;
 }
 
 uint32_t
 nsInputStreamPump::OnStateStop()
 {
-    if (NS_FAILED(mStatus)) {
-        // If EnsureWaiting has failed, it's possible that we could be off main
-        // thread. We may have to dispatch OnStateStop to the main thread
-        // directly. Note: this would result in OnStateStop being called
-        // outside the context of OnInputStreamReady.
-        if (!NS_IsMainThread()) {
-            nsresult rv = NS_DispatchToMainThread(
-                NS_NewRunnableMethod(this, &nsInputStreamPump::OnStateStopForFailure));
-            NS_ENSURE_SUCCESS(rv, STATE_IDLE);
-            return STATE_IDLE;
-        }
-    } else {
-        MOZ_ASSERT(NS_IsMainThread(), "In a success state, OnStateStop should "
-                                      "be on the main thread");
+    if (!NS_IsMainThread()) {
+        // Hopefully temporary hack: OnStateStop should only run on the main
+        // thread, but we're seeing some rare off-main-thread calls. For now
+        // just redispatch to the main thread in release builds, and crash in
+        // debug builds.
+        MOZ_ASSERT(NS_IsMainThread(),
+                   "OnStateStop should only be called on the main thread.");
+        nsresult rv = NS_DispatchToMainThread(
+            NS_NewRunnableMethod(this, &nsInputStreamPump::CallOnStateStop));
+        NS_ENSURE_SUCCESS(rv, STATE_IDLE);
+        return STATE_IDLE;
     }
 
     PROFILER_LABEL("Input", "nsInputStreamPump::OnStateTransfer");
     LOG(("  OnStateStop [this=%p status=%x]\n", this, mStatus));
 
     // if an error occurred, we must be sure to pass the error onto the async
     // stream.  in some cases, this is redundant, but since close is idempotent,
     // this is OK.  otherwise, be sure to honor the "close-when-done" option.
 
+    if (!mAsyncStream || !mListener) {
+        MOZ_ASSERT(mAsyncStream, "null mAsyncStream: OnStateStop called twice?");
+        MOZ_ASSERT(mListener, "null mListener: OnStateStop called twice?");
+        return STATE_IDLE;
+    }
+
     if (NS_FAILED(mStatus))
         mAsyncStream->CloseWithStatus(mStatus);
     else if (mCloseWhenDone)
         mAsyncStream->Close();
 
     mAsyncStream = 0;
     mTargetThread = 0;
     mIsPending = false;
--- a/netwerk/base/src/nsInputStreamPump.h
+++ b/netwerk/base/src/nsInputStreamPump.h
@@ -52,28 +52,20 @@ public:
      * The data from the stream will not be consumed, i.e. the pump's listener
      * can still read all the data.
      *
      * Do not call before asyncRead. Do not call after onStopRequest.
      */
     NS_HIDDEN_(nsresult) PeekStream(PeekSegmentFun callback, void *closure);
 
     /**
-     * Called on the main thread to clean up member variables. Called directly
-     * from OnStateStop if on the main thread, or dispatching to the main
-     * thread if not. Must be called on the main thread to serialize member
-     * variable deletion with calls to Cancel.
+     * Dispatched (to the main thread) by OnStateStop if it's called off main
+     * thread. Updates mState based on return value of OnStateStop.
      */
-    void OnStateStopCleanup();
-
-    /**
-     * Called on the main thread if EnsureWaiting fails, so that we always call
-     * OnStopRequest on main thread.
-     */
-    nsresult OnStateStopForFailure();
+    nsresult CallOnStateStop();
 
 protected:
 
     enum {
         STATE_IDLE,
         STATE_START,
         STATE_TRANSFER,
         STATE_STOP
--- a/netwerk/base/src/nsLoadGroup.cpp
+++ b/netwerk/base/src/nsLoadGroup.cpp
@@ -110,16 +110,17 @@ RescheduleRequests(PLDHashTable *table, 
     RescheduleRequest(e->mKey, *delta);
     return PL_DHASH_NEXT;
 }
 
 
 nsLoadGroup::nsLoadGroup(nsISupports* outer)
     : mForegroundCount(0)
     , mLoadFlags(LOAD_NORMAL)
+    , mDefaultLoadFlags(0)
     , mStatus(NS_OK)
     , mPriority(PRIORITY_NORMAL)
     , mIsCanceling(false)
     , mDefaultLoadIsTimed(false)
     , mTimedRequests(0)
     , mCachedRequests(0)
     , mTimedNonCachedRequestsUntilOnEndPageLoad(0)
 {
@@ -854,16 +855,31 @@ nsLoadGroup::AdjustPriority(int32_t aDel
     // Update the priority for each request that supports nsISupportsPriority
     if (aDelta != 0) {
         mPriority += aDelta;
         PL_DHashTableEnumerate(&mRequests, RescheduleRequests, &aDelta);
     }
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsLoadGroup::GetDefaultLoadFlags(uint32_t *aFlags)
+{
+    *aFlags = mDefaultLoadFlags;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLoadGroup::SetDefaultLoadFlags(uint32_t aFlags)
+{
+    mDefaultLoadFlags = aFlags;
+    return NS_OK;
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 
 void 
 nsLoadGroup::TelemetryReport()
 {
     if (mDefaultLoadIsTimed) {
         Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_PAGE, mTimedRequests);
         if (mTimedRequests) {
@@ -1034,16 +1050,19 @@ nsresult nsLoadGroup::MergeLoadFlags(nsI
     // Inherit the following bits...
     flags |= (mLoadFlags & (LOAD_BACKGROUND |
                             LOAD_BYPASS_CACHE |
                             LOAD_FROM_CACHE |
                             VALIDATE_ALWAYS |
                             VALIDATE_ONCE_PER_SESSION |
                             VALIDATE_NEVER));
 
+    // ... and force the default flags.
+    flags |= mDefaultLoadFlags;
+
     if (flags != oldFlags)
         rv = aRequest->SetLoadFlags(flags);
 
     outFlags = flags;
     return rv;
 }
 
 // nsLoadGroupConnectionInfo
--- a/netwerk/base/src/nsLoadGroup.h
+++ b/netwerk/base/src/nsLoadGroup.h
@@ -65,16 +65,17 @@ protected:
 private:
     void TelemetryReport();
     void TelemetryReportChannel(nsITimedChannel *timedChannel,
                                 bool defaultRequest);
 
 protected:
     uint32_t                        mForegroundCount;
     uint32_t                        mLoadFlags;
+    uint32_t                        mDefaultLoadFlags;
 
     nsCOMPtr<nsILoadGroup>          mLoadGroup; // load groups can contain load groups
     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
     nsCOMPtr<nsILoadGroupConnectionInfo> mConnectionInfo;
 
     nsCOMPtr<nsIRequest>            mDefaultLoadRequest;
     PLDHashTable                    mRequests;
 
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1000,18 +1000,24 @@ nsHttpChannel::CallOnStartRequest()
         // If we have a cache entry, set its predicted size to ContentLength to
         // avoid caching an entry that will exceed the max size limit.
         nsresult rv = mCacheEntry->SetPredictedDataSize(
             mResponseHead->ContentLength());
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     LOG(("  calling mListener->OnStartRequest\n"));
-    nsresult rv = mListener->OnStartRequest(this, mListenerContext);
-    if (NS_FAILED(rv)) return rv;
+    nsresult rv;
+    if (mListener) {
+        nsresult rv = mListener->OnStartRequest(this, mListenerContext);
+        if (NS_FAILED(rv))
+            return rv;
+    } else {
+        NS_WARNING("OnStartRequest skipped because of null listener");
+    }
 
     // install stream converter if required
     rv = ApplyContentConversions();
     if (NS_FAILED(rv)) return rv;
 
     rv = EnsureAssocReq();
     if (NS_FAILED(rv))
         return rv;
@@ -5189,17 +5195,21 @@ nsHttpChannel::OnStopRequest(nsIRequest 
         }
 
         // If DoAuthRetry failed, or if we have been cancelled since showing
         // the auth. dialog, then we need to send OnStartRequest now
         if (authRetry || (mAuthRetryPending && NS_FAILED(status))) {
             MOZ_ASSERT(NS_FAILED(status), "should have a failure code here");
             // NOTE: since we have a failure status, we can ignore the return
             // value from onStartRequest.
-            mListener->OnStartRequest(this, mListenerContext);
+            if (mListener) {
+                mListener->OnStartRequest(this, mListenerContext);
+            } else {
+                NS_WARNING("OnStartRequest skipped because of null listener");
+            }
         }
 
         // if this transaction has been replaced, then bail.
         if (mTransactionReplaced)
             return NS_OK;
 
         if (mUpgradeProtocolCallback && stickyConn &&
             mResponseHead && mResponseHead->Status() == 101) {
--- a/python/mach/mach/registrar.py
+++ b/python/mach/mach/registrar.py
@@ -33,11 +33,33 @@ class MachRegistrar(object):
 
     def register_settings_provider(self, cls):
         self.settings_providers.add(cls)
 
     def register_category(self, name, title, description, priority=50):
         self.categories[name] = (title, description, priority)
         self.commands_by_category[name] = set()
 
+    def dispatch(self, name, context=None, **args):
+        """Dispatch/run a command.
+
+        Commands can use this to call other commands.
+        """
+
+        # TODO The logic in this function overlaps with code in
+        # mach.main.Main._run() and should be consolidated.
+        handler = self.command_handlers[name]
+        cls = handler.cls
+
+        if handler.pass_context and not context:
+            raise Exception('mach command class requires context.')
+
+        if handler.pass_context:
+            instance = cls(context)
+        else:
+            instance = cls()
+
+        fn = getattr(instance, handler.method)
+
+        return fn(**args) or 0
+
 
 Registrar = MachRegistrar()
-
new file mode 100644
--- /dev/null
+++ b/testing/config/marionette_requirements.txt
@@ -0,0 +1,2 @@
+-r mozbase_requirements.txt
+../marionette
new file mode 100644
--- /dev/null
+++ b/testing/config/mozbase_requirements.txt
@@ -0,0 +1,13 @@
+../mozbase/manifestdestiny
+../mozbase/mozcrash
+../mozbase/mozdevice
+../mozbase/mozfile
+../mozbase/mozhttpd
+../mozbase/mozinfo
+../mozbase/mozinstall
+../mozbase/mozlog
+../mozbase/moznetwork
+../mozbase/mozprocess
+../mozbase/mozprofile
+../mozbase/mozrunner
+../mozbase/moztest
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -686,17 +686,17 @@ function checkVisible(el) {
     return false;
   }
   if (el.tagName.toLowerCase() === 'body') {
     return true;
   }
   if (!elementInViewport(el)) {
     //check if scroll function exist. If so, call it.
     if (el.scrollIntoView) {
-      el.scrollIntoView(true);
+      el.scrollIntoView(false);
       if (!elementInViewport(el)) {
         return false;
       }
     }
     else {
       return false;
     }
   }
--- a/testing/talos/talos.json
+++ b/testing/talos/talos.json
@@ -1,16 +1,16 @@
 {
     "talos.zip": {
         "url": "http://talos-bundles.pvt.build.mozilla.org/zips/talos.2a32cc64e7ff.zip",
         "path": ""
     },
     "global": {
         "talos_repo": "http://hg.mozilla.org/build/talos",
-        "talos_revision": "63e4fcd8784d"
+        "talos_revision": "ca2229a32cb6"
     },
     "suites": {
         "chromez": {
             "tests": ["tresize", "tcanvasmark"],
             "talos_options": [
                 "--mozAfterPaint",
                 "--filter",
                 "ignore_first:5",
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -444,17 +444,18 @@ make-stage-dir:
 	$(NSINSTALL) -D $(PKG_STAGE)/peptest
 	$(NSINSTALL) -D $(PKG_STAGE)/mozbase
 	$(NSINSTALL) -D $(PKG_STAGE)/modules
 
 stage-b2g: make-stage-dir
 	$(NSINSTALL) $(topsrcdir)/b2g/test/b2g-unittest-requirements.txt $(PKG_STAGE)/b2g
 
 stage-config: make-stage-dir
-	$(NSINSTALL) $(topsrcdir)/testing/config/mozharness_config.py $(PKG_STAGE)/config
+	$(NSINSTALL) -D $(PKG_STAGE)/config
+	@(cd $(topsrcdir)/testing/config && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/config && tar -xf -)
 
 stage-mochitest: make-stage-dir
 	$(MAKE) -C $(DEPTH)/testing/mochitest stage-package
 ifeq ($(MOZ_BUILD_APP),mobile/android)
 	$(NSINSTALL) $(DEPTH)/mobile/android/base/fennec_ids.txt $(PKG_STAGE)/mochitest
 endif
 
 stage-reftest: make-stage-dir
--- a/toolkit/components/passwordmgr/test/test_prompt_async.html
+++ b/toolkit/components/passwordmgr/test/test_prompt_async.html
@@ -357,29 +357,29 @@
             {
                 case 1:
                 case 2:
                     dialog.acceptDialog();
                     break;
 
                 case 3:
                     dialog.cancelDialog();
-                    setTimeout(onFrameLoad(), 10); // there are no successful frames for test 3
+                    setTimeout(onFrameLoad, 10); // there are no successful frames for test 3
                     break;
 
                 case 4:
                     if (expectedDialogs == 2)
                         dialog.acceptDialog();
                     else
                         dialog.cancelDialog();
                     break;
 
                 case 5:
                     dialog.cancelDialog();
-                    setTimeout(onFrameLoad(), 10); // there are no successful frames for test 5
+                    setTimeout(onFrameLoad, 10); // there are no successful frames for test 5
                     break;
 
                 case 6:
                     if (expectedDialogs == 2)
                         dialog.acceptDialog();
                     else
                         dialog.cancelDialog();
                     break;
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -3888,16 +3888,21 @@
     "kind": "boolean",
     "description": "The result of the startup default desktop browser check."
   },
   "MIXED_CONTENT_PAGE_LOAD": {
     "kind": "enumerated",
     "n_values": 4,
     "description": "Accumulates type of content (mixed, mixed passive, unmixed) per page load"
   },
+  "MIXED_CONTENT_UNBLOCK_COUNTER": {
+    "kind": "enumerated",
+    "n_values": 3,
+    "description": "A simple counter of daily mixed-content unblock operations and top documents loaded"
+  },
   "NTLM_MODULE_USED": {
     "kind": "enumerated",
     "n_values": 8,
     "description": "The module used for the NTLM protocol (Windows_API, Kerberos, Samba_auth or Generic) and whether or not the authentication was used to connect to a proxy server. This data is collected only once per session (at first NTLM authentification)."
   },
   "FX_THUMBNAILS_BG_QUEUE_SIZE_ON_CAPTURE": {
     "kind": "exponential",
     "high": 100,
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -51,27 +51,27 @@ let WebProgressListener = {
 
     sendAsyncMessage("Content:StateChange", json, objects);
   },
 
   onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
   },
 
   onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
-    let spec = aLocationURI ? aLocationURI.spec : "";
-    let charset = content.document.characterSet;
-
     let json = this._setupJSON(aWebProgress, aRequest);
     let objects = this._setupObjects(aWebProgress);
 
-    json.documentURI = aWebProgress.DOMWindow.document.documentURIObject.spec;
-    json.location = spec;
-    json.canGoBack = docShell.canGoBack;
-    json.canGoForward = docShell.canGoForward;
-    json.charset = charset.toString();
+    json.location = aLocationURI ? aLocationURI.spec : "";
+
+    if (json.isTopLevel) {
+      json.canGoBack = docShell.canGoBack;
+      json.canGoForward = docShell.canGoForward;
+      json.documentURI = content.document.documentURIObject.spec;
+      json.charset = content.document.characterSet;
+    }
 
     sendAsyncMessage("Content:LocationChange", json, objects);
   },
 
   onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
     let json = this._setupJSON(aWebProgress, aRequest);
     let objects = this._setupObjects(aWebProgress);
 
--- a/toolkit/modules/RemoteWebProgress.jsm
+++ b/toolkit/modules/RemoteWebProgress.jsm
@@ -14,18 +14,17 @@ Cu.import("resource://gre/modules/XPCOMU
 function newURI(spec)
 {
     return Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
                                                     .newURI(spec, null, null);
 }
 
 function RemoteWebProgressRequest(spec)
 {
-  this.uri = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
-                                                    .newURI(spec, null, null);
+  this.uri = newURI(spec);
 }
 
 RemoteWebProgressRequest.prototype = {
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIChannel]),
 
   get URI() { return this.uri.clone(); }
 };
 
@@ -105,27 +104,29 @@ RemoteWebProgress.prototype = {
     switch (aMessage.name) {
     case "Content:StateChange":
       for each (let p in this._progressListeners) {
         p.onStateChange(this, req, aMessage.json.stateFlags, aMessage.json.status);
       }
       break;
 
     case "Content:LocationChange":
-      let loc = newURI(aMessage.json.location);
+      let location = newURI(aMessage.json.location);
 
-      this._browser.webNavigation._currentURI = loc;
-      this._browser.webNavigation.canGoBack = aMessage.json.canGoBack;
-      this._browser.webNavigation.canGoForward = aMessage.json.canGoForward;
-      this._browser._characterSet = aMessage.json.charset;
-      this._browser._documentURI = newURI(aMessage.json.documentURI);
-      this._browser._imageDocument = null;
+      if (aMessage.json.isTopLevel) {
+        this._browser.webNavigation._currentURI = location;
+        this._browser.webNavigation.canGoBack = aMessage.json.canGoBack;
+        this._browser.webNavigation.canGoForward = aMessage.json.canGoForward;
+        this._browser._characterSet = aMessage.json.charset;
+        this._browser._documentURI = newURI(aMessage.json.documentURI);
+        this._browser._imageDocument = null;
+      }
 
       for each (let p in this._progressListeners) {
-        p.onLocationChange(this, req, loc);
+        p.onLocationChange(this, req, location);
       }
       break;
 
     case "Content:SecurityChange":
       // Invoking this getter triggers the generation of the underlying object,
       // which we need to access with ._securityUI, because .securityUI returns
       // a wrapper that makes _update inaccessible.
       void this._browser.securityUI;
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -704,17 +704,17 @@ AndroidBridge::ShowAlertNotification(con
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     if (nsAppShell::gAppShell && aAlertListener) {
         // This will remove any observers already registered for this id
-        nsAppShell::gAppShell->AddObserver(aAlertName, aAlertListener);
+        nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener));
     }
 
     jvalue args[5];
     args[0].l = NewJavaString(&jniFrame, aImageUrl);
     args[1].l = NewJavaString(&jniFrame, aAlertTitle);
     args[2].l = NewJavaString(&jniFrame, aAlertText);
     args[3].l = NewJavaString(&jniFrame, aAlertCookie);
     args[4].l = NewJavaString(&jniFrame, aAlertName);
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -10,16 +10,17 @@
 #include <android/input.h>
 #include <android/log.h>
 
 #include "nsGeoPosition.h"
 #include "nsPoint.h"
 #include "nsRect.h"
 #include "nsString.h"
 #include "nsTArray.h"
+#include "nsIObserver.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/dom/Touch.h"
 #include "InputData.h"
 #include "Units.h"
 
 //#define FORCE_ALOG 1
 
 #ifndef ALOG
@@ -525,16 +526,24 @@ public:
     static AndroidGeckoEvent* MakeBroadcastEvent(const nsCString& topic, const nsCString& data) {
         AndroidGeckoEvent* event = new AndroidGeckoEvent();
         event->Init(BROADCAST);
         CopyUTF8toUTF16(topic, event->mCharacters);
         CopyUTF8toUTF16(data, event->mCharactersExtra);
         return event;
     }
 
+    static AndroidGeckoEvent* MakeAddObserver(const nsAString &key, nsIObserver *observer) {
+        AndroidGeckoEvent *event = new AndroidGeckoEvent();
+        event->Init(ADD_OBSERVER);
+        event->mCharacters.Assign(key);
+        event->mObserver = observer;
+        return event;
+    }
+
     int Action() { return mAction; }
     int Type() { return mType; }
     bool AckNeeded() { return mAckNeeded; }
     int64_t Time() { return mTime; }
     const nsTArray<nsIntPoint>& Points() { return mPoints; }
     const nsTArray<int>& PointIndicies() { return mPointIndicies; }
     const nsTArray<float>& Pressures() { return mPressures; }
     const nsTArray<float>& Orientations() { return mOrientations; }
@@ -575,16 +584,17 @@ public:
     int DHCPGateway() { return mDHCPGateway; }
     short ScreenOrientation() { return mScreenOrientation; }
     RefCountedJavaObject* ByteBuffer() { return mByteBuffer; }
     int Width() { return mWidth; }
     int Height() { return mHeight; }
     nsTouchEvent MakeTouchEvent(nsIWidget* widget);
     MultiTouchInput MakeMultiTouchInput(nsIWidget* widget);
     void UnionRect(nsIntRect const& aRect);
+    nsIObserver *Observer() { return mObserver; }
 
 protected:
     int mAction;
     int mType;
     bool mAckNeeded;
     int64_t mTime;
     nsTArray<nsIntPoint> mPoints;
     nsTArray<nsIntPoint> mPointRadii;
@@ -607,16 +617,17 @@ protected:
     nsRefPtr<nsGeoPosition> mGeoPosition;
     double mBandwidth;
     bool mCanBeMetered;
     bool mIsWifi;
     int mDHCPGateway;
     short mScreenOrientation;
     nsRefPtr<RefCountedJavaObject> mByteBuffer;
     int mWidth, mHeight;
+    nsCOMPtr<nsIObserver> mObserver;
 
     void ReadIntArray(nsTArray<int> &aVals,
                       JNIEnv *jenv,
                       jfieldID field,
                       int32_t count);
     void ReadFloatArray(nsTArray<float> &aVals,
                         JNIEnv *jenv,
                         jfieldID field,
@@ -712,16 +723,17 @@ public:
         COMPOSITOR_RESUME = 30,
         NATIVE_GESTURE_EVENT = 31,
         IME_KEY_EVENT = 32,
         CALL_OBSERVER = 33,
         REMOVE_OBSERVER = 34,
         LOW_MEMORY = 35,
         NETWORK_LINK_CHANGE = 36,
         TELEMETRY_HISTOGRAM_ADD = 37,
+        ADD_OBSERVER = 38,
         dummy_java_enum_list_end
     };
 
     enum {
         // Memory pressue levels, keep in sync with those in MemoryMonitor.java
         MEMORY_PRESSURE_NONE = 0,
         MEMORY_PRESSURE_CLEANUP = 1,
         MEMORY_PRESSURE_LOW = 2,
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -534,16 +534,20 @@ nsAppShell::ProcessNextNativeEvent(bool 
 
         break;
     }
 
     case AndroidGeckoEvent::REMOVE_OBSERVER:
         mObserversHash.Remove(curEvent->Characters());
         break;
 
+    case AndroidGeckoEvent::ADD_OBSERVER:
+        AddObserver(curEvent->Characters(), curEvent->Observer());
+        break;
+
     case AndroidGeckoEvent::LOW_MEMORY:
         // TODO hook in memory-reduction stuff for different levels here
         if (curEvent->MetaState() >= AndroidGeckoEvent::MEMORY_PRESSURE_MEDIUM) {
             nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
             if (os) {
                 os->NotifyObservers(nullptr,
                                     "memory-pressure",
                                     NS_LITERAL_STRING("low-memory").get());
--- a/xpcom/threads/nsEventQueue.h
+++ b/xpcom/threads/nsEventQueue.h
@@ -55,25 +55,28 @@ public:
   }
 
 private:
 
   bool IsEmpty() {
     return !mHead || (mHead == mTail && mOffsetHead == mOffsetTail);
   }
 
-  enum { EVENTS_PER_PAGE = 250 };
+  enum { EVENTS_PER_PAGE = 255 };
 
   // Page objects are linked together to form a simple deque.
 
   struct Page {
     struct Page *mNext;
     nsIRunnable *mEvents[EVENTS_PER_PAGE];
   };
 
+  static_assert((sizeof(Page) & (sizeof(Page) - 1)) == 0,
+                "sizeof(Page) should be a power of two to avoid heap slop.");
+
   static Page *NewPage() {
     return static_cast<Page *>(calloc(1, sizeof(Page)));
   }
 
   static void FreePage(Page *p) {
     free(p);
   }