Merge mozilla-inbound to mozilla-central
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 17 Oct 2013 13:43:37 +0200
changeset 165874 855da6d8a327c277e9653911b3244c3229134363
parent 165826 6da41e59512d1a06f6c593785e9089c18b02a245 (current diff)
parent 165873 30d9e30f0c8cdb2d3ef48029662a9dab066b1f28 (diff)
child 165888 84cf5a56188eb202e7d267254aa210067ae9072c
child 165964 754c8ebb278eeaf1f472c3c2800406661a4e0c47
child 165997 ac90f9d869c943d94b0e15e6fbaf06e6e0261a84
child 171423 55c7002cc9c4225f72fa4f7c93a06a9f2f1a0041
child 178473 7cd9d464ac58d3250ecd3f8c69adebb4e7b030ae
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central
dom/tests/unit/test_geolocation_reset_accuracy.js
dom/tests/unit/test_geolocation_reset_accuracy_wrap.js
testing/specialpowers/chrome.manifest
--- 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 872934 - Clobber needed for webidl updates for style sheet change events. Again and again.
\ No newline at end of file
+Bug 895047 - Clobber needed for touching js/src/js-confdefs.h.in
--- a/Makefile.in
+++ b/Makefile.in
@@ -2,18 +2,19 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ifndef .PYMAKE
 ifeq (,$(MAKE_VERSION))
 $(error GNU Make is required)
 endif
-ifeq (,$(filter-out 3.78 3.79,$(MAKE_VERSION)))
-$(error GNU Make 3.80 or higher is required)
+make_min_ver := 3.81
+ifneq ($(make_min_ver),$(firstword $(sort $(make_min_ver) $(MAKE_VERSION))))
+$(error GNU Make $(make_min_ver) or higher is required)
 endif
 endif
 
 export TOPLEVEL_BUILD := 1
 
 default::
 
 ifdef COMPILE_ENVIRONMENT
--- a/accessible/src/windows/sdn/sdnAccessible.cpp
+++ b/accessible/src/windows/sdn/sdnAccessible.cpp
@@ -461,22 +461,21 @@ sdnAccessible::get_innerHTML(BSTR __RPC_
 
   if (!aInnerHTML)
     return E_INVALIDARG;
   *aInnerHTML = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
-  nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mNode);
-  if (!htmlElement)
+  if (!mNode->IsElement())
     return S_FALSE;
 
   nsAutoString innerHTML;
-  htmlElement->GetInnerHTML(innerHTML);
+  mNode->AsElement()->GetInnerHTML(innerHTML);
   if (innerHTML.IsEmpty())
     return S_FALSE;
 
   *aInnerHTML = ::SysAllocStringLen(innerHTML.get(), innerHTML.Length());
   if (!*aInnerHTML)
     return E_OUTOFMEMORY;
 
   return S_OK;
--- a/b2g/gaia/Makefile.in
+++ b/b2g/gaia/Makefile.in
@@ -4,29 +4,34 @@
 
 GAIA_PATH := gaia/profile
 
 ifeq ($(OS_ARCH),WINNT)
 DEFINES += \
   -DB2G_NAME=L\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
   -DGAIA_PATH=L\"$(subst /,\\\\,$(GAIA_PATH))\" \
   $(NULL)
-GAIA_MAKE=make
 else # Non-windows machines use the same wrapper program
 CSRCS = run-b2g.c
 DEFINES += \
   -DB2G_NAME=\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
   -DGAIA_PATH=\"$(GAIA_PATH)\" \
   $(NULL)
+endif
+
+ifdef .PYMAKE
+# For use of GNU make in pymake builds.
+GAIA_MAKE=$(GMAKE)
+else
 GAIA_MAKE=$(MAKE)
 endif
 
 # This is needed to avoid making run-b2g depend on mozglue
 WRAP_LDFLAGS :=
 
 GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
 
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(GAIA_MAKE) -j1 -C $(GAIADIR) clean
-	$(GAIA_MAKE) -j1 -C $(GAIADIR) profile
+	+$(GAIA_MAKE) -j1 -C $(GAIADIR) clean
+	+$(GAIA_MAKE) -j1 -C $(GAIADIR) profile
 	(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
--- a/browser/app/profile/extensions/Makefile.in
+++ b/browser/app/profile/extensions/Makefile.in
@@ -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/.
 
-DISTROEXT = $(call core_abspath,$(FINAL_TARGET))/distribution/extensions
+DISTROEXT = $(abspath $(FINAL_TARGET))/distribution/extensions
 
 include $(topsrcdir)/config/config.mk
 
 ifneq (,$(filter beta,$(MOZ_UPDATE_CHANNEL)))
 EXTENSIONS = \
   $(NULL)
 
 all_xpis = $(foreach dir,$(EXTENSIONS),$(DISTROEXT)/$(dir).xpi)
@@ -29,12 +29,12 @@ endef
 
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 $(all_xpis): $(DISTROEXT)/%.xpi: $(call mkdir_deps,$(DISTROEXT)) libs-%
 	cd $* && \
 	$(ZIP) -r9XD $@ * -x \*.in -x \*.mkdir.done
-	cd $(call core_abspath,$(srcdir)/$*) && \
+	cd $(abspath $(srcdir)/$*) && \
 	$(ZIP) -r9XD $@ * -x \*.in -x \*.mkdir.done
 
 .PHONY: $(all_xpis:.xpi=)
--- a/browser/base/Makefile.in
+++ b/browser/base/Makefile.in
@@ -1,16 +1,16 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/config.mk
 
-abs_srcdir = $(call core_abspath,$(srcdir))
+abs_srcdir = $(abspath $(srcdir))
 
 CHROME_DEPS += $(abs_srcdir)/content/overrides/app-license.html
 
 include $(topsrcdir)/config/rules.mk
 
 PRE_RELEASE_SUFFIX := ""
 
 DEFINES += \
--- a/browser/base/content/test/general/browser_popupNotification.js
+++ b/browser/base/content/test/general/browser_popupNotification.js
@@ -150,16 +150,64 @@ function basicNotification() {
     }
   };
   this.addOptions = function(options) {
     for (let [name, value] in Iterator(options))
       self.options[name] = value;
   }
 }
 
+function errorNotification() {
+  var self = this;
+  this.browser = gBrowser.selectedBrowser;
+  this.id = "test-notification-" + gTestIndex;
+  this.message = "This is popup notification " + this.id + " from test " + gTestIndex;
+  this.anchorID = null;
+  this.mainAction = {
+    label: "Main Action",
+    accessKey: "M",
+    callback: function () {
+      self.mainActionClicked = true;
+      throw new Error("Oops!");
+    }
+  };
+  this.secondaryActions = [
+    {
+      label: "Secondary Action",
+      accessKey: "S",
+      callback: function () {
+        self.secondaryActionClicked = true;
+        throw new Error("Oops!");
+      }
+    }
+  ];
+  this.options = {
+    eventCallback: function (eventName) {
+      switch (eventName) {
+        case "dismissed":
+          self.dismissalCallbackTriggered = true;
+          break;
+        case "showing":
+          self.showingCallbackTriggered = true;
+          break;
+        case "shown":
+          self.shownCallbackTriggered = true;
+          break;
+        case "removed":
+          self.removedCallbackTriggered = true;
+          break;
+      }
+    }
+  };
+  this.addOptions = function(options) {
+    for (let [name, value] in Iterator(options))
+      self.options[name] = value;
+  }
+}
+
 var wrongBrowserNotificationObject = new basicNotification();
 var wrongBrowserNotification;
 
 var tests = [
   { // Test #0
     run: function () {
       this.notifyObj = new basicNotification();
       showNotification(this.notifyObj);
@@ -826,17 +874,79 @@ var tests = [
         showNotification(notifyObj);
         executeSoon(function () {
           content.document.getElementById("iframe")
                           .setAttribute("src", "http://example.org/");
         });
       });
     }
   },
-  { // Test #29 -  Existing popup notification shouldn't disappear when adding a dismissed notification
+  { // Test #29 - Popup Notifications should catch exceptions from callbacks
+    run: function () {
+      let callbackCount = 0;
+      this.testNotif1 = new basicNotification();
+      this.testNotif1.message += " 1";
+      showNotification(this.testNotif1);
+      this.testNotif1.options.eventCallback = function (eventName) {
+        info("notifyObj1.options.eventCallback: " + eventName);
+        if (eventName == "dismissed") {
+          throw new Error("Oops 1!");
+          if (++callbackCount == 2) {
+            executeSoon(goNext);
+          }
+        }
+      };
+
+      this.testNotif2 = new basicNotification();
+      this.testNotif2.message += " 2";
+      this.testNotif2.id += "-2";
+      this.testNotif2.options.eventCallback = function (eventName) {
+        info("notifyObj2.options.eventCallback: " + eventName);
+        if (eventName == "dismissed") {
+          throw new Error("Oops 2!");
+          if (++callbackCount == 2) {
+            executeSoon(goNext);
+          }
+        }
+      };
+      showNotification(this.testNotif2);
+    },
+    onShown: function (popup) {
+      is(popup.childNodes.length, 2, "two notifications are shown");
+      dismissNotification(popup);
+    },
+    onHidden: function () {}
+  },
+  { // Test #30 - Popup Notifications main actions should catch exceptions from callbacks
+    run: function () {
+      this.testNotif = new errorNotification();
+      showNotification(this.testNotif);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.testNotif);
+      triggerMainCommand(popup);
+    },
+    onHidden: function (popup) {
+      ok(this.testNotif.mainActionClicked, "main action has been triggered");
+    }
+  },
+  { // Test #31 - Popup Notifications secondary actions should catch exceptions from callbacks
+    run: function () {
+      this.testNotif = new errorNotification();
+      showNotification(this.testNotif);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.testNotif);
+      triggerSecondaryCommand(popup, 0);
+    },
+    onHidden: function (popup) {
+      ok(this.testNotif.secondaryActionClicked, "secondary action has been triggered");
+    }
+  },
+  { // Test #32 -  Existing popup notification shouldn't disappear when adding a dismissed notification
     run: function () {
       this.notifyObj1 = new basicNotification();
       this.notifyObj1.id += "_1";
       this.notifyObj1.anchorID = "default-notification-icon";
       this.notification1 = showNotification(this.notifyObj1);
     },
     onShown: function (popup) {
       // Now show a dismissed notification, and check that it doesn't clobber
@@ -857,17 +967,17 @@ var tests = [
 
       dismissNotification(popup);
     },
     onHidden: function(popup) {
       this.notification1.remove();
       this.notification2.remove();
     }
   },
-  { // Test #30 - Showing should be able to modify the popup data
+  { // Test #33 - Showing should be able to modify the popup data
     run: function() {
       this.notifyObj = new basicNotification();
       var normalCallback = this.notifyObj.options.eventCallback;
       this.notifyObj.options.eventCallback = function (eventName) {
         if (eventName == "showing") {
           this.mainAction.label = "Alternate Label";
         }
         normalCallback.call(this, eventName);
--- a/build/automation-build.mk
+++ b/build/automation-build.mk
@@ -3,17 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(MOZILLA_DIR)/build/binary-location.mk
 
 browser_path := \"$(browser_path)\"
 
 _PROFILE_DIR = $(TARGET_DEPTH)/_profile/pgo
 
-ABSOLUTE_TOPSRCDIR = $(call core_abspath,$(MOZILLA_DIR))
+ABSOLUTE_TOPSRCDIR = $(abspath $(MOZILLA_DIR))
 _CERTS_SRC_DIR = $(ABSOLUTE_TOPSRCDIR)/build/pgo/certs
 
 AUTOMATION_PPARGS = 	\
 			-DBROWSER_PATH=$(browser_path) \
 			-DXPC_BIN_PATH=\"$(LIBXUL_DIST)/bin\" \
 			-DBIN_SUFFIX=\"$(BIN_SUFFIX)\" \
 			-DPROFILE_DIR=\"$(_PROFILE_DIR)\" \
 			-DCERTS_SRC_DIR=\"$(_CERTS_SRC_DIR)\" \
--- a/build/cl.py
+++ b/build/cl.py
@@ -71,18 +71,19 @@ def InvokeClWithDependencyGeneration(cmd
     def on_line(line):
         # cl -showIncludes prefixes every header with "Note: including file:"
         # and an indentation corresponding to the depth (which we don't need)
         if line.startswith(CL_INCLUDES_PREFIX):
             dep = line[len(CL_INCLUDES_PREFIX):].strip()
             # We can't handle pathes with spaces properly in mddepend.pl, but
             # we can assume that anything in a path with spaces is a system
             # header and throw it away.
+            dep = normcase(dep)
             if ' ' not in dep:
-                rule.add_dependencies([normcase(dep)])
+                rule.add_dependencies([dep])
         else:
             # Make sure we preserve the relevant output from cl. mozprocess
             # swallows the newline delimiter, so we need to re-add it.
             sys.stdout.write(line)
             sys.stdout.write('\n')
 
     # We need to ignore children because MSVC can fire up a background process
     # during compilation. This process is cleaned up on its own. If we kill it,
--- a/build/macosx/universal/flight.mk
+++ b/build/macosx/universal/flight.mk
@@ -14,24 +14,22 @@ DIST_ARCH_2 = $(OBJDIR_ARCH_2)/dist
 DIST_UNI = $(DIST_ARCH_1)/universal
 OBJDIR = $(OBJDIR_ARCH_1)
 endif
 
 topsrcdir = $(TOPSRCDIR)
 DEPTH = $(OBJDIR)
 include $(OBJDIR)/config/autoconf.mk
 
-core_abspath = $(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1))
-
 DIST = $(OBJDIR)/dist
 
 postflight_all:
 	mkdir -p $(DIST_UNI)/$(MOZ_PKG_APPNAME)
 	rm -f $(DIST_ARCH_2)/universal
-	ln -s $(call core_abspath,$(DIST_UNI)) $(DIST_ARCH_2)/universal
+	ln -s $(abspath $(DIST_UNI)) $(DIST_ARCH_2)/universal
 # Stage a package for buildsymbols to be happy. Doing so in OBJDIR_ARCH_1
 # actually does a universal staging with both OBJDIR_ARCH_1 and OBJDIR_ARCH_2.
 	$(MAKE) -C $(OBJDIR_ARCH_1)/$(MOZ_BUILD_APP)/installer \
 	   PKG_SKIP_STRIP=1 stage-package
 ifdef ENABLE_TESTS
 # Now, repeat the process for the test package.
 	$(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= CHROME_JAR= package-tests
 	$(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests
--- a/build/mobile/sutagent/android/watcher/RedirOutputThread.java
+++ b/build/mobile/sutagent/android/watcher/RedirOutputThread.java
@@ -96,17 +96,16 @@ public class RedirOutputThread extends T
                             strOutput += sRep;
                         }
                     }
 
                 bStillRunning = (IsProcRunning(pProc) || (sutOut.available() > 0) || (sutErr.available() > 0));
                 }
             catch (IOException e)
                 {
-//                Toast.makeText(SUTAgentAndroid.me.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
                 e.printStackTrace();
                 }
             }
 
         pProc.destroy();
         buffer = null;
         System.gc();
         }
--- a/build/mobile/sutagent/android/watcher/WatcherService.java
+++ b/build/mobile/sutagent/android/watcher/WatcherService.java
@@ -38,23 +38,21 @@ import android.content.pm.PackageManager
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.BatteryManager;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.util.Log;
-import android.view.Gravity;
-import android.widget.Toast;
 import android.os.Environment;
 
 public class WatcherService extends Service
 {
-    private final String prgVersion = "Watcher Version 1.16";
+    private final String prgVersion = "Watcher Version 1.17";
     private final String LOGTAG = "Watcher";
 
     String sErrorPrefix = "##Installer Error## ";
     String currentDir = "/";
     String sPingTarget = "";
     long lDelay = 60000;
     long lPeriod = 300000;
     int nMaxStrikes = 0; // maximum number of tries before we consider network unreachable (0 means don't check)
@@ -130,26 +128,26 @@ public class WatcherService extends Serv
         this.bStartSUTAgent = Boolean.parseBoolean(sHold.trim());
 
         sHold = GetIniData("watcher", "stayon", sIniFile,"0");
         int nStayOn = Integer.parseInt(sHold.trim());
         
         try {
             if (nStayOn != 0) {
                 if (!Settings.System.putInt(getContentResolver(), Settings.System.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB)) {
-                    doToast("Screen couldn't be set to Always On [stay on while plugged in]");
+                    Log.e(LOGTAG, "Screen couldn't be set to Always On [stay on while plugged in]");
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
             String sExcept = e.getMessage();
-            doToast("Screen couldn't be set to Always On [exception " + sExcept + "]");
+            Log.e(LOGTAG, "Screen couldn't be set to Always On [exception " + sExcept + "]");
         }
 
-        doToast("WatcherService created");
+        Log.i(LOGTAG, "WatcherService created");
         }
 
     public String GetIniData(String sSection, String sKey, String sFile, String sDefault)
         {
         String sRet = sDefault;
         String sComp = "";
         String sLine = "";
         boolean bFound = false;
@@ -223,30 +221,30 @@ public class WatcherService extends Serv
                 Log.i(LOGTAG, "WatcherService updating " + sPkgName + " using file " + sPkgFile);
 
                 UpdateApplication worker = new UpdateApplication(sPkgName, sPkgFile, sOutFile, nReboot);
                 }
             else if (sCmd.equalsIgnoreCase("start"))
                 {
                 if (!this.bStartedTimer) 
                     {
-                    doToast("WatcherService started");
+                    Log.i(LOGTAG, "WatcherService started");
                     myTimer = new Timer();
                     Date startSchedule = new Date(System.currentTimeMillis() + lDelay);
                     myTimer.schedule(new MyTime(), startSchedule, lPeriod);
                     this.bStartedTimer = true;
                     }
                 }
             else
                 {
-                doToast("WatcherService unknown command");
+                Log.w(LOGTAG, "WatcherService unknown command");
                 }
             }
         else
-            doToast("WatcherService created");
+            Log.w(LOGTAG, "WatcherService intent had null command");
         }
 
     public void writeVersion() {
         PrintWriter pw = null;
         String appPath = getApplicationContext().getFilesDir().getAbsolutePath();
         String versionPath = appPath + "/version.txt";
         Log.i(LOGTAG, "writing version string to: " + versionPath);
         try {
@@ -275,17 +273,17 @@ public class WatcherService extends Serv
         writeVersion();
         handleCommand(intent);
         return START_STICKY;
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-        doToast("WatcherService destroyed");
+        Log.i(LOGTAG, "WatcherService destroyed");
         if (pwl != null)
             pwl.release();
         stopForegroundCompat(R.string.foreground_service_started);
     }
 
     @Override
     public void onLowMemory() {
         Log.e(LOGTAG, "onLowMemory");
@@ -442,24 +440,16 @@ public class WatcherService extends Serv
                 e.printStackTrace();
             } catch (InvocationTargetException e) {
                 Log.e(LOGTAG, "Unable to invoke setForeground", e);
                 e.printStackTrace();
             }
         }
     }
 
-    public void doToast(String sMsg)
-        {
-        Log.i(LOGTAG, sMsg);
-        Toast toast = Toast.makeText(this, sMsg, Toast.LENGTH_LONG);
-        toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 100);
-        toast.show();
-        }
-
     public void CheckMem() 
         {
         System.gc();
         long lFreeMemory = Runtime.getRuntime().freeMemory();
         long lTotMemory = Runtime.getRuntime().totalMemory();
         long lMaxMemory = Runtime.getRuntime().maxMemory();
 
         Log.i(LOGTAG, "Free: " + lFreeMemory + "Total: " + lTotMemory + "Max: " + lMaxMemory);
--- a/build/unix/elfhack/Makefile.in
+++ b/build/unix/elfhack/Makefile.in
@@ -11,16 +11,18 @@ NO_PROFILE_GUIDED_OPTIMIZE = 1
 VPATH += $(topsrcdir)/build
 
 OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions
 
 WRAP_LDFLAGS=
 
 include $(topsrcdir)/config/rules.mk
 
+DEFINES += -DELFHACK_BUILD
+
 test-array$(DLL_SUFFIX) test-ctors$(DLL_SUFFIX): %$(DLL_SUFFIX): %.$(OBJ_SUFFIX) elfhack $(filter inject/%,$(CSRCS:.c=.$(OBJ_SUFFIX)))
 	$(MKSHLIB) $(LDFLAGS) $< -nostartfiles
 	@echo ===
 	@echo === If you get failures below, please file a bug describing the error
 	@echo === and your environment \(compiler and linker versions\), and use
 	@echo === --disable-elf-hack until this is fixed.
 	@echo ===
 	# Fail if the library doesn't have $(DT_TYPE) .dynamic info
--- a/build/unix/elfhack/inject/Makefile.in
+++ b/build/unix/elfhack/inject/Makefile.in
@@ -25,10 +25,12 @@ include $(topsrcdir)/config/rules.mk
 
 export:: $(CSRCS:.c=.$(OBJ_SUFFIX))
 
 $(CSRCS): %.c: ../inject.c
 	cp $< $@
 
 GARBAGE += $(CSRCS)
 
+DEFINES += -DELFHACK_BUILD
+
 CFLAGS := -O2 -fno-stack-protector $(filter -m% -I%,$(CFLAGS))
 $(CPU)-noinit.$(OBJ_SUFFIX): DEFINES += -DNOINIT
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -123,17 +123,17 @@ install::
 	$(SYSINSTALL) $(IFLAGS1) $(DEPTH)/mozilla-config.h $(DESTDIR)$(includedir)
 
 GARBAGE += \
   $(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) buildid $(srcdir)/*.pyc *.pyc
 
 ifndef CROSS_COMPILE
 ifdef USE_ELF_DYNSTR_GC
 elf-dynstr-gc: elf-dynstr-gc.c $(GLOBAL_DEPS) $(call mkdir_deps,$(MDDEPDIR))
-	$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -o $@ $< $(LDFLAGS) $(GLIB_LIBS)
+	$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -DELFDYNSTRGC_BUILD -o $@ $< $(LDFLAGS) $(GLIB_LIBS)
 endif
 endif
 
 FORCE:
 
 check-preqs = \
   check-jar-mn \
   check-makefiles \
--- a/config/android-common.mk
+++ b/config/android-common.mk
@@ -8,17 +8,17 @@ ifndef ANDROID_SDK
   $(error ANDROID_SDK must be defined before including android-common.mk)
 endif
 
 ifndef JAVA_CLASSPATH
   $(error JAVA_CLASSPATH must be defined before including android-common.mk)
 endif
 
 # DEBUG_JARSIGNER always debug signs.
-DEBUG_JARSIGNER=$(PYTHON) $(call core_abspath,$(topsrcdir)/mobile/android/debug_sign_tool.py) \
+DEBUG_JARSIGNER=$(PYTHON) $(abspath $(topsrcdir)/mobile/android/debug_sign_tool.py) \
   --keytool=$(KEYTOOL) \
   --jarsigner=$(JARSIGNER) \
   $(NULL)
 
 # For Android, this defaults to $(ANDROID_SDK)/android.jar
 ifndef JAVA_BOOTCLASSPATH
   JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar:$(ANDROID_COMPAT_LIB)
 endif
--- a/config/config.mk
+++ b/config/config.mk
@@ -627,17 +627,17 @@ GARBAGE		+= $(DEPENDENCIES) core $(wildc
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
-NSINSTALL_PY := $(PYTHON) $(call core_abspath,$(topsrcdir)/config/nsinstall.py)
+NSINSTALL_PY := $(PYTHON) $(abspath $(topsrcdir)/config/nsinstall.py)
 # For Pymake, wherever we use nsinstall.py we're also going to try to make it
 # a native command where possible. Since native commands can't be used outside
 # of single-line commands, we continue to provide INSTALL for general use.
 # Single-line commands should be switched over to install_cmd.
 NSINSTALL_NATIVECMD := %nsinstall nsinstall
 
 ifdef NSINSTALL_BIN
 NSINSTALL = $(NSINSTALL_BIN)
@@ -686,17 +686,17 @@ sysinstall_cmd = install_cmd
 AB_CD = $(MOZ_UI_LOCALE)
 
 ifndef L10NBASEDIR
   L10NBASEDIR = $(error L10NBASEDIR not defined by configure)
 else
   IS_LANGUAGE_REPACK = 1
 endif
 
-EXPAND_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/$(1)/en-US,$(call core_realpath,$(L10NBASEDIR))/$(AB_CD)/$(subst /locales,,$(1)))
+EXPAND_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/$(1)/en-US,$(or $(realpath $(L10NBASEDIR)),$(abspath $(L10NBASEDIR)))/$(AB_CD)/$(subst /locales,,$(1)))
 
 ifdef relativesrcdir
 LOCALE_SRCDIR ?= $(call EXPAND_LOCALE_SRCDIR,$(relativesrcdir))
 endif
 
 ifdef relativesrcdir
 MAKE_JARS_FLAGS += --relativesrcdir=$(relativesrcdir)
 ifneq (en-US,$(AB_CD))
@@ -737,17 +737,17 @@ endif # ! OS2
 
 # Make sure any compiled classes work with at least JVM 1.4
 JAVAC_FLAGS += -source 1.4
 
 ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
 
-CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
+CREATE_PRECOMPLETE_CMD = $(PYTHON) $(abspath $(topsrcdir)/config/createprecomplete.py)
 
 # MDDEPDIR is the subdirectory where dependency files are stored
 MDDEPDIR := .deps
 
 EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp --target $@)
 EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp)
 EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
 EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
--- a/config/makefiles/functions.mk
+++ b/config/makefiles/functions.mk
@@ -11,12 +11,12 @@
 #
 
 # Define an include-at-most-once flag
 ifdef INCLUDED_FUNCTIONS_MK
 $(error Do not include functions.mk twice!)
 endif
 INCLUDED_FUNCTIONS_MK = 1
 
-core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))
-core_realpath = $(if $(realpath $(1)),$(realpath $(1)),$(call core_abspath,$(1)))
+core_abspath = $(error core_abspath is unsupported, use $$(abspath) instead)
+core_realpath = $(error core_realpath is unsupported)
 
-core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
+core_winabspath = $(error core_winabspath is unsupported)
--- a/config/nspr/Makefile.in
+++ b/config/nspr/Makefile.in
@@ -8,17 +8,17 @@ include $(topsrcdir)/config/rules.mk
 ifdef LIBXUL_SDK
 $(error config/nspr/Makefile.in is not compatible with --enable-libxul-sdk=)
 endif
 ifdef MOZ_NATIVE_NSPR
 $(error config/nspr/Makefile.in is not compatible with MOZ_NATIVE_NSPR)
 endif
 
 # Copy NSPR to the SDK
-ABS_DIST = $(call core_abspath,$(DIST))
+ABS_DIST = $(abspath $(DIST))
 
 ifdef MOZ_FOLD_LIBS
 # Trick the nspr build system into not building shared libraries.
 # bug #851869.
 EXTRA_MAKE_FLAGS := SHARED_LIBRARY= IMPORT_LIBRARY= SHARED_LIB_PDB=
 
 # Work around libVersionPoint conflict between all three libraries.
 # See bug #838566.
new file mode 100644
--- /dev/null
+++ b/content/base/crashtests/851353-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+    <meta charset="UTF-8">
+    <script>
+        function start() {
+            var doc = document.getElementsByTagName("iframe")[0].contentDocument;
+            var vid = doc.getElementsByTagName("video")[0];
+
+            function runnable() {
+                // The doc.write forces us to recreate doc's body.
+                doc.write("Hello, world");
+                doc.body.appendChild(vid);
+                document.documentElement.removeAttribute("class");
+            }
+
+            doc.open();
+            setTimeout(runnable, 0);
+        }
+    </script>
+</head>
+<body onload='start()'>
+    <iframe src="data:text/html,<meta charset=UTF-8><body><video src=http://localhost:8080/ controls=true loop=true autoplay=true autobuffer=false></video>"></iframe>
+</body>
+</html>
--- a/content/base/crashtests/crashtests.list
+++ b/content/base/crashtests/crashtests.list
@@ -128,10 +128,11 @@ load 824719.html
 load 827190.html
 load 828054.html
 load 829428.html
 load 836890.html
 load 841205.html
 load 844404.html
 load 847127.html
 load 849601.html
+skip-if(Android) load 851353-1.html
 load 863950.html
 load 864448.html
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -1168,17 +1168,19 @@ Element::UnbindFromTree(bool aDeep, bool
                                       "RemovedFullScreenElement");
       // Fully exit full-screen.
       nsIDocument::ExitFullscreen(OwnerDoc(), /* async */ false);
     }
     if (HasPointerLock()) {
       nsIDocument::UnlockPointer();
     }
     if (GetParent()) {
-      NS_RELEASE(mParent);
+      nsINode* p = mParent;
+      mParent = nullptr;
+      NS_RELEASE(p);
     } else {
       mParent = nullptr;
     }
     SetParentIsContent(false);
   }
   ClearInDocument();
 
   // Begin keeping track of our subtree root.
--- a/content/base/test/mochitest.ini
+++ b/content/base/test/mochitest.ini
@@ -501,16 +501,17 @@ support-files =
 [test_bug809003.html]
 [test_bug810494.html]
 [test_bug811701.html]
 [test_bug811701.xhtml]
 [test_bug813919.html]
 [test_bug814576.html]
 [test_bug819051.html]
 [test_bug820909.html]
+[test_bug840098.html]
 [test_bug868999.html]
 [test_bug869000.html]
 [test_bug869002.html]
 [test_bug869006.html]
 [test_bug876282.html]
 [test_bug890580.html]
 [test_bug894874.html]
 [test_bug895239.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug840098.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=840098
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 840098</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=840098">Mozilla Bug 840098</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <div id="foo"></div>
+</div>
+<marquee id="m">Hello</marquee>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 840098 **/
+var anonymousNode = document.getElementById("m").outerDiv;
+try {
+  document.implementation.createDocument("", "", null).adoptNode(anonymousNode);
+  ok(false, "shouldn't be able to adopt the root of an anonymous subtree");
+} catch (e) {
+  is(e.name, "NotSupportedError", "threw the correct type of error");
+}
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/canvas/crashtests/916128-1.html
@@ -0,0 +1,13 @@
+<script>
+o0 = document.createElement('canvas');
+(document.body || document.documentElement).appendChild(o0);
+o1 = o0.getContext('2d');
+o2 = document.createElement('img');
+//o2.src = "image2.png";
+o3 = o1.createImageData(0.7409945472006207, 0.8815588599260801);
+o1.save();
+o1.mozCurrentTransform = [0.18777365986904448, 4, 4, -2048, 3, 32];
+o0.width = 0.52;
+o1.putImageData(o3, -32, -0.16596290333335356);
+o0.toBlob(function() {}, "video/mp4", 16);
+</script>
--- a/content/canvas/crashtests/crashtests.list
+++ b/content/canvas/crashtests/crashtests.list
@@ -12,8 +12,9 @@ load 746813-1.html
 # this test crashes in a bunch places still
 #load 745818-large-source.html
 load 743499-negative-size.html
 skip-if(Android) load 767337-1.html
 skip-if(Android||B2G) load 780392-1.html # bug 833371 for B2G
 skip-if(Android||B2G) load 789933-1.html # bug 833371
 load 794463-1.html
 load 802926-1.html
+load 916128-1.html
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -9,18 +9,18 @@
 #include "nsISupports.h"
 #include "nsIInputStream.h"
 #include "nsIDocShell.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "GraphicsFilter.h"
 #include "mozilla/RefPtr.h"
 
 #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
-{ 0x8b8da863, 0xd151, 0x4014, \
-  { 0x8b, 0xdc, 0x62, 0xb5, 0x0d, 0xc0, 0x2b, 0x62 } }
+{ 0x9a6a5bdf, 0x1261, 0x4057, \
+  { 0x85, 0xcc, 0xaf, 0x97, 0x6c, 0x36, 0x99, 0xa9 } }
 
 class gfxContext;
 class gfxASurface;
 class nsDisplayListBuilder;
 
 namespace mozilla {
 namespace layers {
 class CanvasLayer;
@@ -66,16 +66,19 @@ public:
 
   NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) = 0;
 
   // Render the canvas at the origin of the given gfxContext
   NS_IMETHOD Render(gfxContext *ctx,
                     GraphicsFilter aFilter,
                     uint32_t aFlags = RenderFlagPremultAlpha) = 0;
 
+  // Creates an image buffer. Returns null on failure.
+  virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) = 0;
+
   // Gives you a stream containing the image represented by this context.
   // The format is given in aMimeTime, for example "image/png".
   //
   // If the image format does not support transparency or aIncludeTransparency
   // is false, alpha will be discarded and the result will be the image
   // composited on black.
   NS_IMETHOD GetInputStream(const char *aMimeType,
                             const PRUnichar *aEncoderOptions,
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -36,17 +36,17 @@
 #include "nsGfxCIID.h"
 #include "nsIDocShell.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsDisplayList.h"
 
 #include "nsTArray.h"
 
-#include "imgIEncoder.h"
+#include "ImageEncoder.h"
 
 #include "gfxContext.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "gfxFont.h"
 #include "gfxBlur.h"
 #include "gfxUtils.h"
@@ -923,26 +923,28 @@ CanvasRenderingContext2D::GetHeight() co
 }
 #endif
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetDimensions(int32_t width, int32_t height)
 {
   ClearTarget();
 
-  // Zero sized surfaces cause issues, so just go with 1x1.
-  if (height == 0 || width == 0) {
+  // Zero sized surfaces can cause problems.
+  mZero = false;
+  if (height == 0) {
+    height = 1;
     mZero = true;
-    mWidth = 1;
-    mHeight = 1;
-  } else {
-    mZero = false;
-    mWidth = width;
-    mHeight = height;
   }
+  if (width == 0) {
+    width = 1;
+    mZero = true;
+  }
+  mWidth = width;
+  mHeight = height;
 
   return NS_OK;
 }
 
 void
 CanvasRenderingContext2D::ClearTarget()
 {
   Reset();
@@ -1045,81 +1047,81 @@ CanvasRenderingContext2D::Render(gfxCont
       MOZ_ASSERT(gis, "If non-premult alpha, must be able to get image surface!");
 
       gfxUtils::UnpremultiplyImageSurface(gis);
   }
 
   return rv;
 }
 
+void
+CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
+                                         int32_t* aFormat)
+{
+  *aImageBuffer = nullptr;
+  *aFormat = 0;
+
+  nsRefPtr<gfxASurface> surface;
+  nsresult rv = GetThebesSurface(getter_AddRefs(surface));
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  static const fallible_t fallible = fallible_t();
+  uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
+  if (!imageBuffer) {
+    return;
+  }
+
+  nsRefPtr<gfxImageSurface> imgsurf =
+    new gfxImageSurface(imageBuffer,
+                        gfxIntSize(mWidth, mHeight),
+                        mWidth * 4,
+                        gfxImageFormatARGB32);
+
+  if (!imgsurf || imgsurf->CairoStatus()) {
+    delete[] imageBuffer;
+    return;
+  }
+
+  nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
+  if (!ctx || ctx->HasError()) {
+    delete[] imageBuffer;
+    return;
+  }
+
+  ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+  ctx->SetSource(surface, gfxPoint(0, 0));
+  ctx->Paint();
+
+  *aImageBuffer = imageBuffer;
+  *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB;
+}
+
 NS_IMETHODIMP
 CanvasRenderingContext2D::GetInputStream(const char *aMimeType,
                                          const PRUnichar *aEncoderOptions,
                                          nsIInputStream **aStream)
 {
-  EnsureTarget();
-  if (!IsTargetValid()) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsRefPtr<gfxASurface> surface;
-
-  if (NS_FAILED(GetThebesSurface(getter_AddRefs(surface)))) {
+  uint8_t* imageBuffer = nullptr;
+  int32_t format = 0;
+  GetImageBuffer(&imageBuffer, &format);
+  if (!imageBuffer) {
     return NS_ERROR_FAILURE;
   }
 
-  nsresult rv;
-  const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type=";
-  static const fallible_t fallible = fallible_t();
-  nsAutoArrayPtr<char> conid(new (fallible) char[strlen(encoderPrefix) + strlen(aMimeType) + 1]);
-
-  if (!conid) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  strcpy(conid, encoderPrefix);
-  strcat(conid, aMimeType);
-
-  nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid);
+  nsCString enccid("@mozilla.org/image/encoder;2?type=");
+  enccid += aMimeType;
+  nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get());
   if (!encoder) {
     return NS_ERROR_FAILURE;
   }
 
-  nsAutoArrayPtr<uint8_t> imageBuffer(new (fallible) uint8_t[mWidth * mHeight * 4]);
-  if (!imageBuffer) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  nsRefPtr<gfxImageSurface> imgsurf =
-    new gfxImageSurface(imageBuffer.get(),
-                        gfxIntSize(mWidth, mHeight),
-                        mWidth * 4,
-                        gfxImageFormatARGB32);
-
-  if (!imgsurf || imgsurf->CairoStatus()) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
-
-  if (!ctx || ctx->HasError()) {
-    return NS_ERROR_FAILURE;
-  }
-
-  ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-  ctx->SetSource(surface, gfxPoint(0, 0));
-  ctx->Paint();
-
-  rv = encoder->InitFromData(imageBuffer.get(),
-                              mWidth * mHeight * 4, mWidth, mHeight, mWidth * 4,
-                              imgIEncoder::INPUT_FORMAT_HOSTARGB,
-                              nsDependentString(aEncoderOptions));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return CallQueryInterface(encoder, aStream);
+  return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format,
+                                      encoder, aEncoderOptions, aStream);
 }
 
 SurfaceFormat
 CanvasRenderingContext2D::GetSurfaceFormat() const
 {
   return mOpaque ? FORMAT_B8G8R8X8 : FORMAT_B8G8R8A8;
 }
 
@@ -3810,16 +3812,19 @@ CanvasRenderingContext2D::PutImageData_e
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface)
 {
   EnsureTarget();
+  if (!IsTargetValid()) {
+    return NS_ERROR_FAILURE;
+  }
 
   nsRefPtr<gfxASurface> thebesSurface =
       gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget);
 
   if (!thebesSurface) {
     return NS_ERROR_FAILURE;
   }
 
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -17,16 +17,17 @@
 #include "gfxFont.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/CanvasGradient.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/dom/CanvasPattern.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/gfx/2D.h"
 #include "gfx2DGlue.h"
+#include "imgIEncoder.h"
 
 class nsXULElement;
 
 namespace mozilla {
 namespace gfx {
 class SourceSurface;
 }
 
@@ -455,16 +456,18 @@ public:
       mDSPathBuilder->BezierTo(transform * aCP1,
                                 transform * aCP2,
                                 transform * aCP3);
     }
   }
 
   friend class CanvasRenderingContext2DUserData;
 
+  virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
+
 protected:
   nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
                              uint32_t aWidth, uint32_t aHeight,
                              JSObject** aRetval);
 
   nsresult PutImageData_explicit(int32_t x, int32_t y, uint32_t w, uint32_t h,
                                  unsigned char *aData, uint32_t aDataLen,
                                  bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/ImageEncoder.cpp
@@ -0,0 +1,330 @@
+/* -*- 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 "gfxImageSurface.h"
+#include "ImageEncoder.h"
+#include "mozilla/dom/CanvasRenderingContext2D.h"
+
+namespace mozilla {
+namespace dom {
+
+class EncodingCompleteEvent : public nsRunnable
+{
+public:
+  NS_DECL_THREADSAFE_ISUPPORTS
+
+  EncodingCompleteEvent(nsIScriptContext* aScriptContext,
+                        nsIThread* aEncoderThread,
+                        FileCallback& aCallback)
+    : mImgSize(0)
+    , mType()
+    , mImgData(nullptr)
+    , mScriptContext(aScriptContext)
+    , mEncoderThread(aEncoderThread)
+    , mCallback(&aCallback)
+    , mFailed(false)
+  {}
+  virtual ~EncodingCompleteEvent() {}
+
+  NS_IMETHOD Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    mozilla::ErrorResult rv;
+
+    if (!mFailed) {
+      nsRefPtr<nsDOMMemoryFile> blob =
+        new nsDOMMemoryFile(mImgData, mImgSize, mType);
+
+      if (mScriptContext) {
+        JSContext* jsContext = mScriptContext->GetNativeContext();
+        if (jsContext) {
+          JS_updateMallocCounter(jsContext, mImgSize);
+        }
+      }
+
+      mCallback->Call(blob, rv);
+    }
+
+    // These members aren't thread-safe. We're making sure that they're being
+    // released on the main thread here. Otherwise, they could be getting
+    // released by EncodingRunnable's destructor on the encoding thread
+    // (bug 916128).
+    mScriptContext = nullptr;
+    mCallback = nullptr;
+
+    mEncoderThread->Shutdown();
+    return rv.ErrorCode();
+  }
+
+  void SetMembers(void* aImgData, uint64_t aImgSize, const nsAutoString& aType)
+  {
+    mImgData = aImgData;
+    mImgSize = aImgSize;
+    mType = aType;
+  }
+
+  void SetFailed()
+  {
+    mFailed = true;
+  }
+
+private:
+  uint64_t mImgSize;
+  nsAutoString mType;
+  void* mImgData;
+  nsCOMPtr<nsIScriptContext> mScriptContext;
+  nsCOMPtr<nsIThread> mEncoderThread;
+  nsRefPtr<FileCallback> mCallback;
+  bool mFailed;
+};
+
+NS_IMPL_ISUPPORTS1(EncodingCompleteEvent, nsIRunnable);
+
+class EncodingRunnable : public nsRunnable
+{
+public:
+  NS_DECL_THREADSAFE_ISUPPORTS
+
+  EncodingRunnable(const nsAString& aType,
+                   const nsAString& aOptions,
+                   uint8_t* aImageBuffer,
+                   imgIEncoder* aEncoder,
+                   EncodingCompleteEvent* aEncodingCompleteEvent,
+                   int32_t aFormat,
+                   const nsIntSize aSize,
+                   bool aUsingCustomOptions)
+    : mType(aType)
+    , mOptions(aOptions)
+    , mImageBuffer(aImageBuffer)
+    , mEncoder(aEncoder)
+    , mEncodingCompleteEvent(aEncodingCompleteEvent)
+    , mFormat(aFormat)
+    , mSize(aSize)
+    , mUsingCustomOptions(aUsingCustomOptions)
+  {}
+  virtual ~EncodingRunnable() {}
+
+  nsresult ProcessImageData(uint64_t* aImgSize, void** aImgData)
+  {
+    nsCOMPtr<nsIInputStream> stream;
+    nsresult rv = ImageEncoder::ExtractDataInternal(mType,
+                                                    mOptions,
+                                                    mImageBuffer,
+                                                    mFormat,
+                                                    mSize,
+                                                    nullptr,
+                                                    getter_AddRefs(stream),
+                                                    mEncoder);
+
+    // If there are unrecognized custom parse options, we should fall back to
+    // the default values for the encoder without any options at all.
+    if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) {
+      rv = ImageEncoder::ExtractDataInternal(mType,
+                                             EmptyString(),
+                                             mImageBuffer,
+                                             mFormat,
+                                             mSize,
+                                             nullptr,
+                                             getter_AddRefs(stream),
+                                             mEncoder);
+    }
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = stream->Available(aImgSize);
+    NS_ENSURE_SUCCESS(rv, rv);
+    NS_ENSURE_TRUE(*aImgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
+
+    rv = NS_ReadInputStreamToBuffer(stream, aImgData, *aImgSize);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return rv;
+  }
+
+  NS_IMETHOD Run()
+  {
+    uint64_t imgSize;
+    void* imgData = nullptr;
+
+    nsresult rv = ProcessImageData(&imgSize, &imgData);
+    if (NS_FAILED(rv)) {
+      mEncodingCompleteEvent->SetFailed();
+    } else {
+      mEncodingCompleteEvent->SetMembers(imgData, imgSize, mType);
+    }
+    rv = NS_DispatchToMainThread(mEncodingCompleteEvent, NS_DISPATCH_NORMAL);
+    if (NS_FAILED(rv)) {
+      // Better to leak than to crash.
+      mEncodingCompleteEvent.forget();
+      return rv;
+    }
+
+    return rv;
+  }
+
+private:
+  nsAutoString mType;
+  nsAutoString mOptions;
+  nsAutoArrayPtr<uint8_t> mImageBuffer;
+  nsCOMPtr<imgIEncoder> mEncoder;
+  nsRefPtr<EncodingCompleteEvent> mEncodingCompleteEvent;
+  int32_t mFormat;
+  const nsIntSize mSize;
+  bool mUsingCustomOptions;
+};
+
+NS_IMPL_ISUPPORTS1(EncodingRunnable, nsIRunnable)
+
+/* static */
+nsresult
+ImageEncoder::ExtractData(nsAString& aType,
+                          const nsAString& aOptions,
+                          const nsIntSize aSize,
+                          nsICanvasRenderingContextInternal* aContext,
+                          nsIInputStream** aStream)
+{
+  nsCOMPtr<imgIEncoder> encoder = ImageEncoder::GetImageEncoder(aType);
+  if (!encoder) {
+    return NS_IMAGELIB_ERROR_NO_ENCODER;
+  }
+
+  return ExtractDataInternal(aType, aOptions, nullptr, 0, aSize, aContext,
+                             aStream, encoder);
+}
+
+/* static */
+nsresult
+ImageEncoder::ExtractDataAsync(nsAString& aType,
+                               const nsAString& aOptions,
+                               bool aUsingCustomOptions,
+                               uint8_t* aImageBuffer,
+                               int32_t aFormat,
+                               const nsIntSize aSize,
+                               nsICanvasRenderingContextInternal* aContext,
+                               nsIScriptContext* aScriptContext,
+                               FileCallback& aCallback)
+{
+  nsCOMPtr<imgIEncoder> encoder = ImageEncoder::GetImageEncoder(aType);
+  if (!encoder) {
+    return NS_IMAGELIB_ERROR_NO_ENCODER;
+  }
+
+  nsCOMPtr<nsIThread> encoderThread;
+  nsresult rv = NS_NewThread(getter_AddRefs(encoderThread), nullptr);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsRefPtr<EncodingCompleteEvent> completeEvent =
+    new EncodingCompleteEvent(aScriptContext, encoderThread, aCallback);
+
+  nsCOMPtr<nsIRunnable> event = new EncodingRunnable(aType,
+                                                     aOptions,
+                                                     aImageBuffer,
+                                                     encoder,
+                                                     completeEvent,
+                                                     aFormat,
+                                                     aSize,
+                                                     aUsingCustomOptions);
+  return encoderThread->Dispatch(event, NS_DISPATCH_NORMAL);
+}
+
+/*static*/ nsresult
+ImageEncoder::GetInputStream(int32_t aWidth,
+                             int32_t aHeight,
+                             uint8_t* aImageBuffer,
+                             int32_t aFormat,
+                             imgIEncoder* aEncoder,
+                             const PRUnichar* aEncoderOptions,
+                             nsIInputStream** aStream)
+{
+  nsresult rv =
+    aEncoder->InitFromData(aImageBuffer,
+                           aWidth * aHeight * 4, aWidth, aHeight, aWidth * 4,
+                           aFormat,
+                           nsDependentString(aEncoderOptions));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return CallQueryInterface(aEncoder, aStream);
+}
+
+/* static */
+nsresult
+ImageEncoder::ExtractDataInternal(const nsAString& aType,
+                                  const nsAString& aOptions,
+                                  uint8_t* aImageBuffer,
+                                  int32_t aFormat,
+                                  const nsIntSize aSize,
+                                  nsICanvasRenderingContextInternal* aContext,
+                                  nsIInputStream** aStream,
+                                  imgIEncoder* aEncoder)
+{
+  nsCOMPtr<nsIInputStream> imgStream;
+
+  // get image bytes
+  nsresult rv;
+  if (aImageBuffer) {
+    rv = ImageEncoder::GetInputStream(
+      aSize.width,
+      aSize.height,
+      aImageBuffer,
+      aFormat,
+      aEncoder,
+      nsPromiseFlatString(aOptions).get(),
+      getter_AddRefs(imgStream));
+  } else if (aContext) {
+    NS_ConvertUTF16toUTF8 encoderType(aType);
+    rv = aContext->GetInputStream(encoderType.get(),
+                                  nsPromiseFlatString(aOptions).get(),
+                                  getter_AddRefs(imgStream));
+  } else {
+    // no context, so we have to encode an empty image
+    // note that if we didn't have a current context, the spec says we're
+    // supposed to just return transparent black pixels of the canvas
+    // dimensions.
+    nsRefPtr<gfxImageSurface> emptyCanvas =
+      new gfxImageSurface(gfxIntSize(aSize.width, aSize.height),
+                          gfxImageFormatARGB32);
+    if (emptyCanvas->CairoStatus()) {
+      return NS_ERROR_INVALID_ARG;
+    }
+    rv = aEncoder->InitFromData(emptyCanvas->Data(),
+                                aSize.width * aSize.height * 4,
+                                aSize.width,
+                                aSize.height,
+                                aSize.width * 4,
+                                imgIEncoder::INPUT_FORMAT_HOSTARGB,
+                                aOptions);
+    if (NS_SUCCEEDED(rv)) {
+      imgStream = do_QueryInterface(aEncoder);
+    }
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  imgStream.forget(aStream);
+  return rv;
+}
+
+/* static */
+already_AddRefed<imgIEncoder>
+ImageEncoder::GetImageEncoder(nsAString& aType)
+{
+  // Get an image encoder for the media type.
+  nsCString encoderCID("@mozilla.org/image/encoder;2?type=");
+  NS_ConvertUTF16toUTF8 encoderType(aType);
+  encoderCID += encoderType;
+  nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get());
+
+  if (!encoder && aType != NS_LITERAL_STRING("image/png")) {
+    // Unable to create an encoder instance of the specified type. Falling back
+    // to PNG.
+    aType.AssignLiteral("image/png");
+    nsCString PNGEncoderCID("@mozilla.org/image/encoder;2?type=image/png");
+    encoder = do_CreateInstance(PNGEncoderCID.get());
+  }
+
+  return encoder.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/ImageEncoder.h
@@ -0,0 +1,92 @@
+/* -*- 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 ImageEncoder_h
+#define ImageEncoder_h
+
+#include "imgIEncoder.h"
+#include "nsDOMFile.h"
+#include "nsError.h"
+#include "mozilla/dom/HTMLCanvasElementBinding.h"
+#include "nsLayoutUtils.h"
+#include "nsNetUtil.h"
+#include "nsSize.h"
+
+class nsICanvasRenderingContextInternal;
+
+namespace mozilla {
+namespace dom {
+
+class EncodingRunnable;
+
+class ImageEncoder
+{
+public:
+  // Extracts data synchronously and gives you a stream containing the image
+  // represented by aContext. aType may change to "image/png" if we had to fall
+  // back to a PNG encoder. A return value of NS_OK implies successful data
+  // extraction. If there are any unrecognized custom parse options in
+  // aOptions, NS_ERROR_INVALID_ARG will be returned. When encountering this
+  // error it is usual to call this function again without any options at all.
+  static nsresult ExtractData(nsAString& aType,
+                              const nsAString& aOptions,
+                              const nsIntSize aSize,
+                              nsICanvasRenderingContextInternal* aContext,
+                              nsIInputStream** aStream);
+
+  // Extracts data asynchronously. aType may change to "image/png" if we had to
+  // fall back to a PNG encoder. aOptions are the options to be passed to the
+  // encoder and aUsingCustomOptions specifies whether custom parse options were
+  // used (i.e. by using -moz-parse-options). If there are any unrecognized
+  // custom parse options, we fall back to the default values for the encoder
+  // without any options at all. A return value of NS_OK only implies
+  // successful dispatching of the extraction step to the encoding thread.
+  static nsresult ExtractDataAsync(nsAString& aType,
+                                   const nsAString& aOptions,
+                                   bool aUsingCustomOptions,
+                                   uint8_t* aImageBuffer,
+                                   int32_t aFormat,
+                                   const nsIntSize aSize,
+                                   nsICanvasRenderingContextInternal* aContext,
+                                   nsIScriptContext* aScriptContext,
+                                   FileCallback& aCallback);
+
+  // Gives you a stream containing the image represented by aImageBuffer.
+  // The format is given in aFormat, for example
+  // imgIEncoder::INPUT_FORMAT_HOSTARGB.
+  static nsresult GetInputStream(int32_t aWidth,
+                                 int32_t aHeight,
+                                 uint8_t* aImageBuffer,
+                                 int32_t aFormat,
+                                 imgIEncoder* aEncoder,
+                                 const PRUnichar* aEncoderOptions,
+                                 nsIInputStream** aStream);
+
+private:
+  // When called asynchronously, aContext is null.
+  static nsresult
+  ExtractDataInternal(const nsAString& aType,
+                      const nsAString& aOptions,
+                      uint8_t* aImageBuffer,
+                      int32_t aFormat,
+                      const nsIntSize aSize,
+                      nsICanvasRenderingContextInternal* aContext,
+                      nsIInputStream** aStream,
+                      imgIEncoder* aEncoder);
+
+  // Creates and returns an encoder instance of the type specified in aType.
+  // aType may change to "image/png" if no instance of the original type could
+  // be created and we had to fall back to a PNG encoder. A return value of
+  // NULL should be interpreted as NS_IMAGELIB_ERROR_NO_ENCODER and aType is
+  // undefined in this case.
+  static already_AddRefed<imgIEncoder> GetImageEncoder(nsAString& aType);
+
+  friend class EncodingRunnable;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // ImageEncoder_h
\ No newline at end of file
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -17,10 +17,11 @@ CXXFLAGS	+= $(MOZ_CAIRO_CFLAGS) $(MOZ_PI
 INCLUDES	+= \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../html/content/src \
 		-I$(srcdir)/../../../js/xpconnect/src \
 		-I$(srcdir)/../../../dom/base \
+		-I$(srcdir)/../../../image/src \
 		-I$(topsrcdir)/content/xul/content/src \
 		$(NULL)
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -22,17 +22,17 @@
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsError.h"
 #include "nsIGfxInfo.h"
 #include "nsIWidget.h"
 
 #include "nsIVariant.h"
 
-#include "imgIEncoder.h"
+#include "ImageEncoder.h"
 
 #include "gfxContext.h"
 #include "gfxPattern.h"
 #include "gfxUtils.h"
 
 #include "CanvasUtils.h"
 #include "nsDisplayList.h"
 
@@ -376,18 +376,20 @@ WebGLContext::SetDimensions(int32_t widt
     // Early success return cases
 
     GetCanvas()->InvalidateCanvas();
 
     if (gl && mWidth == width && mHeight == height)
         return NS_OK;
 
     // Zero-sized surfaces can cause problems.
-    if (width == 0 || height == 0) {
+    if (width == 0) {
         width = 1;
+    }
+    if (height == 0) {
         height = 1;
     }
 
     // If we already have a gl context, then we just need to resize it
     if (gl) {
         MakeContextCurrent();
 
         gl->ResizeOffscreen(gfxIntSize(width, height)); // Doesn't matter if it succeeds (soft-fail)
@@ -728,67 +730,89 @@ void WebGLContext::LoseOldestWebGLContex
     } else if (numContexts > kMaxWebGLContexts) {
         GenerateWarning("Exceeded %d live WebGL contexts, losing the least recently used one.",
                         kMaxWebGLContexts);
         MOZ_ASSERT(oldestContext); // if we reach this point, this can't be null
         const_cast<WebGLContext*>(oldestContext)->LoseContext();
     }
 }
 
+void
+WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
+{
+    *aImageBuffer = nullptr;
+    *aFormat = 0;
+
+    nsRefPtr<gfxImageSurface> imgsurf =
+        new gfxImageSurface(gfxIntSize(mWidth, mHeight),
+                            gfxImageFormatARGB32);
+
+    if (!imgsurf || imgsurf->CairoStatus()) {
+        return;
+    }
+
+    nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
+    if (!ctx || ctx->HasError()) {
+        return;
+    }
+
+    // Use Render() to make sure that appropriate y-flip gets applied
+    uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0;
+    nsresult rv = Render(ctx, GraphicsFilter::FILTER_NEAREST, flags);
+    if (NS_FAILED(rv)) {
+        return;
+    }
+
+    int32_t format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
+    if (!mOptions.premultipliedAlpha) {
+        // We need to convert to INPUT_FORMAT_RGBA, otherwise
+        // we are automatically considered premult, and unpremult'd.
+        // Yes, it is THAT silly.
+        // Except for different lossy conversions by color,
+        // we could probably just change the label, and not change the data.
+        gfxUtils::ConvertBGRAtoRGBA(imgsurf);
+        format = imgIEncoder::INPUT_FORMAT_RGBA;
+    }
+
+    static const fallible_t fallible = fallible_t();
+    uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
+    if (!imageBuffer) {
+        return;
+    }
+    memcpy(imageBuffer, imgsurf->Data(), mWidth * mHeight * 4);
+
+    *aImageBuffer = imageBuffer;
+    *aFormat = format;
+}
+
 NS_IMETHODIMP
 WebGLContext::GetInputStream(const char* aMimeType,
                              const PRUnichar* aEncoderOptions,
                              nsIInputStream **aStream)
 {
     NS_ASSERTION(gl, "GetInputStream on invalid context?");
     if (!gl)
         return NS_ERROR_FAILURE;
 
-    nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
-                                                         gfxImageFormatARGB32);
-    if (surf->CairoStatus() != 0)
+    uint8_t* imageBuffer = nullptr;
+    int32_t format = 0;
+    GetImageBuffer(&imageBuffer, &format);
+    if (!imageBuffer) {
         return NS_ERROR_FAILURE;
-
-    nsRefPtr<gfxContext> tmpcx = new gfxContext(surf);
-    // Use Render() to make sure that appropriate y-flip gets applied
-    uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0;
-    nsresult rv = Render(tmpcx, GraphicsFilter::FILTER_NEAREST, flags);
-    if (NS_FAILED(rv))
-        return rv;
-
-    const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type=";
-    nsAutoArrayPtr<char> conid(new char[strlen(encoderPrefix) + strlen(aMimeType) + 1]);
-
-    strcpy(conid, encoderPrefix);
-    strcat(conid, aMimeType);
-
-    nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid);
-    if (!encoder)
-        return NS_ERROR_FAILURE;
-
-    int format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
-    if (!mOptions.premultipliedAlpha) {
-        // We need to convert to INPUT_FORMAT_RGBA, otherwise
-        // we are automatically considered premult, and unpremult'd.
-        // Yes, it is THAT silly.
-        // Except for different lossy conversions by color,
-        // we could probably just change the label, and not change the data.
-        gfxUtils::ConvertBGRAtoRGBA(surf);
-        format = imgIEncoder::INPUT_FORMAT_RGBA;
     }
 
-    rv = encoder->InitFromData(surf->Data(),
-                               mWidth * mHeight * 4,
-                               mWidth, mHeight,
-                               surf->Stride(),
-                               format,
-                               nsDependentString(aEncoderOptions));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsCString enccid("@mozilla.org/image/encoder;2?type=");
+    enccid += aMimeType;
+    nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get());
+    if (!encoder) {
+        return NS_ERROR_FAILURE;
+    }
 
-    return CallQueryInterface(encoder, aStream);
+    return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format,
+                                        encoder, aEncoderOptions, aStream);
 }
 
 NS_IMETHODIMP
 WebGLContext::GetThebesSurface(gfxASurface **surface)
 {
     return NS_ERROR_NOT_AVAILABLE;
 }
 
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -162,16 +162,17 @@ public:
     NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
     NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE
         { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD Reset() MOZ_OVERRIDE
         { /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD Render(gfxContext *ctx,
                       GraphicsFilter f,
                       uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
+    virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
     NS_IMETHOD GetInputStream(const char* aMimeType,
                               const PRUnichar* aEncoderOptions,
                               nsIInputStream **aStream) MOZ_OVERRIDE;
     NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE;
 
     NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
     NS_IMETHOD SetContextOptions(JSContext* aCx,
--- a/content/canvas/src/moz.build
+++ b/content/canvas/src/moz.build
@@ -17,16 +17,17 @@ EXPORTS.mozilla.dom += [
 
 CPP_SOURCES += [
     'CanvasImageCache.cpp',
     'CanvasRenderingContext2D.cpp',
     'CanvasUtils.cpp',
     'DocumentRendererChild.cpp',
     'DocumentRendererParent.cpp',
     'ImageData.cpp',
+    'ImageEncoder.cpp',
 ]
 
 if CONFIG['MOZ_WEBGL']:
     CPP_SOURCES += [
         'WebGLActiveInfo.cpp',
         'WebGLBuffer.cpp',
         'WebGL1Context.cpp',
         'WebGL2Context.cpp',
--- a/content/canvas/test/test_mozGetAsFile.html
+++ b/content/canvas/test/test_mozGetAsFile.html
@@ -2,49 +2,50 @@
 <title>Canvas test: mozGetAsFile</title>
 <script src="/MochiKit/MochiKit.js"></script>
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
 <body>
 <canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
 
-var gCompares = 0;
-
-function compareAsync(file, canvas, type)
+function compareAsync(file, canvas, type, callback)
 {
-  ++gCompares;
-
   var reader = new FileReader();
   reader.onload = 
     function(e) {
       is(e.target.result, canvas.toDataURL(type),
  "<canvas>.mozGetAsFile().getAsDataURL() should equal <canvas>.toDataURL()");
-      if (--gCompares == 0) {
-        SimpleTest.finish();
-      }
+      callback(canvas);
     };
   reader.readAsDataURL(file);
 }
 
+function test1(canvas)
+{
+  var pngfile = canvas.mozGetAsFile("foo.png");
+  is(pngfile.type, "image/png", "Default type for mozGetAsFile should be PNG");
+  compareAsync(pngfile, canvas, "image/png", test2);
+  is(pngfile.name, "foo.png", "File name should be what we passed in");
+}
+
+function test2(canvas)
+{
+  var jpegfile = canvas.mozGetAsFile("bar.jpg", "image/jpeg");
+  is(jpegfile.type, "image/jpeg",
+     "When a valid type is specified that should be returned");
+  compareAsync(jpegfile, canvas, "image/jpeg", SimpleTest.finish);
+  is(jpegfile.name, "bar.jpg", "File name should be what we passed in");
+}
+
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function () {
 
 var canvas = document.getElementById('c');
 var ctx = canvas.getContext('2d');
-
 ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
 
-var pngfile = canvas.mozGetAsFile("foo.png");
-is(pngfile.type, "image/png", "Default type for mozGetAsFile should be PNG");
-compareAsync(pngfile, canvas, "image/png");
-is(pngfile.name, "foo.png", "File name should be what we passed in");
-
-var jpegfile = canvas.mozGetAsFile("bar.jpg", "image/jpeg");
-is(jpegfile.type, "image/jpeg",
-   "When a valid type is specified that should be returned");
-compareAsync(jpegfile, canvas, "image/jpeg");
-is(jpegfile.name, "bar.jpg", "File name should be what we passed in");
+test1(canvas);
 
 });
 </script>
 <img src="image_yellow75.png" id="yellow75.png" class="resource">
 
--- a/content/canvas/test/test_toBlob.html
+++ b/content/canvas/test/test_toBlob.html
@@ -1,42 +1,48 @@
 <!DOCTYPE HTML>
-<title>Canvas test: mozGetAsFile</title>
+<title>Canvas test: toBlob</title>
 <script src="/MochiKit/MochiKit.js"></script>
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
 <body>
 <canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
 
-var gCompares = 2;
-
-function BlobListener(type, canvas, file)
+function BlobListener(type, canvas, callback, file)
 {
   is(file.type, type,
      "When a valid type is specified that should be returned");
   var reader = new FileReader();
-  reader.onload = 
+  reader.onload =
     function(e) {
       is(e.target.result, canvas.toDataURL(type),
- "<canvas>.mozGetAsFile().getAsDataURL() should equal <canvas>.toDataURL()");
-      if (--gCompares == 0) {
-        SimpleTest.finish();
-      }
+  "<canvas>.mozGetAsFile().getAsDataURL() should equal <canvas>.toDataURL()");
+      callback(canvas);
     };
   reader.readAsDataURL(file);
 }
 
+function test1(canvas)
+{
+  canvas.toBlob(BlobListener.bind(undefined, "image/png", canvas, test2));
+}
+
+function test2(canvas)
+{
+  canvas.toBlob(
+    BlobListener.bind(undefined, "image/jpeg", canvas, SimpleTest.finish),
+    "image/jpeg");
+}
+
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function () {
 
 var canvas = document.getElementById('c');
 var ctx = canvas.getContext('2d');
-
 ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
 
-canvas.toBlob(BlobListener.bind(undefined, "image/png", canvas));
-canvas.toBlob(BlobListener.bind(undefined, "image/jpeg", canvas), "image/jpeg");
+test1(canvas);
 
 });
 </script>
 <img src="image_yellow75.png" id="yellow75.png" class="resource">
 
--- a/content/html/content/public/HTMLCanvasElement.h
+++ b/content/html/content/public/HTMLCanvasElement.h
@@ -222,20 +222,19 @@ protected:
   nsIntSize GetWidthHeight();
 
   nsresult UpdateContext(JSContext* aCx, JS::Handle<JS::Value> options);
   nsresult ParseParams(JSContext* aCx,
                        const nsAString& aType,
                        const JS::Value& aEncoderOptions,
                        nsAString& aParams,
                        bool* usingCustomParseOptions);
-  nsresult ExtractData(const nsAString& aType,
+  nsresult ExtractData(nsAString& aType,
                        const nsAString& aOptions,
-                       nsIInputStream** aStream,
-                       bool& aFellBackToPNG);
+                       nsIInputStream** aStream);
   nsresult ToDataURLImpl(JSContext* aCx,
                          const nsAString& aMimeType,
                          const JS::Value& aEncoderOptions,
                          nsAString& aDataURL);
   nsresult MozGetAsFileImpl(const nsAString& aName,
                             const nsAString& aType,
                             nsIDOMFile** aResult);
   nsresult GetContextHelper(const nsAString& aContextId,
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -1,33 +1,34 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLCanvasElement.h"
 
-#include "Layers.h"
-#include "imgIEncoder.h"
+#include "ImageEncoder.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "gfxImageSurface.h"
+#include "Layers.h"
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/dom/CanvasRenderingContext2D.h"
 #include "mozilla/dom/HTMLCanvasElementBinding.h"
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsAttrValueInlines.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
 #include "nsDOMFile.h"
+#include "nsDOMJSUtils.h"
 #include "nsFrameManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsITimer.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsIXPConnect.h"
 #include "nsJSUtils.h"
 #include "nsMathUtils.h"
 #include "nsNetUtil.h"
@@ -41,39 +42,16 @@ using namespace mozilla::layers;
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Canvas)
 
 namespace {
 
 typedef mozilla::dom::HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
 HTMLImageOrCanvasOrVideoElement;
 
-class ToBlobRunnable : public nsRunnable
-{
-public:
-  ToBlobRunnable(mozilla::dom::FileCallback& aCallback,
-                 nsIDOMBlob* aBlob)
-    : mCallback(&aCallback),
-      mBlob(aBlob)
-  {
-    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  }
-
-  NS_IMETHOD Run()
-  {
-    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-    mozilla::ErrorResult rv;
-    mCallback->Call(mBlob, rv);
-    return rv.ErrorCode();
-  }
-private:
-  nsRefPtr<mozilla::dom::FileCallback> mCallback;
-  nsCOMPtr<nsIDOMBlob> mBlob;
-};
-
 } // anonymous namespace
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(HTMLCanvasPrintState, mCanvas,
                                         mContext, mCallback)
 
@@ -364,20 +342,20 @@ HTMLCanvasElement::ToDataURL(const nsASt
 NS_IMETHODIMP
 HTMLCanvasElement::MozFetchAsStream(nsIInputStreamCallback *aCallback,
                                     const nsAString& aType)
 {
   if (!nsContentUtils::IsCallerChrome())
     return NS_ERROR_FAILURE;
 
   nsresult rv;
-  bool fellBackToPNG = false;
   nsCOMPtr<nsIInputStream> inputData;
 
-  rv = ExtractData(aType, EmptyString(), getter_AddRefs(inputData), fellBackToPNG);
+  nsAutoString type(aType);
+  rv = ExtractData(type, EmptyString(), getter_AddRefs(inputData));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIAsyncInputStream> asyncData = do_QueryInterface(inputData, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIThread> mainThread;
   rv = NS_GetMainThread(getter_AddRefs(mainThread));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -399,78 +377,25 @@ HTMLCanvasElement::GetMozPrintCallback()
 {
   if (mOriginalCanvas) {
     return mOriginalCanvas->GetMozPrintCallback();
   }
   return mPrintCallback;
 }
 
 nsresult
-HTMLCanvasElement::ExtractData(const nsAString& aType,
+HTMLCanvasElement::ExtractData(nsAString& aType,
                                const nsAString& aOptions,
-                               nsIInputStream** aStream,
-                               bool& aFellBackToPNG)
+                               nsIInputStream** aStream)
 {
-  // note that if we don't have a current context, the spec says we're
-  // supposed to just return transparent black pixels of the canvas
-  // dimensions.
-  nsRefPtr<gfxImageSurface> emptyCanvas;
-  nsIntSize size = GetWidthHeight();
-  if (!mCurrentContext) {
-    emptyCanvas = new gfxImageSurface(gfxIntSize(size.width, size.height), gfxImageFormatARGB32);
-    if (emptyCanvas->CairoStatus()) {
-      return NS_ERROR_INVALID_ARG;
-    }
-  }
-
-  nsresult rv;
-
-  // get image bytes
-  nsCOMPtr<nsIInputStream> imgStream;
-  NS_ConvertUTF16toUTF8 encoderType(aType);
-
- try_again:
-  if (mCurrentContext) {
-    rv = mCurrentContext->GetInputStream(encoderType.get(),
-                                         nsPromiseFlatString(aOptions).get(),
-                                         getter_AddRefs(imgStream));
-  } else {
-    // no context, so we have to encode the empty image we created above
-    nsCString enccid("@mozilla.org/image/encoder;2?type=");
-    enccid += encoderType;
-
-    nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get(), &rv);
-    if (NS_SUCCEEDED(rv) && encoder) {
-      rv = encoder->InitFromData(emptyCanvas->Data(),
-                                 size.width * size.height * 4,
-                                 size.width,
-                                 size.height,
-                                 size.width * 4,
-                                 imgIEncoder::INPUT_FORMAT_HOSTARGB,
-                                 aOptions);
-      if (NS_SUCCEEDED(rv)) {
-        imgStream = do_QueryInterface(encoder);
-      }
-    } else {
-      rv = NS_ERROR_FAILURE;
-    }
-  }
-
-  if (NS_FAILED(rv) && !aFellBackToPNG) {
-    // Try image/png instead.
-    // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    aFellBackToPNG = true;
-    encoderType.AssignLiteral("image/png");
-    goto try_again;
-  }
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  imgStream.forget(aStream);
-  return NS_OK;
+  return ImageEncoder::ExtractData(aType,
+                                   aOptions,
+                                   GetSize(),
+                                   mCurrentContext,
+                                   aStream);
 }
 
 nsresult
 HTMLCanvasElement::ParseParams(JSContext* aCx,
                                const nsAString& aType,
                                const JS::Value& aEncoderOptions,
                                nsAString& aParams,
                                bool* usingCustomParseOptions)
@@ -511,18 +436,16 @@ HTMLCanvasElement::ParseParams(JSContext
 }
 
 nsresult
 HTMLCanvasElement::ToDataURLImpl(JSContext* aCx,
                                  const nsAString& aMimeType,
                                  const JS::Value& aEncoderOptions,
                                  nsAString& aDataURL)
 {
-  bool fallbackToPNG = false;
-
   nsIntSize size = GetWidthHeight();
   if (size.height == 0 || size.width == 0) {
     aDataURL = NS_LITERAL_STRING("data:,");
     return NS_OK;
   }
 
   nsAutoString type;
   nsresult rv = nsContentUtils::ASCIIToLower(aMimeType, type);
@@ -533,43 +456,37 @@ HTMLCanvasElement::ToDataURLImpl(JSConte
   nsAutoString params;
   bool usingCustomParseOptions;
   rv = ParseParams(aCx, type, aEncoderOptions, params, &usingCustomParseOptions);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIInputStream> stream;
-  rv = ExtractData(type, params, getter_AddRefs(stream), fallbackToPNG);
+  rv = ExtractData(type, params, getter_AddRefs(stream));
 
   // If there are unrecognized custom parse options, we should fall back to
   // the default values for the encoder without any options at all.
   if (rv == NS_ERROR_INVALID_ARG && usingCustomParseOptions) {
-    fallbackToPNG = false;
-    rv = ExtractData(type, EmptyString(), getter_AddRefs(stream), fallbackToPNG);
+    rv = ExtractData(type, EmptyString(), getter_AddRefs(stream));
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // build data URL string
-  if (fallbackToPNG)
-    aDataURL = NS_LITERAL_STRING("data:image/png;base64,");
-  else
-    aDataURL = NS_LITERAL_STRING("data:") + type +
-      NS_LITERAL_STRING(";base64,");
+  aDataURL = NS_LITERAL_STRING("data:") + type + NS_LITERAL_STRING(";base64,");
 
   uint64_t count;
   rv = stream->Available(&count);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(count <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
   return Base64EncodeInputStream(stream, aDataURL, (uint32_t)count, aDataURL.Length());
 }
 
-// XXXkhuey the encoding should be off the main thread, but we're lazy.
 void
 HTMLCanvasElement::ToBlob(JSContext* aCx,
                           FileCallback& aCallback,
                           const nsAString& aType,
                           const Optional<JS::Handle<JS::Value> >& aParams,
                           ErrorResult& aRv)
 {
   // do a trust check if this is a write-only canvas
@@ -592,68 +509,45 @@ HTMLCanvasElement::ToBlob(JSContext* aCx
   bool usingCustomParseOptions;
   aRv = ParseParams(aCx, type, encoderOptions, params, &usingCustomParseOptions);
   if (aRv.Failed()) {
     return;
   }
 
 #ifdef DEBUG
   if (mCurrentContext) {
+    // We disallow canvases of width or height zero, and set them to 1, so
+    // we will have a discrepancy with the sizes of the canvas and the context.
+    // That discrepancy is OK, the rest are not.
     nsIntSize elementSize = GetWidthHeight();
-    MOZ_ASSERT(elementSize.width == mCurrentContext->GetWidth());
-    MOZ_ASSERT(elementSize.height == mCurrentContext->GetHeight());
+    MOZ_ASSERT(elementSize.width == mCurrentContext->GetWidth() ||
+               (elementSize.width == 0 && mCurrentContext->GetWidth() == 1));
+    MOZ_ASSERT(elementSize.height == mCurrentContext->GetHeight() ||
+               (elementSize.height == 0 && mCurrentContext->GetHeight() == 1));
   }
 #endif
 
-  bool fallbackToPNG = false;
+  nsCOMPtr<nsIScriptContext> scriptContext =
+    GetScriptContextFromJSContext(nsContentUtils::GetCurrentJSContext());
 
-  nsCOMPtr<nsIInputStream> stream;
-  aRv = ExtractData(type, params, getter_AddRefs(stream), fallbackToPNG);
-  // If there are unrecognized custom parse options, we should fall back to
-  // the default values for the encoder without any options at all.
-  if (aRv.ErrorCode() == NS_ERROR_INVALID_ARG && usingCustomParseOptions) {
-    fallbackToPNG = false;
-    aRv = ExtractData(type, EmptyString(), getter_AddRefs(stream), fallbackToPNG);
-  }
-
-  if (aRv.Failed()) {
-    return;
-  }
-
-  if (fallbackToPNG) {
-    type.AssignLiteral("image/png");
+  uint8_t* imageBuffer = nullptr;
+  int32_t format = 0;
+  if (mCurrentContext) {
+    mCurrentContext->GetImageBuffer(&imageBuffer, &format);
   }
 
-  uint64_t imgSize;
-  aRv = stream->Available(&imgSize);
-  if (aRv.Failed()) {
-    return;
-  }
-  if (imgSize > UINT32_MAX) {
-    aRv.Throw(NS_ERROR_FILE_TOO_BIG);
-    return;
-  }
-
-  void* imgData = nullptr;
-  aRv = NS_ReadInputStreamToBuffer(stream, &imgData, imgSize);
-  if (aRv.Failed()) {
-    return;
-  }
-
-  // The DOMFile takes ownership of the buffer
-  nsRefPtr<nsDOMMemoryFile> blob =
-    new nsDOMMemoryFile(imgData, imgSize, type);
-
-  JSContext* cx = nsContentUtils::GetCurrentJSContext();
-  if (cx) {
-    JS_updateMallocCounter(cx, imgSize);
-  }
-
-  nsRefPtr<ToBlobRunnable> runnable = new ToBlobRunnable(aCallback, blob);
-  aRv = NS_DispatchToCurrentThread(runnable);
+  aRv = ImageEncoder::ExtractDataAsync(type,
+                                       params,
+                                       usingCustomParseOptions,
+                                       imageBuffer,
+                                       format,
+                                       GetSize(),
+                                       mCurrentContext,
+                                       scriptContext,
+                                       aCallback);
 }
 
 already_AddRefed<nsIDOMFile>
 HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
                                 const nsAString& aType,
                                 ErrorResult& aRv)
 {
   nsCOMPtr<nsIDOMFile> file;
@@ -677,28 +571,21 @@ HTMLCanvasElement::MozGetAsFile(const ns
   return MozGetAsFileImpl(aName, aType, aResult);
 }
 
 nsresult
 HTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
                                     const nsAString& aType,
                                     nsIDOMFile** aResult)
 {
-  bool fallbackToPNG = false;
-
   nsCOMPtr<nsIInputStream> stream;
-  nsresult rv = ExtractData(aType, EmptyString(), getter_AddRefs(stream),
-                            fallbackToPNG);
+  nsAutoString type(aType);
+  nsresult rv = ExtractData(type, EmptyString(), getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsAutoString type(aType);
-  if (fallbackToPNG) {
-    type.AssignLiteral("image/png");
-  }
-
   uint64_t imgSize;
   rv = stream->Available(&imgSize);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(imgSize <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
   void* imgData = nullptr;
   rv = NS_ReadInputStreamToBuffer(stream, &imgData, (uint32_t)imgSize);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -17,12 +17,13 @@ INCLUDES	+= \
 		-I$(srcdir)/../../../../layout/tables \
 		-I$(srcdir)/../../../../layout/xul/base/src \
 		-I$(srcdir)/../../../../layout/generic \
 		-I$(srcdir)/../../../../dom/base \
 		-I$(srcdir)/../../../../editor/libeditor/base \
 		-I$(srcdir)/../../../../editor/libeditor/text \
 		-I$(srcdir)/../../../../editor/txmgr/src \
 		-I$(srcdir)/../../../../netwerk/base/src \
+		-I$(srcdir)/../../../../content/canvas/src \
 		-I$(srcdir) \
 		-I$(topsrcdir)/xpcom/ds \
 		-I$(topsrcdir)/content/media/ \
 		$(NULL)
--- a/content/xslt/src/xslt/txExecutionState.cpp
+++ b/content/xslt/src/xslt/txExecutionState.cpp
@@ -11,41 +11,37 @@
 #include "txRtfHandler.h"
 #include "txXSLTProcessor.h"
 #include "txLog.h"
 #include "txURIUtils.h"
 #include "txXMLParser.h"
 
 const int32_t txExecutionState::kMaxRecursionDepth = 20000;
 
-nsresult txLoadedDocumentsHash::init(txXPathNode* aSourceDocument)
+void
+txLoadedDocumentsHash::init(txXPathNode* aSourceDocument)
 {
     mSourceDocument = aSourceDocument;
-    
+
     nsAutoString baseURI;
     txXPathNodeUtils::getBaseURI(*mSourceDocument, baseURI);
 
-    txLoadedDocumentEntry* entry = PutEntry(baseURI);
-    if (!entry) {
-        return NS_ERROR_FAILURE;
-    }
-
-    entry->mDocument = mSourceDocument;
-
-    return NS_OK;
+    PutEntry(baseURI)->mDocument = mSourceDocument;
 }
 
 txLoadedDocumentsHash::~txLoadedDocumentsHash()
 {
-    nsAutoString baseURI;
-    txXPathNodeUtils::getBaseURI(*mSourceDocument, baseURI);
+    if (mSourceDocument) {
+        nsAutoString baseURI;
+        txXPathNodeUtils::getBaseURI(*mSourceDocument, baseURI);
 
-    txLoadedDocumentEntry* entry = GetEntry(baseURI);
-    if (entry) {
-        delete entry->mDocument.forget();
+        txLoadedDocumentEntry* entry = GetEntry(baseURI);
+        if (entry) {
+            delete entry->mDocument.forget();
+        }
     }
 }
 
 txExecutionState::txExecutionState(txStylesheet* aStylesheet,
                                    bool aDisableLoads)
     : mOutputHandler(nullptr),
       mResultHandler(nullptr),
       mStylesheet(aStylesheet),
@@ -113,24 +109,17 @@ txExecutionState::init(const txXPathNode
         createHandlerWith(mStylesheet->getOutputFormat(), &handler);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mOutputHandler = handler;
     mResultHandler = handler;
     mOutputHandler->startDocument();
 
     // Set up loaded-documents-hash
-    nsAutoPtr<txXPathNode> document(txXPathNodeUtils::getOwnerDocument(aNode));
-    NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
-
-    rv = mLoadedDocuments.init(document);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // loaded-documents-hash owns this now
-    document.forget();
+    mLoadedDocuments.init(txXPathNodeUtils::getOwnerDocument(aNode));
 
     // Init members
     rv = mKeyHash.init();
     NS_ENSURE_SUCCESS(rv, rv);
     
     mRecycler = new txResultRecycler;
     NS_ENSURE_TRUE(mRecycler, NS_ERROR_OUT_OF_MEMORY);
     
--- a/content/xslt/src/xslt/txExecutionState.h
+++ b/content/xslt/src/xslt/txExecutionState.h
@@ -52,21 +52,22 @@ public:
     nsAutoPtr<txXPathNode> mDocument;
     nsresult mLoadResult;
 };
 
 class txLoadedDocumentsHash : public nsTHashtable<txLoadedDocumentEntry>
 {
 public:
     txLoadedDocumentsHash()
-        : nsTHashtable<txLoadedDocumentEntry>(8)
+        : nsTHashtable<txLoadedDocumentEntry>(8),
+          mSourceDocument(nullptr)
     {
     }
     ~txLoadedDocumentsHash();
-    nsresult init(txXPathNode* aSourceDocument);
+    void init(txXPathNode* aSourceDocument);
 
 private:
     friend class txExecutionState;
     txXPathNode* mSourceDocument;
 };
 
 
 class txExecutionState : public txIMatchContext
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -96,34 +96,36 @@ LOCAL_INCLUDES += \
 endif
 
 ifdef MOZ_B2G_RIL
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/dom/icc/src \
   $(NULL)
 endif
 
+ABS_DIST := $(abspath $(DIST))
+
 EXTRA_EXPORT_MDDEPEND_FILES := $(addsuffix .pp,$(binding_dependency_trackers))
 
 EXPORTS_GENERATED_FILES := $(exported_binding_headers) $(exported_generated_events_headers)
-EXPORTS_GENERATED_DEST := $(DIST)/include/$(binding_include_path)
+EXPORTS_GENERATED_DEST := $(ABS_DIST)/include/$(binding_include_path)
 EXPORTS_GENERATED_TARGET := export
 INSTALL_TARGETS += EXPORTS_GENERATED
 
 # Install auto-generated GlobalGen files. The rules for the install must
 # be in the same target/subtier as GlobalGen.py, otherwise the files will not
 # get installed into the appropriate location as they are generated.
 globalgen_headers_FILES := \
   GeneratedAtomList.h \
   PrototypeList.h \
   RegisterBindings.h \
   UnionConversions.h \
   UnionTypes.h \
   $(NULL)
-globalgen_headers_DEST = $(DIST)/include/mozilla/dom
+globalgen_headers_DEST = $(ABS_DIST)/include/mozilla/dom
 globalgen_headers_TARGET := export
 INSTALL_TARGETS += globalgen_headers
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 ifdef GNU_CC
 CXXFLAGS += -Wno-uninitialized
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -72,17 +72,17 @@ class nsGeolocationRequest
                        const GeoPositionCallback& aCallback,
                        const GeoPositionErrorCallback& aErrorCallback,
                        PositionOptions* aOptions,
                        bool aWatchPositionRequest = false,
                        int32_t aWatchId = 0);
   void Shutdown();
 
   void SendLocation(nsIDOMGeoPosition* location);
-  bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
+  bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;}
   void SetTimeoutTimer();
   nsIPrincipal* GetPrincipal();
 
   ~nsGeolocationRequest();
 
   virtual bool Recv__delete__(const bool& allow) MOZ_OVERRIDE;
   virtual void IPDLRelease() MOZ_OVERRIDE { Release(); }
 
@@ -440,17 +440,17 @@ nsGeolocationRequest::Allow()
   // if the user has specified a maximumAge, return a cached value.
 
   uint32_t maximumAge = 0;
   if (mOptions) {
     if (mOptions->mMaximumAge > 0) {
       maximumAge = mOptions->mMaximumAge;
     }
   }
-  gs->UpdateAccuracy(WantsHighAccuracy());
+  gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy);
 
   bool canUseCache = lastPosition && maximumAge > 0 &&
     (PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
     PRTime(cachedPositionTime));
 
   if (canUseCache) {
     // okay, we can return a cached position
     // getCurrentPosition requests serviced by the cache
@@ -580,22 +580,22 @@ nsGeolocationRequest::Shutdown()
   MOZ_ASSERT(!mShutdown, "request shutdown twice");
   mShutdown = true;
 
   if (mTimeoutTimer) {
     mTimeoutTimer->Cancel();
     mTimeoutTimer = nullptr;
   }
 
-  // If there are no other high accuracy requests, the geolocation service will
-  // notify the provider to switch to the default accuracy.
+  // This should happen last, to ensure that this request isn't taken into consideration
+  // when deciding whether existing requests still require high accuracy.
   if (mOptions && mOptions->mEnableHighAccuracy) {
     nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
     if (gs) {
-      gs->UpdateAccuracy();
+      gs->SetHigherAccuracy(false);
     }
   }
 }
 
 bool nsGeolocationRequest::Recv__delete__(const bool& allow)
 {
   if (allow) {
     (void) Allow();
@@ -896,19 +896,19 @@ nsGeolocationService::HighAccuracyReques
     if (mGeolocators[i]->HighAccuracyRequested()) {
       return true;
     }
   }
   return false;
 }
 
 void
-nsGeolocationService::UpdateAccuracy(bool aForceHigh)
+nsGeolocationService::SetHigherAccuracy(bool aEnable)
 {
-  bool highRequired = aForceHigh || HighAccuracyRequested();
+  bool highRequired = aEnable || HighAccuracyRequested();
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild* cpc = ContentChild::GetSingleton();
     cpc->SendSetGeolocationHigherAccuracy(highRequired);
     return;
   }
 
   if (!mHigherAccuracy && highRequired) {
@@ -1056,17 +1056,16 @@ void
 Geolocation::Shutdown()
 {
   // Release all callbacks
   mPendingCallbacks.Clear();
   mWatchingCallbacks.Clear();
 
   if (mService) {
     mService->RemoveLocator(this);
-    mService->UpdateAccuracy();
   }
 
   mService = nullptr;
   mPrincipal = nullptr;
 }
 
 nsIDOMWindow*
 Geolocation::GetParentObject() const {
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -80,18 +80,18 @@ public:
   nsresult StartDevice(nsIPrincipal* aPrincipal);
 
   // Stop the started geolocation device (gps, nmea, etc.)
   void     StopDevice();
 
   // create, or reinitalize the callback timer
   void     SetDisconnectTimer();
 
-  // Update the accuracy and notify the provider if changed
-  void     UpdateAccuracy(bool aForceHigh = false);
+  // request higher accuracy, if possible
+  void     SetHigherAccuracy(bool aEnable);
   bool     HighAccuracyRequested();
 
 private:
 
   ~nsGeolocationService();
 
   // Disconnect timer.  When this timer expires, it clears all pending callbacks
   // and closes down the provider, unless we are watching a point, and in that
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -68,19 +68,16 @@ function WifiGeoPositionProvider() {
   try {
     gUseScanning = Services.prefs.getBoolPref("geo.wifi.scan");
   } catch (e) {}
 
   this.wifiService = null;
   this.timer = null;
   this.hasSeenWiFi = false;
   this.started = false;
-  // this is only used when logging is enabled, to debug interactions with the
-  // geolocation service
-  this.highAccuracy = false;
 }
 
 WifiGeoPositionProvider.prototype = {
   classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
                                            Ci.nsIWifiListener,
                                            Ci.nsITimerCallback]),
   startup:  function() {
@@ -130,22 +127,20 @@ WifiGeoPositionProvider.prototype = {
       this.timer.cancel();
       this.timer = null;
     }
 
     this.started = false;
   },
 
   setHighAccuracy: function(enable) {
-    this.highAccuracy = enable;
-    LOG("setting highAccuracy to " + (this.highAccuracy?"TRUE":"FALSE"));
   },
 
   onChange: function(accessPoints) {
-    LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
+    LOG("onChange called");
     this.hasSeenWiFi = true;
 
     let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
 
     function isPublic(ap) {
         let mask = "_nomap"
         let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length) == -1;
         if (result != -1) {
deleted file mode 100644
--- a/dom/tests/unit/test_geolocation_reset_accuracy.js
+++ /dev/null
@@ -1,104 +0,0 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
-const providerContract = "@mozilla.org/geolocation/provider;1";
-
-const categoryName = "geolocation-provider";
-
-var provider = {
-  QueryInterface: function eventsink_qi(iid) {
-    if (iid.equals(Components.interfaces.nsISupports) ||
-        iid.equals(Components.interfaces.nsIFactory) ||
-        iid.equals(Components.interfaces.nsIGeolocationProvider))
-      return this;
-    throw Components.results.NS_ERROR_NO_INTERFACE;
-  },
-  createInstance: function eventsink_ci(outer, iid) {
-    if (outer)
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    return this.QueryInterface(iid);
-  },
-  lockFactory: function eventsink_lockf(lock) {
-    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  startup: function() {
-  },
-  watch: function() {
-  },
-  shutdown: function() {
-  },
-  setHighAccuracy: function(enable) {
-    this._isHigh = enable;
-    if (enable) {
-      this._seenHigh = true;
-    }
-  },
-  _isHigh: false,
-  _seenHigh: false
-};
-
-let runningInParent = true;
-try {
-  runningInParent = Components.classes["@mozilla.org/xre/runtime;1"].
-                    getService(Components.interfaces.nsIXULRuntime).processType
-                    == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-}
-catch (e) { }
-
-function successCallback()
-{
-  do_check_true(false);
-  do_test_finished();
-}
-
-function errorCallback()
-{
-  do_check_true(false);
-  do_test_finished();
-}
-
-function run_test()
-{
-  if (runningInParent) {
-    // XPCShell does not get a profile by default. The geolocation service
-    // depends on the settings service which uses IndexedDB and IndexedDB
-    // needs a place where it can store databases.
-    do_get_profile();
-
-    Components.manager.nsIComponentRegistrar.registerFactory(providerCID,
-      "Unit test geo provider", providerContract, provider);
-    var catMan = Components.classes["@mozilla.org/categorymanager;1"]
-                           .getService(Components.interfaces.nsICategoryManager);
-    catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
-                                               providerContract, false, true);
-
-    var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-    prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
-    prefs.setBoolPref("geo.wifi.scan", false);
-  }
-
-  let geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsISupports);
-
-  do_test_pending();
-
-  let watchID1 = geolocation.watchPosition(successCallback, errorCallback);
-  let watchID2 = geolocation.watchPosition(successCallback, errorCallback,
-                                           {enableHighAccuracy: true});
-
-  do_timeout(1000, function() {
-    geolocation.clearWatch(watchID2);
-    do_timeout(1000, check_results);
-  });
-}
-
-function check_results()
-{
-  if (runningInParent) {
-    // check the provider was set to high accuracy during the test
-    do_check_true(provider._seenHigh);
-    // check the provider is not currently set to high accuracy
-    do_check_false(provider._isHigh);
-  }
-  do_test_finished();
-}
deleted file mode 100644
--- a/dom/tests/unit/test_geolocation_reset_accuracy_wrap.js
+++ /dev/null
@@ -1,70 +0,0 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
-const providerContract = "@mozilla.org/geolocation/provider;1";
-
-const categoryName = "geolocation-provider";
-
-var provider = {
-  QueryInterface: function eventsink_qi(iid) {
-    if (iid.equals(Components.interfaces.nsISupports) ||
-        iid.equals(Components.interfaces.nsIFactory) ||
-        iid.equals(Components.interfaces.nsIGeolocationProvider))
-      return this;
-    throw Components.results.NS_ERROR_NO_INTERFACE;
-  },
-  createInstance: function eventsink_ci(outer, iid) {
-    if (outer)
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    return this.QueryInterface(iid);
-  },
-  lockFactory: function eventsink_lockf(lock) {
-    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  startup: function() {
-  },
-  watch: function() {
-  },
-  shutdown: function() {
-  },
-  setHighAccuracy: function(enable) {
-    this._isHigh = enable;
-    if (enable) {
-      this._seenHigh = true;
-    }
-  },
-  _isHigh: false,
-  _seenHigh: false
-};
-
-function run_test()
-{
-  // XPCShell does not get a profile by default. The geolocation service
-  // depends on the settings service which uses IndexedDB and IndexedDB
-  // needs a place where it can store databases.
-  do_get_profile();
-
-  Components.manager.nsIComponentRegistrar.registerFactory(providerCID,
-    "Unit test geo provider", providerContract, provider);
-  var catMan = Components.classes["@mozilla.org/categorymanager;1"]
-                         .getService(Components.interfaces.nsICategoryManager);
-  catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
-                                             providerContract, false, true);
-
-  var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-  prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
-  prefs.setBoolPref("geo.wifi.scan", false);
-
-  run_test_in_child("test_geolocation_reset_accuracy.js", check_results);
-}
-
-function check_results()
-{
-  // check the provider was set to high accuracy during the test
-  do_check_true(provider._seenHigh);
-  // check the provider is not currently set to high accuracy
-  do_check_false(provider._isHigh);
-
-  do_test_finished();
-}
--- a/dom/tests/unit/xpcshell.ini
+++ b/dom/tests/unit/xpcshell.ini
@@ -7,13 +7,8 @@ tail =
 [test_geolocation_provider.js]
 # Bug 684962: test hangs consistently on Android
 skip-if = os == "android"
 [test_geolocation_timeout.js]
 # Bug 919946: test hangs consistently on Android
 skip-if = os == "android"
 [test_geolocation_timeout_wrap.js]
 skip-if = os == "mac" || os == "android"
-[test_geolocation_reset_accuracy.js]
-# Bug 919946: test hangs consistently on Android
-skip-if = os == "android"
-[test_geolocation_reset_accuracy_wrap.js]
-skip-if = os == "mac" || os == "android"
--- a/image/test/mochitest/test_animSVGImage.html
+++ b/image/test/mochitest/test_animSVGImage.html
@@ -49,64 +49,56 @@ function takeReferenceSnapshot() {
 
   // Re-hide reference div, and take another snapshot to be sure it's gone
   referenceDiv.style.display = "none";
   let blankSnapshot2 = snapshotWindow(window, false);
   ok(compareSnapshots(blankSnapshot, blankSnapshot2, true)[0],
      "reference div should disappear when it becomes display:none");
 }
 
-function myOnStopFrame(aRequest) {
+function myOnStopFrame() {
   gOnStopFrameCounter++;
   ok(true, "myOnStopFrame called");
   let currentSnapshot = snapshotWindow(window, false);
   if (compareSnapshots(currentSnapshot, gReferenceSnapshot, true)[0]) {
     // SUCCESS!
     ok(true, "Animated image looks correct, " +
              "at call #" + gOnStopFrameCounter + " to onStopFrame");
     cleanUpAndFinish();
   }
-  setTimeout(function() { myOnStopFrame(0, 0); }, 1000);
+  else
+    setTimeout(myOnStopFrame, 1);
 }
 
 function failTest() {
   ok(false, "timing out after " + FAILURE_TIMEOUT + "ms.  " +
             "Animated image still doesn't look correct, " +
             "after call #" + gOnStopFrameCounter + " to onStopFrame");
   cleanUpAndFinish();
 }
 
 function cleanUpAndFinish() {
   // On the off chance that failTest and myOnStopFrame are triggered
   // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish.
   if (gIsTestFinished) {
     return;
   }
-  let imgLoadingContent = gImg.QueryInterface(Ci.nsIImageLoadingContent);
-  imgLoadingContent.removeObserver(gMyDecoderObserver);
   SimpleTest.finish();
   gIsTestFinished = true;
 }
 
 function main() {
   takeReferenceSnapshot();
 
-  // Create, customize & attach decoder observer
-  observer = new ImageDecoderObserverStub();
-  observer.frameComplete = myOnStopFrame;
-  gMyDecoderObserver =
-    Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
-      .createScriptedObserver(observer);
-  let imgLoadingContent = gImg.QueryInterface(Ci.nsIImageLoadingContent);
-  imgLoadingContent.addObserver(gMyDecoderObserver);
-
   // We want to test the cold loading behavior, so clear cache in case an
   // earlier test got our image in there already.
   clearImageCache();
 
+  setTimeout(myOnStopFrame, 1);
+
   // kick off image-loading! myOnStopFrame handles the rest.
   gImg.setAttribute("src", "lime-anim-100x100.svg");
 
   // In case something goes wrong, fail earlier than mochitest timeout,
   // and with more information.
   setTimeout(failTest, FAILURE_TIMEOUT);
 }
 
--- a/js/public/TypeDecls.h
+++ b/js/public/TypeDecls.h
@@ -45,21 +45,17 @@ class JSString;
 #endif
 
 #ifdef JS_USE_JSID_STRUCT_TYPES
 struct jsid;
 #else
 typedef ptrdiff_t jsid;
 #endif
 
-#ifdef WIN32
-typedef wchar_t  jschar;
-#else
-typedef uint16_t jschar;
-#endif
+typedef char16_t jschar;
 
 namespace JS {
 
 class Value;
 template <typename T> class Handle;
 template <typename T> class MutableHandle;
 
 typedef Handle<JSFunction*> HandleFunction;
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -1,14 +1,24 @@
 # -*- Mode: makefile -*-
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.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 .PYMAKE
+ifeq (,$(MAKE_VERSION))
+$(error GNU Make is required)
+endif
+make_min_ver := 3.81
+ifneq ($(make_min_ver),$(firstword $(sort $(make_min_ver) $(MAKE_VERSION))))
+$(error GNU Make $(make_min_ver) or higher is required)
+endif
+endif
+
 TOPLEVEL_BUILD := 1
 
 run_for_side_effects := $(shell echo "MAKE: $(MAKE)")
 STATIC_LIBRARY_NAME = js_static
 LIBS		= $(NSPR_LIBS)
 
 # JavaScript must be built shared, even for static builds, as it is used by
 # other modules which are always built shared. Failure to do so results in
--- a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp
+++ b/js/src/assembler/jit/ExecutableAllocatorPosix.cpp
@@ -27,27 +27,35 @@
 
 #if ENABLE_ASSEMBLER && WTF_OS_UNIX && !WTF_OS_SYMBIAN
 
 #include <sys/mman.h>
 #include <unistd.h>
 
 #include "assembler/wtf/Assertions.h"
 #include "assembler/wtf/VMTags.h"
+#include "js/Utility.h"
 
 namespace JSC {
 
 size_t ExecutableAllocator::determinePageSize()
 {
     return getpagesize();
 }
 
 ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n)
 {
-    void* allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0);
+    void* allocation;
+#ifdef JSGC_ROOT_ANALYSIS
+    do {
+#endif
+        allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0);
+#ifdef JSGC_ROOT_ANALYSIS
+    } while (allocation && JS::IsPoisonedPtr(allocation));
+#endif
     if (allocation == MAP_FAILED)
         allocation = NULL;
     ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n };
     return alloc;
 }
 
 void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
 { 
--- a/js/src/build/cl.py
+++ b/js/src/build/cl.py
@@ -71,18 +71,19 @@ def InvokeClWithDependencyGeneration(cmd
     def on_line(line):
         # cl -showIncludes prefixes every header with "Note: including file:"
         # and an indentation corresponding to the depth (which we don't need)
         if line.startswith(CL_INCLUDES_PREFIX):
             dep = line[len(CL_INCLUDES_PREFIX):].strip()
             # We can't handle pathes with spaces properly in mddepend.pl, but
             # we can assume that anything in a path with spaces is a system
             # header and throw it away.
+            dep = normcase(dep)
             if ' ' not in dep:
-                rule.add_dependencies([normcase(dep)])
+                rule.add_dependencies([dep])
         else:
             # Make sure we preserve the relevant output from cl. mozprocess
             # swallows the newline delimiter, so we need to re-add it.
             sys.stdout.write(line)
             sys.stdout.write('\n')
 
     # We need to ignore children because MSVC can fire up a background process
     # during compilation. This process is cleaned up on its own. If we kill it,
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -627,17 +627,17 @@ GARBAGE		+= $(DEPENDENCIES) core $(wildc
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
-NSINSTALL_PY := $(PYTHON) $(call core_abspath,$(topsrcdir)/config/nsinstall.py)
+NSINSTALL_PY := $(PYTHON) $(abspath $(topsrcdir)/config/nsinstall.py)
 # For Pymake, wherever we use nsinstall.py we're also going to try to make it
 # a native command where possible. Since native commands can't be used outside
 # of single-line commands, we continue to provide INSTALL for general use.
 # Single-line commands should be switched over to install_cmd.
 NSINSTALL_NATIVECMD := %nsinstall nsinstall
 
 ifdef NSINSTALL_BIN
 NSINSTALL = $(NSINSTALL_BIN)
@@ -686,17 +686,17 @@ sysinstall_cmd = install_cmd
 AB_CD = $(MOZ_UI_LOCALE)
 
 ifndef L10NBASEDIR
   L10NBASEDIR = $(error L10NBASEDIR not defined by configure)
 else
   IS_LANGUAGE_REPACK = 1
 endif
 
-EXPAND_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/$(1)/en-US,$(call core_realpath,$(L10NBASEDIR))/$(AB_CD)/$(subst /locales,,$(1)))
+EXPAND_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/$(1)/en-US,$(or $(realpath $(L10NBASEDIR)),$(abspath $(L10NBASEDIR)))/$(AB_CD)/$(subst /locales,,$(1)))
 
 ifdef relativesrcdir
 LOCALE_SRCDIR ?= $(call EXPAND_LOCALE_SRCDIR,$(relativesrcdir))
 endif
 
 ifdef relativesrcdir
 MAKE_JARS_FLAGS += --relativesrcdir=$(relativesrcdir)
 ifneq (en-US,$(AB_CD))
@@ -737,17 +737,17 @@ endif # ! OS2
 
 # Make sure any compiled classes work with at least JVM 1.4
 JAVAC_FLAGS += -source 1.4
 
 ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
 
-CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
+CREATE_PRECOMPLETE_CMD = $(PYTHON) $(abspath $(topsrcdir)/config/createprecomplete.py)
 
 # MDDEPDIR is the subdirectory where dependency files are stored
 MDDEPDIR := .deps
 
 EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp --target $@)
 EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp)
 EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
 EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
--- a/js/src/config/makefiles/functions.mk
+++ b/js/src/config/makefiles/functions.mk
@@ -11,12 +11,12 @@
 #
 
 # Define an include-at-most-once flag
 ifdef INCLUDED_FUNCTIONS_MK
 $(error Do not include functions.mk twice!)
 endif
 INCLUDED_FUNCTIONS_MK = 1
 
-core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))
-core_realpath = $(if $(realpath $(1)),$(realpath $(1)),$(call core_abspath,$(1)))
+core_abspath = $(error core_abspath is unsupported, use $$(abspath) instead)
+core_realpath = $(error core_realpath is unsupported)
 
-core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
+core_winabspath = $(error core_winabspath is unsupported)
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4071,21 +4071,23 @@ dnl ====================================
 
 if test "$OS_ARCH" = "Darwin"; then
   AC_DEFINE(XP_MACOSX)
   AC_DEFINE(XP_UNIX)
 elif test "$OS_ARCH" != "WINNT" -a "$OS_ARCH" != "OS2"; then
   AC_DEFINE(XP_UNIX)
 fi
 
-AC_ARG_ENABLE(threadsafe,
-    [  --enable-threadsafe     Enable support for multiple threads.],
-    [if test "x$enableval" = "xyes"; then
-        AC_DEFINE(JS_THREADSAFE)
-    fi],)
+JS_THREADSAFE=1
+MOZ_ARG_DISABLE_BOOL(threadsafe,
+[  --disable-threadsafe Disable support for multiple threads.],
+    JS_THREADSAFE= )
+if test -n "$JS_THREADSAFE"; then
+    AC_DEFINE(JS_THREADSAFE)
+fi
 
 if test "$MOZ_DEBUG"; then
     AC_DEFINE(MOZ_REFLOW_PERF)
     AC_DEFINE(MOZ_REFLOW_PERF_DSP)
 fi
 
 if test "$ACCESSIBILITY" -a "$MOZ_ENABLE_GTK" ; then
     AC_DEFINE(MOZ_ACCESSIBILITY_ATK)
--- a/js/src/jit-test/tests/asm.js/testExpressions.js
+++ b/js/src/jit-test/tests/asm.js/testExpressions.js
@@ -248,18 +248,18 @@ var f = asmLink(asmCompile(USE_ASM + "fu
 assertEq(f(1,true), 1);
 assertEq(f(-1,true), 0);
 assertEq(f(-5,true), 1);
 assertEq(f(1,false), 0);
 assertEq(f(-1,false), 0);
 assertEq(f(-5,false), 1);
 
 assertAsmTypeFail('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return (i32[0]+1)|0 } return f");
-assertAsmTypeFail('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] + 1.0); } return f");
 new Float64Array(BUF_64KB)[0] = 2.3;
+assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] + 2.0) } return f"), this, null, BUF_64KB)(), 2.3+2);
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] - 2.0) } return f"), this, null, BUF_64KB)(), 2.3-2);
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] * 2.0) } return f"), this, null, BUF_64KB)(), 2.3*2);
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] / 2.0) } return f"), this, null, BUF_64KB)(), 2.3/2);
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] % 2.0) } return f"), this, null, BUF_64KB)(), 2.3%2);
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +-f64[0] } return f"), this, null, BUF_64KB)(), -2.3);
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "var sqrt=glob.Math.sqrt; function f() { return +sqrt(f64[0]) } return f"), this, null, BUF_64KB)(), Math.sqrt(2.3));
 new Int32Array(BUF_64KB)[0] = 42;
 assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "var imul=glob.Math.imul; function f() { return imul(i32[0], 2)|0 } return f"), this, null, BUF_64KB)(), 84);
--- a/js/src/jit-test/tests/asm.js/testHeapAccess.js
+++ b/js/src/jit-test/tests/asm.js/testHeapAccess.js
@@ -86,16 +86,22 @@ assertEq(f(0xff),0xff);
 assertEq(f(0x100),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~+f64[i>>3])|0}; return f');
 var f = asmLink(code, this, null, new ArrayBuffer(4096));
 assertEq(f(0, 1.3), 1);
 assertEq(f(4088, 2.5), 2);
 assertEq(f(4096, 3.8), 0);
 
+var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~f64[i>>3])|0}; return f');
+var f = asmLink(code, this, null, new ArrayBuffer(4096));
+assertEq(f(0, 1.3), 1);
+assertEq(f(4088, 2.5), 2);
+assertEq(f(4096, 3.8), 0);
+
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return +f64[i>>3]}; return f');
 var f = asmLink(code, this, null, new ArrayBuffer(4096));
 assertEq(f(0, 1.3), 1.3);
 assertEq(f(4088, 2.5), 2.5);
 assertEq(f(4096, 3.8), NaN);
 
 var i32 = new Int32Array(4096);
 i32[0] = 42;
--- a/js/src/jit-test/tests/basic/testBug756919.js
+++ b/js/src/jit-test/tests/basic/testBug756919.js
@@ -1,8 +1,10 @@
 // |jit-test| allow-oom
 
 gcparam("maxBytes", gcparam("gcBytes") + 1024);
 test();
 function test() {
+  var upvar = "";
+  function f() { upvar += ""; }
   test();
   eval('');
 }
--- a/js/src/jit-test/tests/basic/testBug840012.js
+++ b/js/src/jit-test/tests/basic/testBug840012.js
@@ -1,15 +1,17 @@
 // |jit-test| error:out of memory
 
 gcPreserveCode();
 evaluate("gcparam(\"maxBytes\", gcparam(\"gcBytes\") + 4*1024);");
 evaluate("\
 function testDontEnum(F) { \
   function test() {\
+    var upvar = \"\";\
+    function f() { upvar += \"\"; }\
     typeof (new test(\"1\")) != 'function'\
   }\
   test();\
 } \
 var list = [];\
 for (i in list)\
   var F = this[list[i]];\
 actual = testDontEnum(F);\
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug921035.js
@@ -0,0 +1,14 @@
+// |jit-test| error: TypeError
+
+function $ERROR() {}
+function testMultipleArgumentsObjects() {
+    var testargs = arguments;
+    var f = function (which) {
+        var args = [ testargs ];
+        return args[which][0];
+    };
+    var arr = [0, 0, 0, 0, 1];
+    for (var i = 0; i < arr.length; i++)
+        $ERROR[i] = f(arr[i]);
+}
+testMultipleArgumentsObjects()
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -382,18 +382,17 @@ class Type
     enum Which {
         Double,
         Doublish,
         Fixnum,
         Int,
         Signed,
         Unsigned,
         Intish,
-        Void,
-        Unknown
+        Void
     };
 
   private:
     Which which_;
 
   public:
     Type() : which_(Which(-1)) {}
     Type(Which w) : which_(w) {}
@@ -409,25 +408,25 @@ class Type
         return which_ == Unsigned || which_ == Fixnum;
     }
 
     bool isInt() const {
         return isSigned() || isUnsigned() || which_ == Int;
     }
 
     bool isIntish() const {
-        return isInt() || which_ == Intish || which_ == Unknown;
+        return isInt() || which_ == Intish;
     }
 
     bool isDouble() const {
         return which_ == Double;
     }
 
     bool isDoublish() const {
-        return isDouble() || which_ == Doublish || which_ == Unknown;
+        return isDouble() || which_ == Doublish;
     }
 
     bool isVoid() const {
         return which_ == Void;
     }
 
     bool isExtern() const {
         return isDouble() || isSigned();
@@ -444,33 +443,31 @@ class Type
             return MIRType_Double;
           case Fixnum:
           case Int:
           case Signed:
           case Unsigned:
           case Intish:
             return MIRType_Int32;
           case Void:
-          case Unknown:
             return MIRType_None;
         }
         MOZ_ASSUME_UNREACHABLE("Invalid Type");
     }
 
     const char *toChars() const {
         switch (which_) {
           case Double:    return "double";
           case Doublish:  return "doublish";
           case Fixnum:    return "fixnum";
           case Int:       return "int";
           case Signed:    return "signed";
           case Unsigned:  return "unsigned";
           case Intish:    return "intish";
           case Void:      return "void";
-          case Unknown:   return "unknown";
         }
         MOZ_ASSUME_UNREACHABLE("Invalid Type");
     }
 };
 
 } /* anonymous namespace */
 
 // Represents the subset of Type that can be used as the return type of a
@@ -3942,24 +3939,24 @@ CheckCoerceToInt(FunctionCompiler &f, Pa
     JS_ASSERT(expr->isKind(PNK_BITNOT));
     ParseNode *operand = UnaryKid(expr);
 
     MDefinition *operandDef;
     Type operandType;
     if (!CheckExpr(f, operand, &operandDef, &operandType))
         return false;
 
-    if (operandType.isDouble()) {
+    if (operandType.isDoublish()) {
         *def = f.unary<MTruncateToInt32>(operandDef);
         *type = Type::Signed;
         return true;
     }
 
     if (!operandType.isIntish())
-        return f.failf(operand, "%s is not a subtype of double or intish", operandType.toChars());
+        return f.failf(operand, "%s is not a subtype of doublish or intish", operandType.toChars());
 
     *def = operandDef;
     *type = Type::Signed;
     return true;
 }
 
 static bool
 CheckBitNot(FunctionCompiler &f, ParseNode *neg, MDefinition **def, Type *type)
@@ -4155,38 +4152,29 @@ CheckAddOrSub(FunctionCompiler &f, Parse
             return false;
         rhsNumAddOrSub = 0;
     }
 
     unsigned numAddOrSub = lhsNumAddOrSub + rhsNumAddOrSub + 1;
     if (numAddOrSub > (1<<20))
         return f.fail(expr, "too many + or - without intervening coercion");
 
-    if (expr->isKind(PNK_ADD)) {
-        if (lhsType.isInt() && rhsType.isInt()) {
-            *def = f.binary<MAdd>(lhsDef, rhsDef, MIRType_Int32);
-            *type = Type::Intish;
-        } else if (lhsType.isDouble() && rhsType.isDouble()) {
-            *def = f.binary<MAdd>(lhsDef, rhsDef, MIRType_Double);
-            *type = Type::Double;
-        } else {
-            return f.failf(expr, "operands to + must both be int or double, got %s and %s",
-                           lhsType.toChars(), rhsType.toChars());
-        }
+    if (lhsType.isInt() && rhsType.isInt()) {
+        *def = expr->isKind(PNK_ADD)
+               ? f.binary<MAdd>(lhsDef, rhsDef, MIRType_Int32)
+               : f.binary<MSub>(lhsDef, rhsDef, MIRType_Int32);
+        *type = Type::Intish;
+    } else if (lhsType.isDoublish() && rhsType.isDoublish()) {
+        *def = expr->isKind(PNK_ADD)
+               ? f.binary<MAdd>(lhsDef, rhsDef, MIRType_Double)
+               : f.binary<MSub>(lhsDef, rhsDef, MIRType_Double);
+        *type = Type::Double;
     } else {
-        if (lhsType.isInt() && rhsType.isInt()) {
-            *def = f.binary<MSub>(lhsDef, rhsDef, MIRType_Int32);
-            *type = Type::Intish;
-        } else if (lhsType.isDoublish() && rhsType.isDoublish()) {
-            *def = f.binary<MSub>(lhsDef, rhsDef, MIRType_Double);
-            *type = Type::Double;
-        } else {
-            return f.failf(expr, "operands to - must both be int or doublish, got %s and %s",
-                           lhsType.toChars(), rhsType.toChars());
-        }
+        return f.failf(expr, "operands to +/- must both be int or doublish, got %s and %s",
+                       lhsType.toChars(), rhsType.toChars());
     }
 
     if (numAddOrSubOut)
         *numAddOrSubOut = numAddOrSub;
     return true;
 }
 
 static bool
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -8840,16 +8840,21 @@ DoInstanceOfFallback(JSContext *cx, ICIn
 
     if (!rhs.isObject()) {
         js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rhs, NullPtr());
         return false;
     }
 
     RootedObject obj(cx, &rhs.toObject());
 
+    // For functions, keep track of the |prototype| property in type information,
+    // for use during Ion compilation.
+    if (obj->is<JSFunction>() && IsIonEnabled(cx))
+        types::EnsureTrackPropertyTypes(cx, obj, NameToId(cx->names().prototype));
+
     bool cond = false;
     if (!HasInstance(cx, obj, lhs, &cond))
         return false;
 
     res.setBoolean(cond);
     return true;
 }
 
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -6051,25 +6051,27 @@ CodeGenerator::addSetPropertyCache(LInst
       default:
         MOZ_ASSUME_UNREACHABLE("Bad execution mode");
     }
 }
 
 bool
 CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex,
                                   Register temp, FloatRegister tempFloat, ValueOperand index,
-                                  ConstantOrRegister value, bool strict)
+                                  ConstantOrRegister value, bool strict, bool guardHoles)
 {
     switch (gen->info().executionMode()) {
       case SequentialExecution: {
-        SetElementIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict);
+        SetElementIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
+                           guardHoles);
         return addCache(ins, allocateCache(cache));
       }
       case ParallelExecution: {
-        SetElementParIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict);
+        SetElementParIC cache(obj, unboxIndex, temp, tempFloat, index, value, strict,
+                              guardHoles);
         return addCache(ins, allocateCache(cache));
       }
       default:
         MOZ_ASSUME_UNREACHABLE("Bad execution mode");
     }
 }
 
 bool
@@ -6213,17 +6215,17 @@ CodeGenerator::visitSetElementCacheV(LSe
     Register obj = ToRegister(ins->object());
     Register unboxIndex = ToTempUnboxRegister(ins->tempToUnboxIndex());
     Register temp = ToRegister(ins->temp());
     FloatRegister tempFloat = ToFloatRegister(ins->tempFloat());
     ValueOperand index = ToValue(ins, LSetElementCacheV::Index);
     ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetElementCacheV::Value));
 
     return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
-                              ins->mir()->strict());
+                              ins->mir()->strict(), ins->mir()->guardHoles());
 }
 
 bool
 CodeGenerator::visitSetElementCacheT(LSetElementCacheT *ins)
 {
     Register obj = ToRegister(ins->object());
     Register unboxIndex = ToTempUnboxRegister(ins->tempToUnboxIndex());
     Register temp = ToRegister(ins->temp());
@@ -6232,17 +6234,17 @@ CodeGenerator::visitSetElementCacheT(LSe
     ConstantOrRegister value;
     const LAllocation *tmp = ins->value();
     if (tmp->isConstant())
         value = *tmp->toConstant();
     else
         value = TypedOrValueRegister(ins->mir()->value()->type(), ToAnyRegister(tmp));
 
     return addSetElementCache(ins, obj, unboxIndex, temp, tempFloat, index, value,
-                              ins->mir()->strict());
+                              ins->mir()->strict(), ins->mir()->guardHoles());
 }
 
 typedef bool (*SetElementICFn)(JSContext *, size_t, HandleObject, HandleValue, HandleValue);
 const VMFunction SetElementIC::UpdateInfo =
     FunctionInfo<SetElementICFn>(SetElementIC::update);
 
 bool
 CodeGenerator::visitSetElementIC(OutOfLineUpdateCache *ool, DataPtr<SetElementIC> &ic)
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -338,17 +338,17 @@ class CodeGenerator : public CodeGenerat
                              bool allowGetters);
     bool addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
                             TypedOrValueRegister output, bool monitoredResult);
     bool addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
                              PropertyName *name, ConstantOrRegister value, bool strict,
                              bool needsTypeBarrier);
     bool addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp,
                             FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
-                            bool strict);
+                            bool strict, bool guardHoles);
     bool checkForAbortPar(LInstruction *lir);
 
     bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr);
 
     bool emitAllocateGCThingPar(LInstruction *lir, const Register &objReg, const Register &sliceReg,
                                 const Register &tempReg1, const Register &tempReg2,
                                 JSObject *templateObj);
 
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -206,26 +206,35 @@ IsPhiObservable(MPhi *phi, Observability
         for (MUseIterator iter(phi->usesBegin()); iter != phi->usesEnd(); iter++) {
             if (!iter->consumer()->isDefinition() ||
                 !iter->consumer()->toDefinition()->isPhi())
                 return true;
         }
         break;
     }
 
-    // If the Phi is of the |this| value, it must always be observable.
     uint32_t slot = phi->slot();
     CompileInfo &info = phi->block()->info();
-    if (info.fun() && slot == info.thisSlot())
+    JSFunction *fun = info.fun();
+
+    // If the Phi is of the |this| value, it must always be observable.
+    if (fun && slot == info.thisSlot())
+        return true;
+
+    // If the function is heavyweight, and the Phi is of the |scopeChain|
+    // value, and the function may need an arguments object, then make sure
+    // to preserve the scope chain, because it may be needed to construct the
+    // arguments object during bailout.
+    if (fun && fun->isHeavyweight() && info.hasArguments() && slot == info.scopeChainSlot())
         return true;
 
     // If the Phi is one of the formal argument, and we are using an argument
     // object in the function. The phi might be observable after a bailout.
     // For inlined frames this is not needed, as they are captured in the inlineResumePoint.
-    if (info.fun() && info.hasArguments()) {
+    if (fun && info.hasArguments()) {
         uint32_t first = info.firstArgSlot();
         if (first <= slot && slot - first < info.nargs()) {
             // If arguments obj aliases formals, then the arg slots will never be used.
             if (info.argsObjAliasesFormals())
                 return false;
             return true;
         }
     }
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -7227,18 +7227,24 @@ IonBuilder::setElemTryCache(bool *emitte
         return true;
 
     if (PropertyWriteNeedsTypeBarrier(constraints(), current,
                                       &object, nullptr, &value, /* canModify = */ true))
     {
         return true;
     }
 
+    // We can avoid worrying about holes in the IC if we know a priori we are safe
+    // from them. If TI can guard that there are no indexed properties on the prototype
+    // chain, we know that we anen't missing any setters by overwriting the hole with
+    // another value.
+    bool guardHoles = ElementAccessHasExtraIndexedProperty(constraints(), object);
+
     // Emit SetElementCache.
-    MInstruction *ins = MSetElementCache::New(object, index, value, script()->strict);
+    MInstruction *ins = MSetElementCache::New(object, index, value, script()->strict, guardHoles);
     current->add(ins);
     current->push(value);
 
     if (!resumeAfter(ins))
         return false;
 
     *emitted = true;
     return true;
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1549,27 +1549,29 @@ GetPropertyIC::tryAttachProxy(JSContext 
                                            returnAddr, emitted);
     }
 
     return tryAttachGenericProxy(cx, ion, obj, name, returnAddr, emitted);
 }
 
 static void
 GenerateProxyClassGuards(MacroAssembler &masm, Register object, Register scratchReg,
-                         Label *failures, Label *success)
+                         Label *failures)
 {
+    Label success;
     // Ensure that the incoming object has one of the magic class pointers, i.e,
     // that it is one of an ObjectProxy, FunctionProxy, or OuterWindowProxy.
     // This is equivalent to obj->is<ProxyObject>().
     masm.branchTestObjClass(Assembler::Equal, object, scratchReg,
-                            CallableProxyClassPtr, success);
+                            CallableProxyClassPtr, &success);
     masm.branchTestObjClass(Assembler::Equal, object, scratchReg,
-                            UncallableProxyClassPtr, success);
+                            UncallableProxyClassPtr, &success);
     masm.branchTestObjClass(Assembler::NotEqual, object, scratchReg,
                             OuterWindowProxyClassPtr, failures);
+    masm.bind(&success);
 }
 
 bool
 GetPropertyIC::tryAttachGenericProxy(JSContext *cx, IonScript *ion, HandleObject obj,
                                      HandlePropertyName name, void *returnAddr,
                                      bool *emitted)
 {
     JS_ASSERT(canAttachStub());
@@ -1587,19 +1589,17 @@ GetPropertyIC::tryAttachGenericProxy(JSC
     Label failures;
     MacroAssembler masm(cx);
     RepatchStubAppender attacher(*this);
 
     Register scratchReg = output().valueReg().scratchReg();
 
     masm.setFramePushed(ion->frameSize());
 
-    Label proxySuccess;
-    GenerateProxyClassGuards(masm, object(), scratchReg, &failures, &proxySuccess);
-    masm.bind(&proxySuccess);
+    GenerateProxyClassGuards(masm, object(), scratchReg, &failures);
 
     // Ensure that the incoming object is not a DOM proxy, so that we can get to
     // the specialized stubs
     masm.branchTestProxyHandlerFamily(Assembler::Equal, object(), scratchReg,
                                       GetDOMProxyHandlerFamily(), &failures);
 
     if (!EmitCallProxyGet(cx, masm, attacher, name, liveRegs_, object(), output(), returnAddr))
         return false;
@@ -2174,22 +2174,22 @@ SetPropertyIC::attachGenericProxy(JSCont
         RegisterSet regSet(RegisterSet::All());
         regSet.take(AnyRegister(object()));
         if (!value().constant())
             regSet.takeUnchecked(value().reg());
 
         Register scratch = regSet.takeGeneral();
         masm.push(scratch);
 
-        GenerateProxyClassGuards(masm, object(), scratch, &proxyFailures, &proxySuccess);
+        GenerateProxyClassGuards(masm, object(), scratch, &proxyFailures);
 
         // Remove the DOM proxies. They'll take care of themselves so this stub doesn't
-        // catch too much.
-        masm.branchTestProxyHandlerFamily(Assembler::Equal, object(), scratch,
-                                          GetDOMProxyHandlerFamily(), &proxyFailures);
+        // catch too much. The failure case is actually Equal. Fall through to the failure code.
+        masm.branchTestProxyHandlerFamily(Assembler::NotEqual, object(), scratch,
+                                          GetDOMProxyHandlerFamily(), &proxySuccess);
 
         masm.bind(&proxyFailures);
         masm.pop(scratch);
         // Unify the point of failure to allow for later DOM proxy handling.
         masm.jump(&failures);
 
         masm.bind(&proxySuccess);
         masm.pop(scratch);
@@ -3461,24 +3461,27 @@ IsTypedArrayElementSetInlineable(JSObjec
 {
     // Don't bother attaching stubs for assigning strings and objects.
     return (obj->is<TypedArrayObject>() && idval.isInt32() &&
             !value.isString() && !value.isObject());
 }
 
 static bool
 GenerateSetDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
-                        JSObject *obj, const Value &idval, Register object, ValueOperand indexVal,
-                        ConstantOrRegister value, Register tempToUnboxIndex, Register temp)
+                        JSObject *obj, const Value &idval, bool guardHoles, Register object,
+                        ValueOperand indexVal, ConstantOrRegister value, Register tempToUnboxIndex,
+                        Register temp)
 {
     JS_ASSERT(obj->isNative());
     JS_ASSERT(idval.isInt32());
 
     Label failures;
-    Label outOfBounds; // index >= capacity || index > initialized length
+    Label outOfBounds; // index represents a known hole, or an illegal append
+
+    Label markElem, postBarrier; // used if TI protects us from worrying about holes.
 
     // Guard object is a dense array.
     Shape *shape = obj->lastProperty();
     if (!shape)
         return false;
     masm.branchTestObjShape(Assembler::NotEqual, object, shape, &failures);
 
     // Ensure the index is an int32 value.
@@ -3490,59 +3493,68 @@ GenerateSetDenseElement(JSContext *cx, M
     {
         // Load obj->elements.
         Register elements = temp;
         masm.loadPtr(Address(object, JSObject::offsetOfElements()), elements);
 
         // Compute the location of the element.
         BaseIndex target(elements, index, TimesEight);
 
-        // Guard that we can increase the initialized length.
-        Address capacity(elements, ObjectElements::offsetOfCapacity());
-        masm.branch32(Assembler::BelowOrEqual, capacity, index, &outOfBounds);
-
-        // Guard on the initialized length.
-        Address initLength(elements, ObjectElements::offsetOfInitializedLength());
-        masm.branch32(Assembler::Below, initLength, index, &outOfBounds);
-
-        // if (initLength == index)
-        Label markElem, postBarrier;
-        masm.branch32(Assembler::NotEqual, initLength, index, &markElem);
-        {
-            // Increase initialize length.
-            Int32Key newLength(index);
-            masm.bumpKey(&newLength, 1);
-            masm.storeKey(newLength, initLength);
-
-            // Increase length if needed.
-            Label bumpedLength;
-            Address length(elements, ObjectElements::offsetOfLength());
-            masm.branch32(Assembler::AboveOrEqual, length, index, &bumpedLength);
-            masm.storeKey(newLength, length);
-            masm.bind(&bumpedLength);
-
-            // Restore the index.
-            masm.bumpKey(&newLength, -1);
-            masm.jump(&postBarrier);
+        // If TI cannot help us deal with HOLES by preventing indexed properties
+        // on the prototype chain, we have to be very careful to check for ourselves
+        // to avoid stomping on what should be a setter call. Start by only allowing things
+        // within the initialized length.
+        if (guardHoles) {
+            Address initLength(elements, ObjectElements::offsetOfInitializedLength());
+            masm.branch32(Assembler::BelowOrEqual, initLength, index, &outOfBounds);
+        } else {
+            // Guard that we can increase the initialized length.
+            Address capacity(elements, ObjectElements::offsetOfCapacity());
+            masm.branch32(Assembler::BelowOrEqual, capacity, index, &outOfBounds);
+
+            // Guard on the initialized length.
+            Address initLength(elements, ObjectElements::offsetOfInitializedLength());
+            masm.branch32(Assembler::Below, initLength, index, &outOfBounds);
+
+            // if (initLength == index)
+            masm.branch32(Assembler::NotEqual, initLength, index, &markElem);
+            {
+                // Increase initialize length.
+                Int32Key newLength(index);
+                masm.bumpKey(&newLength, 1);
+                masm.storeKey(newLength, initLength);
+
+                // Increase length if needed.
+                Label bumpedLength;
+                Address length(elements, ObjectElements::offsetOfLength());
+                masm.branch32(Assembler::AboveOrEqual, length, index, &bumpedLength);
+                masm.storeKey(newLength, length);
+                masm.bind(&bumpedLength);
+
+                // Restore the index.
+                masm.bumpKey(&newLength, -1);
+                masm.jump(&postBarrier);
+            }
+            // else
+            masm.bind(&markElem);
         }
-        // else
-        {
-            // Mark old element.
-            masm.bind(&markElem);
-            if (cx->zone()->needsBarrier())
-                masm.callPreBarrier(target, MIRType_Value);
-        }
-
-        // Call post barrier if necessary, and recalculate elements pointer if it got cobbered.
-        masm.bind(&postBarrier);
+
+        if (cx->zone()->needsBarrier())
+            masm.callPreBarrier(target, MIRType_Value);
+
+        // Call post barrier if necessary, and recalculate elements pointer if it got clobbered.
+        if (!guardHoles)
+            masm.bind(&postBarrier);
         Register postBarrierScratch = elements;
         if (masm.maybeCallPostBarrier(object, value, postBarrierScratch))
             masm.loadPtr(Address(object, JSObject::offsetOfElements()), elements);
 
         // Store the value.
+        if (guardHoles)
+            masm.branchTestMagic(Assembler::Equal, target, &failures);
         masm.storeConstantOrRegister(value, target);
     }
     attacher.jumpRejoin(masm);
 
     // All failures flow to here.
     masm.bind(&outOfBounds);
     masm.bind(&failures);
     attacher.jumpNextStub(masm);
@@ -3551,24 +3563,28 @@ GenerateSetDenseElement(JSContext *cx, M
 }
 
 bool
 SetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, const Value &idval)
 {
     MacroAssembler masm(cx);
     RepatchStubAppender attacher(*this);
     if (!GenerateSetDenseElement(cx, masm, attacher, obj, idval,
-                                 object(), index(), value(),
-                                 tempToUnboxIndex(), temp()))
+                                 guardHoles(), object(), index(),
+                                 value(), tempToUnboxIndex(),
+                                 temp()))
     {
         return false;
     }
 
     setHasDenseStub();
-    return linkAndAttachStub(cx, masm, attacher, ion, "dense array");
+    const char *message = guardHoles()            ?
+                            "dense array (holes)" :
+                            "dense array";
+    return linkAndAttachStub(cx, masm, attacher, ion, message);
 }
 
 static bool
 GenerateSetTypedArrayElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
                              TypedArrayObject *tarr, Register object,
                              ValueOperand indexVal, ConstantOrRegister value,
                              Register tempUnbox, Register temp, FloatRegister tempFloat)
 {
@@ -3699,23 +3715,28 @@ SetElementIC::reset()
 
 bool
 SetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObject *obj,
                                     const Value &idval)
 {
     MacroAssembler masm(cx);
     DispatchStubPrepender attacher(*this);
     if (!GenerateSetDenseElement(cx, masm, attacher, obj, idval,
-                                 object(), index(), value(),
-                                 tempToUnboxIndex(), temp()))
+                                 guardHoles(), object(), index(),
+                                 value(), tempToUnboxIndex(),
+                                 temp()))
     {
         return false;
     }
 
-    return linkAndAttachStub(cx, masm, attacher, ion, "parallel dense array");
+    const char *message = guardHoles()                     ?
+                            "parallel dense array (holes)" :
+                            "parallel dense array";
+
+    return linkAndAttachStub(cx, masm, attacher, ion, message);
 }
 
 bool
 SetElementParIC::attachTypedArrayElement(LockedJSContext &cx, IonScript *ion,
                                          TypedArrayObject *tarr)
 {
     MacroAssembler masm(cx);
     DispatchStubPrepender attacher(*this);
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -803,30 +803,32 @@ class SetElementIC : public RepatchIonCa
   protected:
     Register object_;
     Register tempToUnboxIndex_;
     Register temp_;
     FloatRegister tempFloat_;
     ValueOperand index_;
     ConstantOrRegister value_;
     bool strict_;
+    bool guardHoles_;
 
     bool hasDenseStub_ : 1;
 
   public:
     SetElementIC(Register object, Register tempToUnboxIndex, Register temp,
                  FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
-                 bool strict)
+                 bool strict, bool guardHoles)
       : object_(object),
         tempToUnboxIndex_(tempToUnboxIndex),
         temp_(temp),
         tempFloat_(tempFloat),
         index_(index),
         value_(value),
         strict_(strict),
+        guardHoles_(guardHoles),
         hasDenseStub_(false)
     {
     }
 
     CACHE_HEADER(SetElement)
 
     void reset();
 
@@ -846,16 +848,19 @@ class SetElementIC : public RepatchIonCa
         return index_;
     }
     ConstantOrRegister value() const {
         return value_;
     }
     bool strict() const {
         return strict_;
     }
+    bool guardHoles() const {
+        return guardHoles_;
+    }
 
     bool hasDenseStub() const {
         return hasDenseStub_;
     }
     void setHasDenseStub() {
         JS_ASSERT(!hasDenseStub());
         hasDenseStub_ = true;
     }
@@ -1177,28 +1182,30 @@ class SetElementParIC : public ParallelI
   protected:
     Register object_;
     Register tempToUnboxIndex_;
     Register temp_;
     FloatRegister tempFloat_;
     ValueOperand index_;
     ConstantOrRegister value_;
     bool strict_;
+    bool guardHoles_;
 
   public:
     SetElementParIC(Register object, Register tempToUnboxIndex, Register temp,
                     FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value,
-                    bool strict)
+                    bool strict, bool guardHoles)
       : object_(object),
         tempToUnboxIndex_(tempToUnboxIndex),
         temp_(temp),
         tempFloat_(tempFloat),
         index_(index),
         value_(value),
-        strict_(strict)
+        strict_(strict),
+        guardHoles_(guardHoles)
     {
     }
 
     CACHE_HEADER(SetElementPar)
 
 #ifdef JS_CPU_X86
     // x86 lacks a general purpose scratch register for dispatch caches and
     // must be given one manually.
@@ -1221,16 +1228,19 @@ class SetElementParIC : public ParallelI
         return index_;
     }
     ConstantOrRegister value() const {
         return value_;
     }
     bool strict() const {
         return strict_;
     }
+    bool guardHoles() const {
+        return guardHoles_;
+    }
 
     bool attachDenseElement(LockedJSContext &cx, IonScript *ion, JSObject *obj, const Value &idval);
     bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, TypedArrayObject *tarr);
 
     static bool update(ForkJoinSlice *slice, size_t cacheIndex, HandleObject obj,
                        HandleValue idval, HandleValue value);
 };
 
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2797,16 +2797,17 @@ PropertyReadNeedsTypeBarrier(JSContext *
 
     // Type information for singleton objects is not required to reflect the
     // initial 'undefined' value for native properties, in particular global
     // variables declared with 'var'. Until the property is assigned a value
     // other than undefined, a barrier is required.
     if (name && object->singleton() && object->singleton()->isNative()) {
         Shape *shape = object->singleton()->nativeLookup(cx, name);
         if (shape &&
+            shape->hasSlot() &&
             shape->hasDefaultGetter() &&
             object->singleton()->nativeGetSlot(shape->slot()).isUndefined())
         {
             return true;
         }
     }
 
     property.freeze(constraints);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -7130,34 +7130,40 @@ class MSetPropertyCache
     }
 };
 
 class MSetElementCache
   : public MSetElementInstruction,
     public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >
 {
     bool strict_;
-
-    MSetElementCache(MDefinition *obj, MDefinition *index, MDefinition *value, bool strict)
+    bool guardHoles_;
+
+    MSetElementCache(MDefinition *obj, MDefinition *index, MDefinition *value, bool strict,
+                     bool guardHoles)
       : MSetElementInstruction(obj, index, value),
-        strict_(strict)
+        strict_(strict),
+        guardHoles_(guardHoles)
     {
     }
 
   public:
     INSTRUCTION_HEADER(SetElementCache);
 
     static MSetElementCache *New(MDefinition *obj, MDefinition *index, MDefinition *value,
-                                 bool strict) {
-        return new MSetElementCache(obj, index, value, strict);
+                                 bool strict, bool guardHoles) {
+        return new MSetElementCache(obj, index, value, strict, guardHoles);
     }
 
     bool strict() const {
         return strict_;
     }
+    bool guardHoles() const {
+        return guardHoles_;
+    }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     bool canConsumeFloat32() const { return true; }
 };
 
--- a/js/src/js-confdefs.h.in
+++ b/js/src/js-confdefs.h.in
@@ -5,9 +5,11 @@
 
 #ifndef js_confdefs_h
 #define js_confdefs_h
 
 @ALLDEFINES@
 
 #include "js/RequiredDefines.h"
 
+#include "mozilla/Char16.h"
+
 #endif /* js_confdefs_h */
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -45,18 +45,16 @@ BEGIN_TEST(testChromeBuffer)
 {
     JS_SetTrustedPrincipals(rt, &system_principals);
 
     trusted_glob = JS_NewGlobalObject(cx, &global_class, &system_principals, JS::FireOnNewGlobalHook);
     CHECK(trusted_glob);
 
     if (!JS_AddNamedObjectRoot(cx, &trusted_glob, "trusted-global"))
         return false;
-    if (!JS_AddNamedObjectRoot(cx, &trusted_fun, "trusted-function"))
-        return false;
 
     JSFunction *fun;
 
     /*
      * Check that, even after untrusted content has exhausted the stack, code
      * compiled with "trusted principals" can run using reserved trusted-only
      * buffer space.
      */
@@ -65,16 +63,18 @@ BEGIN_TEST(testChromeBuffer)
             JSAutoCompartment ac(cx, trusted_glob);
             const char *paramName = "x";
             const char *bytes = "return x ? 1 + trusted(x-1) : 0";
             JS::HandleObject global = JS::HandleObject::fromMarkedLocation(&trusted_glob);
             CHECK(fun = JS_CompileFunctionForPrincipals(cx, global, &system_principals,
                                                         "trusted", 1, &paramName, bytes, strlen(bytes),
                                                         "", 0));
             trusted_fun = JS_GetFunctionObject(fun);
+            if (!JS_AddNamedObjectRoot(cx, &trusted_fun, "trusted-function"))
+                return false;
         }
 
         JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
         CHECK(JS_WrapValue(cx, v.address()));
 
         const char *paramName = "trusted";
         const char *bytes = "try {                                      "
                             "    return untrusted(trusted);             "
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -1,8 +1,9 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Original author: ekr@rtfm.com
 
 #include "logging.h"
 #include "MediaPipeline.h"
@@ -143,25 +144,25 @@ nsresult MediaPipeline::TransportReady_s
   MOZ_ASSERT(!description_.empty());
   bool rtcp = !(flow == rtp_transport_);
   State *state = rtcp ? &rtcp_state_ : &rtp_state_;
 
   // TODO(ekr@rtfm.com): implement some kind of notification on
   // failure. bug 852665.
   if (*state != MP_CONNECTING) {
     MOZ_MTLOG(ML_ERROR, "Transport ready for flow in wrong state:" <<
-	      description_ << ": " << (rtcp ? "rtcp" : "rtp"));
+              description_ << ": " << (rtcp ? "rtcp" : "rtp"));
     return NS_ERROR_FAILURE;
   }
 
   nsresult res;
 
   MOZ_MTLOG(ML_DEBUG, "Transport ready for pipeline " <<
-	    static_cast<void *>(this) << " flow " << description_ << ": " <<
-	    (rtcp ? "rtcp" : "rtp"));
+            static_cast<void *>(this) << " flow " << description_ << ": " <<
+            (rtcp ? "rtcp" : "rtp"));
 
   // Now instantiate the SRTP objects
   TransportLayerDtls *dtls = static_cast<TransportLayerDtls *>(
       flow->GetLayer(TransportLayerDtls::ID()));
   MOZ_ASSERT(dtls);  // DTLS is mandatory
 
   uint16_t cipher_suite;
   res = dtls->GetSrtpCipher(&cipher_suite);
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
@@ -1,8 +1,9 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Original author: ekr@rtfm.com
 
 #ifndef mediapipeline_h__
 #define mediapipeline_h__
@@ -78,17 +79,16 @@ class MediaPipeline : public sigslot::ha
         track_id_(track_id),
         conduit_(conduit),
         rtp_transport_(rtp_transport),
         rtp_state_(MP_CONNECTING),
         rtcp_transport_(rtcp_transport),
         rtcp_state_(MP_CONNECTING),
         main_thread_(main_thread),
         sts_thread_(sts_thread),
-        transport_(new PipelineTransport(this)),
         rtp_send_srtp_(),
         rtcp_send_srtp_(),
         rtp_recv_srtp_(),
         rtcp_recv_srtp_(),
         rtp_packets_sent_(0),
         rtcp_packets_sent_(0),
         rtp_packets_received_(0),
         rtcp_packets_received_(0),
@@ -97,16 +97,18 @@ class MediaPipeline : public sigslot::ha
       // To indicate rtcp-mux rtcp_transport should be NULL.
       // Therefore it's an error to send in the same flow for
       // both rtp and rtcp.
       MOZ_ASSERT(rtp_transport_ != rtcp_transport_);
 
       if (!rtcp_transport_) {
         rtcp_transport_ = rtp_transport;
       }
+      // PipelineTransport() will access this->sts_thread_; moved here for safety
+      transport_ = new PipelineTransport(this);
   }
 
   virtual ~MediaPipeline();
 
   // Must be called on the STS thread.  Must be called after ShutdownMedia_m().
   void ShutdownTransport_s();
 
   // Must be called on the main thread.
@@ -140,17 +142,17 @@ class MediaPipeline : public sigslot::ha
   virtual void DetachMediaStream() {}
 
   // Separate class to allow ref counting
   class PipelineTransport : public TransportInterface {
    public:
     // Implement the TransportInterface functions
     PipelineTransport(MediaPipeline *pipeline)
         : pipeline_(pipeline),
-	  sts_thread_(pipeline->sts_thread_) {}
+          sts_thread_(pipeline->sts_thread_) {}
 
     void Detach() { pipeline_ = NULL; }
     MediaPipeline *pipeline() const { return pipeline_; }
 
     virtual nsresult SendRtpPacket(const void* data, int len);
     virtual nsresult SendRtcpPacket(const void* data, int len);
 
    private:
@@ -178,22 +180,22 @@ class MediaPipeline : public sigslot::ha
                          size_t len);
   void RtcpPacketReceived(TransportLayer *layer, const unsigned char *data,
                           size_t len);
   void PacketReceived(TransportLayer *layer, const unsigned char *data,
                       size_t len);
 
   Direction direction_;
   RefPtr<MediaStream> stream_;  // A pointer to the stream we are servicing.
-  		      		// Written on the main thread.
-  		      		// Used on STS and MediaStreamGraph threads.
+                                // Written on the main thread.
+                                // Used on STS and MediaStreamGraph threads.
   TrackID track_id_;            // The track on the stream.
                                 // Written and used as the stream_;
   RefPtr<MediaSessionConduit> conduit_;  // Our conduit. Written on the main
-  			      		 // thread. Read on STS thread.
+                                         // thread. Read on STS thread.
 
   // The transport objects. Read/written on STS thread.
   RefPtr<TransportFlow> rtp_transport_;
   State rtp_state_;
   RefPtr<TransportFlow> rtcp_transport_;
   State rtcp_state_;
 
   // Pointers to the threads we need. Initialized at creation
@@ -380,20 +382,20 @@ class MediaPipelineTransmit : public Med
    private:
     void NewData(MediaStreamGraph* graph, TrackID tid,
                  TrackRate rate,
                  TrackTicks offset,
                  uint32_t events,
                  const MediaSegment& media);
 
     virtual void ProcessAudioChunk(AudioSessionConduit *conduit,
-				   TrackRate rate, AudioChunk& chunk);
+                                   TrackRate rate, AudioChunk& chunk);
 #ifdef MOZILLA_INTERNAL_API
     virtual void ProcessVideoChunk(VideoSessionConduit *conduit,
-				   TrackRate rate, VideoChunk& chunk);
+                                   TrackRate rate, VideoChunk& chunk);
 #endif
     RefPtr<MediaSessionConduit> conduit_;
     volatile bool active_;
     bool direct_connect_;
 
     int32_t last_img_; // serial number of last Image
 
     // These vars handle breaking audio samples into exact 10ms chunks:
@@ -512,17 +514,17 @@ class MediaPipelineReceiveVideo : public
                             MediaStream *stream,
                             TrackID track_id,
                             RefPtr<VideoSessionConduit> conduit,
                             RefPtr<TransportFlow> rtp_transport,
                             RefPtr<TransportFlow> rtcp_transport) :
       MediaPipelineReceive(pc, main_thread, sts_thread,
                            stream, track_id, conduit, rtp_transport,
                            rtcp_transport),
-      renderer_(new PipelineRenderer(this)),
+      renderer_(new PipelineRenderer(MOZ_THIS_IN_INITIALIZER_LIST())),
       listener_(new PipelineListener(stream->AsSourceStream(), track_id)) {
   }
 
   // Called on the main thread.
   virtual void DetachMediaStream() {
     ASSERT_ON_THREAD(main_thread_);
 
     listener_->EndTrack();
--- a/mfbt/Char16.h
+++ b/mfbt/Char16.h
@@ -9,19 +9,16 @@
 #ifndef mozilla_Char16_h
 #define mozilla_Char16_h
 
 /*
  * C11 and C++11 introduce a char16_t type and support for UTF-16 string and
  * character literals. C++11's char16_t is a distinct builtin type. C11's
  * char16_t is a typedef for uint_least16_t. Technically, char16_t is a 16-bit
  * code unit of a Unicode code point, not a "character".
- *
- * For now, Char16.h only supports C++ because we don't want mix different C
- * and C++ definitions of char16_t in the same code base.
  */
 
 #ifdef _MSC_VER
    /*
     * C++11 says char16_t is a distinct builtin type, but Windows's yvals.h
     * typedefs char16_t as an unsigned short. We would like to alias char16_t
     * to Windows's 16-bit wchar_t so we can declare UTF-16 literals as constant
     * expressions (and pass char16_t pointers to Windows APIs). We #define our
@@ -34,28 +31,47 @@
       (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
    /* C++11 has a builtin char16_t type. */
 #  define MOZ_UTF16_HELPER(s) u##s
    /**
     * This macro is used to distinguish when char16_t would be a distinct
     * typedef from wchar_t.
     */
 #  define MOZ_CHAR16_IS_NOT_WCHAR
+#elif !defined(__cplusplus)
+#  if defined(WIN32)
+#    include <yvals.h>
+     typedef wchar_t char16_t;
+#  else
+     /**
+      * We can't use the stdint.h uint16_t type here because including
+      * stdint.h will break building some of our C libraries, such as
+      * sqlite.
+      */
+     typedef unsigned short char16_t;
+#  endif
 #else
 #  error "Char16.h requires C++11 (or something like it) for UTF-16 support."
 #endif
 
+/* This is a temporary hack until bug 927728 is fixed. */
+#define __PRUNICHAR__
+typedef char16_t PRUnichar;
+
 /*
  * Macro arguments used in concatenation or stringification won't be expanded.
  * Therefore, in order for |MOZ_UTF16(FOO)| to work as expected (which is to
  * expand |FOO| before doing whatever |MOZ_UTF16| needs to do to it) a helper
  * macro, |MOZ_UTF16_HELPER| needs to be inserted in between to allow the macro
  * argument to expand. See "3.10.6 Separate Expansion of Macro Arguments" of the
  * CPP manual for a more accurate and precise explanation.
  */
 #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s)
 
+#if defined(__cplusplus) && \
+    (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
 static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?");
 static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?");
 static_assert(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?");
 static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?");
+#endif
 
 #endif /* mozilla_Char16_h */
--- a/mfbt/WeakPtr.h
+++ b/mfbt/WeakPtr.h
@@ -9,19 +9,16 @@
 /**
  * SupportsWeakPtr lets you have a pointer to an object 'Foo' without affecting
  * its lifetime. It works by creating a single shared reference counted object
  * (WeakReference) that each WeakPtr will access 'Foo' through. This lets 'Foo'
  * clear the pointer in the WeakReference without having to know about all of
  * the WeakPtrs to it and allows the WeakReference to live beyond the lifetime
  * of 'Foo'.
  *
- * AtomicSupportsWeakPtr can be used for a variant with an atomically updated
- * reference counter.
- *
  * The overhead of WeakPtr is that accesses to 'Foo' becomes an additional
  * dereference, and an additional heap allocated pointer sized object shared
  * between all of the WeakPtrs.
  *
  * Example of usage:
  *
  *   // To have a class C support weak pointers, inherit from SupportsWeakPtr<C>.
  *   class C : public SupportsWeakPtr<C>
@@ -58,41 +55,40 @@
  * The API was loosely inspired by Chromium's weak_ptr.h:
  * http://src.chromium.org/svn/trunk/src/base/memory/weak_ptr.h
  */
 
 #ifndef mozilla_WeakPtr_h
 #define mozilla_WeakPtr_h
 
 #include "mozilla/Assertions.h"
-#include "mozilla/Atomics.h"
 #include "mozilla/NullPtr.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TypeTraits.h"
 
 namespace mozilla {
 
 template <typename T, class WeakReference> class WeakPtrBase;
 template <typename T, class WeakReference> class SupportsWeakPtrBase;
 
 namespace detail {
 
 // This can live beyond the lifetime of the class derived from SupportsWeakPtrBase.
-template<class T, RefCountAtomicity Atomicity>
-class WeakReference : public RefCounted<WeakReference<T, Atomicity>, Atomicity>
+template<class T>
+class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
 {
   public:
     explicit WeakReference(T* p) : ptr(p) {}
     T* get() const {
       return ptr;
     }
 
   private:
-    friend class WeakPtrBase<T, WeakReference>;
-    friend class SupportsWeakPtrBase<T, WeakReference>;
+    friend class WeakPtrBase<T, WeakReference<T> >;
+    friend class SupportsWeakPtrBase<T, WeakReference<T> >;
     void detach() {
       ptr = nullptr;
     }
     T* ptr;
 };
 
 } // namespace detail
 
@@ -116,40 +112,20 @@ class SupportsWeakPtrBase
 
   private:
     friend class WeakPtrBase<T, WeakReference>;
 
     RefPtr<WeakReference> weakRef;
 };
 
 template <typename T>
-class SupportsWeakPtr
-  : public SupportsWeakPtrBase<T, detail::WeakReference<T, detail::NonAtomicRefCount> >
-{
-};
-
-template <typename T>
-class AtomicSupportsWeakPtr
-  : public SupportsWeakPtrBase<T, detail::WeakReference<T, detail::AtomicRefCount> >
+class SupportsWeakPtr : public SupportsWeakPtrBase<T, detail::WeakReference<T> >
 {
 };
 
-namespace detail {
-
-template <typename T>
-struct WeakReferenceCount
-{
-  static const RefCountAtomicity atomicity =
-    IsBaseOf<AtomicSupportsWeakPtr<T>, T>::value
-    ? AtomicRefCount
-    : NonAtomicRefCount;
-};
-
-}
-
 template <typename T, class WeakReference>
 class WeakPtrBase
 {
   public:
     WeakPtrBase(const WeakPtrBase<T, WeakReference>& o) : ref(o.ref) {}
     // Ensure that ref is dereferenceable in the uninitialized state
     WeakPtrBase() : ref(new WeakReference(nullptr)) {}
 
@@ -172,19 +148,19 @@ class WeakPtrBase
     friend class SupportsWeakPtrBase<T, WeakReference>;
 
     explicit WeakPtrBase(const RefPtr<WeakReference> &o) : ref(o) {}
 
     RefPtr<WeakReference> ref;
 };
 
 template <typename T>
-class WeakPtr : public WeakPtrBase<T, detail::WeakReference<T, detail::WeakReferenceCount<T>::atomicity> >
+class WeakPtr : public WeakPtrBase<T, detail::WeakReference<T> >
 {
-    typedef WeakPtrBase<T, detail::WeakReference<T, detail::WeakReferenceCount<T>::atomicity> > Base;
+    typedef WeakPtrBase<T, detail::WeakReference<T> > Base;
   public:
     WeakPtr(const WeakPtr<T>& o) : Base(o) {}
     WeakPtr(const Base& o) : Base(o) {}
     WeakPtr() {}
 };
 
 } // namespace mozilla
 
--- a/mobile/android/base/locales/Makefile.in
+++ b/mobile/android/base/locales/Makefile.in
@@ -3,22 +3,22 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/config.mk
 
 # special case some locale codes, he and id
 # http://code.google.com/p/android/issues/detail?id=3639
 AB_rCD = $(if $(filter he, $(AB_CD)),iw,$(if $(filter id, $(AB_CD)),in,$(subst -,-r,$(AB_CD))))
 
-SYNCSTRINGSPATH = $(call core_abspath,$(call MERGE_FILE,sync_strings.dtd))
-STRINGSPATH = $(call core_abspath,$(call MERGE_FILE,android_strings.dtd))
+SYNCSTRINGSPATH = $(abspath $(call MERGE_FILE,sync_strings.dtd))
+STRINGSPATH = $(abspath $(call MERGE_FILE,android_strings.dtd))
 ifeq (,$(XPI_NAME))
-BRANDPATH = $(call core_abspath,$(DEPTH)/dist/bin/chrome/$(AB_CD)/locale/branding/brand.dtd)
+BRANDPATH = $(abspath $(DEPTH)/dist/bin/chrome/$(AB_CD)/locale/branding/brand.dtd)
 else
-BRANDPATH = $(call core_abspath,$(DIST)/xpi-stage/$(XPI_NAME)/chrome/$(AB_CD)/locale/branding/brand.dtd)
+BRANDPATH = $(abspath $(DIST)/xpi-stage/$(XPI_NAME)/chrome/$(AB_CD)/locale/branding/brand.dtd)
 endif
 $(warnIfEmpty,AB_CD) # todo: $(errorIfEmpty )
 
 DEFINES += -DAB_CD=$(AB_CD)
 
 dir-res-values := ../res/values
 strings-xml    := $(dir-res-values)/strings.xml
 strings-xml-in := $(srcdir)/../strings.xml.in
@@ -27,25 +27,25 @@ GARBAGE += $(strings-xml)
 
 libs realchrome:: $(strings-xml)
 
 chrome-%:: AB_CD=$*
 chrome-%:: 
 	@$(MAKE) $(dir-res-values)-$(AB_rCD)/strings.xml AB_CD=$*
 
 # setup the path to bookmarks.inc. copied and tweaked version of MERGE_FILE from config/config.mk
-MOBILE_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/mobile/locales/en-US,$(call core_realpath,$(L10NBASEDIR))/$(AB_CD)/mobile)
+MOBILE_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/mobile/locales/en-US,$(or $(realpath $(L10NBASEDIR)),$(abspath $(L10NBASEDIR)))/$(AB_CD)/mobile)
 
 ifdef LOCALE_MERGEDIR
 BOOKMARKSPATH = $(firstword \
   $(wildcard $(LOCALE_MERGEDIR)/mobile/profile/bookmarks.inc ) \
   $(wildcard $(MOBILE_LOCALE_SRCDIR)/profile/bookmarks.inc ) \
   $(topsrcdir)/mobile/locales/en-US/profile/bookmarks.inc )
 else
-BOOKMARKSPATH = $(call core_abspath,$(MOBILE_LOCALE_SRCDIR)/profile/bookmarks.inc)
+BOOKMARKSPATH = $(abspath $(MOBILE_LOCALE_SRCDIR)/profile/bookmarks.inc)
 endif
 
 # Determine the ../res/values[-*]/ path
 strings-xml-bypath  = $(filter %/strings.xml,$(MAKECMDGOALS))
 ifeq (,$(strip $(strings-xml-bypath)))
   strings-xml-bypath = $(strings-xml)
 endif
 dir-strings-xml = $(patsubst %/,%,$(dir $(strings-xml-bypath)))
--- a/modules/libmar/tests/Makefile.in
+++ b/modules/libmar/tests/Makefile.in
@@ -1,13 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-TESTROOT = $(call core_abspath,$(DEPTH))/_tests/xpcshell/$(relativesrcdir)
+TESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/$(relativesrcdir)
 
 DEFINES += -DBIN_SUFFIX=$(BIN_SUFFIX)
 
 include $(topsrcdir)/config/rules.mk
 
 libs:: unit/head_libmar.js.in
 	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) $^ > $(TESTROOT)/unit/head_libmar.js
 
--- a/mozilla-config.h.in
+++ b/mozilla-config.h.in
@@ -21,16 +21,29 @@
  */
 #define __STDC_LIMIT_MACROS
 #define __STDC_CONSTANT_MACROS
 #if !defined(__STDC_FORMAT_MACROS)
 #define __STDC_FORMAT_MACROS
 #endif
 
 /*
+ * Force-include Char16.h in order to define PRUnichar as char16_t everywhere.
+ * Note that this should be the first #include to make sure that prtypes.h does
+ * not attempt to define PRUnichar.  This includes the following hunspell-specific
+ * includes.
+ *
+ * We don't use this to build elfhack and elf-dynstr-gc since those builds happen
+ * during the export tier.  Also, disable this when building assembly files too.
+ */
+#if !defined(ELFHACK_BUILD) && !defined(ELFDYNSTRGC_BUILD) && !defined(__ASSEMBLER__)
+#include "mozilla/Char16.h"
+#endif
+
+/*
  * Force-include hunspell_alloc_hooks.h and hunspell_fopen_hooks.h for hunspell,
  * so that we don't need to modify them directly.
  *
  * HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in,
  * unless --enable-system-hunspell is defined.
  */
 #if defined(HUNSPELL_STATIC)
 #include "hunspell_alloc_hooks.h"
--- a/security/build/Makefile.in
+++ b/security/build/Makefile.in
@@ -82,17 +82,17 @@ endif
 ifdef HAVE_FREEBL_LIBS_32INT64
 NSS_EXTRA_DLLS += freebl_32int64_3
 endif
 ifdef HAVE_FREEBL_LIBS_64
 NSS_EXTRA_DLLS += freebl_64int_3
 NSS_EXTRA_DLLS += freebl_64fpu_3
 endif
 
-ABS_DIST := $(call core_abspath,$(DIST))
+ABS_DIST := $(abspath $(DIST))
 ifeq ($(HOST_OS_ARCH),WINNT)
 ifdef CYGDRIVE_MOUNT
 ABS_DIST := $(shell cygpath -w $(ABS_DIST) | sed -e 's|\\|/|g')
 endif
 ifneq (,$(filter mingw%,$(host_os)))
 ABS_DIST := $(shell cd $(DIST) && pwd -W)
 endif
 endif
@@ -283,17 +283,17 @@ NSS_SRCDIR = $(CURDIR)/nss
 # dependencies for patched files.
 export::
 	rm -rf $(NSS_SRCDIR)
 	$(NSINSTALL) -D $(NSS_SRCDIR)/security
 	cp -Rp $(topsrcdir)/security/nss $(NSS_SRCDIR)/security
 	cp -Rp $(topsrcdir)/security/coreconf $(NSS_SRCDIR)/security
 	cp -Rp $(topsrcdir)/security/dbm $(NSS_SRCDIR)/security
 	cp -Rp $(topsrcdir)/dbm $(NSS_SRCDIR)
-	(cd $(NSS_SRCDIR) && patch -p1 < $(call core_abspath,$(MOZ_NSS_PATCH)))
+	(cd $(NSS_SRCDIR) && patch -p1 < $(abspath $(MOZ_NSS_PATCH)))
 else
 NSS_SRCDIR = $(topsrcdir)
 endif
 
 NSS_DIRS =
 ifndef MOZ_FOLD_LIBS
 NSS_DIRS += nss/lib
 else
@@ -445,17 +445,17 @@ libs-nss/lib/freebl: $(DIST)/lib/$(IMPOR
 
 # For each directory where we build static libraries, force the NSS build system
 # to only build static libraries.
 $(addprefix libs-,$(NSS_STATIC_DIRS)): DEFAULT_GMAKE_FLAGS += SHARED_LIBRARY= IMPORT_LIBRARY=
 endif # MOZ_FOLD_LIBS
 
 ifeq ($(NSINSTALL_PY),$(NSINSTALL))
 DEFAULT_GMAKE_FLAGS += PYTHON='$(PYTHON)'
-DEFAULT_GMAKE_FLAGS += NSINSTALL_PY='$(call core_abspath,$(topsrcdir)/config/nsinstall.py)'
+DEFAULT_GMAKE_FLAGS += NSINSTALL_PY='$(abspath $(topsrcdir)/config/nsinstall.py)'
 DEFAULT_GMAKE_FLAGS += NSINSTALL='$$(PYTHON) $$(NSINSTALL_PY)'
 else
 DEFAULT_GMAKE_FLAGS += NSINSTALL='$(NSINSTALL)'
 endif
 ifeq ($(OS_ARCH),WINNT)
 DEFAULT_GMAKE_FLAGS += INSTALL='$$(NSINSTALL) -t'
 endif
 DEFAULT_GMAKE_FLAGS += $(EXTRA_GMAKE_FLAGS)
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -68,22 +68,16 @@ void
 getSiteKey(const nsACString & hostName, uint16_t port,
            /*out*/ nsCSubstring & key)
 {
   key = hostName;
   key.AppendASCII(":");
   key.AppendInt(port);
 }
 
-void
-getSiteKey(const nsNSSSocketInfo & socketInfo, /*out*/ nsCSubstring & key)
-{
-  getSiteKey(socketInfo.GetHostName(), socketInfo.GetPort(), key);
-}
-
 /* SSM_UserCertChoice: enum for cert choice info */
 typedef enum {ASK, AUTO} SSM_UserCertChoice;
 
 } // unnamed namespace
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gPIPNSSLog;
 #endif
@@ -1200,23 +1194,23 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_
   // cert validation is complete.
   int16_t result = fd->lower->methods->poll(fd->lower, in_flags, out_flags);
   PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] poll SSL socket returned %d\n",
                                     (void*)fd, (int) result));
   return result;
 }
 
 nsSSLIOLayerHelpers::nsSSLIOLayerHelpers()
-: mutex("nsSSLIOLayerHelpers.mutex")
-, mRenegoUnrestrictedSites(nullptr)
+: mRenegoUnrestrictedSites(nullptr)
 , mTreatUnsafeNegotiationAsBroken(false)
 , mWarnLevelMissingRFC5746(1)
 , mTLSIntoleranceInfo(16)
 , mFalseStartRequireNPN(true)
 , mFalseStartRequireForwardSecrecy(false)
+, mutex("nsSSLIOLayerHelpers.mutex")
 {
 }
 
 static int _PSM_InvalidInt(void)
 {
     PR_ASSERT(!"I/O method is invalid");
     PR_SetError(PR_INVALID_METHOD_ERROR, 0);
     return -1;
--- a/testing/specialpowers/Makefile.in
+++ b/testing/specialpowers/Makefile.in
@@ -2,32 +2,27 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 NO_JS_MANIFEST = 1
 MOZ_CHROME_FILE_FORMAT = flat
 DIST_FILES = \
   install.rdf \
-  chrome.manifest \
   $(NULL)
 
 XPI_NAME=specialpowers
 
 # Used in install.rdf
 USE_EXTENSION_MANIFEST=1
 
 TEST_EXTENSIONS_DIR = $(DEPTH)/testing/specialpowers
 
 include $(topsrcdir)/config/rules.mk
 
-# JarMaker creates a chrome.manifest already, so the one from the source
-# directory is not copied if it's not forced to be.
-$(FINAL_TARGET)/chrome.manifest: FORCE
-
 libs-preqs = \
   $(call mkdir_deps,$(TEST_EXTENSIONS_DIR)) \
   $(NULL)
 
 libs:: $(libs-preqs)
 	(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -)
 	$(NSINSTALL) -D $(DEPTH)/_tests/testing/mochitest/extensions/specialpowers
 	cp -RL $(DEPTH)/testing/specialpowers/specialpowers $(DEPTH)/_tests/testing/mochitest/extensions
deleted file mode 100644
--- a/testing/specialpowers/chrome.manifest
+++ /dev/null
@@ -1,5 +0,0 @@
-content specialpowers chrome/specialpowers/content/
-resource specialpowers chrome/specialpowers/modules/
-component {59a52458-13e0-4d93-9d85-a637344f29a1} components/SpecialPowersObserver.js
-contract @mozilla.org/special-powers-observer;1 {59a52458-13e0-4d93-9d85-a637344f29a1}
-category profile-after-change @mozilla.org/special-powers-observer;1 @mozilla.org/special-powers-observer;1
--- a/testing/specialpowers/jar.mn
+++ b/testing/specialpowers/jar.mn
@@ -4,8 +4,12 @@ specialpowers.jar:
   content/specialpowersAPI.js (content/specialpowersAPI.js)
   content/SpecialPowersObserverAPI.js (content/SpecialPowersObserverAPI.js)
   content/MozillaLogger.js (content/MozillaLogger.js)
 
 % resource specialpowers %modules/
   modules/MockFilePicker.jsm (content/MockFilePicker.jsm)
   modules/MockColorPicker.jsm (content/MockColorPicker.jsm)
   modules/MockPermissionPrompt.jsm (content/MockPermissionPrompt.jsm)
+
+% component {59a52458-13e0-4d93-9d85-a637344f29a1} components/SpecialPowersObserver.js
+% contract @mozilla.org/special-powers-observer;1 {59a52458-13e0-4d93-9d85-a637344f29a1}
+% category profile-after-change @mozilla.org/special-powers-observer;1 @mozilla.org/special-powers-observer;1
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -29,43 +29,43 @@ ifndef TEST_PACKAGE_NAME
 TEST_PACKAGE_NAME := $(ANDROID_PACKAGE_NAME)
 endif
 
 RUN_MOCHITEST_B2G_DESKTOP = \
   rm -f ./$@.log && \
   $(PYTHON) _tests/testing/mochitest/runtestsb2g.py --autorun --close-when-done \
     --console-level=INFO --log-file=./$@.log --file-level=INFO \
     --desktop --profile ${GAIA_PROFILE_DIR} \
-    --failure-file=$(call core_abspath,_tests/testing/mochitest/makefailures.json) \
+    --failure-file=$(abspath _tests/testing/mochitest/makefailures.json) \
     $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 RUN_MOCHITEST = \
   rm -f ./$@.log && \
   $(PYTHON) _tests/testing/mochitest/runtests.py --autorun --close-when-done \
     --console-level=INFO --log-file=./$@.log --file-level=INFO \
-    --failure-file=$(call core_abspath,_tests/testing/mochitest/makefailures.json) \
-    --testing-modules-dir=$(call core_abspath,_tests/modules) \
+    --failure-file=$(abspath _tests/testing/mochitest/makefailures.json) \
+    --testing-modules-dir=$(abspath _tests/modules) \
     --extra-profile-file=$(DIST)/plugins \
     $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 RERUN_MOCHITEST = \
   rm -f ./$@.log && \
   $(PYTHON) _tests/testing/mochitest/runtests.py --autorun --close-when-done \
     --console-level=INFO --log-file=./$@.log --file-level=INFO \
     --run-only-tests=makefailures.json \
-    --testing-modules-dir=$(call core_abspath,_tests/modules) \
+    --testing-modules-dir=$(abspath _tests/modules) \
     --extra-profile-file=$(DIST)/plugins \
     $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 RUN_MOCHITEST_REMOTE = \
   rm -f ./$@.log && \
   $(PYTHON) _tests/testing/mochitest/runtestsremote.py --autorun --close-when-done \
     --console-level=INFO --log-file=./$@.log --file-level=INFO $(DM_FLAGS) --dm_trans=$(DM_TRANS) \
     --app=$(TEST_PACKAGE_NAME) --deviceIP=${TEST_DEVICE} --xre-path=${MOZ_HOST_BIN} \
-    --testing-modules-dir=$(call core_abspath,_tests/modules) --httpd-path=. \
+    --testing-modules-dir=$(abspath _tests/modules) --httpd-path=. \
     $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 RUN_MOCHITEST_ROBOCOP = \
   rm -f ./$@.log && \
   $(PYTHON) _tests/testing/mochitest/runtestsremote.py \
     --robocop-apk=$(DEPTH)/build/mobile/robocop/robocop-debug.apk \
     --robocop-ids=$(DEPTH)/mobile/android/base/fennec_ids.txt \
     --robocop-ini=$(DEPTH)/build/mobile/robocop/robocop.ini \
@@ -282,19 +282,19 @@ xpcshell-tests:
 	  -I$(DEPTH)/build \
 	  -I$(topsrcdir)/build \
 	  -I$(DEPTH)/_tests/mozbase/mozinfo \
 	  $(topsrcdir)/testing/xpcshell/runxpcshelltests.py \
 	  --manifest=$(DEPTH)/_tests/xpcshell/xpcshell.ini \
 	  --build-info-json=$(DEPTH)/mozinfo.json \
 	  --no-logfiles \
 	  --test-plugin-path="$(DIST)/plugins" \
-	  --tests-root-dir=$(call core_abspath,_tests/xpcshell) \
-	  --testing-modules-dir=$(call core_abspath,_tests/modules) \
-	  --xunit-file=$(call core_abspath,_tests/xpcshell/results.xml) \
+	  --tests-root-dir=$(abspath _tests/xpcshell) \
+	  --testing-modules-dir=$(abspath _tests/modules) \
+	  --xunit-file=$(abspath _tests/xpcshell/results.xml) \
 	  --xunit-suite-name=xpcshell \
           $(SYMBOLS_PATH) \
 	  $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS) \
 	  $(LIBXUL_DIST)/bin/xpcshell
 
 B2G_XPCSHELL = \
 	rm -f ./@.log && \
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
@@ -329,17 +329,17 @@ xpcshell-tests-b2g:
 
 xpcshell-tests-remote: DM_TRANS?=adb
 xpcshell-tests-remote:
 	@if [ "${TEST_DEVICE}" != "" -o "$(DM_TRANS)" = "adb" ]; \
           then $(PYTHON) -u $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
 	    --manifest=$(DEPTH)/_tests/xpcshell/xpcshell_android.ini \
 	    --build-info-json=$(DEPTH)/mozinfo.json \
 	    --no-logfiles \
-	    --testing-modules-dir=$(call core_abspath,_tests/modules) \
+	    --testing-modules-dir=$(abspath _tests/modules) \
 	    --dm_trans=$(DM_TRANS) \
 	    --deviceIP=${TEST_DEVICE} \
 	    --objdir=$(DEPTH) \
 	    $(SYMBOLS_PATH) \
 	    $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS); \
 	    $(CHECK_TEST_ERROR); \
         else \
           echo "please prepare your host with environment variables for TEST_DEVICE"; \
@@ -418,17 +418,17 @@ package-tests:
 ifndef UNIVERSAL_BINARY
 	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
 else
 	#building tests.jar (bug 543800) fails on unify, so we build tests.jar after unify is run
 	$(MAKE) -C $(DEPTH)/testing/mochitest stage-chromejar PKG_STAGE=$(DIST)/universal
 endif
 	find $(PKG_STAGE) -name "*.pyc" -exec rm {} \;
 	cd $(PKG_STAGE) && \
-	  zip -rq9D "$(call core_abspath,$(DIST)/$(PKG_PATH)$(TEST_PACKAGE))" \
+	  zip -rq9D "$(abspath $(DIST)/$(PKG_PATH)$(TEST_PACKAGE))" \
 	  * -x \*/.mkdir.done
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 package-tests: stage-android
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
 package-tests: stage-b2g
--- a/toolkit/components/feeds/Makefile.in
+++ b/toolkit/components/feeds/Makefile.in
@@ -1,17 +1,17 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MOZILLA_INTERNAL_API = 1
 include $(topsrcdir)/config/rules.mk
 
-ABS_SRCDIR := $(call core_abspath,$(srcdir))
+ABS_SRCDIR := $(abspath $(srcdir))
 ifeq ($(OS_ARCH),WINNT)
 
 check::
 	cd $(srcdir)/test; $(LIBXUL_DIST)/bin/xpcshell$(BIN_SUFFIX) shell.js 
 
 else
 
 check::
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.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 "nsExceptionHandler.h"
 #include "nsDataHashtable.h"
 #include "mozilla/dom/CrashReporterChild.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
+#include "mozilla/unused.h"
 #include "mozilla/Util.h"
 
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 
 #if defined(XP_WIN32)
 #ifdef WIN32_LEAN_AND_MEAN
 #undef WIN32_LEAN_AND_MEAN
@@ -448,18 +449,17 @@ bool MinidumpCallback(
       WriteFile(hFile, minidumpPath, 2*wcslen(minidumpPath), &nBytes, nullptr);
       CloseHandle(hFile);
     }
 #elif defined(XP_UNIX)
     int fd = sys_open(crashMarkerFilename,
                       O_WRONLY | O_CREAT | O_TRUNC,
                       0600);
     if (fd != -1) {
-      ssize_t ignored = sys_write(fd, minidumpPath, my_strlen(minidumpPath));
-      (void)ignored;
+      unused << sys_write(fd, minidumpPath, my_strlen(minidumpPath));
       sys_close(fd);
     }
 #endif
   }
 
   char oomAllocationSizeBuffer[32];
   int oomAllocationSizeBufferLen = 0;
   if (gOOMAllocationSize) {
@@ -502,18 +502,17 @@ bool MinidumpCallback(
       WriteFile(hFile, crashTimeString, crashTimeStringLen, &nBytes, nullptr);
       CloseHandle(hFile);
     }
 #elif defined(XP_UNIX)
     int fd = sys_open(lastCrashTimeFilename,
                       O_WRONLY | O_CREAT | O_TRUNC,
                       0600);
     if (fd != -1) {
-      ssize_t ignored = sys_write(fd, crashTimeString, crashTimeStringLen);
-      (void)ignored;
+      unused << sys_write(fd, crashTimeString, crashTimeStringLen);
       sys_close(fd);
     }
 #endif
   }
 
 #if defined(XP_WIN32)
   if (!crashReporterAPIData->IsEmpty()) {
     // write out API data
@@ -609,39 +608,40 @@ bool MinidumpCallback(
   if (!crashReporterAPIData->IsEmpty()) {
     // write out API data
     int fd = sys_open(extraDataPath,
                       O_WRONLY | O_CREAT | O_TRUNC,
                       0666);
 
     if (fd != -1) {
       // not much we can do in case of error
-      ssize_t ignored = sys_write(fd, crashReporterAPIData->get(),
+      unused << sys_write(fd, crashReporterAPIData->get(),
                                   crashReporterAPIData->Length());
-      ignored = sys_write(fd, kCrashTimeParameter, kCrashTimeParameterLen);
-      ignored = sys_write(fd, crashTimeString, crashTimeStringLen);
-      ignored = sys_write(fd, "\n", 1);
+      unused << sys_write(fd, kCrashTimeParameter, kCrashTimeParameterLen);
+      unused << sys_write(fd, crashTimeString, crashTimeStringLen);
+      unused << sys_write(fd, "\n", 1);
       if (timeSinceLastCrash != 0) {
-        ignored = sys_write(fd, kTimeSinceLastCrashParameter,
+        unused << sys_write(fd, kTimeSinceLastCrashParameter,
                         kTimeSinceLastCrashParameterLen);
-        ignored = sys_write(fd, timeSinceLastCrashString,
+        unused << sys_write(fd, timeSinceLastCrashString,
                         timeSinceLastCrashStringLen);
-        ignored = sys_write(fd, "\n", 1);
+        unused << sys_write(fd, "\n", 1);
       }
       if (isGarbageCollecting) {
-        ignored = sys_write(fd, kIsGarbageCollectingParameter, kIsGarbageCollectingParameterLen);
-        ignored = sys_write(fd, isGarbageCollecting ? "1" : "0", 1);
-        ignored = sys_write(fd, "\n", 1);
+        unused << sys_write(fd, kIsGarbageCollectingParameter, kIsGarbageCollectingParameterLen);
+        unused << sys_write(fd, isGarbageCollecting ? "1" : "0", 1);
+        unused << sys_write(fd, "\n", 1);
       }
       if (oomAllocationSizeBufferLen) {
-        sys_write(fd, kOOMAllocationSizeParameter,
-                  kOOMAllocationSizeParameterLen);
-        sys_write(fd, oomAllocationSizeBuffer, oomAllocationSizeBufferLen);
-        sys_write(fd, "\n", 1);
-      }        
+        unused << sys_write(fd, kOOMAllocationSizeParameter,
+                            kOOMAllocationSizeParameterLen);
+        unused << sys_write(fd, oomAllocationSizeBuffer,
+                            oomAllocationSizeBufferLen);
+        unused << sys_write(fd, "\n", 1);
+      }
       sys_close(fd);
     }
   }
 
   if (!doReport) {
     return returnValue;
   }
 
@@ -671,37 +671,37 @@ bool MinidumpCallback(
 
   if (pid == -1)
     return false;
   else if (pid == 0) {
 #if !defined(MOZ_WIDGET_ANDROID)
     // need to clobber this, as libcurl might load NSS,
     // and we want it to load the system NSS.
     unsetenv("LD_LIBRARY_PATH");
-    (void) execl(crashReporterPath,
-                 crashReporterPath, minidumpPath, (char*)0);
+    unused << execl(crashReporterPath,
+                    crashReporterPath, minidumpPath, (char*)0);
 #else
     // Invoke the reportCrash activity using am
     if (androidUserSerial) {
-      (void) execlp("/system/bin/am",
-                    "/system/bin/am",
-                    "start",
-                    "--user", androidUserSerial,
-                    "-a", "org.mozilla.gecko.reportCrash",
-                    "-n", crashReporterPath,
-                    "--es", "minidumpPath", minidumpPath,
-                    (char*)0);
+      unused << execlp("/system/bin/am",
+                       "/system/bin/am",
+                       "start",
+                       "--user", androidUserSerial,
+                       "-a", "org.mozilla.gecko.reportCrash",
+                       "-n", crashReporterPath,
+                       "--es", "minidumpPath", minidumpPath,
+                       (char*)0);
     } else {
-      (void) execlp("/system/bin/am",
-                    "/system/bin/am",
-                    "start",
-                    "-a", "org.mozilla.gecko.reportCrash",
-                    "-n", crashReporterPath,
-                    "--es", "minidumpPath", minidumpPath,
-                    (char*)0);
+      unused << execlp("/system/bin/am",
+                       "/system/bin/am",
+                       "start",
+                       "-a", "org.mozilla.gecko.reportCrash",
+                       "-n", crashReporterPath,
+                       "--es", "minidumpPath", minidumpPath,
+                       (char*)0);
     }
 #endif
     _exit(1);
   }
 #endif // XP_MACOSX
 #endif // XP_UNIX
 
   return returnValue;
--- a/toolkit/locales/l10n.mk
+++ b/toolkit/locales/l10n.mk
@@ -29,34 +29,32 @@
 
 run_for_effects := $(shell if test ! -d $(DIST); then $(NSINSTALL) -D $(DIST); fi)
 
 # This makefile uses variable overrides from the libs-% target to
 # build non-default locales to non-default dist/ locations. Be aware!
 
 AB = $(firstword $(subst -, ,$(AB_CD)))
 
-core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))
-
 # These are defaulted to be compatible with the files the wget-en-US target
 # pulls. You may override them if you provide your own files. You _must_
 # override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not
 # work in that case.
 ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE)
 WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
 
 # Allows overriding the final destination of the repackaged file
 ZIP_OUT ?= $(_ABS_DIST)/$(PACKAGE)
 
 DEFINES += \
 	-DAB_CD=$(AB_CD) \
 	-DMOZ_LANGPACK_EID=$(MOZ_LANGPACK_EID) \
 	-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
 	-DMOZ_APP_MAXVERSION=$(MOZ_APP_MAXVERSION) \
-	-DLOCALE_SRCDIR=$(call core_abspath,$(LOCALE_SRCDIR)) \
+	-DLOCALE_SRCDIR=$(abspath $(LOCALE_SRCDIR)) \
 	-DPKG_BASENAME="$(PKG_BASENAME)" \
 	-DPKG_INST_BASENAME="$(PKG_INST_BASENAME)" \
 	$(NULL)
 
 
 clobber-%:
 	$(RM) -rf $(DIST)/xpi-stage/locale-$*
 
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 this.EXPORTED_SYMBOLS = ["PopupNotifications"];
 
-var Cc = Components.classes, Ci = Components.interfaces;
+var Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
 
-Components.utils.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const NOTIFICATION_EVENT_DISMISSED = "dismissed";
 const NOTIFICATION_EVENT_REMOVED = "removed";
 const NOTIFICATION_EVENT_SHOWING = "showing";
 const NOTIFICATION_EVENT_SHOWN = "shown";
 
 const ICON_SELECTOR = ".notification-anchor-icon";
 const ICON_ATTRIBUTE_SHOWING = "showing";
@@ -743,18 +743,22 @@ PopupNotifications.prototype = {
         n.dismissed = false;
     });
 
     // ...and then show them.
     this._update(notifications, anchor);
   },
 
   _fireCallback: function PopupNotifications_fireCallback(n, event) {
-    if (n.options.eventCallback)
-      n.options.eventCallback.call(n, event);
+    try {
+      if (n.options.eventCallback)
+        n.options.eventCallback.call(n, event);
+    } catch (error) {
+      Cu.reportError(error);
+    }
   },
 
   _onPopupHidden: function PopupNotifications_onPopupHidden(event) {
     if (event.target != this.panel || this._ignoreDismissal)
       return;
 
     let browser = this.panel.firstChild &&
                   this.panel.firstChild.notification.browser;
@@ -812,29 +816,37 @@ PopupNotifications.prototype = {
     }
 
     if (timeSinceShown < this.buttonDelay) {
       Services.console.logStringMessage("PopupNotifications_onButtonCommand: " +
                                         "Button click happened before the security delay: " +
                                         timeSinceShown + "ms");
       return;
     }
-    notification.mainAction.callback.call();
+    try {
+      notification.mainAction.callback.call();
+    } catch(error) {
+      Cu.reportError(error);
+    }
 
     this._remove(notification);
     this._update();
   },
 
   _onMenuCommand: function PopupNotifications_onMenuCommand(event) {
     let target = event.originalTarget;
     if (!target.action || !target.notification)
       throw "menucommand target has no associated action/notification";
 
     event.stopPropagation();
-    target.action.callback.call();
+    try {
+      target.action.callback.call();
+    } catch(error) {
+      Cu.reportError(error);
+    }
 
     this._remove(target.notification);
     this._update();
   },
 
   _notify: function PopupNotifications_notify(topic) {
     Services.obs.notifyObservers(null, "PopupNotifications-" + topic, "");
   },
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -95,18 +95,18 @@ JSSHELL_BINS += \
   $(DIST)/bin/$(DLL_PREFIX)plds4$(DLL_SUFFIX) \
   $(DIST)/bin/$(DLL_PREFIX)plc4$(DLL_SUFFIX) \
   $(NULL)
 endif # MOZ_FOLD_LIBS
 endif # MOZ_NATIVE_NSPR
 MAKE_JSSHELL  = $(ZIP) -9j $(PKG_JSSHELL) $(JSSHELL_BINS)
 endif # LIBXUL_SDK
 
-_ABS_DIST = $(call core_abspath,$(DIST))
-JARLOG_DIR = $(call core_abspath,$(DEPTH)/jarlog/)
+_ABS_DIST = $(abspath $(DIST))
+JARLOG_DIR = $(abspath $(DEPTH)/jarlog/)
 JARLOG_FILE_AB_CD = $(JARLOG_DIR)/$(AB_CD).log
 
 TAR_CREATE_FLAGS := --exclude=.mkdir.done $(TAR_CREATE_FLAGS)
 CREATE_FINAL_TAR = $(TAR) -c --owner=0 --group=0 --numeric-owner \
   --mode="go-w" --exclude=.mkdir.done -f
 UNPACK_TAR       = tar -xf-
 
 ifeq ($(MOZ_PKG_FORMAT),TAR)
@@ -319,17 +319,17 @@ ABI_DIR = x86
 else
 ifdef MOZ_THUMB2
 ABI_DIR = armeabi-v7a
 else
 ABI_DIR = armeabi
 endif
 endif
 
-GECKO_APP_AP_PATH = $(call core_abspath,$(DEPTH)/mobile/android/base)
+GECKO_APP_AP_PATH = $(abspath $(DEPTH)/mobile/android/base)
 
 ifdef ENABLE_TESTS
 INNER_ROBOCOP_PACKAGE=echo
 INNER_BACKGROUND_TESTS_PACKAGE=echo
 ifeq ($(MOZ_BUILD_APP),mobile/android)
 UPLOAD_EXTRA_FILES += robocop.apk
 UPLOAD_EXTRA_FILES += fennec_ids.txt
 UPLOAD_EXTRA_FILES += geckoview_library/geckoview_library.zip
@@ -341,22 +341,22 @@ UPLOAD_EXTRA_FILES += geckoview_library/
 # $(1) is the full path to input:  foo-debug-unsigned-unaligned.apk.
 # $(2) is the full path to output: foo.apk.
 RELEASE_SIGN_ANDROID_APK = \
   cp $(1) $(2)-unaligned.apk && \
   $(RELEASE_JARSIGNER) $(2)-unaligned.apk && \
   $(ZIPALIGN) -f -v 4 $(2)-unaligned.apk $(2) && \
   $(RM) $(2)-unaligned.apk
 
-ROBOCOP_PATH = $(call core_abspath,$(_ABS_DIST)/../build/mobile/robocop)
+ROBOCOP_PATH = $(abspath $(_ABS_DIST)/../build/mobile/robocop)
 INNER_ROBOCOP_PACKAGE= \
   $(NSINSTALL) $(GECKO_APP_AP_PATH)/fennec_ids.txt $(_ABS_DIST) && \
   $(call RELEASE_SIGN_ANDROID_APK,$(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk,$(_ABS_DIST)/robocop.apk)
 
-BACKGROUND_TESTS_PATH = $(call core_abspath,$(_ABS_DIST)/../mobile/android/tests/background/junit3)
+BACKGROUND_TESTS_PATH = $(abspath $(_ABS_DIST)/../mobile/android/tests/background/junit3)
 INNER_BACKGROUND_TESTS_PACKAGE= \
   $(call RELEASE_SIGN_ANDROID_APK,$(BACKGROUND_TESTS_PATH)/background-debug-unsigned-unaligned.apk,$(_ABS_DIST)/background.apk)
 endif
 else
 INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Android Robocop for you'
 INNER_BACKGROUND_TESTS_PACKAGE=echo 'Testing is disabled - No Android Background tests for you'
 endif
 
--- a/toolkit/mozapps/update/test/Makefile.in
+++ b/toolkit/mozapps/update/test/Makefile.in
@@ -1,13 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-TESTROOT = $(call core_abspath,$(DEPTH))/_tests/xpcshell/$(relativesrcdir)
+TESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/$(relativesrcdir)
 
 DEFINES += \
   -DAB_CD=$(AB_CD) \
   -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
   -DMOZ_APP_DISPLAYNAME="$(MOZ_APP_DISPLAYNAME)" \
   -DBIN_SUFFIX=$(BIN_SUFFIX) \
   -DNS_NO_XPCOM \
   -DMOZ_DEBUG=$(MOZ_DEBUG) \
--- a/toolkit/mozapps/update/test_svc/Makefile.in
+++ b/toolkit/mozapps/update/test_svc/Makefile.in
@@ -1,13 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-TESTROOT = $(call core_abspath,$(DEPTH))/_tests/xpcshell/$(relativesrcdir)
+TESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/$(relativesrcdir)
 
 DEFINES += \
   -DAB_CD=$(AB_CD) \
   -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
   -DMOZ_APP_DISPLAYNAME="$(MOZ_APP_DISPLAYNAME)" \
   -DBIN_SUFFIX=$(BIN_SUFFIX) \
   -DNS_NO_XPCOM \
   -DMOZ_DEBUG=$(MOZ_DEBUG) \
--- a/toolkit/xre/nsWindowsDllBlocklist.cpp
+++ b/toolkit/xre/nsWindowsDllBlocklist.cpp
@@ -130,16 +130,19 @@ static DllBlockInfo sWindowsDllBlocklist
   { "pmnx.dll", MAKE_VERSION(1, 3, 334, 9) },
   { "opnx.dll", MAKE_VERSION(1, 3, 334, 9) },
   { "prnx.dll", MAKE_VERSION(1, 3, 334, 9) },
 
   // Older belgian ID card software causes Firefox to crash or hang on
   // shutdown, bug 831285 and 918399.
   { "beid35cardlayer.dll", MAKE_VERSION(3, 5, 6, 6968) },
 
+  // bug 925459, bitguard crashes
+  { "bitguard.dll", MAKE_VERSION(2, 6, 1694, 24) },
+
   { nullptr, 0 }
 };
 
 #ifndef STATUS_DLL_NOT_FOUND
 #define STATUS_DLL_NOT_FOUND ((DWORD)0xC0000135L)
 #endif
 
 // define this for very verbose dll load debug spew
--- a/tools/mach_commands.py
+++ b/tools/mach_commands.py
@@ -189,8 +189,96 @@ class UUIDProvider(object):
             shutil.rmtree(tmpdir)
 
         updates = IDLUpdater(registry)
 
         for interface in interfaces:
             updates.add(interface)
 
         updates.update()
+
+@CommandProvider
+class PastebinProvider(object):
+    @Command('pastebin', category='misc',
+        description='Command line interface to pastebin.mozilla.org.')
+    @CommandArgument('--language', default=None,
+                     help='Language to use for syntax highlighting')
+    @CommandArgument('--poster', default=None,
+                     help='Specify your name for use with pastebin.mozilla.org')
+    @CommandArgument('--duration', default='day',
+                     choices=['d', 'day', 'm', 'month', 'f', 'forever'],
+                     help='Keep for specified duration (default: %(default)s)')
+    @CommandArgument('file', nargs='?', default=None,
+                     help='Specify the file to upload to pastebin.mozilla.org')
+
+    def pastebin(self, language, poster, duration, file):
+        import sys
+        import urllib
+        import urllib2
+
+        URL = 'http://pastebin.mozilla.org/'
+
+        FILE_TYPES = [{'value': 'text', 'name': 'None', 'extension': 'txt'},
+        {'value': 'bash', 'name': 'Bash', 'extension': 'sh'},
+        {'value': 'c', 'name': 'C', 'extension': 'c'},
+        {'value': 'cpp', 'name': 'C++', 'extension': 'cpp'},
+        {'value': 'html4strict', 'name': 'HTML', 'extension': 'html'},
+        {'value': 'javascript', 'name': 'Javascript', 'extension': 'js'},
+        {'value': 'javascript', 'name': 'Javascript', 'extension': 'jsm'},
+        {'value': 'lua', 'name': 'Lua', 'extension': 'lua'},
+        {'value': 'perl', 'name': 'Perl', 'extension': 'pl'},
+        {'value': 'php', 'name': 'PHP', 'extension': 'php'},
+        {'value': 'python', 'name': 'Python', 'extension': 'py'},
+        {'value': 'ruby', 'name': 'Ruby', 'extension': 'rb'},
+        {'value': 'css', 'name': 'CSS', 'extension': 'css'},
+        {'value': 'diff', 'name': 'Diff', 'extension': 'diff'},
+        {'value': 'ini', 'name': 'INI file', 'extension': 'ini'},
+        {'value': 'java', 'name': 'Java', 'extension': 'java'},
+        {'value': 'xml', 'name': 'XML', 'extension': 'xml'},
+        {'value': 'xml', 'name': 'XML', 'extension': 'xul'}]
+
+        lang = ''
+
+        if file:
+            try:
+                with open(file, 'r') as f:
+                    content = f.read()
+                # TODO: Use mime-types instead of extensions; suprocess('file <f_name>')
+                # Guess File-type based on file extension
+                extension = file.split('.')[-1]
+                for l in FILE_TYPES:
+                    if extension == l['extension']:
+                        print('Identified file as %s' % l['name'])
+                        lang = l['value']
+            except IOError:
+                print('ERROR. No such file')
+                return 1
+        else:
+            content = sys.stdin.read()
+        duration = duration[0]
+
+        if language:
+            lang = language
+
+
+        params = [
+            ('parent_pid', ''),
+            ('format', lang),
+            ('code2', content),
+            ('poster', poster),
+            ('expiry', duration),
+            ('paste', 'Send')]
+
+        data = urllib.urlencode(params)
+        print('Uploading ...')
+        try:
+            req = urllib2.Request(URL, data)
+            response = urllib2.urlopen(req)
+            http_response_code = response.getcode()
+            if http_response_code == 200:
+                print(response.geturl())
+            else:
+                print('Could not upload the file, '
+                      'HTTP Response Code %s' %(http_response_code))
+        except urllib2.URLError:
+            print('ERROR. Could not connect to pastebin.mozilla.org.')
+            return 1
+        return 0
--- a/tools/profiler/EHABIStackWalk.cpp
+++ b/tools/profiler/EHABIStackWalk.cpp
@@ -337,18 +337,29 @@ bool EHInterp::unwind() {
         mState[r] = *ptr++;
       if (lr)
         mState[R_LR] = *ptr++;
       continue;
     }
 
     // 1011000: Finish
     if (insn == I_FINISH) {
-      if (mState[R_PC] == 0)
+      if (mState[R_PC] == 0) {
         mState[R_PC] = mState[R_LR];
+        // Non-standard change (bug 916106): Prevent the caller from
+        // re-using LR.  Since the caller is by definition not a leaf
+        // routine, it will have to restore LR from somewhere to
+        // return to its own caller, so we can safely zero it here.
+        // This makes a difference only if an error in unwinding
+        // (e.g., caused by starting from within a prologue/epilogue)
+        // causes us to load a pointer to a leaf routine as LR; if we
+        // don't do something, we'll go into an infinite loop of
+        // "returning" to that same function.
+        mState[R_LR] = 0;
+      }
       return true;
     }
 
     // 1001nnnn: Set vsp = r[nnnn]
     if ((insn & M_MOVSP) == I_MOVSP) {
       vSP() = mState[insn & 0x0f];
       checkStack();
       continue;
--- a/uriloader/exthandler/tests/Makefile.in
+++ b/uriloader/exthandler/tests/Makefile.in
@@ -8,16 +8,16 @@ include $(topsrcdir)/config/config.mk
 
 LIBS +=		\
 		$(NSPR_LIBS) \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 ifdef MOZ_WIDGET_GTK
-export PERSONAL_MAILCAP=$(call core_abspath,$(srcdir))/mailcap
+export PERSONAL_MAILCAP=$(abspath $(srcdir))/mailcap
 endif
 
 # need the executable for running the xpcshell unit tests
 ifneq (,$(SIMPLE_PROGRAMS))
 libs::
 	$(INSTALL) $(SIMPLE_PROGRAMS) $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit
 endif
--- a/widget/cocoa/Makefile.in
+++ b/widget/cocoa/Makefile.in
@@ -18,17 +18,17 @@ libs:: $(addprefix $(NIB_DEST)/,$(NIB_FI
 
 $(NIB_DEST):
 	$(NSINSTALL) -D $@
 
 $(NIB_DEST)/%: $(srcdir)/resources/MainMenu.nib/% $(NIB_DEST)
 	$(INSTALL) $< $(NIB_DEST)
 
 # for objdir builds, symlink the cursors dir
-ABS_topsrcdir   := $(call core_abspath,$(topsrcdir))
+ABS_topsrcdir   := $(abspath $(topsrcdir))
 ifneq ($(ABS_topsrcdir),$(MOZ_BUILD_ROOT))
 export::
 	ln -fs $(srcdir)/cursors
 endif
 
 export::
 	$(INSTALL) $(srcdir)/cursors $(DIST)/bin/res
 
--- a/xpcom/base/nscore.h
+++ b/xpcom/base/nscore.h
@@ -320,28 +320,16 @@
  * IUnknown.
  */
 #ifdef XP_WIN
 typedef unsigned long nsrefcnt;
 #else
 typedef uint32_t nsrefcnt;
 #endif
 
-/* ------------------------------------------------------------------------ */
-/* Casting macros for hiding C++ features from older compilers */
-
-#ifndef __PRUNICHAR__
-#define __PRUNICHAR__
-  #if defined(WIN32)
-    typedef wchar_t PRUnichar;
-  #else
-    typedef uint16_t PRUnichar;
-  #endif
-#endif
-
 /*
  * Use these macros to do 64bit safe pointer conversions.
  */
 
 #define NS_PTR_TO_INT32(x)  ((int32_t)  (intptr_t) (x))
 #define NS_PTR_TO_UINT32(x) ((uint32_t) (intptr_t) (x))
 #define NS_INT32_TO_PTR(x)  ((void *)   (intptr_t) (x))
 
--- a/xpcom/tests/Makefile.in
+++ b/xpcom/tests/Makefile.in
@@ -34,15 +34,15 @@ install::
 	$(SYSINSTALL) $(IFLAGS1) $(srcdir)/test.properties $(DESTDIR)$(mozappdir)/res
 
 ifeq (,$(filter-out WINNT os2-emx, $(HOST_OS_ARCH)))
 getnativepath = $(call normalizepath,$(1))
 else
 getnativepath = $(1)
 endif
 
-abs_srcdir = $(call core_abspath,$(srcdir))
+abs_srcdir = $(abspath $(srcdir))
 
 regOrderDir="$(call getnativepath,$(abs_srcdir)/regorder)";
 
 check::
 	XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) \
 	  $(DIST)/bin/TestRegistrationOrder$(BIN_SUFFIX) $(regOrderDir)
--- a/xulrunner/installer/windows/Makefile.in
+++ b/xulrunner/installer/windows/Makefile.in
@@ -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/.
 
-CONFIG_DIR=$(call core_abspath,$(srcdir))
-OBJ_DIR=$(call core_abspath,$(DEPTH))
-SRC_DIR=$(call core_abspath,$(topsrcdir))
+CONFIG_DIR=$(abspath $(srcdir))
+OBJ_DIR=$(abspath $(DEPTH))
+SRC_DIR=$(abspath $(topsrcdir))
 
 include $(topsrcdir)/config/rules.mk
 
 export::
 	$(NSINSTALL) -D $(DIST)/branding
 	cp $(srcdir)/Header.bmp    $(DIST)/branding/Header.bmp
 	cp $(srcdir)/Watermrk.bmp  $(DIST)/branding/Watermrk.bmp