Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 17 Feb 2012 14:20:51 -0800
changeset 105849 75ec3cbf558c3a4342e6fba75e30e91692486676
parent 105848 99423ac2464380aed37b70fa7ea40201d5e0d111 (current diff)
parent 87075 bd3a2666218c25419a1c50c72cbf9b6cc616f26f (diff)
child 105850 6f0cf6e2bf8f3d3336ac23c3b3d5f971bfe69ce0
push id23447
push userdanderson@mozilla.com
push dateTue, 11 Sep 2012 17:34:27 +0000
treeherdermozilla-central@fdfaef738a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.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 from mozilla-central.
aclocal.m4
browser/base/content/browser.xul
browser/base/content/tabbrowser.xml
browser/components/sessionstore/src/nsSessionStore.js
config/autoconf.mk.in
configure.in
content/base/src/nsDOMFile.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
dom/workers/File.cpp
dom/workers/test/fileMozSlice_worker.js
dom/workers/test/fileReadMozSlice_worker.js
dom/workers/test/test_fileMozSlice.xul
dom/workers/test/test_fileReadMozSlice.xul
editor/composer/src/nsEditorSpellCheck.cpp
editor/libeditor/html/nsHTMLAnonymousUtils.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/harfbuzz/src/hb-ot-shape.cc
gfx/thebes/gfxPlatform.cpp
js/src/assembler/assembler/X86Assembler.h
js/src/configure.in
js/src/gc/Barrier.h
js/src/ion/Ion.cpp
js/src/ion/IonFrames.cpp
js/src/ion/arm/Assembler-arm.cpp
js/src/ion/shared/Assembler-x86-shared.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsbool.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsgcmark.cpp
js/src/jsgcmark.h
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jswrapper.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/xpcprivate.h
layout/base/nsPresShell.cpp
layout/build/nsLayoutModule.cpp
layout/build/nsLayoutStatics.cpp
layout/generic/nsInlineFrame.cpp
layout/generic/nsInlineFrame.h
layout/generic/nsObjectFrame.cpp
layout/reftests/canvas/reftest.list
layout/style/nsDOMCSSAttrDeclaration.cpp
layout/style/nsDOMCSSAttrDeclaration.h
layout/style/ua.css
media/libjpeg/cderror.h
media/libjpeg/cdjpeg.h
media/libjpeg/jconfig.h.in
media/libjpeg/simd/jsimdcfg.inc.h
media/libjpeg/transupp.h
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/sync/crypto/Cryptographer.java
mobile/android/base/sync/cryptographer/CryptoStatusBundle.java
mobile/android/base/sync/cryptographer/SyncCryptographer.java
mobile/android/base/sync/jpake/Gx4IsOneException.java
mobile/android/base/sync/jpake/JPakeUtils.java
mozglue/android/nsGeckoUtils.cpp
netwerk/test/TestProtocols.cpp
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/components/telemetry/TelemetryPing.js
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gtk2/nsWindow.cpp
widget/nsIWidget.h
widget/nsWidgetInitData.h
widget/windows/JumpListItem.cpp
widget/windows/nsFilePicker.cpp
widget/xpwidgets/nsBaseWidget.h
xpcom/base/nsCycleCollector.cpp
xpcom/io/nsLocalFileWin.cpp
xpfe/appshell/src/nsAppShellService.cpp
xpfe/appshell/src/nsXULWindow.cpp
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -12,16 +12,17 @@ builtin(include, build/autoconf/codeset.
 builtin(include, build/autoconf/altoptions.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
 builtin(include, build/autoconf/mozcommonheader.m4)dnl
 builtin(include, build/autoconf/acwinpaths.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/gcc-pr49911.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
+builtin(include, build/autoconf/compiler-opts.m4)dnl
 
 MOZ_PROG_CHECKMSYS()
 
 # Read the user's .mozconfig script.  We can't do this in
 # configure.in: autoconf puts the argument parsing code above anything
 # expanded from configure.in, and we need to get the configure options
 # from .mozconfig in place before that argument parsing code.
 MOZ_READ_MOZCONFIG(.)
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -425,8 +425,10 @@ pref("media.realtime_decoder.enabled", t
 // secondary bug isn't really worth investigating since it's obseleted
 // by bug 710563.
 pref("layout.frame_rate.precise", true);
 
 // Screen timeout in minutes
 pref("power.screen.timeout", 60);
 
 pref("full-screen-api.enabled", true);
+
+pref("media.volume.steps", 10);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -181,16 +181,34 @@ var shell = {
     if (this.isDebug) {
       Services.prefs.setBoolPref("layers.acceleration.draw-fps", true);
       Services.prefs.setBoolPref("nglayout.debug.paint_flashing", true);
     } else {
       Services.prefs.setBoolPref("layers.acceleration.draw-fps", false);
       Services.prefs.setBoolPref("nglayout.debug.paint_flashing", false);
     }
   },
+ 
+  changeVolume: function shell_changeVolume(aDelta) {
+    let audioManager = Cc["@mozilla.org/telephony/audiomanager;1"].getService(Ci.nsIAudioManager);
+
+    let steps = 10;
+    try {
+      steps = Services.prefs.getIntPref("media.volume.steps");
+      if (steps <= 0)
+        steps = 1;
+    } catch(e) {}
+
+    let volume = audioManager.masterVolume + aDelta / steps;
+    if (volume > 1)
+      volume = 1;
+    if (volume < 0)
+      volume = 0;
+    audioManager.masterVolume = volume;
+  },
 
   handleEvent: function shell_handleEvent(evt) {
     switch (evt.type) {
       case 'keypress':
         switch (evt.keyCode) {
           case evt.DOM_VK_HOME:
             this.sendEvent(content, 'home');
             break;
@@ -212,16 +230,22 @@ var shell = {
       case 'AppCommand':
         switch (evt.command) {
           case 'Menu':
             this.sendEvent(content, 'menu');
             break;
           case 'Search':
             this.toggleDebug();
             break;
+          case 'VolumeUp':
+            this.changeVolume(1);
+            break;
+          case 'VolumeDown':
+            this.changeVolume(-1);
+            break;
         }
         break;
       case 'load':
         this.contentBrowser.removeEventListener('load', this, true);
         this.turnScreenOn();
 
         let chromeWindow = window.QueryInterface(Ci.nsIDOMChromeWindow);
         chromeWindow.browserDOMWindow = new nsBrowserAccess();
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -85,16 +85,17 @@
         titlemodifier="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@"
         titlemodifier_normal="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@"
         titlemodifier_privatebrowsing="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@ &mainWindow.titlePrivateBrowsingSuffix;"
 #endif
         titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
         lightweightthemes="true"
         lightweightthemesfooter="browser-bottombox"
         windowtype="navigator:browser"
+        macanimationtype="document"
         screenX="4" screenY="4"
         browsingmode="normal"
         persist="screenX screenY width height sizemode">
 
 # All JS files which are not content (only) dependent that browser.xul
 # wishes to include *must* go into the global-scripts.inc file
 # so that they can be shared by macBrowserOverlay.xul.
 #include global-scripts.inc
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1261,16 +1261,22 @@
               }, 0, this.tabContainer);
             } else {
               setTimeout(function (tabContainer) {
                 if (t.pinned)
                   tabContainer._handleNewTab(t);
                 else {
                   t._animStartTime = Date.now();
                   t.setAttribute("fadein", "true");
+
+                  // This call to adjustTabstrip is redundant but needed so that
+                  // when opening a second tab, the first tab's close buttons
+                  // appears immediately rather than when the transition ends.
+                  if (tabContainer.childNodes.length == 2)
+                    tabContainer.adjustTabstrip();
                 }
               }, 0, this.tabContainer);
             }
 
             this.tabContainer.appendChild(t);
 
             // invalidate cache, because tabContainer is about to change
             this._browsers = null;
@@ -4050,17 +4056,17 @@
         ]]></body>
       </method>
 
       <method name="_calcMouseTargetRect">
         <body><![CDATA[
           let alignRight = false;
 
           if (getComputedStyle(document.documentElement).direction == "rtl")
-            alighRight = !alignRight;
+            alignRight = !alignRight;
 
           let rect = this.getBoundingClientRect();
           this._mouseTargetRect = {
             top:    rect.top,
             bottom: rect.bottom,
             left:   alignRight ? window.innerWidth - rect.width : 0,
             right:  alignRight ? window.innerWidth : rect.width
           };
--- a/browser/components/sessionstore/src/nsSessionStartup.js
+++ b/browser/components/sessionstore/src/nsSessionStartup.js
@@ -67,16 +67,17 @@
 /* :::::::: Constants and Helpers ::::::::::::::: */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource:///modules/TelemetryStopwatch.jsm");
 
 const STATE_RUNNING_STR = "running";
 const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 megabytes
 
 function debug(aMsg) {
   aMsg = ("SessionStartup: " + aMsg).replace(/\S{80}/g, "$&\n");
   Services.console.logStringMessage(aMsg);
 }
@@ -122,45 +123,51 @@ SessionStartup.prototype = {
       return;
 
     // get string containing session state
     let iniString = this._readStateFile(sessionFile);
     if (!iniString)
       return;
 
     // parse the session state into a JS object
+    // remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
+    if (iniString.charAt(0) == '(')
+      iniString = iniString.slice(1, -1);
+    let corruptFile = false;
     try {
-      // remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
-      if (iniString.charAt(0) == '(')
-        iniString = iniString.slice(1, -1);
+      this._initialState = JSON.parse(iniString);
+    }
+    catch (ex) {
+      debug("The session file contained un-parse-able JSON: " + ex);
+      // Try to eval.
+      // evalInSandbox will throw if iniString is not parse-able.
       try {
-        this._initialState = JSON.parse(iniString);
-      }
-      catch (exJSON) {
         var s = new Cu.Sandbox("about:blank", {sandboxName: 'nsSessionStartup'});
         this._initialState = Cu.evalInSandbox("(" + iniString + ")", s);
+      } catch(ex) {
+        debug("The session file contained un-eval-able JSON: " + ex);
+        corruptFile = true;
       }
+    }
+    Services.telemetry.getHistogramById("FX_SESSION_RESTORE_CORRUPT_FILE").add(corruptFile);
 
-      // If this is a normal restore then throw away any previous session
-      if (!doResumeSessionOnce)
-        delete this._initialState.lastSessionState;
-    }
-    catch (ex) { debug("The session file is invalid: " + ex); }
+    // If this is a normal restore then throw away any previous session
+    if (!doResumeSessionOnce)
+      delete this._initialState.lastSessionState;
 
     let resumeFromCrash = prefBranch.getBoolPref("sessionstore.resume_from_crash");
     let lastSessionCrashed =
       this._initialState && this._initialState.session &&
       this._initialState.session.state &&
       this._initialState.session.state == STATE_RUNNING_STR;
 
     // Report shutdown success via telemetry. Shortcoming here are
     // being-killed-by-OS-shutdown-logic, shutdown freezing after
     // session restore was written, etc.
-    let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
-    Telemetry.getHistogramById("SHUTDOWN_OK").add(!lastSessionCrashed);
+    Services.telemetry.getHistogramById("SHUTDOWN_OK").add(!lastSessionCrashed);
 
     // set the startup type
     if (lastSessionCrashed && resumeFromCrash)
       this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
     else if (!lastSessionCrashed && doResumeSession)
       this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
     else if (this._initialState)
       this._sessionType = Ci.nsISessionStartup.DEFER_SESSION;
@@ -291,19 +298,21 @@ SessionStartup.prototype = {
   /**
    * Reads a session state file into a string and lets
    * observers modify the state before it's being used
    *
    * @param aFile is any nsIFile
    * @returns a session state string
    */
   _readStateFile: function sss_readStateFile(aFile) {
+    TelemetryStopwatch.start("FX_SESSION_RESTORE_READ_FILE_MS");
     var stateString = Cc["@mozilla.org/supports-string;1"].
                         createInstance(Ci.nsISupportsString);
     stateString.data = this._readFile(aFile) || "";
+    TelemetryStopwatch.finish("FX_SESSION_RESTORE_READ_FILE_MS");
 
     Services.obs.notifyObservers(stateString, "sessionstore-state-read", "");
 
     return stateString.data;
   },
 
   /**
    * reads a file into a string
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -126,16 +126,17 @@ const TAB_EVENTS = ["TabOpen", "TabClose
 #endif
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 // debug.js adds NS_ASSERT. cf. bug 669196
 Cu.import("resource://gre/modules/debug.js");
 
 Cu.import("resource:///modules/TelemetryTimestamps.jsm");
+Cu.import("resource:///modules/TelemetryStopwatch.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
 XPCOMUtils.defineLazyGetter(this, "ScratchpadManager", function() {
   Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
@@ -3648,16 +3649,18 @@ SessionStoreService.prototype = {
     // if we're in private browsing mode, do nothing
     if (this._inPrivateBrowsing)
       return;
 
     // If crash recovery is disabled, we only want to resume with pinned tabs
     // if we crash.
     let pinnedOnly = this._loadState == STATE_RUNNING && !this._resume_from_crash;
 
+    TelemetryStopwatch.start("FX_SESSION_RESTORE_COLLECT_DATA_MS");
+
     var oState = this._getCurrentState(aUpdateAll, pinnedOnly);
     if (!oState)
       return;
 
 #ifndef XP_MACOSX
     // We want to restore closed windows that are marked with _shouldRestore.
     // We're doing this here because we want to control this only when saving
     // the file.
@@ -3686,26 +3689,30 @@ SessionStoreService.prototype = {
         Services.prefs.savePrefFile(null);
       }
     }
 
     // Persist the last session if we deferred restoring it
     if (this._lastSessionState)
       oState.lastSessionState = this._lastSessionState;
 
+    TelemetryStopwatch.finish("FX_SESSION_RESTORE_COLLECT_DATA_MS");
+
     this._saveStateObject(oState);
   },
 
   /**
    * write a state object to disk
    */
   _saveStateObject: function sss_saveStateObject(aStateObj) {
+    TelemetryStopwatch.start("FX_SESSION_RESTORE_SERIALIZE_DATA_MS");
     var stateString = Cc["@mozilla.org/supports-string;1"].
                         createInstance(Ci.nsISupportsString);
     stateString.data = this._toJSONString(aStateObj);
+    TelemetryStopwatch.finish("FX_SESSION_RESTORE_SERIALIZE_DATA_MS");
 
     Services.obs.notifyObservers(stateString, "sessionstore-state-write", "");
 
     // don't touch the file if an observer has deleted all state data
     if (stateString.data)
       this._writeFile(this._sessionFile, stateString.data);
 
     this._lastSaveTime = Date.now();
@@ -3804,17 +3811,17 @@ SessionStoreService.prototype = {
    *        Object containing session data
    */
   _openWindowWithState: function sss_openWindowWithState(aState) {
     var argString = Cc["@mozilla.org/supports-string;1"].
                     createInstance(Ci.nsISupportsString);
     argString.data = "";
 
     // Build feature string
-    let features = "chrome,dialog=no,all";
+    let features = "chrome,dialog=no,macsuppressanimation,all";
     let winState = aState.windows[0];
     WINDOW_ATTRIBUTES.forEach(function(aFeature) {
       // Use !isNaN as an easy way to ignore sizemode and check for numbers
       if (aFeature in winState && !isNaN(winState[aFeature]))
         features += "," + aFeature + "=" + winState[aFeature];
     });
 
     var window =
@@ -4422,31 +4429,33 @@ SessionStoreService.prototype = {
   /**
    * write file to disk
    * @param aFile
    *        nsIFile
    * @param aData
    *        String data
    */
   _writeFile: function sss_writeFile(aFile, aData) {
+    TelemetryStopwatch.start("FX_SESSION_RESTORE_WRITE_FILE_MS");
     // Initialize the file output stream.
     var ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
                   createInstance(Ci.nsIFileOutputStream);
     ostream.init(aFile, 0x02 | 0x08 | 0x20, 0600, ostream.DEFER_OPEN);
 
     // Obtain a converter to convert our data to a UTF-8 encoded input stream.
     var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
                     createInstance(Ci.nsIScriptableUnicodeConverter);
     converter.charset = "UTF-8";
 
     // Asynchronously copy the data to the file.
     var istream = converter.convertToInputStream(aData);
     var self = this;
     NetUtil.asyncCopy(istream, ostream, function(rc) {
       if (Components.isSuccessCode(rc)) {
+        TelemetryStopwatch.finish("FX_SESSION_RESTORE_WRITE_FILE_MS");
         Services.obs.notifyObservers(null,
                                      "sessionstore-state-write-complete",
                                      "");
       }
     });
   }
 };
 
copy from browser/config/mozconfigs/macosx-universal/nightly
copy to browser/config/mozconfigs/macosx-lion-universal/nightly
--- a/browser/config/mozconfigs/macosx-universal/nightly
+++ b/browser/config/mozconfigs/macosx-lion-universal/nightly
@@ -10,14 +10,15 @@ ac_add_options --disable-install-strip
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
-mk_add_options MOZ_MAKE_FLAGS="-j4"
+mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 ac_add_options --with-macbundlename-prefix=Firefox
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
+ac_add_options --with-ccache
copy from browser/config/mozconfigs/macosx-universal/release
copy to browser/config/mozconfigs/macosx-lion-universal/release
--- a/browser/config/mozconfigs/macosx-universal/release
+++ b/browser/config/mozconfigs/macosx-lion-universal/release
@@ -12,8 +12,9 @@ export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
+ac_add_options --with-ccache
copy from browser/config/mozconfigs/macosx-universal/shark
copy to browser/config/mozconfigs/macosx-lion-universal/shark
--- a/browser/config/mozconfigs/macosx-universal/shark
+++ b/browser/config/mozconfigs/macosx-lion-universal/shark
@@ -7,19 +7,20 @@ ac_add_options --enable-application=brow
 
 ac_add_options --disable-tests
 ac_add_options --disable-install-strip
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # Enable parallel compiling
-mk_add_options MOZ_MAKE_FLAGS="-j4"
+mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 # shark specific options
 ac_add_options --enable-shark
 ac_add_options --enable-dtrace
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL="shark"
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
+ac_add_options --with-ccache
copy from browser/config/mozconfigs/macosx32/debug
copy to browser/config/mozconfigs/macosx32-lion/debug
--- a/browser/config/mozconfigs/macosx32/debug
+++ b/browser/config/mozconfigs/macosx32-lion/debug
@@ -1,11 +1,12 @@
 . $topsrcdir/build/macosx/mozconfig.leopard
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 
 # Enable parallel compiling
-mk_add_options MOZ_MAKE_FLAGS="-j4"
+mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 ac_add_options --with-macbundlename-prefix=Firefox
+ac_add_options --with-ccache
copy from browser/config/mozconfigs/macosx64/debug
copy to browser/config/mozconfigs/macosx64-lion/debug
--- a/browser/config/mozconfigs/macosx64/debug
+++ b/browser/config/mozconfigs/macosx64-lion/debug
@@ -1,16 +1,17 @@
 . $topsrcdir/build/macosx/common
 
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-accessibility
 
 # Enable parallel compiling
-mk_add_options MOZ_MAKE_FLAGS="-j4"
+mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 ac_add_options --with-macbundlename-prefix=Firefox
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
+ac_add_options --with-ccache
copy from browser/config/mozconfigs/macosx64/l10n-mozconfig
copy to browser/config/mozconfigs/macosx64-lion/l10n-mozconfig
--- a/browser/config/mozconfigs/macosx64/l10n-mozconfig
+++ b/browser/config/mozconfigs/macosx64-lion/l10n-mozconfig
@@ -1,4 +1,5 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
+ac_add_options --with-ccache
--- a/browser/devtools/scratchpad/scratchpad.xul
+++ b/browser/devtools/scratchpad/scratchpad.xul
@@ -46,16 +46,17 @@
 <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
 <?xul-overlay href="chrome://browser/content/source-editor-overlay.xul"?>
 
 <window id="main-window"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="&window.title;"
         windowtype="devtools:scratchpad"
+        macanimationtype="document"
         screenX="4" screenY="4"
         width="640" height="480"
         persist="screenX screenY width height sizemode">
 
 <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
 <script type="application/javascript" src="chrome://browser/content/scratchpad.js"/>
 
 <commandset id="editMenuCommands"/>
--- a/browser/makefiles.sh
+++ b/browser/makefiles.sh
@@ -83,16 +83,22 @@ browser/fuel/public/Makefile
 browser/fuel/src/Makefile
 browser/installer/Makefile
 browser/locales/Makefile
 browser/modules/Makefile
 browser/themes/Makefile
 $MOZ_BRANDING_DIRECTORY/Makefile
 $MOZ_BRANDING_DIRECTORY/content/Makefile
 $MOZ_BRANDING_DIRECTORY/locales/Makefile
+toolkit/locales/Makefile
+extensions/spellcheck/locales/Makefile
+intl/locales/Makefile
+netwerk/locales/Makefile
+dom/locales/Makefile
+security/manager/locales/Makefile
 "
 
 if [ "$MOZ_SAFE_BROWSING" ]; then
   add_makefiles "
     browser/components/safebrowsing/Makefile
   "
 fi
 
new file mode 100644
--- /dev/null
+++ b/build/autoconf/compiler-opts.m4
@@ -0,0 +1,13 @@
+dnl Add compiler specific options
+
+AC_DEFUN([MOZ_COMPILER_OPTS],
+[
+if test "$CLANG_CXX"; then
+    ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
+    ## returned by C functions. This is possible because we use knowledge about the ABI
+    ## to typedef it to a C type with the same layout when the headers are included
+    ## from C.
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-return-type-c-linkage"
+fi
+])
+
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -1,10 +1,23 @@
 #!/usr/bin/python
 
+# The directories end up in the debug info, so the easy way of getting
+# a reproducible build is to run it in a know absolute directory.
+# We use a directory in /builds/slave because the mozilla infrastructure
+# cleans it up automatically.
+base_dir = "/builds/slave/moz-toolschain"
+
+source_dir = base_dir + "/src"
+build_dir  = base_dir + "/build"
+aux_inst_dir = build_dir + '/aux_inst'
+old_make = aux_inst_dir + '/bin/make'
+
+##############################################
+
 import urllib
 import os
 import os.path
 import shutil
 import tarfile
 import subprocess
 
 def download_uri(uri):
@@ -28,27 +41,31 @@ def run_in(path, args):
     check_run(args)
     os.chdir(d)
 
 def patch(patch, plevel, srcdir):
     patch = os.path.realpath(patch)
     check_run(['patch', '-d', srcdir, '-p%s' % plevel, '-i', patch, '--fuzz=0',
                '-s'])
 
-def build_package(package_source_dir, package_build_dir, configure_args):
+def build_package(package_source_dir, package_build_dir, configure_args,
+                   make = old_make):
     os.mkdir(package_build_dir)
     run_in(package_build_dir,
            ["%s/configure" % package_source_dir] + configure_args)
-    run_in(package_build_dir, ["make", "-j8"])
-    run_in(package_build_dir, ["make", "install"])
+    run_in(package_build_dir, [make, "-j8"])
+    run_in(package_build_dir, [make, "install"])
 
-def build_tar(base_dir, tar_inst_dir):
+def build_aux_tools(base_dir):
+    make_build_dir = base_dir + '/make_build'
+    build_package(make_source_dir, make_build_dir,
+                  ["--prefix=%s" % aux_inst_dir], "make")
     tar_build_dir = base_dir + '/tar_build'
     build_package(tar_source_dir, tar_build_dir,
-                  ["--prefix=%s" % tar_inst_dir])
+                  ["--prefix=%s" % aux_inst_dir])
 
 def with_env(env, f):
     old_env = os.environ.copy()
     os.environ.update(env)
     f()
     os.environ.clear()
     os.environ.update(old_env)
 
@@ -128,94 +145,90 @@ def build_one_stage_aux(stage_dir, is_st
 
 def build_tar_package(tar, name, base, directory):
     name = os.path.realpath(name)
     run_in(base, [tar, "-cf", name, "--mtime=2012-01-01", "--owner=root",
                   directory])
 
 ##############################################
 
-# The directories end up in the debug info, so the easy way of getting
-# a reproducible build is to run it in a know absolute directory.
-# We use a directory in /builds/slave because the mozilla infrastructure
-# cleans it up automatically.
-base_dir = "/builds/slave/moz-toolschain"
-
-source_dir = base_dir + "/src"
-build_dir  = base_dir + "/build"
-
 def build_source_dir(prefix, version):
     return source_dir + '/' + prefix + version
 
 binutils_version = "2.21.1"
-glibc_version = "2.12.2" #FIXME: should probably use 2.5.1
+glibc_version = "2.7" #FIXME: should probably use 2.5.1
 tar_version = "1.26"
+make_version = "3.81"
 gcc_version = "4.5.2"
 mpfr_version = "2.4.2"
 gmp_version = "5.0.1"
 mpc_version = "0.8.1"
 
 binutils_source_uri = "http://ftp.gnu.org/gnu/binutils/binutils-%sa.tar.bz2" % \
     binutils_version
 glibc_source_uri = "http://ftp.gnu.org/gnu/glibc/glibc-%s.tar.bz2" % \
     glibc_version
 tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \
     tar_version
+make_source_uri = "http://ftp.gnu.org/gnu/make/make-%s.tar.bz2" % \
+    make_version
 gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
     (gcc_version, gcc_version)
 mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
     (mpfr_version, mpfr_version)
 gmp_source_uri = "http://ftp.gnu.org/gnu/gmp/gmp-%s.tar.bz2" % gmp_version
 mpc_source_uri = "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % \
     mpc_version
 
 binutils_source_tar = download_uri(binutils_source_uri)
 glibc_source_tar = download_uri(glibc_source_uri)
 tar_source_tar = download_uri(tar_source_uri)
+make_source_tar = download_uri(make_source_uri)
 mpc_source_tar = download_uri(mpc_source_uri)
 mpfr_source_tar = download_uri(mpfr_source_uri)
 gmp_source_tar = download_uri(gmp_source_uri)
 gcc_source_tar = download_uri(gcc_source_uri)
 
 binutils_source_dir  = build_source_dir('binutils-', binutils_version)
 glibc_source_dir  = build_source_dir('glibc-', glibc_version)
 tar_source_dir  = build_source_dir('tar-', tar_version)
+make_source_dir  = build_source_dir('make-', make_version)
 mpc_source_dir  = build_source_dir('mpc-', mpc_version)
 mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
 gmp_source_dir  = build_source_dir('gmp-', gmp_version)
 gcc_source_dir  = build_source_dir('gcc-', gcc_version)
 
 if not os.path.exists(source_dir):
     os.makedirs(source_dir)
     extract(binutils_source_tar, source_dir)
     patch('binutils-deterministic.patch', 1, binutils_source_dir)
     extract(glibc_source_tar, source_dir)
     patch('glibc-deterministic.patch', 1, glibc_source_dir)
     run_in(glibc_source_dir, ["autoconf"])
     extract(tar_source_tar, source_dir)
+    extract(make_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('pr49911.diff', 1, gcc_source_dir)
     patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
 
 if os.path.exists(build_dir):
     shutil.rmtree(build_dir)
 os.makedirs(build_dir)
 
-tar_inst_dir = build_dir + '/tar_inst'
-build_tar(build_dir, tar_inst_dir)
+build_aux_tools(build_dir)
 
 stage1_dir = build_dir + '/stage1'
 build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True)
 
 stage1_tool_inst_dir = stage1_dir + '/inst'
 stage2_dir = build_dir + '/stage2'
 build_one_stage({"CC"     : stage1_tool_inst_dir + "/bin/gcc",
                  "CXX"    : stage1_tool_inst_dir + "/bin/g++",
                  "AR"     : stage1_tool_inst_dir + "/bin/ar",
                  "RANLIB" : "true" },
                 stage2_dir, False)
 
-build_tar_package(tar_inst_dir + "/bin/tar",
+build_tar_package(aux_inst_dir + "/bin/tar",
                   "toolchain.tar", stage2_dir, "inst")
--- a/build/unix/build-toolchain/glibc-deterministic.patch
+++ b/build/unix/build-toolchain/glibc-deterministic.patch
@@ -1,36 +1,78 @@
 diff -ru a/configure.in b/configure.in
 --- a/configure.in	2011-01-17 23:34:07.000000000 -0500
 +++ b/configure.in	2012-01-25 20:40:27.919485606 -0500
-@@ -2230,6 +2230,7 @@
+@@ -841,14 +841,6 @@
+ LIBC_PROG_BINUTILS
+ AC_SUBST(MIG)dnl Needed by sysdeps/mach/configure.in
+ 
+-# Accept binutils 2.13 or newer.
+-AC_CHECK_PROG_VER(AS, $AS, --version,
+-		  [GNU assembler.* \([0-9]*\.[0-9.]*\)],
+-		  [2.1[3-9]*], AS=: critic_missing="$critic_missing as")
+-AC_CHECK_PROG_VER(LD, $LD, --version,
+-		  [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)],
+-		  [2.1[3-9]*], LD=: critic_missing="$critic_missing ld")
+-
+ # We need the physical current working directory.  We cannot use the
+ # "pwd -P" shell builtin since that's not portable.  Instead we try to
+ # find a pwd binary.  Note that assigning to the PWD environment
+@@ -2175,6 +2167,7 @@
  fi
  AC_SUBST(old_glibc_headers)
  
 +libc_cv_slibdir=${prefix}/lib64
  AC_SUBST(libc_cv_slibdir)
  AC_SUBST(libc_cv_localedir)
  AC_SUBST(libc_cv_sysconfdir)
 diff -ru a/csu/Makefile b/csu/Makefile
 --- a/csu/Makefile	2011-01-17 23:34:07.000000000 -0500
 +++ b/csu/Makefile	2012-01-23 13:58:28.957792633 -0500
-@@ -234,8 +234,7 @@
+@@ -223,8 +223,7 @@
  		   if [ -z "$$os" ]; then \
  		     os=Linux; \
  		   fi; \
 -		   printf '"Compiled on a %s %s system on %s.\\n"\n' \
 -			  "$$os" "$$version" "`date +%Y-%m-%d`";; \
 +                   ;; \
  	   *) ;; \
  	 esac; \
  	 files="$(all-Banner-files)";				\
+diff -ru a/elf/Makefile b/elf/Makefile
+--- a/elf/Makefile	2008-10-31 16:35:11.000000000 -0400
++++ b/elf/Makefile	2012-02-16 12:20:00.038593752 -0500
+@@ -295,20 +295,13 @@
+ z-now-yes = -Wl,-z,now
+ 
+ $(objpfx)ld.so: $(objpfx)librtld.os $(ld-map)
+-	@rm -f $@.lds
+-	$(LINK.o) -nostdlib -nostartfiles -shared $(z-now-$(bind-now))	\
+-		  $(LDFLAGS-rtld) -Wl,-z,defs -Wl,--verbose 2>&1 |	\
+-		  LC_ALL=C \
+-		  sed -e '/^=========/,/^=========/!d;/^=========/d'	\
+-		      -e 's/\. = 0 + SIZEOF_HEADERS;/& _begin = . - SIZEOF_HEADERS;/' \
+-		  > $@.lds
+ 	$(LINK.o) -nostdlib -nostartfiles -shared -o $@			\
+ 		  $(LDFLAGS-rtld) -Wl,-z,defs $(z-now-$(bind-now))	\
+ 		  $(filter-out $(map-file),$^) $(load-map-file)		\
+-		  -Wl,-soname=$(rtld-installed-name) -T $@.lds
+-	rm -f $@.lds
++		  -Wl,-soname=$(rtld-installed-name)			\
++		  -Wl,-defsym=_begin=0
+ 	readelf -s $@ \
+-	  | awk '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }'
++	  | $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }'
+ 
+ # interp.c exists just to get this string into the libraries.
+ CFLAGS-interp.c = -D'RUNTIME_LINKER="$(slibdir)/$(rtld-installed-name)"' \
 diff -ru a/Makerules b/Makerules
 --- a/Makerules	2011-01-17 23:34:07.000000000 -0500
 +++ b/Makerules	2012-01-30 08:47:56.565068903 -0500
-@@ -992,9 +992,9 @@
+@@ -977,9 +977,9 @@
  	 echo '   Use the shared library, but some functions are only in';\
  	 echo '   the static library, so try that secondarily.  */';\
  	 cat $<; \
 -	 echo 'GROUP ( $(slibdir)/libc.so$(libc.so-version)' \
 -	      '$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)$(libc-name))'\
 -	      ' AS_NEEDED (' $(slibdir)/$(rtld-installed-name) ') )' \
 +	 echo 'GROUP ( libc.so$(libc.so-version)' \
 +	      '$(patsubst %,$(libtype.oS),$(libprefix)$(libc-name))'\
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -176,16 +176,17 @@ VPX_AS_CONVERSION = @VPX_AS_CONVERSION@
 VPX_ASM_SUFFIX = @VPX_ASM_SUFFIX@
 VPX_X86_ASM = @VPX_X86_ASM@
 VPX_ARM_ASM = @VPX_ARM_ASM@
 VPX_NEED_OBJ_INT_EXTRACT = @VPX_NEED_OBJ_INT_EXTRACT@
 LIBJPEG_TURBO_AS = @LIBJPEG_TURBO_AS@
 LIBJPEG_TURBO_ASFLAGS = @LIBJPEG_TURBO_ASFLAGS@
 LIBJPEG_TURBO_X86_ASM = @LIBJPEG_TURBO_X86_ASM@
 LIBJPEG_TURBO_X64_ASM = @LIBJPEG_TURBO_X64_ASM@
+LIBJPEG_TURBO_ARM_ASM = @LIBJPEG_TURBO_ARM_ASM@
 NS_PRINTING = @NS_PRINTING@
 MOZ_PDF_PRINTING = @MOZ_PDF_PRINTING@
 MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
 MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
 MOC = @MOC@
 RCC = @RCC@
 MOZ_NSS_PATCH = @MOZ_NSS_PATCH@
 MOZ_WEBGL = @MOZ_WEBGL@
--- a/config/optimizejars.py
+++ b/config/optimizejars.py
@@ -30,17 +30,17 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-import sys, os, subprocess, struct
+import sys, os, subprocess, struct, re
 
 local_file_header = [
     ("signature", "uint32"),
     ("min_version", "uint16"),
     ("general_flag", "uint16"),
     ("compression", "uint16"),
     ("lastmod_time", "uint16"),
     ("lastmod_date", "uint16"),
@@ -324,35 +324,37 @@ def optimizejar(jar, outjar, inlog = Non
                               reordered_count, len(central_directory), outjar)
     outfd.close()
     return outlog
         
 if len(sys.argv) != 5:
     print "Usage: --optimize|--deoptimize %s JAR_LOG_DIR IN_JAR_DIR OUT_JAR_DIR" % sys.argv[0]
     exit(1)
 
+jar_regex = re.compile("\\.jar?$")
+
 def optimize(JAR_LOG_DIR, IN_JAR_DIR, OUT_JAR_DIR):
     ls = os.listdir(IN_JAR_DIR)
     for jarfile in ls:
-        if not jarfile.endswith(".jar"):
+        if not re.search(jar_regex, jarfile):
             continue
         injarfile = os.path.join(IN_JAR_DIR, jarfile)
         outjarfile = os.path.join(OUT_JAR_DIR, jarfile) 
         logfile = os.path.join(JAR_LOG_DIR, jarfile + ".log")
         if not os.path.isfile(logfile):
             logfile = None
         optimizejar(injarfile, outjarfile, logfile)
 
 def deoptimize(JAR_LOG_DIR, IN_JAR_DIR, OUT_JAR_DIR):
     if not os.path.exists(JAR_LOG_DIR):
         os.makedirs(JAR_LOG_DIR)
 
     ls = os.listdir(IN_JAR_DIR)
     for jarfile in ls:
-        if not jarfile.endswith(".jar"):
+        if not re.search(jar_regex, jarfile):
             continue
         injarfile = os.path.join(IN_JAR_DIR, jarfile)
         outjarfile = os.path.join(OUT_JAR_DIR, jarfile) 
         logfile = os.path.join(JAR_LOG_DIR, jarfile + ".log")
         log = optimizejar(injarfile, outjarfile, None)
         open(logfile, "wb").write("\n".join(log))
 
 def main():        
--- a/configure.in
+++ b/configure.in
@@ -3338,16 +3338,17 @@ fi         # GNU_CC
 if test "$SOLARIS_SUNPRO_CC"; then
 VISIBILITY_FLAGS='-xldscope=hidden'
 fi         # Sun Studio on Solaris
 
 AC_SUBST(WRAP_SYSTEM_INCLUDES)
 AC_SUBST(VISIBILITY_FLAGS)
 
 MOZ_GCC_PR49911
+MOZ_COMPILER_OPTS
 
 dnl Check for __force_align_arg_pointer__ for SSE2 on gcc
 dnl ========================================================
 if test "$GNU_CC"; then
   CFLAGS_save="${CFLAGS}"
   CFLAGS="${CFLAGS} -Werror"
   AC_CACHE_CHECK(for __force_align_arg_pointer__ attribute,
                  ac_cv_force_align_arg_pointer,
@@ -4607,16 +4608,17 @@ VPX_AS_DASH_C_FLAG=
 VPX_AS_CONVERSION=
 VPX_ASM_SUFFIX=
 VPX_X86_ASM=
 VPX_ARM_ASM=
 LIBJPEG_TURBO_AS=
 LIBJPEG_TURBO_ASFLAGS=
 LIBJPEG_TURBO_X86_ASM=
 LIBJPEG_TURBO_X64_ASM=
+LIBJPEG_TURBO_ARM_ASM=
 MOZ_PANGO=1
 MOZ_PERMISSIONS=1
 MOZ_PLACES=1
 MOZ_PREF_EXTENSIONS=1
 MOZ_PROFILELOCKING=1
 MOZ_PSM=1
 MOZ_REFLOW_PERF=
 MOZ_SAFE_BROWSING=
@@ -6166,48 +6168,61 @@ if test -n "$MOZ_LIBJPEG_TURBO"; then
   WINNT:x86|WINNT:i?86)
     LIBJPEG_TURBO_ASFLAGS="-f win32 -rnasm -pnasm -DPIC -DWIN32"
     LIBJPEG_TURBO_X86_ASM=1
   ;;
   WINNT:x86_64)
     LIBJPEG_TURBO_ASFLAGS="-f win64 -rnasm -pnasm -D__x86_64__ -DPIC -DWIN64 -DMSVC"
     LIBJPEG_TURBO_X64_ASM=1
   ;;
+  *:arm*)
+    LIBJPEG_TURBO_ASFLAGS="-march=armv7-a -mfpu=neon"
+    LIBJPEG_TURBO_ARM_ASM=1
+  ;;
   esac
 
 fi
 
-dnl If we're on a system which supports libjpeg-turbo's asm routines and
-dnl --disable-libjpeg-turbo wasn't passed, check for yasm, and error out if it
-dnl doesn't exist or we have too old of a version.
+dnl If we're on an x86 or x64 system which supports libjpeg-turbo's asm routines
+dnl and --disable-libjpeg-turbo wasn't passed, check for Yasm, and error out if
+dnl it doesn't exist or we have too old of a version.
 if test -n "$LIBJPEG_TURBO_X86_ASM" -o -n "$LIBJPEG_TURBO_X64_ASM" ; then
-    AC_MSG_CHECKING([for YASM assembler])
+    AC_MSG_CHECKING([for Yasm assembler])
     AC_CHECK_PROGS(LIBJPEG_TURBO_AS, yasm, "")
 
     if test -z "$LIBJPEG_TURBO_AS" ; then
-        AC_MSG_ERROR([yasm is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you do not appear to have yasm installed.  Either install it or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder.  See https://developer.mozilla.org/en/YASM for more details.])
+        AC_MSG_ERROR([Yasm is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you do not appear to have Yasm installed.  Either install it or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder.  See https://developer.mozilla.org/en/YASM for more details.])
     fi
 
     dnl Check that we have the right yasm version.  We require 1.0.1 or newer
     dnl on Linux and 1.1 or newer everywhere else.
     if test "$OS_ARCH" = "Linux" ; then
         if test "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -eq "0" -a "$_YASM_RELEASE" -lt "1" \) ; then
-            AC_MSG_ERROR([yasm 1.0.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.$_YASM_RELEASE.  Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder.  See https://developer.mozilla.org/en/YASM for more details.])
+            AC_MSG_ERROR([Yasm 1.0.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.$_YASM_RELEASE.  Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder.  See https://developer.mozilla.org/en/YASM for more details.])
         fi
     else
         if test "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -lt "1" \) ; then
-            AC_MSG_ERROR([yasm 1.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.  Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder.  See https://developer.mozilla.org/en/YASM for more details.])
+            AC_MSG_ERROR([Yasm 1.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.  Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder.  See https://developer.mozilla.org/en/YASM for more details.])
         fi
     fi
 fi
 
+dnl If we're on an ARM system which supports libjpeg-turbo's asm routines and
+dnl --disable-libjpeg-turbo wasn't passed, use the C compiler as the assembler.
+if test -n "$LIBJPEG_TURBO_ARM_ASM" ; then
+    echo "Using $AS as the assembler for ARM code."
+    LIBJPEG_TURBO_AS=$AS
+fi
+
 if test -n "$LIBJPEG_TURBO_X86_ASM"; then
     AC_DEFINE(LIBJPEG_TURBO_X86_ASM)
 elif test -n "$LIBJPEG_TURBO_X64_ASM"; then
     AC_DEFINE(LIBJPEG_TURBO_X64_ASM)
+elif test -n "$LIBJPEG_TURBO_ARM_ASM"; then
+    AC_DEFINE(LIBJPEG_TURBO_ARM_ASM)
 elif test -n "$MOZ_LIBJPEG_TURBO"; then
     dnl Warn if we're not building the optimized routines, even though the user
     dnl didn't specify --disable-libjpeg-turbo.
     AC_MSG_WARN([No assembler or assembly support for libjpeg-turbo.  Using unoptimized C routines.])
 fi
 
 dnl ========================================================
 dnl = Enable compilation of specific extension modules
@@ -8751,16 +8766,17 @@ AC_SUBST(VPX_ASM_SUFFIX)
 AC_SUBST(VPX_X86_ASM)
 AC_SUBST(VPX_ARM_ASM)
 AC_SUBST(VPX_NEED_OBJ_INT_EXTRACT)
 AC_SUBST(MOZ_INSTRUMENT_EVENT_LOOP)
 AC_SUBST(LIBJPEG_TURBO_AS)
 AC_SUBST(LIBJPEG_TURBO_ASFLAGS)
 AC_SUBST(LIBJPEG_TURBO_X86_ASM)
 AC_SUBST(LIBJPEG_TURBO_X64_ASM)
+AC_SUBST(LIBJPEG_TURBO_ARM_ASM)
 
 AC_MSG_CHECKING([for posix_fallocate])
 AC_TRY_LINK([#define _XOPEN_SOURCE 600
   #include <fcntl.h>],
                  [posix_fallocate(0, 0, 0);],
                  [ac_cv___posix_fallocate=true],
                  [ac_cv___posix_fallocate=false])
 
--- a/content/base/crashtests/700512-worker.js
+++ b/content/base/crashtests/700512-worker.js
@@ -1,7 +1,7 @@
 onmessage = function(event) {
   var blob = event.data;
 
-  blob.mozSlice(1, 5);
+  blob.slice(1, 5);
 
   postMessage("done");
 }
--- a/content/base/public/nsIDOMFile.idl
+++ b/content/base/public/nsIDOMFile.idl
@@ -66,19 +66,19 @@ interface nsIDOMBlob : nsISupports
   readonly attribute unsigned long long size;
   readonly attribute DOMString type;
 
   [noscript] readonly attribute nsIInputStream internalStream;
   // The caller is responsible for releasing the internalUrl from the
   // blob: protocol handler
   [noscript] DOMString getInternalUrl(in nsIPrincipal principal);
 
-  [optional_argc] nsIDOMBlob mozSlice([optional] in long long start,
-                                      [optional] in long long end,
-                                      [optional] in DOMString contentType);
+  [optional_argc] nsIDOMBlob slice([optional] in long long start,
+                                   [optional] in long long end,
+                                   [optional] in DOMString contentType);
 
   // Get internal id of stored file. Returns -1 if it is not a stored file.
   // Intended only for testing. It can be called on any thread.
   [notxpcom] long long getFileId();
 
   // Called when the blob was successfully stored in a database or when
   // the blob is initialized from a database. It can be called on any thread.
   [notxpcom] void addFileInfo(in FileInfo aFileInfo);
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -117,19 +117,19 @@ nsDOMMultipartFile::CreateSlice(PRUint64
     PRUint64 l;
     nsresult rv = blob->GetSize(&l);
     NS_ENSURE_SUCCESS(rv, nsnull);
 
     if (skipStart < l) {
       PRUint64 upperBound = NS_MIN<PRUint64>(l - skipStart, length);
 
       nsCOMPtr<nsIDOMBlob> firstBlob;
-      rv = blob->MozSlice(skipStart, skipStart + upperBound,
-                          aContentType, 3,
-                          getter_AddRefs(firstBlob));
+      rv = blob->Slice(skipStart, skipStart + upperBound,
+                       aContentType, 3,
+                       getter_AddRefs(firstBlob));
       NS_ENSURE_SUCCESS(rv, nsnull);
 
       // Avoid wrapping a single blob inside an nsDOMMultipartFile
       if (length == upperBound) {
         return firstBlob.forget();
       }
 
       blobs.AppendElement(firstBlob);
@@ -145,18 +145,18 @@ nsDOMMultipartFile::CreateSlice(PRUint64
     nsIDOMBlob* blob = mBlobs[i].get();
 
     PRUint64 l;
     nsresult rv = blob->GetSize(&l);
     NS_ENSURE_SUCCESS(rv, nsnull);
 
     if (length < l) {
       nsCOMPtr<nsIDOMBlob> lastBlob;
-      rv = blob->MozSlice(0, length, aContentType, 3,
-                          getter_AddRefs(lastBlob));
+      rv = blob->Slice(0, length, aContentType, 3,
+                       getter_AddRefs(lastBlob));
       NS_ENSURE_SUCCESS(rv, nsnull);
 
       blobs.AppendElement(lastBlob);
     } else {
       blobs.AppendElement(blob);
     }
     length -= NS_MIN<PRUint64>(l, length);
   }
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -233,19 +233,19 @@ ParseSize(PRInt64 aSize, PRInt64& aStart
   }
   else {
     aStart = newStartOffset.value();
     aEnd = newEndOffset.value();
   }
 }
 
 NS_IMETHODIMP
-nsDOMFileBase::MozSlice(PRInt64 aStart, PRInt64 aEnd,
-                        const nsAString& aContentType, PRUint8 optional_argc,
-                        nsIDOMBlob **aBlob)
+nsDOMFileBase::Slice(PRInt64 aStart, PRInt64 aEnd,
+                     const nsAString& aContentType, PRUint8 optional_argc,
+                     nsIDOMBlob **aBlob)
 {
   *aBlob = nsnull;
 
   // Truncate aStart and aEnd so that we stay within this file.
   PRUint64 thisLength;
   nsresult rv = GetSize(&thisLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1695,30 +1695,64 @@ nsINode::SetExplicitBaseURI(nsIURI* aURI
     SetHasExplicitBaseURI();
     NS_ADDREF(aURI);
   }
   return rv;
 }
 
 //----------------------------------------------------------------------
 
+static JSObject*
+GetJSObjectChild(nsWrapperCache* aCache)
+{
+  if (aCache->PreservingWrapper()) {
+    return aCache->GetWrapperPreserveColor();
+  }
+  return aCache->GetExpandoObjectPreserveColor();
+}
+
+static bool
+NeedsScriptTraverse(nsWrapperCache* aCache)
+{
+  JSObject* o = GetJSObjectChild(aCache);
+  return o && xpc_IsGrayGCThing(o);
+}
+
+//----------------------------------------------------------------------
+
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsChildContentList)
 
+// If nsChildContentList is changed so that any additional fields are
+// traversed by the cycle collector, then CAN_SKIP must be updated.
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsChildContentList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsChildContentList)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsChildContentList)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsChildContentList)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
+// nsChildContentList only ever has a single child, its wrapper, so if
+// the wrapper is black, the list can't be part of a garbage cycle.
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsChildContentList)
+  return !NeedsScriptTraverse(tmp);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
+
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsChildContentList)
+  return !NeedsScriptTraverse(tmp);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
+
+// CanSkipThis returns false to avoid problems with incomplete unlinking.
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsChildContentList)
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
+
 NS_INTERFACE_TABLE_HEAD(nsChildContentList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsChildContentList)
     NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsINodeList)
     NS_INTERFACE_TABLE_ENTRY(nsChildContentList, nsIDOMNodeList)
   NS_OFFSET_AND_INTERFACE_TABLE_END
   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsChildContentList)
@@ -4400,32 +4434,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
     }
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
   nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-static JSObject*
-GetJSObjectChild(nsINode* aNode)
-{
-  if (aNode->PreservingWrapper()) {
-    return aNode->GetWrapperPreserveColor();
-  }
-  return aNode->GetExpandoObjectPreserveColor();
-}
-                                  
-static bool
-NeedsScriptTraverse(nsINode* aNode)
-{
-  JSObject* o = GetJSObjectChild(aNode);
-  return o && xpc_IsGrayGCThing(o);
-}
-
 void
 nsGenericElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
                                void* aData)
 {
   PRUint32* gen = static_cast<PRUint32*>(aData);
   xpc_MarkInCCGeneration(static_cast<nsISupports*>(aChild), *gen);
 }
 
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -97,17 +97,17 @@ class nsChildContentList : public nsINod
 public:
   nsChildContentList(nsINode* aNode)
     : mNode(aNode)
   {
     SetIsProxy();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsChildContentList)
+  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
 
   // nsWrapperCache
   virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
                                bool *triedToWrap);
 
   // nsIDOMNodeList interface
   NS_DECL_NSIDOMNODELIST
 
--- a/content/base/test/fileutils.js
+++ b/content/base/test/fileutils.js
@@ -196,34 +196,34 @@ function checkMPSubmission(sub, expected
 }
 
 function testSlice(file, size, type, contents, fileType) {
   is(file.type, type, fileType + " file is correct type");
   is(file.size, size, fileType + " file is correct size");
   ok(file instanceof File, fileType + " file is a File");
   ok(file instanceof Blob, fileType + " file is also a Blob");
   
-  var slice = file.mozSlice(0, size);
+  var slice = file.slice(0, size);
   ok(slice instanceof Blob, fileType + " fullsize slice is a Blob");
   ok(!(slice instanceof File), fileType + " fullsize slice is not a File");
   
-  slice = file.mozSlice(0, 1234);
+  slice = file.slice(0, 1234);
   ok(slice instanceof Blob, fileType + " sized slice is a Blob");
   ok(!(slice instanceof File), fileType + " sized slice is not a File");
   
-  slice = file.mozSlice(0, size, "foo/bar");
+  slice = file.slice(0, size, "foo/bar");
   is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type");
 
-  slice = file.mozSlice(0, 5432, "foo/bar");
+  slice = file.slice(0, 5432, "foo/bar");
   is(slice.type, "foo/bar", fileType + " sized slice foo/bar type");
   
-  is(slice.mozSlice(0, 10).type, "", fileType + " slice-slice type");
-  is(slice.mozSlice(0, 10).size, 10, fileType + " slice-slice size");
-  is(slice.mozSlice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type");
-  is(slice.mozSlice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size");
+  is(slice.slice(0, 10).type, "", fileType + " slice-slice type");
+  is(slice.slice(0, 10).size, 10, fileType + " slice-slice size");
+  is(slice.slice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type");
+  is(slice.slice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size");
 
   // Start, end, expected size
   var indexes = [[0, size, size],
                  [0, 1234, 1234],
                  [size-500, size, 500],
                  [size-500, size+500, 500],
                  [size+500, size+1500, 0],
                  [0, 0, 0],
@@ -242,38 +242,38 @@ function testSlice(file, size, type, con
                  [0, 33000, 33000],
                  [1000, 34000, 33000],
                 ];
   
   for (var i = 0; i < indexes.length; ++i) {
     var sliceContents;
     var testName;
     if (indexes[i][0] == undefined) {
-      slice = file.mozSlice();
+      slice = file.slice();
       sliceContents = contents.slice();
       testName = fileType + " slice()";
     }
     else if (indexes[i][1] == undefined) {
-      slice = file.mozSlice(indexes[i][0]);
+      slice = file.slice(indexes[i][0]);
       sliceContents = contents.slice(indexes[i][0]);
       testName = fileType + " slice(" + indexes[i][0] + ")";
     }
     else {
-      slice = file.mozSlice(indexes[i][0], indexes[i][1]);
+      slice = file.slice(indexes[i][0], indexes[i][1]);
       sliceContents = contents.slice(indexes[i][0], indexes[i][1]);
       testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")";
     }
     is(slice.type, "", testName + " type");
     is(slice.size, indexes[i][2], testName + " size");
     is(sliceContents.length, indexes[i][2], testName + " data size");
     testFile(slice, sliceContents, testName);
   }
 
   // Slice of slice
-  var slice = file.mozSlice(0, 40000);
-  testFile(slice.mozSlice(5000, 42000), contents.slice(5000, 40000), "file slice slice");
+  var slice = file.slice(0, 40000);
+  testFile(slice.slice(5000, 42000), contents.slice(5000, 40000), "file slice slice");
   
   // ...of slice of slice
-  slice = slice.mozSlice(5000, 42000).mozSlice(400, 700);
+  slice = slice.slice(5000, 42000).slice(400, 700);
   SpecialPowers.gc();
   testFile(slice, contents.slice(5400, 5700), "file slice slice slice");
 }
 
--- a/content/base/test/test_blobbuilder.html
+++ b/content/base/test/test_blobbuilder.html
@@ -146,17 +146,17 @@ function doTest(data) {
 
     blobs.forEach(doAppend);
     ok(true, "Test " + testCounter + " appended all successfully");
     let blob = bb.getBlob();
     ok(blob, "Test " + testCounter + " got blob");
     ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob");
     ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File");
 
-    let slice = blob.mozSlice(test.start, test.start + test.length);
+    let slice = blob.slice(test.start, test.start + test.length);
     ok(slice, "Test " + testCounter + " got slice");
     ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob");
     ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File");
     is(slice.size, test.contents.length,
        "Test " + testCounter + " slice is correct size");
 
     testFile(slice, test.contents, "Test " + testCounter);
   }
--- a/content/base/test/test_fileapi_slice.html
+++ b/content/base/test/test_fileapi_slice.html
@@ -99,39 +99,39 @@ function imageLoadHandler(event) {
 
   testHasRun();
 }
 
 // image in the middle
 var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData);
 is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)");
 var img = new Image;
-img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size));
+img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
 img.onload = imageLoadHandler;
 expectedTestCount++;
 
 // image at start
 var imgfile = createFileWithData(fileData + testBinaryData);
 is(imgfile.size, size + testBinaryData.length, "correct file size (start)");
 var img = new Image;
-img.src = URL.createObjectURL(imgfile.mozSlice(0, size));
+img.src = URL.createObjectURL(imgfile.slice(0, size));
 img.onload = imageLoadHandler;
 expectedTestCount++;
 
 // image at end
 var imgfile = createFileWithData(testBinaryData + fileData);
 is(imgfile.size, size + testBinaryData.length, "correct file size (end)");
 var img = new Image;
-img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size));
+img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
 img.onload = imageLoadHandler;
 expectedTestCount++;
 
 // image past end
 var imgfile = createFileWithData(testBinaryData + fileData);
 is(imgfile.size, size + testBinaryData.length, "correct file size (past end)");
 var img = new Image;
-img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size + 1000));
+img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size + 1000));
 img.onload = imageLoadHandler;
 expectedTestCount++;
 
 </script>
 </pre>
 </body> </html>
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1019,17 +1019,17 @@ struct WebGLVertexAttribData {
     }
 
     GLuint actualStride() const {
         if (stride) return stride;
         return size * componentSize();
     }
 };
 
-class WebGLBuffer
+class WebGLBuffer MOZ_FINAL
     : public nsIWebGLBuffer
     , public WebGLRefCountedObject<WebGLBuffer>
     , public WebGLContextBoundObject
 {
 public:
     WebGLBuffer(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mHasEverBeenBound(false)
@@ -1153,17 +1153,17 @@ protected:
     PRUint8 mCachedMaxUbyteElement;
     bool mHasCachedMaxUbyteElement;
     PRUint16 mCachedMaxUshortElement;
     bool mHasCachedMaxUshortElement;
 
     void* mData; // in the case of an Element Array Buffer, we keep a copy.
 };
 
-class WebGLTexture
+class WebGLTexture MOZ_FINAL
     : public nsIWebGLTexture
     , public WebGLRefCountedObject<WebGLTexture>
     , public WebGLContextBoundObject
 {
 public:
     WebGLTexture(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mHasEverBeenBound(false)
@@ -1603,17 +1603,17 @@ public:
             if (mFakeBlackStatus == DontKnowIfNeedFakeBlack)
                 mFakeBlackStatus = DoNotNeedFakeBlack;
         }
 
         return mFakeBlackStatus == DoNeedFakeBlack;
     }
 };
 
-class WebGLShader
+class WebGLShader MOZ_FINAL
     : public nsIWebGLShader
     , public WebGLRefCountedObject<WebGLShader>
     , public WebGLContextBoundObject
 {
 public:
     WebGLShader(WebGLContext *context, WebGLenum stype)
         : WebGLContextBoundObject(context)
         , mType(stype)
@@ -1668,17 +1668,17 @@ protected:
     WebGLuint mGLName;
     WebGLenum mType;
     nsString mSource;
     nsCString mTranslationLog;
     bool mNeedsTranslation;
     WebGLMonotonicHandle mMonotonicHandle;
 };
 
-class WebGLProgram
+class WebGLProgram MOZ_FINAL
     : public nsIWebGLProgram
     , public WebGLRefCountedObject<WebGLProgram>
     , public WebGLContextBoundObject
 {
 public:
     WebGLProgram(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mLinkStatus(false)
@@ -1790,17 +1790,17 @@ protected:
     GLint mUniformMaxNameLength;
     GLint mAttribMaxNameLength;
     GLint mUniformCount;
     GLint mAttribCount;
     std::vector<bool> mAttribsInUse;
     WebGLMonotonicHandle mMonotonicHandle;
 };
 
-class WebGLRenderbuffer
+class WebGLRenderbuffer MOZ_FINAL
     : public nsIWebGLRenderbuffer
     , public WebGLRefCountedObject<WebGLRenderbuffer>
     , public WebGLRectangleObject
     , public WebGLContextBoundObject
 {
 public:
     WebGLRenderbuffer(WebGLContext *context)
         : WebGLContextBoundObject(context)
@@ -1996,17 +1996,17 @@ public:
             }
         }
 
         NS_ABORT(); // should never get there
         return false;
     }
 };
 
-class WebGLFramebuffer
+class WebGLFramebuffer MOZ_FINAL
     : public nsIWebGLFramebuffer
     , public WebGLRefCountedObject<WebGLFramebuffer>
     , public WebGLContextBoundObject
 {
 public:
     WebGLFramebuffer(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mHasEverBeenBound(false)
@@ -2291,17 +2291,17 @@ public:
     WebGLFramebufferAttachment mColorAttachment,
                                mDepthAttachment,
                                mStencilAttachment,
                                mDepthStencilAttachment;
 
     WebGLMonotonicHandle mMonotonicHandle;
 };
 
-class WebGLUniformLocation
+class WebGLUniformLocation MOZ_FINAL
     : public nsIWebGLUniformLocation
     , public WebGLContextBoundObject
     , public WebGLRefCountedObject<WebGLUniformLocation>
 {
 public:
     WebGLUniformLocation(WebGLContext *context, WebGLProgram *program, GLint location)
         : WebGLContextBoundObject(context)
         , mProgram(program)
@@ -2332,17 +2332,17 @@ protected:
     nsRefPtr<WebGLProgram> mProgram;
 
     PRUint32 mProgramGeneration;
     GLint mLocation;
     WebGLMonotonicHandle mMonotonicHandle;
     friend class WebGLProgram;
 };
 
-class WebGLActiveInfo
+class WebGLActiveInfo MOZ_FINAL
     : public nsIWebGLActiveInfo
 {
 public:
     WebGLActiveInfo(WebGLint size, WebGLenum type, const char *nameptr, PRUint32 namelength) :
         mSize(size),
         mType(type)
     {
         mName.AssignASCII(nameptr, namelength);
@@ -2351,17 +2351,17 @@ public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLACTIVEINFO
 protected:
     WebGLint mSize;
     WebGLenum mType;
     nsString mName;
 };
 
-class WebGLShaderPrecisionFormat
+class WebGLShaderPrecisionFormat MOZ_FINAL
     : public nsIWebGLShaderPrecisionFormat
 {
 public:
     WebGLShaderPrecisionFormat(WebGLint rangeMin, WebGLint rangeMax, WebGLint precision) :
         mRangeMin(rangeMin),
         mRangeMax(rangeMax),
         mPrecision(precision)
     {
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -4372,17 +4372,17 @@ WebGLContext::CompileShader(nsIWebGLShad
 
         // notice that on Android, we always use SH_GLSL_OUTPUT, we never use the ESSL backend.
         // see bug 709947, the reason is that 1) we dont really need a ESSL backend since the
         // source is already ESSL, and 2) we ran into massive Android crashes when we used the ESSL backend.
         // But if we wanted to use shader transformations on ES platforms, we would have to use the
         // ESSL backend
         compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
                                        SH_WEBGL_SPEC,
-#ifdef MOZ_WIDGET_ANDROID
+#ifdef ANDROID
                                        SH_GLSL_OUTPUT,
 #else
                                        gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT,
 #endif
                                        &resources);
 
         // We're storing an actual instance of StripComments because, if we don't, the 
         // cleanSource nsAString instance will be destroyed before the reference is
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -175,17 +175,17 @@ CopyContext(gfxContext* dest, gfxContext
     }
 }
 
 /**
  ** nsCanvasGradient
  **/
 #define NS_CANVASGRADIENT_PRIVATE_IID \
     { 0x491d39d8, 0x4058, 0x42bd, { 0xac, 0x76, 0x70, 0xd5, 0x62, 0x7f, 0x02, 0x10 } }
-class nsCanvasGradient : public nsIDOMCanvasGradient
+class nsCanvasGradient MOZ_FINAL : public nsIDOMCanvasGradient
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID)
 
     nsCanvasGradient(gfxPattern* pat)
         : mPattern(pat)
     {
     }
@@ -233,17 +233,17 @@ NS_INTERFACE_MAP_BEGIN(nsCanvasGradient)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 /**
  ** nsCanvasPattern
  **/
 #define NS_CANVASPATTERN_PRIVATE_IID \
     { 0xb85c6c8a, 0x0624, 0x4530, { 0xb8, 0xee, 0xff, 0xdf, 0x42, 0xe8, 0x21, 0x6d } }
-class nsCanvasPattern : public nsIDOMCanvasPattern
+class nsCanvasPattern MOZ_FINAL : public nsIDOMCanvasPattern
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERN_PRIVATE_IID)
 
     nsCanvasPattern(gfxPattern* pat,
                     nsIPrincipal* principalForSecurityCheck,
                     bool forceWriteOnly,
                     bool CORSUsed)
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -2,8 +2,10 @@ conformance/context/premultiplyalpha-tes
 conformance/glsl/misc/glsl-function-nodes.html
 conformance/glsl/misc/glsl-long-variable-names.html
 conformance/glsl/misc/shader-with-256-character-identifier.frag.html
 conformance/glsl/misc/shader-with-long-line.html
 conformance/more/conformance/quickCheckAPI-S_V.html
 conformance/glsl/misc/attrib-location-length-limits.html
 conformance/glsl/misc/uniform-location-length-limits.html
 conformance/programs/program-test.html
+conformance/textures/texture-mips.html
+conformance/textures/texture-npot.html
--- a/dom/interfaces/css/nsIDOMCSSStyleDeclaration.idl
+++ b/dom/interfaces/css/nsIDOMCSSStyleDeclaration.idl
@@ -55,14 +55,14 @@ interface nsIDOMCSSStyleDeclaration : ns
 
   DOMString          getPropertyValue(in DOMString propertyName);
   nsIDOMCSSValue     getPropertyCSSValue(in DOMString propertyName);
   DOMString          removeProperty(in DOMString propertyName)
                                         raises(DOMException);
   DOMString          getPropertyPriority(in DOMString propertyName);
   void               setProperty(in DOMString propertyName, 
                                  in DOMString value, 
-                                 in DOMString priority)
+                                 [optional] in DOMString priority)
                                         raises(DOMException);
   readonly attribute unsigned long    length;
   DOMString          item(in unsigned long index);
   readonly attribute nsIDOMCSSRule    parentRule;
 };
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -3110,18 +3110,23 @@ nsresult nsPluginHost::NewPluginURLStrea
       // Plug-ins seem to depend on javascript: URIs running synchronously
       scriptChannel->SetExecuteAsync(false);
     }
   }
 
   // deal with headers and post data
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
   if (httpChannel) {
-    rv = httpChannel->SetReferrer(doc->GetDocumentURI());  
-    NS_ENSURE_SUCCESS(rv,rv);
+    if (!aPostStream) {
+      // Only set the Referer header for GET requests because IIS throws
+      // errors about malformed requests if we include it in POSTs. See
+      // bug 724465.
+      rv = httpChannel->SetReferrer(doc->GetDocumentURI());  
+      NS_ENSURE_SUCCESS(rv,rv);
+    }
       
     if (aPostStream) {
       // XXX it's a bit of a hack to rewind the postdata stream
       // here but it has to be done in case the post data is
       // being reused multiple times.
       nsCOMPtr<nsISeekableStream>
       postDataSeekable(do_QueryInterface(aPostStream));
       if (postDataSeekable)
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1385,75 +1385,74 @@ void nsPluginInstanceOwner::CARefresh(ns
     r.left = 0;
     r.top = 0;
     r.right = window->width;
     r.bottom = window->height; 
     instanceOwner->InvalidateRect(&r);
   }
 }
 
-void nsPluginInstanceOwner::AddToCARefreshTimer(nsPluginInstanceOwner *aPluginInstance) {
+void nsPluginInstanceOwner::AddToCARefreshTimer() {
+  if (!mInstance) {
+    return;
+  }
+
+  // Flash invokes InvalidateRect for us.
+  const char* mime = nsnull;
+  if (NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime) {
+    if (strcmp(mime, "application/x-shockwave-flash") == 0) {
+      return;
+    }
+  }
+
   if (!sCARefreshListeners) {
     sCARefreshListeners = new nsTArray<nsPluginInstanceOwner*>();
     if (!sCARefreshListeners) {
       return;
     }
   }
 
-  NS_ASSERTION(!sCARefreshListeners->Contains(aPluginInstance), 
-      "pluginInstanceOwner already registered as a listener");
-  sCARefreshListeners->AppendElement(aPluginInstance);
+  if (sCARefreshListeners->Contains(this)) {
+    return;
+  }
+
+  sCARefreshListeners->AppendElement(this);
 
   if (!sCATimer) {
     sCATimer = new nsCOMPtr<nsITimer>();
     if (!sCATimer) {
       return;
     }
   }
 
   if (sCARefreshListeners->Length() == 1) {
     *sCATimer = do_CreateInstance("@mozilla.org/timer;1");
     (*sCATimer)->InitWithFuncCallback(CARefresh, NULL, 
                    DEFAULT_REFRESH_RATE, nsITimer::TYPE_REPEATING_SLACK);
   }
 }
 
-void nsPluginInstanceOwner::RemoveFromCARefreshTimer(nsPluginInstanceOwner *aPluginInstance) {
-  if (!sCARefreshListeners || sCARefreshListeners->Contains(aPluginInstance) == false) {
+void nsPluginInstanceOwner::RemoveFromCARefreshTimer() {
+  if (!sCARefreshListeners || sCARefreshListeners->Contains(this) == false) {
     return;
   }
 
-  sCARefreshListeners->RemoveElement(aPluginInstance);
+  sCARefreshListeners->RemoveElement(this);
 
   if (sCARefreshListeners->Length() == 0) {
     if (sCATimer) {
       (*sCATimer)->Cancel();
       delete sCATimer;
       sCATimer = NULL;
     }
     delete sCARefreshListeners;
     sCARefreshListeners = NULL;
   }
 }
 
-void nsPluginInstanceOwner::SetupCARefresh()
-{
-  if (!mInstance) {
-    return;
-  }
-
-  const char* mime = nsnull;
-  if (NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime) {
-    // Flash invokes InvalidateRect for us.
-    if (strcmp(mime, "application/x-shockwave-flash") != 0) {
-    AddToCARefreshTimer(this);
-  }
-}
-}
-
 void nsPluginInstanceOwner::RenderCoreAnimation(CGContextRef aCGContext,
                                                 int aWidth, int aHeight)
 {
   if (aWidth == 0 || aHeight == 0)
     return;
 
   if (!mIOSurface ||
       (mIOSurface->GetWidth() != (size_t)aWidth ||
@@ -2694,17 +2693,17 @@ nsPluginInstanceOwner::Destroy()
   if (mObjectFrame)
     mObjectFrame->SetInstanceOwner(nsnull);
 
 #ifdef MAC_CARBON_PLUGINS
   // stop the timer explicitly to reduce reference count.
   CancelTimer();
 #endif
 #ifdef XP_MACOSX
-  RemoveFromCARefreshTimer(this);
+  RemoveFromCARefreshTimer();
   if (mColorProfile)
     ::CGColorSpaceRelease(mColorProfile);  
 #endif
 
   // unregister context menu listener
   if (mCXMenuListener) {
     mCXMenuListener->Destroy(mContent);
     mCXMenuListener = nsnull;
@@ -3272,17 +3271,17 @@ void nsPluginInstanceOwner::ReleasePlugi
   }
 #endif
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
 {
   NS_ENSURE_TRUE(mPluginWindow, NS_ERROR_NULL_POINTER);
 
-    nsresult rv = NS_ERROR_FAILURE;
+  nsresult rv = NS_ERROR_FAILURE;
   
   // Can't call this twice!
   if (mWidget) {
     NS_WARNING("Trying to create a plugin widget twice!");
     return NS_ERROR_FAILURE;
   }
   
   bool windowless = false;
@@ -3313,16 +3312,31 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
       mWidget->Destroy();
       mWidget = nsnull;
       return rv;
     }
 
     mWidget->EnableDragDrop(true);
     mWidget->Show(false);
     mWidget->Enable(false);
+
+#ifdef XP_MACOSX
+    // Now that we have a widget we want to set the event model before
+    // any events are processed.
+    nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
+    if (!pluginWidget) {
+      return NS_ERROR_FAILURE;
+    }
+    pluginWidget->SetPluginEventModel(GetEventModel());
+    pluginWidget->SetPluginDrawingModel(GetDrawingModel());
+
+    if (GetDrawingModel() == NPDrawingModelCoreAnimation) {
+      AddToCARefreshTimer();
+    }
+#endif
   }
 
   if (mObjectFrame) {
     // NULL widget is fine, will result in windowless setup.
     mObjectFrame->PrepForDrawing(mWidget);
   }
 
   if (windowless) {
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -177,19 +177,18 @@ public:
   
 #ifdef XP_MACOSX
   enum { ePluginPaintEnable, ePluginPaintDisable };
   
   NPDrawingModel GetDrawingModel();
   bool IsRemoteDrawingCoreAnimation();
   NPEventModel GetEventModel();
   static void CARefresh(nsITimer *aTimer, void *aClosure);
-  static void AddToCARefreshTimer(nsPluginInstanceOwner *aPluginInstance);
-  static void RemoveFromCARefreshTimer(nsPluginInstanceOwner *aPluginInstance);
-  void SetupCARefresh();
+  void AddToCARefreshTimer();
+  void RemoveFromCARefreshTimer();
   // This calls into the plugin (NPP_SetWindow) and can run script.
   void* FixUpPluginWindow(PRInt32 inPaintState);
   void HidePluginWindow();
   // Set a flag that (if true) indicates the plugin port info has changed and
   // SetWindow() needs to be called.
   void SetPluginPortChanged(bool aState) { mPluginPortChanged = aState; }
   // Return a pointer to the internal nsPluginPort structure that's used to
   // store a copy of plugin port info and to detect when it's been changed.
--- a/dom/plugins/test/mochitest/Makefile.in
+++ b/dom/plugins/test/mochitest/Makefile.in
@@ -104,16 +104,18 @@ include $(topsrcdir)/config/rules.mk
   test_zero_opacity.html \
   test_NPPVpluginWantsAllNetworkStreams.html \
   test_npruntime_npnsetexception.html \
   test_NPNVdocumentOrigin.html \
   test_instance_re-parent.html \
   test_instance_unparent1.html \
   test_instance_unparent2.html \
   test_instance_unparent3.html \
+  test_pluginstream_referer.html \
+  plugin-stream-referer.sjs \
   $(NULL)
 
 #  test_plugin_scroll_painting.html \ bug 596491
 
 ifeq ($(OS_ARCH),WINNT)
 _MOCHITEST_FILES += \
   test_windowed_invalidate.html \
   $(NULL)
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/mochitest/plugin-stream-referer.sjs
@@ -0,0 +1,10 @@
+function handleRequest(request, response)
+{
+  response.setHeader('Content-Type', 'text/plain', false);
+  if (request.hasHeader('Referer')) {
+    response.write('Referer found: ' + request.getHeader('Referer'));
+  }
+  else {
+    response.write('No Referer found');
+  }
+}
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/mochitest/test_pluginstream_referer.html
@@ -0,0 +1,42 @@
+<head>
+  <title>Do plugin stream requests send the Referer header correctly?</title>
+  <script type="application/javascript"
+	  src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" 
+        href="/tests/SimpleTest/test.css" />
+
+<body onload="runTests()">
+  <p id="display"></p>
+
+  <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
+
+  <script class="testbody" type="application/javascript">
+  SimpleTest.waitForExplicitFinish();
+
+  var pending = 2;
+  function testDone() {
+    --pending;
+    if (0 == pending)
+      SimpleTest.finish()
+  }
+
+  function runTests() {
+    var p = document.getElementById('plugin1');
+
+    ok(p.streamTest('plugin-stream-referer.sjs', false, null, null,
+                    function(r, t) {
+                      is(r, 0, "GET plugin-stream-referer.sjs");
+                      is(t, "Referer found: " + window.location,
+                         "GET Referer correct");
+                      testDone();
+                    }, null, true), "referer GET");
+
+    ok(p.streamTest('plugin-stream-referer.sjs', true, "Dummy Data", null,
+                    function(r, t) {
+                      is(r, 0, "POST plugin-stream-referer.sjs");
+                      is(t, "No Referer found", "POST Referer absent");
+                      testDone();
+                    }, null, true), "referer POST");
+  }
+  </script>
+
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -166,24 +166,24 @@ private:
     }
 
     *aVp = STRING_TO_JSVAL(jsType);
 
     return true;
   }
 
   static JSBool
-  MozSlice(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Slice(JSContext* aCx, uintN aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
-    nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "mozSlice");
+    nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "slice");
     if (!blob) {
       return false;
     }
 
     jsdouble start = 0, end = 0;
     JSString* jsContentType = JS_GetEmptyString(JS_GetRuntime(aCx));
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "/IIS", &start,
                              &end, &jsContentType)) {
@@ -192,20 +192,20 @@ private:
 
     nsDependentJSString contentType;
     if (!contentType.init(aCx, jsContentType)) {
       return false;
     }
 
     PRUint8 optionalArgc = aArgc;
     nsCOMPtr<nsIDOMBlob> rtnBlob;
-    if (NS_FAILED(blob->MozSlice(static_cast<PRUint64>(start),
-                                 static_cast<PRUint64>(end),
-                                 contentType, optionalArgc,
-                                 getter_AddRefs(rtnBlob)))) {
+    if (NS_FAILED(blob->Slice(static_cast<PRUint64>(start),
+                              static_cast<PRUint64>(end),
+                              contentType, optionalArgc,
+                              getter_AddRefs(rtnBlob)))) {
       ThrowFileExceptionForCode(aCx, FILE_NOT_READABLE_ERR);
       return false;
     }
 
     JSObject* rtnObj = file::CreateBlob(aCx, rtnBlob);
     if (!rtnObj) {
       return false;
     }
@@ -225,17 +225,17 @@ JSClass Blob::sClass = {
 
 JSPropertySpec Blob::sProperties[] = {
   { "size", 0, PROPERTY_FLAGS, GetSize, js_GetterOnlyPropertyStub },
   { "type", 0, PROPERTY_FLAGS, GetType, js_GetterOnlyPropertyStub },
   { 0, 0, 0, NULL, NULL }
 };
 
 JSFunctionSpec Blob::sFunctions[] = {
-  JS_FN("mozSlice", MozSlice, 1, JSPROP_ENUMERATE),
+  JS_FN("slice", Slice, 1, JSPROP_ENUMERATE),
   JS_FS_END
 };
 
 class File : public Blob
 {
   // File should never be instantiated.
   File();
   ~File();
--- a/dom/workers/test/Makefile.in
+++ b/dom/workers/test/Makefile.in
@@ -131,31 +131,31 @@ include $(topsrcdir)/config/rules.mk
   $(NULL)
 
 _CHROME_TEST_FILES = \
   test_chromeWorker.xul \
   test_chromeWorkerJSM.xul \
   test_extension.xul \
   test_extensionBootstrap.xul \
   test_file.xul \
-  test_fileMozSlice.xul \
+  test_fileSlice.xul \
   test_fileBlobPosting.xul \
   test_filePosting.xul \
   test_fileReaderSync.xul \
   test_fileReaderSyncErrors.xul \
-  test_fileReadMozSlice.xul \
+  test_fileReadSlice.xul \
   test_fileSubWorker.xul \
   test_fileBlobSubWorker.xul \
   file_worker.js \
   fileBlob_worker.js \
-  fileMozSlice_worker.js \
+  fileSlice_worker.js \
   filePosting_worker.js \
   fileReaderSync_worker.js \
   fileReaderSyncErrors_worker.js \
-  fileReadMozSlice_worker.js \
+  fileReadSlice_worker.js \
   fileSubWorker_worker.js \
   fileBlobSubWorker_worker.js \
   WorkerTest.jsm \
   WorkerTest_worker.js \
   WorkerTest_subworker.js \
   chromeWorker_worker.js \
   chromeWorker_subworker.js \
   test_workersDisabled.xul \
rename from dom/workers/test/fileReadMozSlice_worker.js
rename to dom/workers/test/fileReadSlice_worker.js
--- a/dom/workers/test/fileReadMozSlice_worker.js
+++ b/dom/workers/test/fileReadSlice_worker.js
@@ -2,15 +2,15 @@
  * Expects an object containing a blob, a start index and an end index
  * for slicing. Returns the contents of the blob read as text.
  */
 onmessage = function(event) {
   var blob = event.data.blob;
   var start = event.data.start;
   var end = event.data.end;
 
-  var slicedBlob = blob.mozSlice(start, end);
+  var slicedBlob = blob.slice(start, end);
 
   var fileReader = new FileReaderSync();
   var text = fileReader.readAsText(slicedBlob);
 
   postMessage(text);
 };
rename from dom/workers/test/fileMozSlice_worker.js
rename to dom/workers/test/fileSlice_worker.js
--- a/dom/workers/test/fileMozSlice_worker.js
+++ b/dom/workers/test/fileSlice_worker.js
@@ -6,21 +6,21 @@
 onmessage = function(event) {
   var blob = event.data.blob;
   var start = event.data.start;
   var end = event.data.end;
   var contentType = event.data.contentType;
 
   var slicedBlob;
   if (contentType == undefined && end == undefined) {
-    slicedBlob = blob.mozSlice(start);
+    slicedBlob = blob.slice(start);
   } else if (contentType == undefined) {
-    slicedBlob = blob.mozSlice(start, end);
+    slicedBlob = blob.slice(start, end);
   } else {
-    slicedBlob = blob.mozSlice(start, end, contentType);
+    slicedBlob = blob.slice(start, end, contentType);
   }
 
   var rtnObj = new Object();
 
   rtnObj.size = slicedBlob.size;
   rtnObj.type = slicedBlob.type;
 
   postMessage(rtnObj);
--- a/dom/workers/test/test_fileBlobPosting.xul
+++ b/dom/workers/test/test_fileBlobPosting.xul
@@ -65,17 +65,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     };
 
     worker.onmessage = function(event) {
       console.log(event.data);
       is(event.data.size, file.size, "size of file posted from worker does not match file posted to worker.");
       finish();
     };
 
-    var blob = file.mozSlice();
+    var blob = file.slice();
     worker.postMessage(blob);
     waitForWorkerFinish();
   }
 
   // Empty file.
   postBlob(createFileWithData(""));
 
   // Typical use case.
--- a/dom/workers/test/test_fileBlobSubWorker.xul
+++ b/dom/workers/test/test_fileBlobSubWorker.xul
@@ -67,17 +67,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       if (event.data == undefined) {
         ok(false, "Worker had an error.");
       } else {
         is(event.data.size, expectedSize, "size proproperty accessed from worker is not the same as on main thread.");
       }
       finish();
     };
 
-    var blob = file.mozSlice();
+    var blob = file.slice();
     worker.postMessage(blob);
     waitForWorkerFinish();
   }
 
   // Empty file.
   accessFileProperties(createFileWithData(""), 0);
 
   // Typical use case.
rename from dom/workers/test/test_fileReadMozSlice.xul
rename to dom/workers/test/test_fileReadSlice.xul
--- a/dom/workers/test/test_fileReadMozSlice.xul
+++ b/dom/workers/test/test_fileReadSlice.xul
@@ -31,17 +31,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   /**
    * Create a file which contains the given data.
    */
   function createFileWithData(fileData) {
     var testFile = Components.classes["@mozilla.org/file/directory_service;1"]
                        .getService(Components.interfaces.nsIProperties)
                        .get("ProfD", Components.interfaces.nsIFile);
-    testFile.append("workerReadMozSlice" + fileNum++);
+    testFile.append("workerReadSlice" + fileNum++);
 
     var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
                         .createInstance(Components.interfaces.nsIFileOutputStream);
     outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
                    0666, 0);
     outStream.write(fileData, fileData.length);
     outStream.close();
 
@@ -50,18 +50,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     return fileList.files[0];
   }
 
   /**
    * Creates a worker which slices a blob to the given start and end offset and
    * reads the content as text.
    */
-  function readMozSlice(blob, start, end, expectedText) {
-    var worker = new Worker("fileReadMozSlice_worker.js");
+  function readSlice(blob, start, end, expectedText) {
+    var worker = new Worker("fileReadSlice_worker.js");
 
     worker.onerror = function(event) {
       ok(false, "Worker had an error: " + event.data);
       finish();
     };
 
     worker.onmessage = function(event) {
       is(event.data, expectedText, "Text from sliced blob in worker is incorrect.");
@@ -69,22 +69,22 @@ https://bugzilla.mozilla.org/show_bug.cg
     };
 
     var params = {blob: blob, start: start, end: end};
     worker.postMessage(params);
     waitForWorkerFinish();
   }
 
   // Empty file.
-  readMozSlice(createFileWithData(""), 0, 0, "");
+  readSlice(createFileWithData(""), 0, 0, "");
 
   // Typical use case.
-  readMozSlice(createFileWithData("HelloBye"), 5, 8, "Bye");
+  readSlice(createFileWithData("HelloBye"), 5, 8, "Bye");
 
   // End offset too large.
-  readMozSlice(createFileWithData("HelloBye"), 5, 9, "Bye");
+  readSlice(createFileWithData("HelloBye"), 5, 9, "Bye");
 
   // Start of file.
-  readMozSlice(createFileWithData("HelloBye"), 0, 5, "Hello");
+  readSlice(createFileWithData("HelloBye"), 0, 5, "Hello");
 
   ]]>
   </script>
 </window>
rename from dom/workers/test/test_fileMozSlice.xul
rename to dom/workers/test/test_fileSlice.xul
--- a/dom/workers/test/test_fileMozSlice.xul
+++ b/dom/workers/test/test_fileSlice.xul
@@ -32,17 +32,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   /**
    * Create a file which contains the given data and optionally adds the specified file extension.
    */
   function createFileWithData(fileData, /** optional */ extension) {
     var testFile = Components.classes["@mozilla.org/file/directory_service;1"]
                        .getService(Components.interfaces.nsIProperties)
                        .get("ProfD", Components.interfaces.nsIFile);
     var fileExtension = (extension == undefined) ? "" : "." + extension;
-    testFile.append("workerMozSlice" + fileNum++ + fileExtension);
+    testFile.append("workerSlice" + fileNum++ + fileExtension);
 
     var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
                         .createInstance(Components.interfaces.nsIFileOutputStream);
     outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
                    0666, 0);
     outStream.write(fileData, fileData.length);
     outStream.close();
 
@@ -51,18 +51,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     return fileList.files[0];
   }
 
   /**
    * Starts a worker which slices the blob to the given start offset and optional end offset and
    * content type. It then verifies that the size and type of the sliced blob is correct.
    */
-  function createMozSlice(blob, start, expectedLength, /** optional */ end, /** optional */ contentType) {
-    var worker = new Worker("fileMozSlice_worker.js");
+  function createSlice(blob, start, expectedLength, /** optional */ end, /** optional */ contentType) {
+    var worker = new Worker("fileSlice_worker.js");
 
     worker.onerror = function(event) {
       ok(false, "Worker had an error: " + event.data);
       finish();
     };
 
     worker.onmessage = function(event) {
       is(event.data.size, expectedLength, "size property of slice is incorrect.");
@@ -71,36 +71,36 @@ https://bugzilla.mozilla.org/show_bug.cg
     };
 
     var params = {blob: blob, start: start, end: end, contentType: contentType};
     worker.postMessage(params);
     waitForWorkerFinish();
   }
 
   // Empty file.
-  createMozSlice(createFileWithData(""), 0, 0, 0);
+  createSlice(createFileWithData(""), 0, 0, 0);
 
   // Typical use case.
-  createMozSlice(createFileWithData("Hello"), 1, 1, 2);
+  createSlice(createFileWithData("Hello"), 1, 1, 2);
 
   // Longish file.
   var text = "";
   for (var i = 0; i < 10000; ++i) {
     text += "long";
   }
-  createMozSlice(createFileWithData(text), 2000, 2000, 4000);
+  createSlice(createFileWithData(text), 2000, 2000, 4000);
 
   // Slice to different type.
-  createMozSlice(createFileWithData("text", "txt"), 0, 2, 2, "image/png");
+  createSlice(createFileWithData("text", "txt"), 0, 2, 2, "image/png");
 
   // Length longer than blob.
-  createMozSlice(createFileWithData("text"), 0, 4, 20);
+  createSlice(createFileWithData("text"), 0, 4, 20);
 
   // Start longer than blob.
-  createMozSlice(createFileWithData("text"), 20, 0, 4);
+  createSlice(createFileWithData("text"), 20, 0, 4);
 
   // No optional arguments
-  createMozSlice(createFileWithData("text"), 0, 4);
-  createMozSlice(createFileWithData("text"), 2, 2);
+  createSlice(createFileWithData("text"), 0, 4);
+  createSlice(createFileWithData("text"), 2, 2);
 
   ]]>
   </script>
 </window>
--- a/editor/composer/src/nsEditorSpellCheck.cpp
+++ b/editor/composer/src/nsEditorSpellCheck.cpp
@@ -78,17 +78,17 @@ class UpdateDictionnaryHolder {
       if (mSpellCheck) {
         mSpellCheck->EndUpdateDictionary();
       }
     }
 };
 
 #define CPS_PREF_NAME NS_LITERAL_STRING("spellcheck.lang")
 
-class LastDictionary {
+class LastDictionary MOZ_FINAL {
 public:
   /**
    * Store current dictionary for editor document url. Use content pref
    * service.
    */
   NS_IMETHOD StoreCurrentDictionary(nsIEditor* aEditor, const nsAString& aDictionary);
 
   /**
--- a/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
+++ b/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
@@ -97,17 +97,17 @@ static PRInt32 GetCSSFloatValue(nsIDOMCS
         f = 5;
       break;
     }
   }
 
   return (PRInt32) f;
 }
 
-class nsElementDeletionObserver : public nsIMutationObserver
+class nsElementDeletionObserver MOZ_FINAL : public nsIMutationObserver
 {
 public:
   nsElementDeletionObserver(nsINode* aNativeAnonNode, nsINode* aObservedNode)
   : mNativeAnonNode(aNativeAnonNode), mObservedNode(aObservedNode) {}
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMUTATIONOBSERVER
 protected:
   nsINode* mNativeAnonNode;
--- a/embedding/browser/webBrowser/nsIWebBrowserChrome.idl
+++ b/embedding/browser/webBrowser/nsIWebBrowserChrome.idl
@@ -42,17 +42,17 @@
 interface nsIWebBrowser;
 interface nsIDocShellTreeItem;
 
 /**
  * nsIWebBrowserChrome corresponds to the top-level, outermost window
  * containing an embedded Gecko web browser.
  */
 
-[scriptable, uuid(BA434C60-9D52-11d3-AFB0-00A024FFC08C)]
+[scriptable, uuid(E8C414C4-DC38-4BA3-AB4E-EC4CBBE22907)]
 interface nsIWebBrowserChrome : nsISupports
 {
     const unsigned long STATUS_SCRIPT         = 0x00000001;
     const unsigned long STATUS_SCRIPT_DEFAULT = 0x00000002;
     const unsigned long STATUS_LINK           = 0x00000003;
 
     /**
      * Called when the status text in the chrome needs to be updated.
@@ -70,53 +70,57 @@ interface nsIWebBrowserChrome : nsISuppo
      * as if it had created the WebBrowser itself.  This includes positioning
      * setting up listeners etc.
      */
     attribute nsIWebBrowser webBrowser;
 
     /**
      * Definitions for the chrome flags
      */
-    const unsigned long CHROME_DEFAULT          = 0x00000001;
-    const unsigned long CHROME_WINDOW_BORDERS   = 0x00000002;
-    const unsigned long CHROME_WINDOW_CLOSE     = 0x00000004;
-    const unsigned long CHROME_WINDOW_RESIZE    = 0x00000008;
-    const unsigned long CHROME_MENUBAR          = 0x00000010;
-    const unsigned long CHROME_TOOLBAR          = 0x00000020;
-    const unsigned long CHROME_LOCATIONBAR      = 0x00000040;
-    const unsigned long CHROME_STATUSBAR        = 0x00000080;
-    const unsigned long CHROME_PERSONAL_TOOLBAR = 0x00000100;
-    const unsigned long CHROME_SCROLLBARS       = 0x00000200;
-    const unsigned long CHROME_TITLEBAR         = 0x00000400;
-    const unsigned long CHROME_EXTRA            = 0x00000800;
+    const unsigned long CHROME_DEFAULT                = 0x00000001;
+    const unsigned long CHROME_WINDOW_BORDERS         = 0x00000002;
+    const unsigned long CHROME_WINDOW_CLOSE           = 0x00000004;
+    const unsigned long CHROME_WINDOW_RESIZE          = 0x00000008;
+    const unsigned long CHROME_MENUBAR                = 0x00000010;
+    const unsigned long CHROME_TOOLBAR                = 0x00000020;
+    const unsigned long CHROME_LOCATIONBAR            = 0x00000040;
+    const unsigned long CHROME_STATUSBAR              = 0x00000080;
+    const unsigned long CHROME_PERSONAL_TOOLBAR       = 0x00000100;
+    const unsigned long CHROME_SCROLLBARS             = 0x00000200;
+    const unsigned long CHROME_TITLEBAR               = 0x00000400;
+    const unsigned long CHROME_EXTRA                  = 0x00000800;
     
     // createBrowserWindow specific flags
-    const unsigned long CHROME_WITH_SIZE        = 0x00001000;
-    const unsigned long CHROME_WITH_POSITION    = 0x00002000;
+    const unsigned long CHROME_WITH_SIZE              = 0x00001000;
+    const unsigned long CHROME_WITH_POSITION          = 0x00002000;
 
     // special cases
-    const unsigned long CHROME_WINDOW_MIN       = 0x00004000;
-    const unsigned long CHROME_WINDOW_POPUP     = 0x00008000;
+    const unsigned long CHROME_WINDOW_MIN             = 0x00004000;
+    const unsigned long CHROME_WINDOW_POPUP           = 0x00008000;
 
-    const unsigned long CHROME_WINDOW_RAISED    = 0x02000000;
-    const unsigned long CHROME_WINDOW_LOWERED   = 0x04000000;
-    const unsigned long CHROME_CENTER_SCREEN    = 0x08000000;
+    // Prevents new window animations on Mac OS X Lion.  Ignored on other
+    // platforms.
+    const unsigned long CHROME_MAC_SUPPRESS_ANIMATION = 0x01000000;
+
+    const unsigned long CHROME_WINDOW_RAISED          = 0x02000000;
+    const unsigned long CHROME_WINDOW_LOWERED         = 0x04000000;
+    const unsigned long CHROME_CENTER_SCREEN          = 0x08000000;
 
     // Make the new window dependent on the parent.  This flag is only
     // meaningful if CHROME_OPENAS_CHROME is set; content windows should not be
     // dependent.
-    const unsigned long CHROME_DEPENDENT        = 0x10000000;
+    const unsigned long CHROME_DEPENDENT              = 0x10000000;
 
     // Note: The modal style bit just affects the way the window looks and does
     //       mean it's actually modal.
-    const unsigned long CHROME_MODAL            = 0x20000000; 
-    const unsigned long CHROME_OPENAS_DIALOG    = 0x40000000;
-    const unsigned long CHROME_OPENAS_CHROME    = 0x80000000;
+    const unsigned long CHROME_MODAL                  = 0x20000000; 
+    const unsigned long CHROME_OPENAS_DIALOG          = 0x40000000;
+    const unsigned long CHROME_OPENAS_CHROME          = 0x80000000;
     
-    const unsigned long CHROME_ALL              = 0x00000ffe;
+    const unsigned long CHROME_ALL                    = 0x00000ffe;
     
     /**
      * The chrome flags for this browser chrome. The implementation should
      * reflect the value of this attribute by hiding or showing its chrome
      * appropriately.
      */
     attribute unsigned long chromeFlags;
 
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -1522,16 +1522,19 @@ PRUint32 nsWindowWatcher::CalculateChrom
      instructions. (Note modality implies dependence.) */
 
   if (WinHasOption(aFeatures, "alwaysLowered", 0, nsnull) ||
       WinHasOption(aFeatures, "z-lock", 0, nsnull))
     chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_LOWERED;
   else if (WinHasOption(aFeatures, "alwaysRaised", 0, nsnull))
     chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_RAISED;
 
+  chromeFlags |= WinHasOption(aFeatures, "macsuppressanimation", 0, nsnull) ?
+    nsIWebBrowserChrome::CHROME_MAC_SUPPRESS_ANIMATION : 0;
+
   chromeFlags |= WinHasOption(aFeatures, "chrome", 0, nsnull) ?
     nsIWebBrowserChrome::CHROME_OPENAS_CHROME : 0;
   chromeFlags |= WinHasOption(aFeatures, "extrachrome", 0, nsnull) ?
     nsIWebBrowserChrome::CHROME_EXTRA : 0;
   chromeFlags |= WinHasOption(aFeatures, "centerscreen", 0, nsnull) ?
     nsIWebBrowserChrome::CHROME_CENTER_SCREEN : 0;
   chromeFlags |= WinHasOption(aFeatures, "dependent", 0, nsnull) ?
     nsIWebBrowserChrome::CHROME_DEPENDENT : 0;
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -628,17 +628,17 @@ DrawTargetD2D::DrawSurfaceWithShadow(Sou
                                            (-Float(aSurface->GetSize().height) / mSize.height) * 2.0f));
   mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
     SetFloatVector(ShaderConstantRectD3D10(0, 0, Float(srcSurfSize.width) / tmpSurfSize.width,
                                                  Float(srcSurfSize.height) / tmpSurfSize.height));
 
   if (mPushedClips.size()) {
     mPrivateData->mEffect->GetVariableByName("mask")->AsShaderResource()->SetResource(maskSRView);
     mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
-      SetFloatVector(ShaderConstantRectD3D10(shadowDest.x / mSize.width, shadowDest.y / mSize.width,
+      SetFloatVector(ShaderConstantRectD3D10(shadowDest.x / mSize.width, shadowDest.y / mSize.height,
                                              Float(aSurface->GetSize().width) / mSize.width,
                                              Float(aSurface->GetSize().height) / mSize.height));
     mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
       GetPassByIndex(2)->Apply(0);
   } else {
     mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
       GetPassByIndex(1)->Apply(0);
   }
@@ -653,17 +653,17 @@ DrawTargetD2D::DrawSurfaceWithShadow(Sou
                                            (Float(aSurface->GetSize().width) / mSize.width) * 2.0f,
                                            (-Float(aSurface->GetSize().height) / mSize.height) * 2.0f));
   mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(static_cast<SourceSurfaceD2DTarget*>(aSurface)->GetSRView());
   mPrivateData->mEffect->GetVariableByName("TexCoords")->AsVector()->
     SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
 
   if (mPushedClips.size()) {
     mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
-      SetFloatVector(ShaderConstantRectD3D10(aDest.x / mSize.width, aDest.y / mSize.width,
+      SetFloatVector(ShaderConstantRectD3D10(aDest.x / mSize.width, aDest.y / mSize.height,
                                              Float(aSurface->GetSize().width) / mSize.width,
                                              Float(aSurface->GetSize().height) / mSize.height));
     mPrivateData->mEffect->GetTechniqueByName("SampleMaskedTexture")->
       GetPassByIndex(0)->Apply(0);
   } else {
     mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->
       GetPassByIndex(0)->Apply(0);
   }
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1447,16 +1447,18 @@ GLContext::ResizeOffscreenFBO(const gfxI
     }
 #endif
 
     // Make sure we know that the buffers are new and thus dirty:
     ForceDirtyFBOs();
 
     // We're good, and the framebuffer is already attached.
     // Now restore the GL state back to what it was before the resize took place.
+    // If the user was using fb 0, this will bind the offscreen framebuffer we
+    // just created.
     BindDrawFBO(curBoundFramebufferDraw);
     BindReadFBO(curBoundFramebufferRead);
     fBindTexture(LOCAL_GL_TEXTURE_2D, curBoundTexture);
     fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, curBoundRenderbuffer);
     fViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
 
     return true;
 }
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -536,18 +536,20 @@ class GLContext
     : public LibrarySymbolLoader
 {
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLContext)
 public:
     GLContext(const ContextFormat& aFormat,
               bool aIsOffscreen = false,
               GLContext *aSharedContext = nsnull)
       : mFlushGuaranteesResolve(false),
-        mBoundDrawFBO(0),
-        mBoundReadFBO(0),
+        mUserBoundDrawFBO(0),
+        mUserBoundReadFBO(0),
+        mInternalBoundDrawFBO(0),
+        mInternalBoundReadFBO(0),
         mOffscreenFBOsDirty(false),
         mInitialized(false),
         mIsOffscreen(aIsOffscreen),
 #ifdef USE_GLES2
         mIsGLES2(true),
 #else
         mIsGLES2(false),
 #endif
@@ -857,66 +859,116 @@ public:
 
     virtual bool SupportsOffscreenSplit() {
         return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit);
     }
 
 
 
 private:
-    GLuint mBoundDrawFBO;
-    GLuint mBoundReadFBO;
+    GLuint mUserBoundDrawFBO;
+    GLuint mUserBoundReadFBO;
+    GLuint mInternalBoundDrawFBO;
+    GLuint mInternalBoundReadFBO;
 
 public:
     void fBindFramebuffer(GLenum target, GLuint framebuffer) {
         switch (target) {
-          case LOCAL_GL_FRAMEBUFFER:
-            mBoundDrawFBO = mBoundReadFBO = framebuffer;
+          case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
+            mUserBoundDrawFBO = framebuffer;
+
+            if (framebuffer == 0) {
+                mInternalBoundDrawFBO = mOffscreenDrawFBO;
+            } else {
+                mInternalBoundDrawFBO = mUserBoundDrawFBO;
+            }
+
+            raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT,
+                                 mInternalBoundDrawFBO);
+            break;
+
+          case LOCAL_GL_READ_FRAMEBUFFER_EXT:
+            mUserBoundReadFBO = framebuffer;
+
+            if (framebuffer == 0) {
+                mInternalBoundReadFBO = mOffscreenReadFBO;
+            } else {
+                mInternalBoundReadFBO = mUserBoundReadFBO;
+            }
+
+            raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT,
+                                 mInternalBoundReadFBO);
             break;
-          case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
-            mBoundDrawFBO = framebuffer;
+
+          case LOCAL_GL_FRAMEBUFFER:
+            mUserBoundDrawFBO = mUserBoundReadFBO = framebuffer;
+
+            if (framebuffer == 0) {
+                mInternalBoundDrawFBO = mOffscreenDrawFBO;
+                mInternalBoundReadFBO = mOffscreenReadFBO;
+            } else {
+                mInternalBoundDrawFBO = mUserBoundDrawFBO;
+                mInternalBoundReadFBO = mUserBoundReadFBO;
+            }
+
+            if (SupportsOffscreenSplit()) {
+                raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT,
+                                     mInternalBoundDrawFBO);
+                raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT,
+                                     mInternalBoundReadFBO);
+            } else {
+                raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER,
+                                     mInternalBoundDrawFBO);
+            }
+
             break;
-          case LOCAL_GL_READ_FRAMEBUFFER_EXT:
-            mBoundReadFBO = framebuffer;
+
+          default:
+            raw_fBindFramebuffer(target, framebuffer);
             break;
         }
-        raw_fBindFramebuffer(target, framebuffer);
     }
 
     GLuint GetBoundDrawFBO() {
 #ifdef DEBUG
         GLint ret = 0;
         // Don't need a branch here, because:
         // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
-        fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
-
-        if (mBoundDrawFBO != (GLuint)ret) {
-          printf_stderr("!!! Draw FBO mismatch: Was: %d, Expected: %d\n", ret, mBoundDrawFBO);
+        // We use raw_ here because this is debug code and we need to see what
+        // the driver thinks.
+        raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
+
+        if (mInternalBoundDrawFBO != (GLuint)ret) {
+          printf_stderr("!!! Draw FBO mismatch: Was: %d, Expected: %d\n", ret, mInternalBoundDrawFBO);
           NS_ABORT();
         }
 #endif
 
-        return mBoundDrawFBO;
+        // We only ever expose the user's bound FBOs
+        return mUserBoundDrawFBO;
     }
 
     GLuint GetBoundReadFBO() {
 #ifdef DEBUG
         GLint ret = 0;
+        // We use raw_ here because this is debug code and we need to see what
+        // the driver thinks.
         if (SupportsOffscreenSplit())
-            fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, &ret);
+            raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, &ret);
         else
-            fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
-
-        if (mBoundReadFBO != (GLuint)ret) {
-          printf_stderr("!!! Read FBO mismatch: Was: %d, Expected: %d\n", ret, mBoundReadFBO);
+            raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
+
+        if (mInternalBoundReadFBO != (GLuint)ret) {
+          printf_stderr("!!! Read FBO mismatch: Was: %d, Expected: %d\n", ret, mInternalBoundReadFBO);
           NS_ABORT();
         }
 #endif
 
-        return mBoundReadFBO;
+        // We only ever expose the user's bound FBOs
+        return mUserBoundReadFBO;
     }
 
     void BindDrawFBO(GLuint name) {
         if (SupportsOffscreenSplit())
             fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, name);
         else
             fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
     }
@@ -949,18 +1001,16 @@ public:
     }
 
     void BindOffscreenBuffers() {
         BindOffscreenDrawBuffer();
         BindOffscreenReadBuffer();
     }
 
 private:
-    GLuint mPrevDrawFBOBinding;
-    GLuint mPrevReadFBOBinding;
     bool mOffscreenFBOsDirty;
 
     void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
         switch (precisiontype) {
             case LOCAL_GL_LOW_FLOAT:
             case LOCAL_GL_MEDIUM_FLOAT:
             case LOCAL_GL_HIGH_FLOAT:
                 // Assume IEEE 754 precision
@@ -975,85 +1025,73 @@ private:
                 // which can accurately represent integers up to +/-16777216
                 range[0] = 24;
                 range[1] = 24;
                 *precision = 0;
                 break;
         }
     }
 
+    // Do whatever setup is necessary to draw to our offscreen FBO, if it's
+    // bound.
     void BeforeGLDrawCall() {
-        // Record and rebind if necessary
-        mPrevDrawFBOBinding = GetBoundDrawFBO();
-        if (mPrevDrawFBOBinding == 0) {
-            BindDrawFBO(mOffscreenDrawFBO);
-        } else if (mPrevDrawFBOBinding != mOffscreenDrawFBO)
+        if (mInternalBoundDrawFBO != mOffscreenDrawFBO)
             return;
 
-        // Must be after binding the proper FBO
         if (mOffscreenDrawFBO == mOffscreenReadFBO)
             return;
 
-        // If we're already dirty, no need to set it again
-        if (mOffscreenFBOsDirty)
-            return;
-
         mOffscreenFBOsDirty = true;
     }
 
+    // Do whatever tear-down is necessary after drawing to our offscreen FBO,
+    // if it's bound.
     void AfterGLDrawCall() {
-        if (mPrevDrawFBOBinding == 0) {
-            BindDrawFBO(0);
-        }
     }
 
+    // Do whatever setup is necessary to read from our offscreen FBO, if it's
+    // bound.
     void BeforeGLReadCall() {
-        // Record and rebind if necessary
-        mPrevReadFBOBinding = GetBoundReadFBO();
-        if (mPrevReadFBOBinding == 0) {
-            BindReadFBO(mOffscreenReadFBO);
-        } else if (mPrevReadFBOBinding != mOffscreenReadFBO)
+        if (mInternalBoundReadFBO != mOffscreenReadFBO)
             return;
 
-        // Must be after binding the proper FBO
         if (mOffscreenDrawFBO == mOffscreenReadFBO)
             return;
 
         // If we're not dirty, there's no need to blit
         if (!mOffscreenFBOsDirty)
             return;
 
         const bool scissor = fIsEnabled(LOCAL_GL_SCISSOR_TEST);
         if (scissor)
             fDisable(LOCAL_GL_SCISSOR_TEST);
 
         // flip read/draw for blitting
         GLuint prevDraw = SwapBoundDrawFBO(mOffscreenReadFBO);
-        BindReadFBO(mOffscreenDrawFBO); // We know that Read must already be mOffscreenRead, so no need to write that down
+        GLuint prevRead = SwapBoundReadFBO(mOffscreenDrawFBO);
 
         GLint width = mOffscreenActualSize.width;
         GLint height = mOffscreenActualSize.height;
         raw_fBlitFramebuffer(0, 0, width, height,
                              0, 0, width, height,
                              LOCAL_GL_COLOR_BUFFER_BIT,
                              LOCAL_GL_NEAREST);
 
         BindDrawFBO(prevDraw);
-        BindReadFBO(mOffscreenReadFBO);
+        BindReadFBO(prevRead);
 
         if (scissor)
             fEnable(LOCAL_GL_SCISSOR_TEST);
 
         mOffscreenFBOsDirty = false;
     }
 
+    // Do whatever tear-down is necessary after reading from our offscreen FBO,
+    // if it's bound.
     void AfterGLReadCall() {
-        if (mPrevReadFBOBinding == 0) {
-            BindReadFBO(0);
-        }
     }
 
 public:
     // Draw call hooks:
     void fClear(GLbitfield mask) {
         BeforeGLDrawCall();
         raw_fClear(mask);
         AfterGLDrawCall();
@@ -1992,22 +2030,44 @@ public:
 
     GLint fGetAttribLocation (GLuint program, const GLchar* name) {
         BEFORE_GL_CALL;
         GLint retval = mSymbols.fGetAttribLocation(program, name);
         AFTER_GL_CALL;
         return retval;
     }
 
-    void fGetIntegerv(GLenum pname, GLint *params) {
+private:
+    void raw_fGetIntegerv(GLenum pname, GLint *params) {
         BEFORE_GL_CALL;
         mSymbols.fGetIntegerv(pname, params);
         AFTER_GL_CALL;
     }
 
+public:
+    void fGetIntegerv(GLenum pname, GLint *params) {
+        switch (pname)
+        {
+            // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
+            // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, so we don't need two
+            // cases.
+            case LOCAL_GL_FRAMEBUFFER_BINDING:
+                *params = GetBoundDrawFBO();
+                break;
+
+            case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
+                *params = GetBoundReadFBO();
+                break;
+
+            default:
+                raw_fGetIntegerv(pname, params);
+                break;
+        }
+    }
+
     void fGetFloatv(GLenum pname, GLfloat *params) {
         BEFORE_GL_CALL;
         mSymbols.fGetFloatv(pname, params);
         AFTER_GL_CALL;
     }
 
     void fGetBooleanv(GLenum pname, realGLboolean *params) {
         BEFORE_GL_CALL;
--- a/gfx/harfbuzz/src/hb-ot-layout.cc
+++ b/gfx/harfbuzz/src/hb-ot-layout.cc
@@ -27,16 +27,17 @@
  */
 
 #include "hb-ot-layout-private.hh"
 
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
 #include "hb-ot-maxp-table.hh"
+#include "hb-ot-shape-private.hh"
 
 
 #include <stdlib.h>
 #include <string.h>
 
 
 
 hb_ot_layout_t *
@@ -491,14 +492,52 @@ hb_ot_layout_position_lookup   (hb_font_
 				hb_buffer_t  *buffer,
 				unsigned int  lookup_index,
 				hb_mask_t     mask)
 {
   return _get_gpos (font->face).position_lookup (font, buffer, lookup_index, mask);
 }
 
 void
-hb_ot_layout_position_finish (hb_buffer_t  *buffer)
+hb_ot_layout_position_finish (hb_face_t *face, hb_buffer_t *buffer)
 {
+  /* force diacritics to have zero width */
+  unsigned int count = buffer->len;
+  if (hb_ot_layout_has_glyph_classes (face)) {
+    const GDEF& gdef = _get_gdef (face);
+    if (buffer->props.direction == HB_DIRECTION_RTL) {
+      for (unsigned int i = 1; i < count; i++) {
+        if (gdef.get_glyph_class (buffer->info[i].codepoint) == GDEF::MarkGlyph) {
+          buffer->pos[i].x_advance = 0;
+        }
+      }
+    } else {
+      for (unsigned int i = 1; i < count; i++) {
+        if (gdef.get_glyph_class (buffer->info[i].codepoint) == GDEF::MarkGlyph) {
+          hb_glyph_position_t& pos = buffer->pos[i];
+          pos.x_offset -= pos.x_advance;
+          pos.x_advance = 0;
+        }
+      }
+    }
+  } else {
+    /* no GDEF classes available, so use General Category as a fallback */
+    if (buffer->props.direction == HB_DIRECTION_RTL) {
+      for (unsigned int i = 1; i < count; i++) {
+        if (buffer->info[i].general_category() == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
+          buffer->pos[i].x_advance = 0;
+        }
+      }
+    } else {
+      for (unsigned int i = 1; i < count; i++) {
+        if (buffer->info[i].general_category() == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
+          hb_glyph_position_t& pos = buffer->pos[i];
+          pos.x_offset -= pos.x_advance;
+          pos.x_advance = 0;
+        }
+      }
+    }
+  }
+
   GPOS::position_finish (buffer);
 }
 
 
--- a/gfx/harfbuzz/src/hb-ot-layout.h
+++ b/gfx/harfbuzz/src/hb-ot-layout.h
@@ -194,14 +194,14 @@ hb_ot_layout_position_start (hb_buffer_t
 hb_bool_t
 hb_ot_layout_position_lookup (hb_font_t    *font,
 			      hb_buffer_t  *buffer,
 			      unsigned int  lookup_index,
 			      hb_mask_t     mask);
 
 /* Should be called after all the position_lookup's are done */
 void
-hb_ot_layout_position_finish (hb_buffer_t  *buffer);
+hb_ot_layout_position_finish (hb_face_t *face, hb_buffer_t *buffer);
 
 
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_H */
--- a/gfx/harfbuzz/src/hb-ot-shape-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-private.hh
@@ -99,22 +99,50 @@ is_variation_selector (hb_codepoint_t un
 }
 
 static inline unsigned int
 _hb_unicode_modified_combining_class (hb_unicode_funcs_t *ufuncs,
 				      hb_codepoint_t      unicode)
 {
   int c = hb_unicode_combining_class (ufuncs, unicode);
 
+  /* For Hebrew, we permute the "fixed-position" classes 10-25 into the order
+   * described in the SBL Hebrew manual http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
+   * (as recommended by http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
+   */
+  static const int permuted_hebrew_classes[25 - 10 + 1] = {
+    /* 10 sheva */        15,
+    /* 11 hataf segol */  16,
+    /* 12 hataf patah */  17,
+    /* 13 hataf qamats */ 18,
+    /* 14 hiriq */        19,
+    /* 15 tsere */        20,
+    /* 16 segol */        21,
+    /* 17 patah */        22,
+    /* 18 qamats */       23,
+    /* 19 holam */        14,
+    /* 20 qubuts */       24,
+    /* 21 dagesh */       12,
+    /* 22 meteg */        25,
+    /* 23 rafe */         13,
+    /* 24 shin dot */     10,
+    /* 25 sin dot */      11,
+  };
+
   /* Modify the combining-class to suit Arabic better.  See:
    * http://unicode.org/faq/normalization.html#8
    * http://unicode.org/faq/normalization.html#9
    */
   if (unlikely (hb_in_range<int> (c, 27, 33)))
     c = c == 33 ? 27 : c + 1;
+  /* The equivalent fix for Hebrew is more complex,
+   * see the SBL Hebrew manual.
+   */
+  else if (unlikely (hb_in_range<int> (c, 10, 25)))
+    c = permuted_hebrew_classes[c - 10];
 
   return c;
 }
 
 static inline void
 hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
 {
   info->general_category() = hb_unicode_general_category (unicode, info->codepoint);
--- a/gfx/harfbuzz/src/hb-ot-shape.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape.cc
@@ -294,25 +294,46 @@ hb_ot_position_complex (hb_ot_shape_cont
 						   HB_DIRECTION_LTR,
 						   &c->buffer->pos[i].x_offset,
 						   &c->buffer->pos[i].y_offset);
     }
 
     c->applied_position_complex = TRUE;
   }
 
-  hb_ot_layout_position_finish (c->buffer);
+  hb_ot_layout_position_finish (c->face, c->buffer);
 
   return;
 }
 
 static void
-hb_position_complex_fallback (hb_ot_shape_context_t *c HB_UNUSED)
+hb_position_complex_fallback (hb_ot_shape_context_t *c)
 {
-  /* TODO Mark pos */
+  unsigned int count = c->buffer->len;
+  if (c->buffer->props.direction == HB_DIRECTION_RTL) {
+    for (unsigned int i = 1; i < count; i++) {
+      unsigned int gen_cat = c->buffer->info[i].general_category();
+      if ((1<<gen_cat) & ((1<<HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)|
+                          (1<<HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK)|
+                          (1<<HB_UNICODE_GENERAL_CATEGORY_FORMAT))) {
+        c->buffer->pos[i].x_advance = 0;
+      }
+    }
+  } else {
+    for (unsigned int i = 1; i < count; i++) {
+      unsigned int gen_cat = c->buffer->info[i].general_category();
+      if ((1<<gen_cat) & ((1<<HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)|
+                          (1<<HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK)|
+                          (1<<HB_UNICODE_GENERAL_CATEGORY_FORMAT))) {
+        hb_glyph_position_t& pos = c->buffer->pos[i];
+        pos.x_offset = -pos.x_advance;
+        pos.x_advance = 0;
+      }
+    }
+  }
 }
 
 static void
 hb_truetype_kern (hb_ot_shape_context_t *c)
 {
   /* TODO Check for kern=0 */
   unsigned int count = c->buffer->len;
   for (unsigned int i = 1; i < count; i++) {
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1353,21 +1353,29 @@ gfxPlatform::FontsPrefsChanged(const cha
     NS_ASSERTION(aPref != nsnull, "null preference");
     if (!strcmp(GFX_DOWNLOADABLE_FONTS_ENABLED, aPref)) {
         mAllowDownloadableFonts = UNINITIALIZED_VALUE;
     } else if (!strcmp(GFX_DOWNLOADABLE_FONTS_SANITIZE, aPref)) {
         mDownloadableFontsSanitize = UNINITIALIZED_VALUE;
 #ifdef MOZ_GRAPHITE
     } else if (!strcmp(GFX_PREF_GRAPHITE_SHAPING, aPref)) {
         mGraphiteShapingEnabled = UNINITIALIZED_VALUE;
-        gfxFontCache::GetCache()->AgeAllGenerations();
+        gfxFontCache *fontCache = gfxFontCache::GetCache();
+        if (fontCache) {
+            fontCache->AgeAllGenerations();
+            fontCache->FlushShapedWordCaches();
+        }
 #endif
     } else if (!strcmp(GFX_PREF_HARFBUZZ_SCRIPTS, aPref)) {
         mUseHarfBuzzScripts = UNINITIALIZED_VALUE;
-        gfxFontCache::GetCache()->AgeAllGenerations();
+        gfxFontCache *fontCache = gfxFontCache::GetCache();
+        if (fontCache) {
+            fontCache->AgeAllGenerations();
+            fontCache->FlushShapedWordCaches();
+        }
     } else if (!strcmp(BIDI_NUMERAL_PREF, aPref)) {
         mBidiNumeralOption = UNINITIALIZED_VALUE;
     }
 }
 
 
 PRLogModuleInfo*
 gfxPlatform::GetLog(eGfxLog aWhichLog)
--- a/gfx/thebes/nsIOSurface.h
+++ b/gfx/thebes/nsIOSurface.h
@@ -39,17 +39,17 @@
 
 #ifndef nsIOSurface_h__
 #define nsIOSurface_h__
 #ifdef XP_MACOSX
 
 #import <OpenGL/OpenGL.h>
 
 class gfxASurface;
-class _CGLContextObject;
+struct _CGLContextObject;
 
 typedef _CGLContextObject* CGLContextObj;
 typedef uint32_t IOSurfaceID;
 
 class THEBES_API nsIOSurface {
     NS_INLINE_DECL_REFCOUNTING(nsIOSurface)
 public:
   static already_AddRefed<nsIOSurface> CreateIOSurface(int aWidth, int aHeight);
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -263,20 +263,39 @@ GetCurrentBatteryInformation(hal::Batter
   FILE *capacityFile = fopen("/sys/class/power_supply/battery/capacity", "r");
   double capacity = dom::battery::kDefaultLevel * 100;
   if (capacityFile) {
     fscanf(capacityFile, "%lf", &capacity);
     fclose(capacityFile);
   }
 
   FILE *chargingFile = fopen("/sys/class/power_supply/battery/charging_source", "r");
-  int chargingSrc = 1;
+  int chargingSrc = BATTERY_CHARGING_USB;
+  bool done = false;
   if (chargingFile) {
     fscanf(chargingFile, "%d", &chargingSrc);
     fclose(chargingFile);
+    done = true;
+  }
+
+  if (!done) {
+    // toro devices support
+    chargingFile = fopen("/sys/class/power_supply/battery/status", "r");
+    if (chargingFile) {
+      char status[16];
+      fscanf(chargingFile, "%s", &status);
+      if (!strcmp(status, "Charging") || !strcmp(status, "Full")) {
+        // no way here to know if we're charging from USB or AC.
+        chargingSrc = BATTERY_CHARGING_USB;
+      } else {
+        chargingSrc = BATTERY_NOT_CHARGING;
+      }
+      fclose(chargingFile);
+      done = true;
+    }
   }
 
   #ifdef DEBUG
   if (chargingSrc != BATTERY_NOT_CHARGING &&
       chargingSrc != BATTERY_CHARGING_USB &&
       chargingSrc != BATTERY_CHARGING_AC) {
     HAL_LOG(("charging_source contained unknown value: %d", chargingSrc));
   }
--- a/js/src/aclocal.m4
+++ b/js/src/aclocal.m4
@@ -9,10 +9,11 @@ builtin(include, build/autoconf/altoptio
 builtin(include, build/autoconf/moznbytetype.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
 builtin(include, build/autoconf/mozcommonheader.m4)dnl
 builtin(include, build/autoconf/acwinpaths.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/gcc-pr49911.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
+builtin(include, build/autoconf/compiler-opts.m4)dnl
 
 MOZ_PROG_CHECKMSYS()
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -2691,16 +2691,21 @@ public:
         return (char *)where + rel;
     }
 
     static void *getPointer(void* where)
     {
         return reinterpret_cast<void **>(where)[-1];
     }
 
+    static void **getPointerRef(void* where)
+    {
+        return &reinterpret_cast<void **>(where)[-1];
+    }
+
     static void setPointer(void* where, const void* value)
     {
         js::JaegerSpew(js::JSpew_Insns,
                        ISPFX "##setPtr     ((where=%p)) ((value=%p))\n", where, value);
         reinterpret_cast<const void**>(where)[-1] = value;
     }
 
 private:
--- a/js/src/assembler/wtf/Assertions.h
+++ b/js/src/assembler/wtf/Assertions.h
@@ -24,18 +24,26 @@
  */
 
 #ifndef WTF_Assertions_h
 #define WTF_Assertions_h
 
 #include "Platform.h"
 #include "mozilla/Assertions.h"
 
+#ifndef DEBUG
+   /*
+    * Prevent unused-variable warnings by defining the macro WTF uses to test
+    * for assertions taking effect.
+    */
+#  define ASSERT_DISABLED 1
+#endif
+
 #define ASSERT(assertion) MOZ_ASSERT(assertion)
-#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
+#define ASSERT_UNUSED(variable, assertion) (((void)variable), ASSERT(assertion))
 #define ASSERT_NOT_REACHED() MOZ_NOT_REACHED("")
 #define CRASH() MOZ_Crash()
 #define COMPILE_ASSERT(exp, name) MOZ_STATIC_ASSERT(exp, #name)
 
 #endif
 
 #if 0
 /*
new file mode 100644
--- /dev/null
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -0,0 +1,13 @@
+dnl Add compiler specific options
+
+AC_DEFUN([MOZ_COMPILER_OPTS],
+[
+if test "$CLANG_CXX"; then
+    ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
+    ## returned by C functions. This is possible because we use knowledge about the ABI
+    ## to typedef it to a C type with the same layout when the headers are included
+    ## from C.
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-return-type-c-linkage"
+fi
+])
+
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -180,18 +180,21 @@ MapObject::initClass(JSContext *cx, JSOb
 }
 
 void
 MapObject::mark(JSTracer *trc, JSObject *obj)
 {
     MapObject *mapobj = static_cast<MapObject *>(obj);
     if (ValueMap *map = mapobj->getData()) {
         for (ValueMap::Range r = map->all(); !r.empty(); r.popFront()) {
-            gc::MarkValue(trc, r.front().key, "key");
-            gc::MarkValue(trc, r.front().value, "value");
+            const HeapValue &key = r.front().key;
+            HeapValue tmp(key);
+            gc::MarkValue(trc, &tmp, "key");
+            JS_ASSERT(tmp.get() == key.get());
+            gc::MarkValue(trc, &r.front().value, "value");
         }
     }
 }
 
 void
 MapObject::finalize(JSContext *cx, JSObject *obj)
 {
     MapObject *mapobj = static_cast<MapObject *>(obj);
@@ -326,18 +329,22 @@ SetObject::initClass(JSContext *cx, JSOb
     return InitClass(cx, &obj->asGlobal(), &class_, JSProto_Set, construct, methods);
 }
 
 void
 SetObject::mark(JSTracer *trc, JSObject *obj)
 {
     SetObject *setobj = static_cast<SetObject *>(obj);
     if (ValueSet *set = setobj->getData()) {
-        for (ValueSet::Range r = set->all(); !r.empty(); r.popFront())
-            gc::MarkValue(trc, r.front(), "key");
+        for (ValueSet::Range r = set->all(); !r.empty(); r.popFront()) {
+            const HeapValue &key = r.front();
+            HeapValue tmp(key);
+            gc::MarkValue(trc, &tmp, "key");
+            JS_ASSERT(tmp.get() == key.get());
+        }
     }
 }
 
 void
 SetObject::finalize(JSContext *cx, JSObject *obj)
 {
     SetObject *setobj = static_cast<SetObject *>(obj);
     if (ValueSet *set = setobj->getData())
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -3150,16 +3150,17 @@ fi         # GNU_CC
 if test "$SOLARIS_SUNPRO_CC"; then
 VISIBILITY_FLAGS='-xldscope=hidden'
 fi         # Sun Studio on Solaris
 
 AC_SUBST(WRAP_SYSTEM_INCLUDES)
 AC_SUBST(VISIBILITY_FLAGS)
 
 MOZ_GCC_PR49911
+MOZ_COMPILER_OPTS
 
 dnl Check for __force_align_arg_pointer__ for SSE2 on gcc
 dnl ========================================================
 if test "$GNU_CC"; then
   CFLAGS_save="${CFLAGS}"
   CFLAGS="${CFLAGS} -Werror"
   AC_CACHE_CHECK(for __force_align_arg_pointer__ attribute,
                  ac_cv_force_align_arg_pointer,
--- a/js/src/gc/Barrier-inl.h
+++ b/js/src/gc/Barrier-inl.h
@@ -129,18 +129,21 @@ inline void
 HeapValue::writeBarrierPost(const Value &value, void *addr)
 {
 }
 
 inline void
 HeapValue::writeBarrierPre(JSCompartment *comp, const Value &value)
 {
 #ifdef JSGC_INCREMENTAL
-    if (comp->needsBarrier())
-        js::gc::MarkValueUnbarriered(comp->barrierTracer(), value, "write barrier");
+    if (comp->needsBarrier()) {
+        Value tmp(value);
+        js::gc::MarkValueUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
+        JS_ASSERT(tmp == value);
+    }
 #endif
 }
 
 inline void
 HeapValue::writeBarrierPost(JSCompartment *comp, const Value &value, void *addr)
 {
 }
 
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -314,16 +314,17 @@ class HeapValue
      * This is a faster version of operator=. Normally, operator= has to
      * determine the compartment of the value before it can decide whether to do
      * the barrier. If you already know the compartment, it's faster to pass it
      * in.
      */
     inline void set(JSCompartment *comp, const Value &v);
 
     const Value &get() const { return value; }
+    Value *unsafeGet() { return &value; }
     operator const Value &() const { return value; }
 
     bool isUndefined() const { return value.isUndefined(); }
     bool isNull() const { return value.isNull(); }
     bool isBoolean() const { return value.isBoolean(); }
     bool isTrue() const { return value.isTrue(); }
     bool isFalse() const { return value.isFalse(); }
     bool isNumber() const { return value.isNumber(); }
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -470,17 +470,17 @@ IonScript::trace(JSTracer *trc)
 {
     if (method_)
         MarkIonCode(trc, method_, "method");
 
     if (deoptTable_)
         MarkIonCode(trc, deoptTable_, "deoptimizationTable");
 
     for (size_t i = 0; i < numConstants(); i++)
-        gc::MarkValue(trc, getConstant(i), "constant");
+        gc::MarkValue(trc, &getConstant(i), "constant");
 }
 
 void
 IonScript::copySnapshots(const SnapshotWriter *writer)
 {
     JS_ASSERT(writer->size() == snapshotsSize_);
     memcpy((uint8 *)this + snapshots_, writer->buffer(), snapshotsSize_);
 }
--- a/js/src/ion/IonFrames.cpp
+++ b/js/src/ion/IonFrames.cpp
@@ -331,17 +331,17 @@ MarkIonJSFrame(JSTracer *trc, const IonF
         // is now NULL or recompiled). Manually trace it here.
         IonScript::Trace(trc, ionScript);
     } else if (CalleeTokenIsFunction(layout->calleeToken())) {
         JSFunction *fun = CalleeTokenToFunction(layout->calleeToken());
 
         // Trace function arguments.
         Value *argv = layout->argv();
         for (size_t i = 0; i < fun->nargs; i++)
-            gc::MarkValueRoot(trc, argv[i], "ion-argv");
+            gc::MarkValueRoot(trc, &argv[i], "ion-argv");
 
         ionScript = fun->script()->ion;
     } else {
         ionScript = CalleeTokenToScript(layout->calleeToken())->ion;
     }
 
     const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp());
 
@@ -355,22 +355,22 @@ MarkIonJSFrame(JSTracer *trc, const IonF
     // No support for manual spill calls yet.
     JS_ASSERT(actual.empty() && spilled.empty());
 
     // Scan through slots which contain pointers (or on punboxing systems,
     // actual values).
     uint32 slot;
     while (safepoint.getGcSlot(&slot)) {
         uintptr_t *ref = layout->slotRef(slot);
-        gc::MarkThingOrValueRoot(trc, *ref, "ion-gc-slot");
+        gc::MarkThingOrValueRoot(trc, ref, "ion-gc-slot");
     }
 
     while (safepoint.getValueSlot(&slot)) {
         Value *v = (Value *)layout->slotRef(slot);
-        gc::MarkValueRoot(trc, *v, "ion-gc-slot");
+        gc::MarkValueRoot(trc, v, "ion-gc-slot");
     }
 }
 
 static void
 MarkIonActivation(JSTracer *trc, uint8 *top)
 {
     for (IonFrameIterator frames(top); frames.more(); ++frames) {
         switch (frames.type()) {
--- a/js/src/ion/arm/Assembler-arm.cpp
+++ b/js/src/ion/arm/Assembler-arm.cpp
@@ -553,27 +553,27 @@ Assembler::TraceJumpRelocations(JSTracer
 }
 
 static void
 TraceDataRelocations(JSTracer *trc, uint8 *buffer, CompactBufferReader &reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
         void *ptr = js::ion::Assembler::getPtr32Target((Instruction*)(buffer + offset));
-        gc::MarkThingOrValueRoot(trc, (uintptr_t)ptr, "immgcptr");
+        gc::MarkThingOrValueRoot(trc, reinterpret_cast<uintptr_t *>(&ptr), "immgcptr");
     }
 
 }
 static void
 TraceDataRelocations(JSTracer *trc, ARMBuffer *buffer, CompactBufferReader &reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
         void *ptr = ion::Assembler::getPtr32Target((Instruction*)(buffer->getInst(BufferOffset(offset))));
-        gc::MarkThingOrValueRoot(trc, (uintptr_t)ptr, "immgcptr");
+        gc::MarkThingOrValueRoot(trc, reinterpret_cast<uintptr_t *>(&ptr), "immgcptr");
     }
 
 }
 void
 Assembler::TraceDataRelocations(JSTracer *trc, IonCode *code, CompactBufferReader &reader)
 {
     ::TraceDataRelocations(trc, code->raw(), reader);
 }
--- a/js/src/ion/shared/Assembler-x86-shared.cpp
+++ b/js/src/ion/shared/Assembler-x86-shared.cpp
@@ -59,18 +59,18 @@ AssemblerX86Shared::copyDataRelocationTa
         memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length());
 }
 
 static void
 TraceDataRelocations(JSTracer *trc, uint8 *buffer, CompactBufferReader &reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
-        void *ptr = JSC::X86Assembler::getPointer(buffer + offset);
-        gc::MarkThingOrValueRoot(trc, reinterpret_cast<uintptr_t>(ptr), "imm-gc-word");
+        void **ptr = JSC::X86Assembler::getPointerRef(buffer + offset);
+        gc::MarkThingOrValueRoot(trc, reinterpret_cast<uintptr_t *>(ptr), "imm-gc-word");
     }
 }
 
 void
 AssemblerX86Shared::TraceDataRelocations(JSTracer *trc, IonCode *code, CompactBufferReader &reader)
 {
     ::TraceDataRelocations(trc, code->raw(), reader);
 }
--- a/js/src/jit-test/lib/prolog.js
+++ b/js/src/jit-test/lib/prolog.js
@@ -3,8 +3,11 @@
 var appendToActual = function(s) {
     actual += s + ',';
 }
 
 if (!("gczeal" in this)) {
   gczeal = function() { }
 }
 
+if (!("schedulegc" in this)) {
+  schedulegc = function() { }
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug727921.js
@@ -0,0 +1,10 @@
+(function() {
+    let(d) {
+        yield
+    }
+})()
+eval("\
+    (function(){\
+        schedulegc(5), 'a'.replace(/a/,function(){yield})\
+    })\
+")()
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4428,30 +4428,23 @@ JS_ElementIteratorStub(JSContext *cx, JS
 {
     JS_ASSERT(!keysonly);
     return JS_NewElementIterator(cx, obj);
 }
 
 JS_PUBLIC_API(jsval)
 JS_GetReservedSlot(JSObject *obj, uint32_t index)
 {
-    if (!obj->isNative())
-        return UndefinedValue();
-
-    return GetReservedSlot(obj, index);
+    return obj->getReservedSlot(index);
 }
 
 JS_PUBLIC_API(void)
 JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v)
 {
-    if (!obj->isNative())
-        return;
-
-    SetReservedSlot(obj, index, v);
-    GCPoke(obj->compartment()->rt, NullValue());
+    obj->setReservedSlot(index, v);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1857,17 +1857,21 @@ JS_StringHasBeenInterned(JSContext *cx, 
  * string must be appropriately rooted to avoid being collected by the GC.
  */
 static JS_ALWAYS_INLINE jsid
 INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str)
 {
     jsid id;
     JS_ASSERT(str);
     JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
+#ifdef DEBUG
     JS_ASSERT(JS_StringHasBeenInterned(cx, str));
+#else
+    (void)cx;
+#endif
     JSID_BITS(id) = (size_t)str;
     return id;
 }
 
 static JS_ALWAYS_INLINE JSBool
 JSID_IS_INT(jsid id)
 {
     return !!(JSID_BITS(id) & JSID_TYPE_INT);
@@ -5310,16 +5314,18 @@ JS_IsConstructing(JSContext *cx, const j
 #ifdef DEBUG
     JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
     if (JS_ObjectIsFunction(cx, callee)) {
         JSFunction *fun = JS_ValueToFunction(cx, JS_CALLEE(cx, vp));
         JS_ASSERT((JS_GetFunctionFlags(fun) & JSFUN_CONSTRUCTOR) != 0);
     } else {
         JS_ASSERT(JS_GetClass(callee)->construct != NULL);
     }
+#else
+    (void)cx;
 #endif
 
     return JSVAL_IS_MAGIC_IMPL(JSVAL_TO_IMPL(vp[1]));
 }
 
 /*
  * If a constructor does not have any static knowledge about the type of
  * object to create, it can request that the JS engine create a default new
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -1429,43 +1429,42 @@ JSObject::makeDenseArraySlow(JSContext *
 
     return true;
 }
 
 #if JS_HAS_TOSOURCE
 class ArraySharpDetector
 {
     JSContext *cx;
-    JSHashEntry *he;
+    bool success;
     bool alreadySeen;
     bool sharp;
 
   public:
     ArraySharpDetector(JSContext *cx)
       : cx(cx),
-        he(NULL),
+        success(false),
         alreadySeen(false),
         sharp(false)
     {}
 
     bool init(JSObject *obj) {
-        he = js_EnterSharpObject(cx, obj, NULL, &alreadySeen);
-        if (!he)
+        success = js_EnterSharpObject(cx, obj, NULL, &alreadySeen, &sharp);
+        if (!success)
             return false;
-        sharp = IS_SHARP(he);
         return true;
     }
 
     bool initiallySharp() const {
         JS_ASSERT_IF(sharp, alreadySeen);
         return sharp;
     }
 
     ~ArraySharpDetector() {
-        if (he && !sharp)
+        if (success && !sharp)
             js_LeaveSharpObject(cx, NULL);
     }
 };
 
 static JSBool
 array_toSource(JSContext *cx, uintN argc, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -152,17 +152,17 @@ js_InitBooleanClass(JSContext *cx, JSObj
 {
     JS_ASSERT(obj->isNative());
 
     GlobalObject *global = &obj->asGlobal();
 
     JSObject *booleanProto = global->createBlankPrototype(cx, &BooleanClass);
     if (!booleanProto)
         return NULL;
-    booleanProto->setPrimitiveThis(BooleanValue(false));
+    booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
 
     JSFunction *ctor = global->createConstructor(cx, Boolean, &BooleanClass,
                                                  CLASS_ATOM(cx, Boolean), 1);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, booleanProto))
         return NULL;
--- a/js/src/jsboolinlines.h
+++ b/js/src/jsboolinlines.h
@@ -37,23 +37,25 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsboolinlines_h___
 #define jsboolinlines_h___
 
 #include "jsobjinlines.h"
 
+#include "vm/BooleanObject-inl.h"
+
 namespace js {
 
 inline bool
 BooleanGetPrimitiveValue(JSContext *cx, JSObject &obj, Value *vp)
 {
     if (obj.isBoolean()) {
-        *vp = obj.getPrimitiveThis();
+        *vp = BooleanValue(obj.asBoolean().unbox());
         return true;
     }
 
     extern bool BooleanGetPrimitiveValueSlow(JSContext *, JSObject &, Value *);
     return BooleanGetPrimitiveValueSlow(cx, obj, vp);
 }
 
 } /* namespace js */
--- a/js/src/jsclone.cpp
+++ b/js/src/jsclone.cpp
@@ -37,17 +37,20 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "jsclone.h"
 #include "jsdate.h"
 #include "jstypedarray.h"
 
 #include "jstypedarrayinlines.h"
 
+#include "vm/BooleanObject-inl.h"
+#include "vm/NumberObject-inl.h"
 #include "vm/RegExpObject-inl.h"
+#include "vm/StringObject-inl.h"
 
 using namespace js;
 
 JS_FRIEND_API(uint64_t)
 js_GetSCOffset(JSStructuredCloneWriter* writer)
 {
     JS_ASSERT(writer);
     return writer->output().count() * sizeof(uint64_t);
@@ -531,22 +534,22 @@ JSStructuredCloneWriter::startWrite(cons
             return out.writePair(SCTAG_DATE_OBJECT, 0) && out.writeDouble(d);
         } else if (obj->isObject() || obj->isArray()) {
             return startObject(obj);
         } else if (js_IsTypedArray(obj)) {
             return writeTypedArray(obj);
         } else if (js_IsArrayBuffer(obj)) {
             return writeArrayBuffer(obj);
         } else if (obj->isBoolean()) {
-            return out.writePair(SCTAG_BOOLEAN_OBJECT, obj->getPrimitiveThis().toBoolean());
+            return out.writePair(SCTAG_BOOLEAN_OBJECT, obj->asBoolean().unbox());
         } else if (obj->isNumber()) {
             return out.writePair(SCTAG_NUMBER_OBJECT, 0) &&
-                   out.writeDouble(obj->getPrimitiveThis().toNumber());
+                   out.writeDouble(obj->asNumber().unbox());
         } else if (obj->isString()) {
-            return writeString(SCTAG_STRING_OBJECT, obj->getPrimitiveThis().toString());
+            return writeString(SCTAG_STRING_OBJECT, obj->asString().unbox());
         }
 
         if (callbacks && callbacks->write)
             return callbacks->write(context(), this, obj, closure);
         /* else fall through */
     }
 
     JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_SC_UNSUPPORTED_TYPE);
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -965,16 +965,17 @@ JSContext::JSContext(JSRuntime *rt)
     reportGranularity(JS_DEFAULT_JITREPORT_GRANULARITY),
     localeCallbacks(NULL),
     resolvingList(NULL),
     generatingError(false),
     compartment(NULL),
     stack(thisDuringConstruction()),  /* depends on cx->thread_ */
     parseMapPool_(NULL),
     globalObject(NULL),
+    sharpObjectMap(this),
     argumentFormatMap(NULL),
     lastMessage(NULL),
     errorReporter(NULL),
     operationCallback(NULL),
     data(NULL),
     data2(NULL),
 #ifdef JS_THREADSAFE
     outstandingRequests(0),
@@ -1265,16 +1266,36 @@ JSContext::sizeOfIncludingThis(JSMallocS
     /*
      * There are other JSContext members that could be measured; the following
      * ones have been found by DMD to be worth measuring.  More stuff may be
      * added later.
      */
     return mallocSizeOf(this) + busyArrays.sizeOfExcludingThis(mallocSizeOf);
 }
 
+void
+JSContext::mark(JSTracer *trc)
+{
+    /* Stack frames and slots are traced by StackSpace::mark. */
+
+    /* Mark other roots-by-definition in the JSContext. */
+    if (globalObject && !hasRunOption(JSOPTION_UNROOTED_GLOBAL))
+        MarkObjectRoot(trc, globalObject, "global object");
+    if (isExceptionPending())
+        MarkValueRoot(trc, &exception, "exception");
+
+    if (autoGCRooters)
+        autoGCRooters->traceAll(trc);
+
+    if (sharpObjectMap.depth > 0)
+        js_TraceSharpMap(trc, &sharpObjectMap);
+
+    MarkValueRoot(trc, &iterValue, "iterValue");
+}
+
 namespace JS {
 
 #if defined JS_THREADSAFE && defined DEBUG
 
 AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx)
     : cx(cx)
 {
     JS_ASSERT(cx->runtime->requestDepth || cx->runtime->gcRunning);
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -71,22 +71,33 @@
 #pragma warning(push)
 #pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
 #endif
 
 JS_BEGIN_EXTERN_C
 struct DtoaState;
 JS_END_EXTERN_C
 
+struct JSSharpInfo {
+    bool hasGen;
+    bool isSharp;
+
+    JSSharpInfo() : hasGen(false), isSharp(false) {}
+};
+
+typedef js::HashMap<JSObject *, JSSharpInfo> JSSharpTable;
+
 struct JSSharpObjectMap {
-    jsrefcount  depth;
-    uint32_t    sharpgen;
-    JSHashTable *table;
+    jsrefcount   depth;
+    uint32_t     sharpgen;
+    JSSharpTable table;
 
-    JSSharpObjectMap() : depth(0), sharpgen(0), table(NULL) {}
+    JSSharpObjectMap(JSContext *cx) : depth(0), sharpgen(0), table(js::TempAllocPolicy(cx)) {
+        table.init();
+    }
 };
 
 namespace js {
 
 namespace mjit {
 class JaegerCompartment;
 }
 
@@ -1129,16 +1140,18 @@ struct JSContext : js::ContextFriendFiel
 
     JS_FRIEND_API(size_t) sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const;
 
     static inline JSContext *fromLinkField(JSCList *link) {
         JS_ASSERT(link);
         return reinterpret_cast<JSContext *>(uintptr_t(link) - offsetof(JSContext, link));
     }
 
+    void mark(JSTracer *trc);
+
   private:
     /*
      * The allocation code calls the function to indicate either OOM failure
      * when p is null or that a memory pressure counter has reached some
      * threshold when p is not null. The function takes the pointer and not
      * a boolean flag to minimize the amount of code in its inlined callers.
      */
     JS_FRIEND_API(void) checkMallocGCPressure(void *p);
@@ -1566,28 +1579,28 @@ class AutoShapeVector : public AutoVecto
         JS_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 class AutoValueArray : public AutoGCRooter
 {
-    const js::Value *start_;
+    js::Value *start_;
     unsigned length_;
 
   public:
-    AutoValueArray(JSContext *cx, const js::Value *start, unsigned length
+    AutoValueArray(JSContext *cx, js::Value *start, unsigned length
                    JS_GUARD_OBJECT_NOTIFIER_PARAM)
         : AutoGCRooter(cx, VALARRAY), start_(start), length_(length)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
-    const Value *start() const { return start_; }
+    Value *start() { return start_; }
     unsigned length() const { return length_; }
 
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 /*
  * Allocation policy that uses JSRuntime::malloc_ and friends, so that
  * memory pressure is properly accounted for. This is suitable for
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -441,18 +441,21 @@ JSCompartment::wrap(JSContext *cx, AutoI
  * called only for per-compartment GCs, since full GCs naturally follow pointers
  * across compartments.
  */
 void
 JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
 {
     JS_ASSERT(trc->runtime->gcCurrentCompartment);
 
-    for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront())
-        MarkValueRoot(trc, e.front().key, "cross-compartment wrapper");
+    for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
+        Value tmp = e.front().key;
+        MarkValueRoot(trc, &tmp, "cross-compartment wrapper");
+        JS_ASSERT(tmp == e.front().key);
+    }
 }
 
 void
 JSCompartment::mark(JSTracer *trc)
 {
 #ifdef JS_ION
     if (ionCompartment_)
         ionCompartment_->mark(trc, this);
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -427,19 +427,18 @@ exn_trace(JSTracer *trc, JSObject *obj)
         for (vcount = i = 0; i != priv->stackDepth; ++i, ++elem) {
             if (elem->funName)
                 MarkString(trc, elem->funName, "stack trace function name");
             if (IS_GC_MARKING_TRACER(trc) && elem->filename)
                 js_MarkScriptFilename(elem->filename);
             vcount += elem->argc;
         }
         vp = GetStackTraceValueBuffer(priv);
-        for (i = 0; i != vcount; ++i, ++vp) {
-            MarkValue(trc, *vp, "stack trace argument");
-        }
+        for (i = 0; i != vcount; ++i, ++vp)
+            MarkValue(trc, vp, "stack trace argument");
     }
 }
 
 /* NB: An error object's private must be set through this function. */
 static void
 SetExnPrivate(JSContext *cx, JSObject *exnObject, JSExnPrivate *priv)
 {
     JS_ASSERT(!exnObject->getPrivate());
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -95,22 +95,16 @@
 #include "vm/ArgumentsObject-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace mozilla;
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
-inline JSObject *
-JSObject::getThrowTypeError() const
-{
-    return global().getThrowTypeError();
-}
-
 JSBool
 js_GetArgsValue(JSContext *cx, StackFrame *fp, Value *vp)
 {
     JSObject *argsobj;
     if (fp->hasOverriddenArgs()) {
         JS_ASSERT(fp->hasCallObj());
         return fp->callObj().getProperty(cx, cx->runtime->atomState.argumentsAtom, vp);
     }
@@ -470,18 +464,18 @@ strictargs_resolve(JSContext *cx, JSObje
             return true;
     } else {
         if (!JSID_IS_ATOM(id, cx->runtime->atomState.calleeAtom) &&
             !JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
             return true;
         }
 
         attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED;
-        getter = CastAsPropertyOp(argsobj.getThrowTypeError());
-        setter = CastAsStrictPropertyOp(argsobj.getThrowTypeError());
+        getter = CastAsPropertyOp(argsobj.global().getThrowTypeError());
+        setter = CastAsStrictPropertyOp(argsobj.global().getThrowTypeError());
     }
 
     Value undef = UndefinedValue();
     if (!js_DefineProperty(cx, &argsobj, id, &undef, getter, setter, attrs))
         return false;
 
     *objp = &argsobj;
     return true;
@@ -525,17 +519,17 @@ args_finalize(JSContext *cx, JSObject *o
     cx->free_(reinterpret_cast<void *>(obj->asArguments().data()));
 }
 
 static void
 args_trace(JSTracer *trc, JSObject *obj)
 {
     ArgumentsObject &argsobj = obj->asArguments();
     ArgumentsData *data = argsobj.data();
-    MarkValue(trc, data->callee, js_callee_str);
+    MarkValue(trc, &data->callee, js_callee_str);
     MarkValueRange(trc, argsobj.initialLength(), data->slots, js_arguments_str);
 
     /*
      * If a generator's arguments or call object escapes, and the generator
      * frame is not executing, the generator object needs to be marked because
      * it is not otherwise reachable. An executing generator is rooted by its
      * invocation.  To distinguish the two cases (which imply different access
      * paths to the generator object), we use the JSFRAME_FLOATING_GENERATOR
@@ -1324,17 +1318,17 @@ fun_resolve(JSContext *cx, JSObject *obj
 
         if (JSID_IS_ATOM(id, OFFSET_TO_ATOM(cx->runtime, offset))) {
             JS_ASSERT(!IsInternalFunctionObject(fun));
 
             PropertyOp getter;
             StrictPropertyOp setter;
             uintN attrs = JSPROP_PERMANENT;
             if (fun->isInterpreted() ? fun->inStrictMode() : fun->isBoundFunction()) {
-                JSObject *throwTypeError = fun->getThrowTypeError();
+                JSObject *throwTypeError = fun->global().getThrowTypeError();
 
                 getter = CastAsPropertyOp(throwTypeError);
                 setter = CastAsStrictPropertyOp(throwTypeError);
                 attrs |= JSPROP_GETTER | JSPROP_SETTER;
             } else {
                 getter = fun_getProperty;
                 setter = JS_StrictPropertyStub;
             }
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1894,17 +1894,17 @@ gc_root_traversal(JSTracer *trc, const R
         }
         JS_ASSERT(test == CGCT_VALID);
     }
 #endif
     const char *name = entry.value.name ? entry.value.name : "root";
     if (entry.value.type == JS_GC_ROOT_GCTHING_PTR)
         MarkGCThingRoot(trc, *reinterpret_cast<void **>(entry.key), name);
     else
-        MarkValueRoot(trc, *reinterpret_cast<Value *>(entry.key), name);
+        MarkValueRoot(trc, reinterpret_cast<Value *>(entry.key), name);
 }
 
 static void
 gc_lock_traversal(const GCLocks::Entry &entry, JSTracer *trc)
 {
     JS_ASSERT(entry.value >= 1);
     MarkGCThingRoot(trc, entry.key, "locked object");
 }
@@ -1922,17 +1922,17 @@ AutoEnumStateRooter::trace(JSTracer *trc
     gc::MarkObjectRoot(trc, obj, "JS::AutoEnumStateRooter.obj");
 }
 
 inline void
 AutoGCRooter::trace(JSTracer *trc)
 {
     switch (tag) {
       case JSVAL:
-        MarkValueRoot(trc, static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
+        MarkValueRoot(trc, &static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
         return;
 
       case PARSER:
         static_cast<Parser *>(this)->trace(trc);
         return;
 
       case ENUMERATOR:
         static_cast<AutoEnumStateRooter *>(this)->trace(trc);
@@ -1944,29 +1944,29 @@ AutoGCRooter::trace(JSTracer *trc)
         return;
       }
 
       case DESCRIPTORS: {
         PropDescArray &descriptors =
             static_cast<AutoPropDescArrayRooter *>(this)->descriptors;
         for (size_t i = 0, len = descriptors.length(); i < len; i++) {
             PropDesc &desc = descriptors[i];
-            MarkValueRoot(trc, desc.pd, "PropDesc::pd");
-            MarkValueRoot(trc, desc.value, "PropDesc::value");
-            MarkValueRoot(trc, desc.get, "PropDesc::get");
-            MarkValueRoot(trc, desc.set, "PropDesc::set");
+            MarkValueRoot(trc, &desc.pd, "PropDesc::pd");
+            MarkValueRoot(trc, &desc.value, "PropDesc::value");
+            MarkValueRoot(trc, &desc.get, "PropDesc::get");
+            MarkValueRoot(trc, &desc.set, "PropDesc::set");
         }
         return;
       }
 
       case DESCRIPTOR : {
         PropertyDescriptor &desc = *static_cast<AutoPropertyDescriptorRooter *>(this);
         if (desc.obj)
             MarkObjectRoot(trc, desc.obj, "Descriptor::obj");
-        MarkValueRoot(trc, desc.value, "Descriptor::value");
+        MarkValueRoot(trc, &desc.value, "Descriptor::value");
         if ((desc.attrs & JSPROP_GETTER) && desc.getter)
             MarkObjectRoot(trc, CastAsObject(desc.getter), "Descriptor::get");
         if (desc.attrs & JSPROP_SETTER && desc.setter)
             MarkObjectRoot(trc, CastAsObject(desc.setter), "Descriptor::set");
         return;
       }
 
       case NAMESPACES: {
@@ -2042,36 +2042,16 @@ void
 AutoGCRooter::traceAll(JSTracer *trc)
 {
     for (js::AutoGCRooter *gcr = this; gcr; gcr = gcr->down)
         gcr->trace(trc);
 }
 
 namespace js {
 
-JS_FRIEND_API(void)
-MarkContext(JSTracer *trc, JSContext *acx)
-{
-    /* Stack frames and slots are traced by StackSpace::mark. */
-
-    /* Mark other roots-by-definition in acx. */
-    if (acx->globalObject && !acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL))
-        MarkObjectRoot(trc, acx->globalObject, "global object");
-    if (acx->isExceptionPending())
-        MarkValueRoot(trc, acx->getPendingException(), "exception");
-
-    if (acx->autoGCRooters)
-        acx->autoGCRooters->traceAll(trc);
-
-    if (acx->sharpObjectMap.depth > 0)
-        js_TraceSharpMap(trc, &acx->sharpObjectMap);
-
-    MarkValueRoot(trc, acx->iterValue, "iterValue");
-}
-
 void
 MarkWeakReferences(GCMarker *gcmarker)
 {
     JS_ASSERT(gcmarker->isMarkStackEmpty());
     while (WatchpointMap::markAllIteratively(gcmarker) ||
            WeakMapBase::markAllIteratively(gcmarker) ||
            Debugger::markAllIteratively(gcmarker)) {
         gcmarker->drainMarkStack();
@@ -2099,17 +2079,17 @@ MarkRuntime(JSTracer *trc)
             MarkScriptRoot(trc, vec[i].script, "scriptPCCounters");
     }
 
     js_TraceAtomState(trc);
     rt->staticStrings.trace(trc);
 
     JSContext *iter = NULL;
     while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter))
-        MarkContext(trc, acx);
+        acx->mark(trc);
 
     for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
         if (c->activeAnalysis)
             c->markTypes(trc);
 
         /* During a GC, these are treated as weak pointers. */
         if (!IS_GC_MARKING_TRACER(trc)) {
             if (c->watchpointMap)
--- a/js/src/jsgcmark.cpp
+++ b/js/src/jsgcmark.cpp
@@ -41,19 +41,16 @@
  * The MarkX functions also handle non-GC object traversal. In this case, they
  * call a callback for each object visited. This is a recursive process; the
  * mark stacks are not involved. These callbacks may ask for the outgoing
  * pointers to be visited. Eventually, this leads to the MarkChildren functions
  * being called. These functions duplicate much of the functionality of
  * scanning functions, but they don't push onto an explicit stack.
  */
 
-using namespace js;
-using namespace js::gc;
-
 namespace js {
 namespace gc {
 
 static inline void
 PushMarkStack(GCMarker *gcmarker, JSXML *thing);
 
 static inline void
 PushMarkStack(GCMarker *gcmarker, JSObject *thing);
@@ -143,28 +140,30 @@ static void
 MarkRoot(JSTracer *trc, T *thing, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkInternal(trc, thing);
 }
 
 template <typename T>
 static void
-MarkRange(JSTracer *trc, size_t len, HeapPtr<T> *vec, const char *name) {
+MarkRange(JSTracer *trc, size_t len, HeapPtr<T> *vec, const char *name)
+{
     for (size_t i = 0; i < len; ++i) {
         if (T *obj = vec[i]) {
             JS_SET_TRACING_INDEX(trc, name, i);
             MarkInternal(trc, obj);
         }
     }
 }
 
 template <typename T>
 static void
-MarkRootRange(JSTracer *trc, size_t len, T **vec, const char *name) {
+MarkRootRange(JSTracer *trc, size_t len, T **vec, const char *name)
+{
     for (size_t i = 0; i < len; ++i) {
         JS_SET_TRACING_INDEX(trc, name, i);
         MarkInternal(trc, vec[i]);
     }
 }
 
 #define DeclMarkerImpl(base, type)                                                                \
 void                                                                                              \
@@ -299,53 +298,53 @@ MarkIdRootRange(JSTracer *trc, size_t le
         JS_SET_TRACING_INDEX(trc, name, i);
         MarkIdInternal(trc, vec[i]);
     }
 }
 
 /*** Value Marking ***/
 
 static inline void
-MarkValueInternal(JSTracer *trc, const Value &v)
+MarkValueInternal(JSTracer *trc, Value *v)
 {
-    if (v.isMarkable()) {
-        JS_ASSERT(v.toGCThing());
-        return MarkKind(trc, v.toGCThing(), v.gcKind());
+    if (v->isMarkable()) {
+        JS_ASSERT(v->toGCThing());
+        return MarkKind(trc, v->toGCThing(), v->gcKind());
     }
 }
 
 void
-MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name)
+MarkValue(JSTracer *trc, HeapValue *v, const char *name)
+{
+    JS_SET_TRACING_NAME(trc, name);
+    MarkValueInternal(trc, v->unsafeGet());
+}
+
+void
+MarkValueRoot(JSTracer *trc, Value *v, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkValueInternal(trc, v);
 }
 
 void
-MarkValueRoot(JSTracer *trc, const Value &v, const char *name)
-{
-    JS_SET_TRACING_NAME(trc, name);
-    MarkValueInternal(trc, v);
-}
-
-void
-MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name)
+MarkValueRange(JSTracer *trc, size_t len, HeapValue *vec, const char *name)
 {
     for (size_t i = 0; i < len; ++i) {
         JS_SET_TRACING_INDEX(trc, name, i);
-        MarkValueInternal(trc, vec[i]);
+        MarkValueInternal(trc, vec[i].unsafeGet());
     }
 }
 
 void
-MarkValueRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name)
+MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
 {
     for (size_t i = 0; i < len; ++i) {
         JS_SET_TRACING_INDEX(trc, name, i);
-        MarkValueInternal(trc, vec[i]);
+        MarkValueInternal(trc, &vec[i]);
     }
 }
 
 /*** Special Marking ***/
 
 /*
  * The unioned HeapPtr stored in script->globalObj needs special treatment to
  * typecheck correctly.
@@ -360,27 +359,27 @@ MarkObject(JSTracer *trc, const HeapPtr<
 void
 MarkShape(JSTracer *trc, const HeapPtr<const Shape> &thing, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkInternal(trc, const_cast<Shape *>(thing.get()));
 }
 
 void
-MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name)
+MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name)
 {
     JS_SET_TRACING_NAME(trc, name);
     MarkValueInternal(trc, v);
 }
 
 void
-MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name)
+MarkCrossCompartmentValue(JSTracer *trc, HeapValue *v, const char *name)
 {
-    if (v.isMarkable()) {
-        js::gc::Cell *cell = (js::gc::Cell *)v.toGCThing();
+    if (v->isMarkable()) {
+        Cell *cell = (Cell *)v->toGCThing();
         JSRuntime *rt = trc->runtime;
         if (rt->gcCurrentCompartment && cell->compartment() != rt->gcCurrentCompartment)
             return;
 
         MarkValue(trc, v, name);
     }
 }
 
@@ -430,33 +429,34 @@ PushMarkStack(GCMarker *gcmarker, types:
     if (thing->markIfUnmarked(gcmarker->getMarkColor()))
         gcmarker->pushType(thing);
 }
 
 static void
 MarkChildren(JSTracer *trc, JSScript *script);
 
 void
-MarkThingOrValueRoot(JSTracer *trc, uintptr_t word, const char *name)
+MarkThingOrValueRoot(JSTracer *trc, uintptr_t *word, const char *name)
 {
 #ifdef JS_PUNBOX64
     // All pointers on x64 will have the top bits cleared. If those bits
     // are not cleared, this must be a Value.
     {
-        if (word >> JSVAL_TAG_SHIFT) {
+        if (*word >> JSVAL_TAG_SHIFT) {
             jsval_layout layout;
-            layout.asBits = word;
+            layout.asBits = *word;
             Value v = IMPL_TO_JSVAL(layout);
-            gc::MarkValueRoot(trc, v, name);
+            gc::MarkValueRoot(trc, &v, name);
+	    *word = JSVAL_TO_IMPL(v).asBits;
 	    return;
         }
     }
 #endif
 
-    gc::MarkGCThingRoot(trc, reinterpret_cast<void *>(word), name);
+    gc::MarkGCThingRoot(trc, reinterpret_cast<void *>(*word), name);
 }
 
 static void
 PushMarkStack(GCMarker *gcmarker, JSScript *thing)
 {
     JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
 
     /*
@@ -673,17 +673,17 @@ MarkChildren(JSTracer *trc, JSObject *ob
     Class *clasp = shape->getObjectClass();
     if (clasp->trace)
         clasp->trace(trc, obj);
 
     if (shape->isNative()) {
         uint32_t nslots = obj->slotSpan();
         for (uint32_t i = 0; i < nslots; i++) {
             JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i);
-            MarkValueInternal(trc, obj->nativeGetSlot(i));
+            MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet());
         }
     }
 }
 
 static void
 MarkChildren(JSTracer *trc, JSString *str)
 {
     /*
@@ -702,17 +702,20 @@ MarkChildren(JSTracer *trc, JSString *st
 static void
 MarkChildren(JSTracer *trc, JSScript *script)
 {
     CheckScript(script, NULL);
 
     JS_ASSERT_IF(trc->runtime->gcCheckCompartment,
                  script->compartment() == trc->runtime->gcCheckCompartment);
 
-    MarkStringRootRange(trc, script->natoms, script->atoms, "atoms");
+    for (uint32_t i = 0; i < script->natoms; ++i) {
+        if (JSAtom *p = script->atoms[i])
+            MarkStringUnbarriered(trc, p, "atom");
+    }
 
     if (JSScript::isValidOffset(script->objectsOffset)) {
         JSObjectArray *objarray = script->objects();
         MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
     }
 
     if (JSScript::isValidOffset(script->regexpsOffset)) {
         JSObjectArray *objarray = script->regexps();
@@ -895,16 +898,18 @@ static void
 MarkChildren(JSTracer *trc, JSXML *xml)
 {
     js_TraceXML(trc, xml);
 }
 #endif
 
 } /* namespace gc */
 
+using namespace js::gc;
+
 inline void
 GCMarker::processMarkStackTop()
 {
     /*
      * The function uses explicit goto and implements the scanning of the
      * object directly. It allows to eliminate the tail recursion and
      * significantly improve the marking performance, see bug 641025.
      */
@@ -962,17 +967,17 @@ GCMarker::processMarkStackTop()
     }
     return;
 
   scan_obj:
     {
         types::TypeObject *type = obj->typeFromGC();
         PushMarkStack(this, type);
 
-        js::Shape *shape = obj->lastProperty();
+        Shape *shape = obj->lastProperty();
         PushMarkStack(this, shape);
 
         /* Call the trace hook if necessary. */
         Class *clasp = shape->getObjectClass();
         if (clasp->trace) {
             if (clasp == &ArrayClass) {
                 JS_ASSERT(!shape->isNative());
                 vp = obj->getDenseArrayElements();
--- a/js/src/jsgcmark.h
+++ b/js/src/jsgcmark.h
@@ -95,52 +95,52 @@ void
 MarkIdRange(JSTracer *trc, size_t len, js::HeapId *vec, const char *name);
 
 void
 MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
 
 /*** Value Marking ***/
 
 void
-MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name);
+MarkValue(JSTracer *trc, HeapValue *v, const char *name);
 
 void
-MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name);
+MarkValueRange(JSTracer *trc, size_t len, HeapValue *vec, const char *name);
 
 void
-MarkValueRoot(JSTracer *trc, const Value &v, const char *name);
+MarkValueRoot(JSTracer *trc, Value *v, const char *name);
 
 void
-MarkThingOrValueRoot(JSTracer *trc, uintptr_t word, const char *name);
+MarkThingOrValueRoot(JSTracer *trc, uintptr_t *word, const char *name);
 
 void
-MarkValueRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name);
+MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name);
 
 inline void
-MarkValueRootRange(JSTracer *trc, const Value *begin, const Value *end, const char *name)
+MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
 {
     MarkValueRootRange(trc, end - begin, begin, name);
 }
 
 /*** Special Cases ***/
 
 /* TypeNewObject contains a HeapPtr<const Shape> that needs a unique cast. */
 void
 MarkShape(JSTracer *trc, const HeapPtr<const Shape> &thing, const char *name);
 
 /* Direct value access used by the write barriers and the methodjit */
 void
-MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name);
+MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
 
 /*
  * Mark a value that may be in a different compartment from the compartment
  * being GC'd. (Although it won't be marked if it's in the wrong compartment.)
  */
 void
-MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name);
+MarkCrossCompartmentValue(JSTracer *trc, HeapValue *v, const char *name);
 
 /*
  * MarkChildren<JSObject> is exposed solely for preWriteBarrier on
  * JSObject::TradeGuts. It should not be considered external interface.
  */
 void
 MarkChildren(JSTracer *trc, JSObject *obj);
 
@@ -154,17 +154,17 @@ MarkCycleCollectorChildren(JSTracer *trc
 
 /*** Generic ***/
 /*
  * The Mark() functions interface should only be used by code that must be
  * templated.  Other uses should use the more specific, type-named functions.
  */
 
 inline void
-Mark(JSTracer *trc, const js::HeapValue &v, const char *name)
+Mark(JSTracer *trc, HeapValue *v, const char *name)
 {
     MarkValue(trc, v, name);
 }
 
 inline void
 Mark(JSTracer *trc, const HeapPtr<JSObject> &o, const char *name)
 {
     MarkObject(trc, o, name);
@@ -178,17 +178,17 @@ Mark(JSTracer *trc, const HeapPtr<JSXML>
 
 inline void
 Mark(JSTracer *trc, const HeapPtr<ion::IonCode> &code, const char *name)
 {
     MarkIonCode(trc, code, name);
 }
 
 inline bool
-IsMarked(const js::Value &v)
+IsMarked(const Value &v)
 {
     if (v.isMarkable())
         return !IsAboutToBeFinalized(v);
     return true;
 }
 
 inline bool
 IsMarked(JSContext *cx, ion::IonCode *code)
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -485,20 +485,19 @@ Number(JSContext *cx, uintN argc, Value 
         vp[0] = vp[2];
     } else {
         vp[0].setInt32(0);
     }
 
     if (!isConstructing)
         return true;
 
-    JSObject *obj = NewBuiltinClassInstance(cx, &NumberClass);
+    JSObject *obj = NumberObject::create(cx, vp[0].toNumber());
     if (!obj)
         return false;
-    obj->setPrimitiveThis(vp[0]);
     vp->setObject(*obj);
     return true;
 }
 
 #if JS_HAS_TOSOURCE
 static JSBool
 num_toSource(JSContext *cx, uintN argc, Value *vp)
 {
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -198,46 +198,34 @@ obj_setProto(JSContext *cx, JSObject *ob
 }
 
 #else  /* !JS_HAS_OBJ_PROTO_PROP */
 
 #define object_props NULL
 
 #endif /* !JS_HAS_OBJ_PROTO_PROP */
 
-static JSHashNumber
-js_hash_object(const void *key)
-{
-    return JSHashNumber(uintptr_t(key) >> JS_GCTHING_ALIGN);
-}
-
-static JSHashEntry *
-MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
+static bool
+MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap, JSSharpInfo *value)
 {
     JS_CHECK_RECURSION(cx, return NULL);
 
     JSIdArray *ida;
 
     JSSharpObjectMap *map = &cx->sharpObjectMap;
     JS_ASSERT(map->depth >= 1);
-    JSHashTable *table = map->table;
-    JSHashNumber hash = js_hash_object(obj);
-    JSHashEntry **hep = JS_HashTableRawLookup(table, hash, obj);
-    JSHashEntry *he = *hep;
-    if (!he) {
-        jsatomid sharpid = 0;
-        he = JS_HashTableRawAdd(table, hep, hash, obj, (void *) sharpid);
-        if (!he) {
-            JS_ReportOutOfMemory(cx);
-            return NULL;
-        }
+    JSSharpInfo sharpid;
+    JSSharpTable::Ptr p = map->table.lookup(obj);
+    if (!p) {
+        if (!map->table.put(obj, sharpid))
+            return false;
 
         ida = JS_Enumerate(cx, obj);
         if (!ida)
-            return NULL;
+            return false;
 
         bool ok = true;
         for (jsint i = 0, length = ida->length; i < length; i++) {
             jsid id = ida->vector[i];
             JSObject *obj2;
             JSProperty *prop;
             ok = obj->lookupGeneric(cx, id, &obj2, &prop);
             if (!ok)
@@ -256,181 +244,160 @@ MarkSharpObjects(JSContext *cx, JSObject
                 if (hasSetter)
                     setter.set(shape->setterValue());
             } else {
                 hasGetter = hasSetter = false;
             }
             if (hasSetter) {
                 /* Mark the getter, then set val to setter. */
                 if (hasGetter && v.value().isObject()) {
-                    ok = !!MarkSharpObjects(cx, &v.value().toObject(), NULL);
+                    ok = MarkSharpObjects(cx, &v.value().toObject(), NULL, NULL);
                     if (!ok)
                         break;
                 }
                 v.set(setter.value());
             } else if (!hasGetter) {
                 ok = obj->getGeneric(cx, id, v.addr());
                 if (!ok)
                     break;
             }
-            if (v.value().isObject() && !MarkSharpObjects(cx, &v.value().toObject(), NULL)) {
+            if (v.value().isObject() && !MarkSharpObjects(cx, &v.value().toObject(), NULL, NULL)) {
                 ok = false;
                 break;
             }
         }
         if (!ok || !idap)
             JS_DestroyIdArray(cx, ida);
         if (!ok)
-            return NULL;
+            return false;
     } else {
-        jsatomid sharpid = uintptr_t(he->value);
-        if (sharpid == 0) {
-            sharpid = ++map->sharpgen << SHARP_ID_SHIFT;
-            he->value = (void *) sharpid;
+        if (!p->value.hasGen && !p->value.isSharp) {
+            p->value.hasGen = true;
         }
+        sharpid = p->value;
         ida = NULL;
     }
     if (idap)
         *idap = ida;
-    return he;
-}
-
-JSHashEntry *
-js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, bool *alreadySeen)
+    if (value)
+        *value = sharpid;
+    return true;
+}
+
+bool
+js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, bool *alreadySeen, bool *isSharp)
 {
     if (!JS_CHECK_OPERATION_LIMIT(cx))
-        return NULL;
+        return false;
 
     *alreadySeen = false;
 
     JSSharpObjectMap *map = &cx->sharpObjectMap;
-    JSHashTable *table = map->table;
-    if (!table) {
-        table = JS_NewHashTable(8, js_hash_object, JS_CompareValues,
-                                JS_CompareValues, NULL, NULL);
-        if (!table) {
-            JS_ReportOutOfMemory(cx);
-            return NULL;
-        }
-        map->table = table;
-        JS_KEEP_ATOMS(cx->runtime);
-    }
-
-    JSHashEntry *he;
-    jsatomid sharpid;
+
+    JS_ASSERT_IF(map->depth == 0, map->table.count() == 0);
+    JS_ASSERT_IF(map->table.count() == 0, map->depth == 0);
+
+    JSSharpTable::Ptr p;
+    JSSharpInfo sharpid;
     JSIdArray *ida = NULL;
 
     /* From this point the control must flow either through out: or bad:. */
     if (map->depth == 0) {
+        JS_KEEP_ATOMS(cx->runtime);
+
         /*
          * Although MarkSharpObjects tries to avoid invoking getters,
          * it ends up doing so anyway under some circumstances; for
          * example, if a wrapped object has getters, the wrapper will
          * prevent MarkSharpObjects from recognizing them as such.
          * This could lead to js_LeaveSharpObject being called while
          * MarkSharpObjects is still working.
          *
          * Increment map->depth while we call MarkSharpObjects, to
          * ensure that such a call doesn't free the hash table we're
          * still using.
          */
-        ++map->depth;
-        he = MarkSharpObjects(cx, obj, &ida);
-        --map->depth;
-        if (!he)
+        map->depth = 1;
+        bool success = MarkSharpObjects(cx, obj, &ida, &sharpid);
+        JS_ASSERT(map->depth == 1);
+        map->depth = 0;
+        if (!success)
             goto bad;
-        JS_ASSERT((uintptr_t(he->value) & SHARP_BIT) == 0);
+        JS_ASSERT(!sharpid.isSharp);
         if (!idap) {
             JS_DestroyIdArray(cx, ida);
             ida = NULL;
         }
     } else {
-        JSHashNumber hash = js_hash_object(obj);
-        JSHashEntry **hep = JS_HashTableRawLookup(table, hash, obj);
-        he = *hep;
-
         /*
          * It's possible that the value of a property has changed from the
          * first time the object's properties are traversed (when the property
          * ids are entered into the hash table) to the second (when they are
          * converted to strings), i.e., the JSObject::getProperty() call is not
          * idempotent.
          */
-        if (!he) {
-            he = JS_HashTableRawAdd(table, hep, hash, obj, NULL);
-            if (!he) {
-                JS_ReportOutOfMemory(cx);
+        p = map->table.lookup(obj);
+        if (!p) {
+            if (!map->table.put(obj, sharpid))
                 goto bad;
-            }
-            sharpid = 0;
             goto out;
         }
-    }
-
-    sharpid = uintptr_t(he->value);
-    if (sharpid != 0)
+        sharpid = p->value;
+    }
+
+    if (sharpid.isSharp || sharpid.hasGen)
         *alreadySeen = true;
 
 out:
-    JS_ASSERT(he);
-    if ((sharpid & SHARP_BIT) == 0) {
+    if (!sharpid.isSharp) {
         if (idap && !ida) {
             ida = JS_Enumerate(cx, obj);
             if (!ida)
                 goto bad;
         }
         map->depth++;
     }
 
     if (idap)
         *idap = ida;
-    return he;
+    *isSharp = sharpid.isSharp;
+    return true;
 
 bad:
     /* Clean up the sharpObjectMap table on outermost error. */
     if (map->depth == 0) {
         JS_UNKEEP_ATOMS(cx->runtime);
         map->sharpgen = 0;
-        JS_HashTableDestroy(map->table);
-        map->table = NULL;
-    }
-    return NULL;
+        map->table.clear();
+    }
+    return false;
 }
 
 void
 js_LeaveSharpObject(JSContext *cx, JSIdArray **idap)
 {
     JSSharpObjectMap *map = &cx->sharpObjectMap;
     JS_ASSERT(map->depth > 0);
     if (--map->depth == 0) {
         JS_UNKEEP_ATOMS(cx->runtime);
         map->sharpgen = 0;
-        JS_HashTableDestroy(map->table);
-        map->table = NULL;
+        map->table.clear();
     }
     if (idap) {
         if (JSIdArray *ida = *idap) {
             JS_DestroyIdArray(cx, ida);
             *idap = NULL;
         }
     }
 }
 
-static intN
-gc_sharp_table_entry_marker(JSHashEntry *he, intN i, void *arg)
-{
-    MarkObjectRoot((JSTracer *)arg, (JSObject *)he->key, "sharp table entry");
-    return JS_DHASH_NEXT;
-}
-
 void
 js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map)
 {
     JS_ASSERT(map->depth > 0);
-    JS_ASSERT(map->table);
 
     /*
      * During recursive calls to MarkSharpObjects a non-native object or
      * object with a custom getProperty method can potentially return an
      * unrooted value or even cut from the object graph an argument of one of
      * MarkSharpObjects recursive invocations. So we must protect map->table
      * entries against GC.
      *
@@ -442,17 +409,18 @@ js_TraceSharpMap(JSTracer *trc, JSSharpO
      * confusing js_EnterSharpObject. So to address the problem we simply
      * mark all objects from map->table.
      *
      * An alternative "proper" solution is to use JSTempValueRooter in
      * MarkSharpObjects with code to remove during finalization entries
      * with otherwise unreachable objects. But this is way too complex
      * to justify spending efforts.
      */
-    JS_HashTableEnumerateEntries(map->table, gc_sharp_table_entry_marker, trc);
+    for (JSSharpTable::Range r = map->table.all(); !r.empty(); r.popFront())
+        MarkObjectRoot(trc, r.front().key, "sharp table entry");
 }
 
 #if JS_HAS_TOSOURCE
 static JSBool
 obj_toSource(JSContext *cx, uintN argc, Value *vp)
 {
     bool comma = false;
     const jschar *vchars;
@@ -470,36 +438,40 @@ obj_toSource(JSContext *cx, uintN argc, 
     bool outermost = (cx->sharpObjectMap.depth == 0);
 
     JSObject *obj = ToObject(cx, &vp[1]);
     if (!obj)
         return false;
 
     JSIdArray *ida;
     bool alreadySeen = false;
-    JSHashEntry *he = js_EnterSharpObject(cx, obj, &ida, &alreadySeen);
-    if (!he)
+    bool isSharp = false;
+    if (!js_EnterSharpObject(cx, obj, &ida, &alreadySeen, &isSharp))
         return false;
 
     if (!ida) {
         /*
          * We've already seen obj, so don't serialize it again (particularly as
          * we might recur in the process): just serialize an empty object.
          */
         JS_ASSERT(alreadySeen);
         JSString *str = js_NewStringCopyZ(cx, "{}");
         if (!str)
             return false;
         vp->setString(str);
         return true;
     }
-    JS_ASSERT(!IS_SHARP(he));
-
-    if (alreadySeen)
-        MAKE_SHARP(he);
+
+    JS_ASSERT(!isSharp);
+    if (alreadySeen) {
+        JSSharpTable::Ptr p = cx->sharpObjectMap.table.lookup(obj);
+        JS_ASSERT(p);
+        JS_ASSERT(!p->value.isSharp);
+        p->value.isSharp = true;
+    }
 
     /* Automatically call js_LeaveSharpObject when we leave this frame. */
     class AutoLeaveSharpObject {
         JSContext *cx;
         JSIdArray *ida;
       public:
         AutoLeaveSharpObject(JSContext *cx, JSIdArray *ida) : cx(cx), ida(ida) {}
         ~AutoLeaveSharpObject() {
@@ -532,17 +504,16 @@ obj_toSource(JSContext *cx, uintN argc, 
 
         /*
          * Convert id to a value and then to a string.  Decide early whether we
          * prefer get/set or old getter/setter syntax.
          */
         JSString *s = ToString(cx, IdToValue(id));
         if (!s || !(idstr = s->ensureLinear(cx)))
             return false;
-        vp->setString(idstr);                           /* local root */
 
         int valcnt = 0;
         if (prop) {
             bool doGet = true;
             if (obj2->isNative()) {
                 const Shape *shape = (Shape *) prop;
                 unsigned attrs = shape->attributes();
                 if (attrs & JSPROP_GETTER) {
@@ -571,17 +542,16 @@ obj_toSource(JSContext *cx, uintN argc, 
          * integer, then it must be quoted.
          */
         if (JSID_IS_ATOM(id)
             ? !IsIdentifier(idstr)
             : (!JSID_IS_INT(id) || JSID_TO_INT(id) < 0)) {
             s = js_QuoteString(cx, idstr, jschar('\''));
             if (!s || !(idstr = s->ensureLinear(cx)))
                 return false;
-            vp->setString(idstr);                       /* local root */
         }
 
         for (int j = 0; j < valcnt; j++) {
             /*
              * Censor an accessor descriptor getter or setter part if it's
              * undefined.
              */
             if (gsop[j] && val[j].isUndefined())
@@ -3520,16 +3490,21 @@ JSObject::TradeGuts(JSContext *cx, JSObj
     }
 
 #ifdef JSGC_GENERATIONAL
     Shape::writeBarrierPost(a->shape_, &a->shape_);
     Shape::writeBarrierPost(b->shape_, &b->shape_);
     types::TypeObject::writeBarrierPost(a->type_, &a->type_);
     types::TypeObject::writeBarrierPost(b->type_, &b->type_);
 #endif
+
+    if (a->inDictionaryMode())
+        a->lastProperty()->listp = &a->shape_;
+    if (b->inDictionaryMode())
+        b->lastProperty()->listp = &b->shape_;
 }
 
 /*
  * Use this method with extreme caution. It trades the guts of two objects and updates
  * scope ownership. This operation is not thread-safe, just as fast array to slow array
  * transitions are inherently not thread-safe. Don't perform a swap operation on objects
  * shared across threads or, or bad things will happen. You have been warned.
  */
@@ -3590,17 +3565,17 @@ DefineStandardSlot(JSContext *cx, JSObje
          * reserved slot. Otherwise, go through the normal property path.
          */
         JS_ASSERT(obj->isGlobal());
         JS_ASSERT(obj->isNative());
 
         const Shape *shape = obj->nativeLookup(cx, id);
         if (!shape) {
             uint32_t slot = 2 * JSProto_LIMIT + key;
-            SetReservedSlot(obj, slot, v);
+            obj->setReservedSlot(slot, v);
             if (!obj->addProperty(cx, id, JS_PropertyStub, JS_StrictPropertyStub, slot, attrs, 0, 0))
                 return false;
             AddTypePropertyId(cx, obj, id, v);
 
             named = true;
             return true;
         }
     }
@@ -3613,18 +3588,18 @@ namespace js {
 
 static void
 SetClassObject(JSObject *obj, JSProtoKey key, JSObject *cobj, JSObject *proto)
 {
     JS_ASSERT(!obj->getParent());
     if (!obj->isGlobal())
         return;
 
-    SetReservedSlot(obj, key, ObjectOrNullValue(cobj));
-    SetReservedSlot(obj, JSProto_LIMIT + key, ObjectOrNullValue(proto));
+    obj->setReservedSlot(key, ObjectOrNullValue(cobj));
+    obj->setReservedSlot(JSProto_LIMIT + key, ObjectOrNullValue(proto));
 }
 
 static void
 ClearClassObject(JSContext *cx, JSObject *obj, JSProtoKey key)
 {
     JS_ASSERT(!obj->getParent());
     if (!obj->isGlobal())
         return;
@@ -5882,17 +5857,17 @@ DefaultValue(JSContext *cx, JSObject *ob
     Class *clasp = obj->getClass();
     if (hint == JSTYPE_STRING) {
         /* Optimize (new String(...)).toString(). */
         if (clasp == &StringClass &&
             ClassMethodIsNative(cx, obj,
                                  &StringClass,
                                  ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
                                  js_str_toString)) {
-            *vp = obj->getPrimitiveThis();
+            *vp = StringValue(obj->asString().unbox());
             return true;
         }
 
         if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
 
@@ -5905,17 +5880,19 @@ DefaultValue(JSContext *cx, JSObject *ob
         if ((clasp == &StringClass &&
              ClassMethodIsNative(cx, obj, &StringClass,
                                  ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
                                  js_str_toString)) ||
             (clasp == &NumberClass &&
              ClassMethodIsNative(cx, obj, &NumberClass,
                                  ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
                                  js_num_valueOf))) {
-            *vp = obj->getPrimitiveThis();
+            *vp = obj->isString()
+                  ? StringValue(obj->asString().unbox())
+                  : NumberValue(obj->asNumber().unbox());
             return true;
         }
 
         if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -993,32 +993,16 @@ struct JSObject : js::gc::Cell
     /* ES5 15.2.3.8: non-extensible, all props non-configurable */
     inline bool seal(JSContext *cx) { return sealOrFreeze(cx, SEAL); }
     /* ES5 15.2.3.9: non-extensible, all properties non-configurable, all data props read-only */
     bool freeze(JSContext *cx) { return sealOrFreeze(cx, FREEZE); }
 
     bool isSealed(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, SEAL, resultp); }
     bool isFrozen(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, FREEZE, resultp); }
 
-    /*
-     * Primitive-specific getters and setters.
-     */
-
-  private:
-    static const uint32_t JSSLOT_PRIMITIVE_THIS = 0;
-
-  public:
-    inline const js::Value &getPrimitiveThis() const;
-    inline void setPrimitiveThis(const js::Value &pthis);
-
-    static size_t getPrimitiveThisOffset() {
-        /* All primitive objects have their value in a fixed slot. */
-        return getFixedSlotOffset(JSSLOT_PRIMITIVE_THIS);
-    }
-
     /* Accessors for elements. */
 
     js::ObjectElements *getElementsHeader() const {
         return js::ObjectElements::fromElements(elements);
     }
 
     inline bool ensureElements(JSContext *cx, uintN cap);
     bool growElements(JSContext *cx, uintN cap);
@@ -1360,18 +1344,16 @@ struct JSObject : js::gc::Cell
 
     inline bool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp);
     inline bool defaultValue(JSContext *cx, JSType hint, js::Value *vp);
     inline JSType typeOf(JSContext *cx);
     inline JSObject *thisObject(JSContext *cx);
 
     static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
 
-    inline JSObject *getThrowTypeError() const;
-
     bool swap(JSContext *cx, JSObject *other);
 
     inline void initArrayClass();
 
     static inline void writeBarrierPre(JSObject *obj);
     static inline void writeBarrierPost(JSObject *obj, void *addr);
     inline void privateWriteBarrierPre(void **oldval);
     inline void privateWriteBarrierPost(void **oldval);
@@ -1549,23 +1531,18 @@ class ValueArray {
   public:
     js::Value *array;
     size_t length;
 
     ValueArray(js::Value *v, size_t c) : array(v), length(c) {}
 };
 
 /* For manipulating JSContext::sharpObjectMap. */
-#define SHARP_BIT       ((jsatomid) 1)
-#define SHARP_ID_SHIFT  2
-#define IS_SHARP(he)    (uintptr_t((he)->value) & SHARP_BIT)
-#define MAKE_SHARP(he)  ((he)->value = (void *) (uintptr_t((he)->value)|SHARP_BIT))
-
-extern JSHashEntry *
-js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, bool *alreadySeen);
+extern bool
+js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, bool *alreadySeen, bool *isSharp);
 
 extern void
 js_LeaveSharpObject(JSContext *cx, JSIdArray **idap);
 
 /*
  * Mark objects stored in map if GC happens between js_EnterSharpObject
  * and js_LeaveSharpObject. GC calls this when map->depth > 0.
  */
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -60,18 +60,22 @@
 #include "jsscope.h"
 #include "jsstr.h"
 #include "jstypedarray.h"
 #include "jsxml.h"
 #include "jswrapper.h"
 
 #include "gc/Barrier.h"
 #include "js/TemplateLib.h"
+
+#include "vm/BooleanObject.h"
 #include "vm/GlobalObject.h"
+#include "vm/NumberObject.h"
 #include "vm/RegExpStatics.h"
+#include "vm/StringObject.h"
 
 #include "jsatominlines.h"
 #include "jsfuninlines.h"
 #include "jsgcinlines.h"
 #include "jsinferinlines.h"
 #include "jsscopeinlines.h"
 #include "jsscriptinlines.h"
 
@@ -431,30 +435,16 @@ JSObject::getReservedSlotRef(uintN index
 
 inline void
 JSObject::setReservedSlot(uintN index, const js::Value &v)
 {
     JS_ASSERT(index < JSSLOT_FREE(getClass()));
     setSlot(index, v);
 }
 
-inline const js::Value &
-JSObject::getPrimitiveThis() const
-{
-    JS_ASSERT(isPrimitive());
-    return getFixedSlot(JSSLOT_PRIMITIVE_THIS);
-}
-
-inline void
-JSObject::setPrimitiveThis(const js::Value &pthis)
-{
-    JS_ASSERT(isPrimitive());
-    setFixedSlot(JSSLOT_PRIMITIVE_THIS, pthis);
-}
-
 inline bool
 JSObject::hasContiguousSlots(size_t start, size_t count) const
 {
     /*
      * Check that the range [start, start+count) is either all inline or all
      * out of line.
      */
     JS_ASSERT(slotInRange(start + count, SENTINEL_ALLOWED));
@@ -1911,32 +1901,35 @@ namespace detail {
 
 template<typename T> class PrimitiveBehavior { };
 
 template<>
 class PrimitiveBehavior<JSString *> {
   public:
     static inline bool isType(const Value &v) { return v.isString(); }
     static inline JSString *extract(const Value &v) { return v.toString(); }
+    static inline JSString *extract(JSObject &obj) { return obj.asString().unbox(); }
     static inline Class *getClass() { return &StringClass; }
 };
 
 template<>
 class PrimitiveBehavior<bool> {
   public:
     static inline bool isType(const Value &v) { return v.isBoolean(); }
     static inline bool extract(const Value &v) { return v.toBoolean(); }
+    static inline bool extract(JSObject &obj) { return obj.asBoolean().unbox(); }
     static inline Class *getClass() { return &BooleanClass; }
 };
 
 template<>
 class PrimitiveBehavior<double> {
   public:
     static inline bool isType(const Value &v) { return v.isNumber(); }
     static inline double extract(const Value &v) { return v.toNumber(); }
+    static inline double extract(JSObject &obj) { return obj.asNumber().unbox(); }
     static inline Class *getClass() { return &NumberClass; }
 };
 
 } /* namespace detail */
 
 inline JSObject *
 NonGenericMethodGuard(JSContext *cx, CallArgs args, Native native, Class *clasp, bool *ok)
 {
@@ -1963,17 +1956,17 @@ BoxedPrimitiveMethodGuard(JSContext *cx,
     if (Behavior::isType(thisv)) {
         *v = Behavior::extract(thisv);
         return true;
     }
 
     if (!NonGenericMethodGuard(cx, args, native, Behavior::getClass(), ok))
         return false;
 
-    *v = Behavior::extract(thisv.toObject().getPrimitiveThis());
+    *v = Behavior::extract(thisv.toObject());
     return true;
 }
 
 inline bool
 ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx)
 {
     if (JS_UNLIKELY(obj.isProxy()))
         return Proxy::objectClassIs(&obj, classValue, cx);
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -52,32 +52,32 @@
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
-static inline const HeapValue &
+static inline HeapValue &
 GetCall(JSObject *proxy)
 {
     JS_ASSERT(IsFunctionProxy(proxy));
     return proxy->getSlotRef(JSSLOT_PROXY_CALL);
 }
 
 static inline Value
 GetConstruct(JSObject *proxy)
 {
     if (proxy->slotSpan() <= JSSLOT_PROXY_CONSTRUCT)
         return UndefinedValue();
     return proxy->getSlot(JSSLOT_PROXY_CONSTRUCT);
 }
 
-static inline const HeapValue &
+static inline HeapValue &
 GetFunctionProxyConstruct(JSObject *proxy)
 {
     JS_ASSERT(IsFunctionProxy(proxy));
     JS_ASSERT(proxy->slotSpan() > JSSLOT_PROXY_CONSTRUCT);
     return proxy->getSlotRef(JSSLOT_PROXY_CONSTRUCT);
 }
 
 static bool
@@ -87,16 +87,19 @@ OperationInProgress(JSContext *cx, JSObj
     while (op) {
         if (op->object == proxy)
             return true;
         op = op->next;
     }
     return false;
 }
 
+static bool
+FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp);
+
 ProxyHandler::ProxyHandler(void *family) : mFamily(family)
 {
 }
 
 ProxyHandler::~ProxyHandler()
 {
 }
 
@@ -1238,31 +1241,31 @@ proxy_DeleteSpecial(JSContext *cx, JSObj
 {
     return proxy_DeleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
 }
 
 static void
 proxy_TraceObject(JSTracer *trc, JSObject *obj)
 {
     GetProxyHandler(obj)->trace(trc, obj);
-    MarkCrossCompartmentValue(trc, obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
-    MarkCrossCompartmentValue(trc, obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
-    MarkCrossCompartmentValue(trc, obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
+    MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
+    MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
+    MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
     if (IsFunctionProxy(obj)) {
-        MarkCrossCompartmentValue(trc, GetCall(obj), "call");
-        MarkCrossCompartmentValue(trc, GetFunctionProxyConstruct(obj), "construct");
+        MarkCrossCompartmentValue(trc, &GetCall(obj), "call");
+        MarkCrossCompartmentValue(trc, &GetFunctionProxyConstruct(obj), "construct");
     }
 }
 
 static void
 proxy_TraceFunction(JSTracer *trc, JSObject *obj)
 {
     proxy_TraceObject(trc, obj);
-    MarkCrossCompartmentValue(trc, GetCall(obj), "call");
-    MarkCrossCompartmentValue(trc, GetFunctionProxyConstruct(obj), "construct");
+    MarkCrossCompartmentValue(trc, &GetCall(obj), "call");
+    MarkCrossCompartmentValue(trc, &GetFunctionProxyConstruct(obj), "construct");
 }
 
 static JSBool
 proxy_Convert(JSContext *cx, JSObject *proxy, JSType hint, Value *vp)
 {
     JS_ASSERT(proxy->isProxy());
     return Proxy::defaultValue(cx, proxy, hint, vp);
 }
@@ -1730,18 +1733,18 @@ Class js::CallableObjectClass = {
     JS_ConvertStub,
     NULL,                    /* finalize    */
     NULL,                    /* reserved0   */
     NULL,                    /* checkAccess */
     callable_Call,
     callable_Construct,
 };
 
-JS_FRIEND_API(JSBool)
-js::FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
+static bool
+FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
 {
     if (OperationInProgress(cx, proxy)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROXY_FIX);
         return false;
     }
 
     AutoValueRooter tvr(cx);
     if (!Proxy::fix(cx, proxy, tvr.addr()))
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -178,23 +178,16 @@ GetProxyHandler(const JSObject *obj)
 
 inline const Value &
 GetProxyPrivate(const JSObject *obj)
 {
     JS_ASSERT(IsProxy(obj));
     return GetReservedSlot(obj, JSSLOT_PROXY_PRIVATE);
 }
 
-inline void
-SetProxyPrivate(JSObject *obj, const Value &priv)
-{
-    JS_ASSERT(IsProxy(obj));
-    SetReservedSlot(obj, JSSLOT_PROXY_PRIVATE, priv);
-}
-
 inline const Value &
 GetProxyExtra(const JSObject *obj, size_t n)
 {
     JS_ASSERT(IsProxy(obj));
     return GetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n);
 }
 
 inline void
@@ -205,19 +198,16 @@ SetProxyExtra(JSObject *obj, size_t n, c
     SetReservedSlot(obj, JSSLOT_PROXY_EXTRA + n, extra);
 }
 
 JS_FRIEND_API(JSObject *)
 NewProxyObject(JSContext *cx, ProxyHandler *handler, const Value &priv,
                JSObject *proto, JSObject *parent,
                JSObject *call = NULL, JSObject *construct = NULL);
 
-JS_FRIEND_API(JSBool)
-FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp);
-
 } /* namespace js */
 
 JS_BEGIN_EXTERN_C
 
 extern JS_FRIEND_API(JSObject *)
 js_InitProxyClass(JSContext *cx, JSObject *obj);
 
 JS_END_EXTERN_C
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1903,11 +1903,11 @@ JSScript::clearTraps(JSContext *cx)
 void
 JSScript::markTrapClosures(JSTracer *trc)
 {
     JS_ASSERT(hasAnyBreakpointsOrStepMode());
 
     for (unsigned i = 0; i < length; i++) {
         BreakpointSite *site = debug->breakpoints[i];
         if (site && site->trapHandler)
-            MarkValue(trc, site->trapClosure, "trap closure");
+            MarkValue(trc, &site->trapClosure, "trap closure");
     }
 }
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -394,17 +394,17 @@ static JSFunctionSpec string_functions[]
 jschar      js_empty_ucstr[]  = {0};
 JSSubString js_EmptySubString = {0, js_empty_ucstr};
 
 static const uintN STRING_ELEMENT_ATTRS = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
 
 static JSBool
 str_enumerate(JSContext *cx, JSObject *obj)
 {
-    JSString *str = obj->getPrimitiveThis().toString();
+    JSString *str = obj->asString().unbox();
     for (size_t i = 0, length = str->length(); i < length; i++) {
         JSString *str1 = js_NewDependentString(cx, str, i, 1);
         if (!str1)
             return false;
         if (!obj->defineElement(cx, i, StringValue(str1),
                                 JS_PropertyStub, JS_StrictPropertyStub,
                                 STRING_ELEMENT_ATTRS)) {
             return false;
@@ -416,17 +416,17 @@ str_enumerate(JSContext *cx, JSObject *o
 
 static JSBool
 str_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
             JSObject **objp)
 {
     if (!JSID_IS_INT(id))
         return JS_TRUE;
 
-    JSString *str = obj->getPrimitiveThis().toString();
+    JSString *str = obj->asString().unbox();
 
     jsint slot = JSID_TO_INT(id);
     if ((size_t)slot < str->length()) {
         JSString *str1 = cx->runtime->staticStrings.getUnitStringForElement(cx, str, size_t(slot));
         if (!str1)
             return JS_FALSE;
         if (!obj->defineElement(cx, uint32_t(slot), StringValue(str1), NULL, NULL,
                                 STRING_ELEMENT_ATTRS)) {
@@ -467,18 +467,19 @@ ThisToStringForStringProto(JSContext *cx
     if (call.thisv().isObject()) {
         JSObject *obj = &call.thisv().toObject();
         if (obj->isString() &&
             ClassMethodIsNative(cx, obj,
                                 &StringClass,
                                 ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
                                 js_str_toString))
         {
-            call.thisv() = obj->getPrimitiveThis();
-            return call.thisv().toString();
+            JSString *str = obj->asString().unbox();
+            call.thisv().setString(str);
+            return str;
         }
     } else if (call.thisv().isNullOrUndefined()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
                              call.thisv().isNull() ? "null" : "undefined", "object");
         return NULL;
     }
 
     JSString *str = ToStringSlow(cx, call.thisv());
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -1092,17 +1092,17 @@ class TypedArrayTemplate
     static inline Class *fastClass()
     {
         return &TypedArray::fastClasses[ArrayTypeID()];
     }
 
     static void
     obj_trace(JSTracer *trc, JSObject *obj)
     {
-        MarkValue(trc, obj->getFixedSlotRef(FIELD_BUFFER), "typedarray.buffer");
+        MarkValue(trc, &obj->getFixedSlotRef(FIELD_BUFFER), "typedarray.buffer");
     }
 
     static JSBool
     obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name,
                     Value *vp)
     {
         JSObject *tarray = getTypedArray(obj);
 
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -86,17 +86,17 @@ namespace js {
 //
 //     MarkPolicy(JSTracer *)
 //
 //   and the following member functions:
 //
 //     bool isMarked(const Type &x)
 //        Return true if x has been marked as live by the garbage collector.
 //
-//     bool mark(const Type &x)
+//     bool mark(Type &x)
 //        Return false if x is already marked. Otherwise, mark x and return true.
 //
 //   If omitted, the MarkPolicy parameter defaults to js::DefaultMarkPolicy<Type>,
 //   a policy template with the obvious definitions for some typical
 //   SpiderMonkey type combinations.
 
 // A policy template holding default marking algorithms for common type combinations. This
 // provides default types for WeakMap's MarkPolicy template parameter.
@@ -208,17 +208,17 @@ class WeakMap : public HashMap<Key, Valu
     }
 
     bool markIteratively(JSTracer *trc) {
         KeyMarkPolicy kp(trc);
         ValueMarkPolicy vp(trc);
         bool markedAny = false;
         for (Range r = Base::all(); !r.empty(); r.popFront()) {
             const Key &k = r.front().key;
-            const Value &v = r.front().value;
+            Value &v = r.front().value;
             /* If the entry is live, ensure its key and value are marked. */
             if (kp.isMarked(k)) {
                 markedAny |= vp.mark(v);
             }
             JS_ASSERT_IF(kp.isMarked(k), vp.isMarked(v));
         }
         return markedAny;
     }
@@ -259,51 +259,51 @@ class DefaultMarkPolicy<HeapValue> {
     JSTracer *tracer;
   public:
     DefaultMarkPolicy(JSTracer *t) : tracer(t) { }
     bool isMarked(const HeapValue &x) {
         if (x.isMarkable())
             return !IsAboutToBeFinalized(x);
         return true;
     }
-    bool mark(const HeapValue &x) {
+    bool mark(HeapValue &x) {
         if (isMarked(x))
             return false;
-        js::gc::MarkValue(tracer, x, "WeakMap entry");
+        js::gc::MarkValue(tracer, &x, "WeakMap entry");
         return true;
     }
 };
 
 template <>
 class DefaultMarkPolicy<HeapPtrObject> {
   private:
     JSTracer *tracer;
   public:
     DefaultMarkPolicy(JSTracer *t) : tracer(t) { }
     bool isMarked(const HeapPtrObject &x) {
         return !IsAboutToBeFinalized(x);
     }
-    bool mark(const HeapPtrObject &x) {
+    bool mark(HeapPtrObject &x) {
         if (isMarked(x))
             return false;
         js::gc::MarkObject(tracer, x, "WeakMap entry");
         return true;
     }
 };
 
 template <>
 class DefaultMarkPolicy<HeapPtrScript> {
   private:
     JSTracer *tracer;
   public:
     DefaultMarkPolicy(JSTracer *t) : tracer(t) { }
     bool isMarked(const HeapPtrScript &x) {
         return !IsAboutToBeFinalized(x);
     }
-    bool mark(const HeapPtrScript &x) {
+    bool mark(HeapPtrScript &x) {
         if (isMarked(x))
             return false;
         js::gc::MarkScript(tracer, x, "WeakMap entry");
         return true;
     }
 };
 
 // Default trace policies
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -362,17 +362,17 @@ Wrapper::iteratorNext(JSContext *cx, JSO
         vp->setMagic(JS_NO_ITER_VALUE);
     }
     return true;
 }
 
 void
 Wrapper::trace(JSTracer *trc, JSObject *wrapper)
 {
-    MarkValue(trc, wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "wrappedObject");
+    MarkValue(trc, &wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "wrappedObject");
 }
 
 JSObject *
 Wrapper::wrappedObject(const JSObject *wrapper)
 {
     return GetProxyPrivate(wrapper).toObjectOrNull();
 }
 
@@ -870,17 +870,17 @@ CrossCompartmentWrapper::iteratorNext(JS
            NOTHING,
            Wrapper::iteratorNext(cx, wrapper, vp),
            call.origin->wrap(cx, vp));
 }
 
 void
 CrossCompartmentWrapper::trace(JSTracer *trc, JSObject *wrapper)
 {
-    MarkCrossCompartmentValue(trc, wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE),
+    MarkCrossCompartmentValue(trc, &wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE),
                               "wrappedObject");
 }
 
 CrossCompartmentWrapper CrossCompartmentWrapper::singleton(0u);
 
 /* Security wrappers. */
 
 template <class Base>
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -172,16 +172,21 @@ mjit::Compiler::compile()
 CompileStatus
 mjit::Compiler::checkAnalysis(JSScript *script)
 {
     if (script->hasClearedGlobal()) {
         JaegerSpew(JSpew_Abort, "script has a cleared global\n");
         return Compile_Abort;
     }
 
+    if (JSOp(*script->code) == JSOP_GENERATOR) {
+        JaegerSpew(JSpew_Abort, "script is a generator\n");
+        return Compile_Abort;
+    }
+
     if (!script->ensureRanAnalysis(cx, NULL))
         return Compile_Error;
     if (cx->typeInferenceEnabled() && !script->ensureRanInference(cx))
         return Compile_Error;
 
     ScriptAnalysis *analysis = script->analysis();
     analysis->assertMatchingDebugMode();
     if (analysis->failed()) {
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -48,16 +48,17 @@
 #include "jstypedarray.h"
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
 #include "jsscopeinlines.h"
 #include "jsinterpinlines.h"
 #include "jsautooplen.h"
 
 #include "vm/ScopeObject-inl.h"
+#include "vm/StringObject-inl.h"
 
 #if defined JS_POLYIC
 
 using namespace js;
 using namespace js::mjit;
 using namespace js::mjit::ic;
 
 typedef JSC::FunctionPtr FunctionPtr;
@@ -939,17 +940,17 @@ class GetPropCompiler : public PICStubCo
     }
 
     LookupStatus generateStringObjLengthStub()
     {
         Assembler masm;
 
         Jump notStringObj = masm.guardShape(pic.objReg, obj);
 
-        masm.loadPayload(Address(pic.objReg, JSObject::getPrimitiveThisOffset()), pic.objReg);
+        masm.loadPayload(Address(pic.objReg, StringObject::getPrimitiveValueOffset()), pic.objReg);
         masm.loadPtr(Address(pic.objReg, JSString::offsetOfLengthAndFlags()), pic.objReg);
         masm.urshift32(Imm32(JSString::LENGTH_SHIFT), pic.objReg);
         masm.move(ImmType(JSVAL_TYPE_INT32), pic.shapeReg);
         Jump done = masm.jump();
 
         pic.updatePCCounters(f, masm);
 
         PICLinker buffer(masm, pic);
@@ -1880,17 +1881,17 @@ GetPropMaybeCached(VMFrame &f, ic::PICIn
                     LookupStatus status = cc.generateArgsLengthStub();
                     if (status == Lookup_Error)
                         THROW();
                     f.regs.sp[-1].setInt32(int32_t(obj->asArguments().initialLength()));
                 } else if (obj->isString()) {
                     LookupStatus status = cc.generateStringObjLengthStub();
                     if (status == Lookup_Error)
                         THROW();
-                    JSString *str = obj->getPrimitiveThis().toString();
+                    JSString *str = obj->asString().unbox();
                     f.regs.sp[-1].setInt32(str->length());
                 }
                 return;
             }
         }
     }
 
     if (f.regs.sp[-1].isString()) {
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1958,18 +1958,18 @@ stubs::ConvertToTypedFloat(JSContext *cx
         JS_ASSERT(success);
         vp->setDouble(d);
     }
 }
 
 void JS_FASTCALL
 stubs::WriteBarrier(VMFrame &f, Value *addr)
 {
-    js::gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), *addr, "write barrier");
+    gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), addr, "write barrier");
 }
 
 void JS_FASTCALL
 stubs::GCThingWriteBarrier(VMFrame &f, Value *addr)
 {
     gc::Cell *cell = (gc::Cell *)addr->toGCThing();
     if (cell && !cell->isMarked())
-        gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), *addr, "write barrier");
+        gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), addr, "write barrier");
 }
--- a/js/src/vm/BooleanObject.h
+++ b/js/src/vm/BooleanObject.h
@@ -62,24 +62,23 @@ class BooleanObject : public JSObject
     static inline BooleanObject *create(JSContext *cx, bool b);
 
     /*
      * Identical to create(), but uses |proto| as [[Prototype]].  This method
      * must not be used to create |Boolean.prototype|.
      */
     static inline BooleanObject *createWithProto(JSContext *cx, bool b, JSObject &proto);
 
-    Value unbox() const {
-        JS_ASSERT(getSlot(PRIMITIVE_VALUE_SLOT).isBoolean());
-        return getSlot(PRIMITIVE_VALUE_SLOT);
+    bool unbox() const {
+        return getFixedSlot(PRIMITIVE_VALUE_SLOT).toBoolean();
     }
 
   private:
     inline void setPrimitiveValue(bool b) {
-        setSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b));
+        setFixedSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b));
     }
 
     /* For access to init, as Boolean.prototype is special. */
     friend JSObject *
     ::js_InitBooleanClass(JSContext *cx, JSObject *global);
 
   private:
     BooleanObject() MOZ_DELETE;
--- a/js/src/vm/NumberObject.h
+++ b/js/src/vm/NumberObject.h
@@ -62,24 +62,23 @@ class NumberObject : public JSObject
     static inline NumberObject *create(JSContext *cx, jsdouble d);
 
     /*
      * Identical to create(), but uses |proto| as [[Prototype]].  This method
      * must not be used to create |Number.prototype|.
      */
     static inline NumberObject *createWithProto(JSContext *cx, jsdouble d, JSObject &proto);
 
-    Value unbox() const {
-        JS_ASSERT(getSlot(PRIMITIVE_VALUE_SLOT).isNumber());
-        return getSlot(PRIMITIVE_VALUE_SLOT);
+    double unbox() const {
+        return getFixedSlot(PRIMITIVE_VALUE_SLOT).toNumber();
     }
 
   private:
     inline void setPrimitiveValue(jsdouble d) {
-        setSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d));
+        setFixedSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d));
     }
 
     /* For access to init, as Number.prototype is special. */
     friend JSObject *
     ::js_InitNumberClass(JSContext *cx, JSObject *global);
 
   private:
     NumberObject() MOZ_DELETE;
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -271,17 +271,17 @@ StackFrame::mark(JSTracer *trc)
         gc::MarkObjectUnbarriered(trc, fun(), "fun");
         if (isEvalFrame())
             gc::MarkScriptUnbarriered(trc, script(), "eval script");
     } else {
         gc::MarkScriptUnbarriered(trc, script(), "script");
     }
     if (IS_GC_MARKING_TRACER(trc))
         script()->compartment()->active = true;
-    gc::MarkValueUnbarriered(trc, returnValue(), "rval");
+    gc::MarkValueUnbarriered(trc, &returnValue(), "rval");
 }
 
 /*****************************************************************************/
 
 bool
 StackSegment::contains(const StackFrame *fp) const
 {
     /* NB: this depends on the continuity of segments in memory. */
@@ -481,17 +481,17 @@ StackSpace::markFrameSlots(JSTracer *trc
     analyze::ScriptAnalysis *analysis = script->analysis();
     uint32_t offset = pc - script->code;
     Value *fixedEnd = slotsBegin + script->nfixed;
     for (Value *vp = slotsBegin; vp < fixedEnd; vp++) {
         uint32_t slot = analyze::LocalSlot(script, vp - slotsBegin);
 
         /* Will this slot be synced by the JIT? */
         if (!analysis->trackSlot(slot) || analysis->liveness(slot).live(offset))
-            gc::MarkValueRoot(trc, *vp, "vm_stack");
+            gc::MarkValueRoot(trc, vp, "vm_stack");
         else
             *vp = UndefinedValue();
     }
 
     gc::MarkValueRootRange(trc, fixedEnd, slotsEnd, "vm_stack");
 }
 
 void
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -999,17 +999,17 @@ class StackFrame
     }
 
     /* Return value */
 
     bool hasReturnValue() const {
         return !!(flags_ & HAS_RVAL);
     }
 
-    const Value &returnValue() {
+    Value &returnValue() {
         if (!(flags_ & HAS_RVAL))
             rval_.setUndefined();
         return rval_;
     }
 
     void markReturnValue() {
         flags_ |= HAS_RVAL;
     }
--- a/js/src/vm/StringObject.h
+++ b/js/src/vm/StringObject.h
@@ -45,17 +45,17 @@
 
 #include "jsobj.h"
 #include "jsstr.h"
 
 namespace js {
 
 class StringObject : public JSObject
 {
-    static const uintN PRIMITIVE_THIS_SLOT = 0;
+    static const uintN PRIMITIVE_VALUE_SLOT = 0;
     static const uintN LENGTH_SLOT = 1;
 
   public:
     static const uintN RESERVED_SLOTS = 2;
 
     /*
      * Creates a new String object boxing the given string.  The object's
      * [[Prototype]] is determined from context.
@@ -64,30 +64,34 @@ class StringObject : public JSObject
 
     /*
      * Identical to create(), but uses |proto| as [[Prototype]].  This method
      * must not be used to create |String.prototype|.
      */
     static inline StringObject *createWithProto(JSContext *cx, JSString *str, JSObject &proto);
 
     JSString *unbox() const {
-        return getSlot(PRIMITIVE_THIS_SLOT).toString();
+        return getFixedSlot(PRIMITIVE_VALUE_SLOT).toString();
     }
 
     inline size_t length() const {
-        return size_t(getSlot(LENGTH_SLOT).toInt32());
+        return size_t(getFixedSlot(LENGTH_SLOT).toInt32());
+    }
+
+    static size_t getPrimitiveValueOffset() {
+        return getFixedSlotOffset(PRIMITIVE_VALUE_SLOT);
     }
 
   private:
     inline bool init(JSContext *cx, JSString *str);
 
     void setStringThis(JSString *str) {
-        JS_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined());
-        setSlot(PRIMITIVE_THIS_SLOT, StringValue(str));
-        setSlot(LENGTH_SLOT, Int32Value(int32_t(str->length())));
+        JS_ASSERT(getReservedSlot(PRIMITIVE_VALUE_SLOT).isUndefined());
+        setFixedSlot(PRIMITIVE_VALUE_SLOT, StringValue(str));
+        setFixedSlot(LENGTH_SLOT, Int32Value(int32_t(str->length())));
     }
 
     /* For access to init, as String.prototype is special. */
     friend JSObject *
     ::js_InitStringClass(JSContext *cx, JSObject *global);
 
     /*
      * Compute the initial shape to associate with fresh String objects, which
--- a/js/xpconnect/src/XPCQuickStubs.h
+++ b/js/xpconnect/src/XPCQuickStubs.h
@@ -534,18 +534,18 @@ castNativeFromWrapper(JSContext *cx,
 
     *rv = NS_ERROR_XPC_BAD_CONVERT_JS;
 
     if (!native)
         return nsnull;
 
     NS_ASSERTION(IS_WRAPPER_CLASS(js::GetObjectClass(cur)), "Not a wrapper?");
 
-    XPCNativeScriptableSharedJSClass *clasp =
-      (XPCNativeScriptableSharedJSClass*)js::GetObjectClass(cur);
+    XPCWrappedNativeJSClass *clasp =
+      (XPCWrappedNativeJSClass*)js::GetObjectClass(cur);
     if (!(clasp->interfacesBitmap & (1 << interfaceBit)))
         return nsnull;
 
     *pRef = nsnull;
     *pVal = OBJECT_TO_JSVAL(cur);
 
     if (lccx) {
         if (wrapper)
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -1086,17 +1086,17 @@ XPCWrappedNative::Init(XPCCallContext& c
             if (!mScriptableInfo)
                 return false;
         }
     }
     XPCNativeScriptableInfo* si = mScriptableInfo;
 
     // create our flatJSObject
 
-    JSClass* jsclazz = si ? si->GetJSClass() : Jsvalify(&XPC_WN_NoHelper_JSClass);
+    JSClass* jsclazz = si ? si->GetJSClass() : Jsvalify(&XPC_WN_NoHelper_JSClass.base);
 
     if (isGlobal) {
         // Resolving a global object's class can cause us to create a global's
         // JS class without the proper global flags. Notice that here and fix
         // the problem.
         if (!(jsclazz->flags & JSCLASS_IS_GLOBAL))
             jsclazz->flags |= XPCONNECT_GLOBAL_FLAGS;
     } else
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -809,17 +809,18 @@ XPC_WN_OuterObject(JSContext *cx, JSObje
         }
 
         obj = newThis;
     }
 
     return obj;
 }
 
-js::Class XPC_WN_NoHelper_JSClass = {
+XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
+  { // base
     "XPCWrappedNative_NoHelper",    // name;
     WRAPPER_SLOTS |
     JSCLASS_PRIVATE_IS_NSISUPPORTS, // flags
 
     /* Mandatory non-null function pointer members. */
     XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
     XPC_WN_CannotModifyPropertyStub,   // delProperty
     JS_PropertyStub,                   // getProperty
@@ -880,16 +881,18 @@ js::Class XPC_WN_NoHelper_JSClass = {
         nsnull, // deleteElement
         nsnull, // deleteSpecial
         XPC_WN_JSOp_Enumerate,
         XPC_WN_JSOp_TypeOf_Object,
         nsnull, // fix
         XPC_WN_JSOp_ThisObject,
         XPC_WN_JSOp_Clear
     }
+  },
+  0 // interfacesBitmap
 };
 
 
 /***************************************************************************/
 
 static JSBool
 XPC_WN_MaybeResolvingPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
@@ -1199,17 +1202,17 @@ XPC_WN_Helper_NewResolve(JSContext *cx, 
             do shared enumerate - don't use this JSOp thing at all
 */
 
 JSBool
 XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                       jsval *statep, jsid *idp)
 {
     js::Class *clazz = js::GetObjectClass(obj);
-    if (!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass) {
+    if (!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass.base) {
         // obj must be a prototype object or a wrapper w/o a
         // helper. Short circuit this call to the default
         // implementation.
 
         return JS_EnumerateState(cx, obj, enum_op, statep, idp);
     }
 
     MORPH_SLIM_WRAPPER(cx, obj);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1346,17 +1346,18 @@ private:
 * Core classes for wrapped native objects for use from JavaScript...
 *
 ****************************************************************************
 ***************************************************************************/
 
 // These are the various JSClasses and callbacks whose use that required
 // visibility from more than one .cpp file.
 
-extern js::Class XPC_WN_NoHelper_JSClass;
+struct XPCWrappedNativeJSClass;
+extern XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass;
 extern js::Class XPC_WN_NoMods_WithCall_Proto_JSClass;
 extern js::Class XPC_WN_NoMods_NoCall_Proto_JSClass;
 extern js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
 extern js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
 extern js::Class XPC_WN_Tearoff_JSClass;
 extern js::Class XPC_WN_NoHelper_Proto_JSClass;
 
 extern JSBool
@@ -2030,17 +2031,20 @@ public:
 // XPCNativeScriptableShared is used to hold the JSClass and the
 // associated scriptable flags for XPCWrappedNatives. These are shared across
 // the runtime and are garbage collected by xpconnect. We *used* to just store
 // this inside the XPCNativeScriptableInfo (usually owned by instances of
 // XPCWrappedNativeProto. This had two problems... It was wasteful, and it
 // was a big problem when wrappers are reparented to different scopes (and
 // thus different protos (the DOM does this).
 
-struct XPCNativeScriptableSharedJSClass
+// We maintain the invariant that every JSClass for which ext.isWrappedNative
+// is true is a contained in an instance of this struct, and can thus be cast
+// to it.
+struct XPCWrappedNativeJSClass
 {
     js::Class base;
     PRUint32 interfacesBitmap;
 };
 
 class XPCNativeScriptableShared
 {
 public:
@@ -2072,17 +2076,17 @@ public:
     void PopulateJSClass(JSBool isGlobal);
 
     void Mark()       {mFlags.Mark();}
     void Unmark()     {mFlags.Unmark();}
     JSBool IsMarked() const {return mFlags.IsMarked();}
 
 private:
     XPCNativeScriptableFlags mFlags;
-    XPCNativeScriptableSharedJSClass mJSClass;
+    XPCWrappedNativeJSClass  mJSClass;
     JSBool                   mCanBeSlim;
 };
 
 /***************************************************************************/
 // XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
 // given class or instance.
 
 class XPCNativeScriptableInfo
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5209,17 +5209,17 @@ void PresShell::SetIgnoreViewportScrolli
 
 void PresShell::SetDisplayPort(const nsRect& aDisplayPort)
 {
   NS_ABORT_IF_FALSE(false, "SetDisplayPort is deprecated");
 }
 
 nsresult PresShell::SetResolution(float aXResolution, float aYResolution)
 {
-  if (!(aXResolution > 0.0 && aXResolution > 0.0)) {
+  if (!(aXResolution > 0.0 && aYResolution > 0.0)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
   if (aXResolution == mXResolution && aYResolution == mYResolution) {
     return NS_OK;
   }
   RenderingState state(this);
   state.mXResolution = aXResolution;
   state.mYResolution = aYResolution;
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -66,16 +66,30 @@
 // Basic nsInlineFrame methods
 
 nsIFrame*
 NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsInlineFrame(aContext);
 }
 
+NS_IMETHODIMP
+nsInlineFrame::Init(nsIContent*      aContent,
+                    nsIFrame*        aParent,
+                    nsIFrame*        aPrevInFlow)
+{
+  // Let the base class do its processing
+  nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
+
+  // Transforms do not affect regular inline elements (bug 722463)
+  mState &= ~NS_FRAME_MAY_BE_TRANSFORMED;
+
+  return rv;
+}
+
 NS_IMPL_FRAMEARENA_HELPERS(nsInlineFrame)
 
 NS_QUERYFRAME_HEAD(nsInlineFrame)
   NS_QUERYFRAME_ENTRY(nsInlineFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 #ifdef DEBUG
 NS_IMETHODIMP
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -64,16 +64,23 @@ class nsInlineFrame : public nsContainer
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsInlineFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
+  /** sets defaults for inline-specific style.
+    * @see nsIFrame::Init
+    */
+  NS_IMETHOD Init(nsIContent*      aContent,
+                  nsIFrame*        aParent,
+                  nsIFrame*        aPrevInFlow);
+
   // nsIFrame overrides
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
 
 #ifdef ACCESSIBILITY
   virtual already_AddRefed<nsAccessible> CreateAccessible();
 #endif
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -475,30 +475,16 @@ nsObjectFrame::PrepForDrawing(nsIWidget 
     for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
       nscolor bgcolor =
         frame->GetVisitedDependentColor(eCSSProperty_background_color);
       if (NS_GET_A(bgcolor) > 0) {  // make sure we got an actual color
         mWidget->SetBackgroundColor(bgcolor);
         break;
       }
     }
-
-#ifdef XP_MACOSX
-    // Now that we have a widget we want to set the event model before
-    // any events are processed.
-    nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
-    if (!pluginWidget)
-      return NS_ERROR_FAILURE;
-    pluginWidget->SetPluginEventModel(mInstanceOwner->GetEventModel());
-    pluginWidget->SetPluginDrawingModel(mInstanceOwner->GetDrawingModel());
-
-    if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation) {
-      mInstanceOwner->SetupCARefresh();
-    }
-#endif
   } else {
     // Changing to windowless mode changes the NPWindow geometry.
     FixupWindow(GetContentRectRelativeToSelf().Size());
 
 #ifndef XP_MACOSX
     rpc->RegisterPluginForGeometryUpdates(this);
     rpc->RequestUpdatePluginGeometry(this);
 #endif
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/726951-shadow-clips-ref.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<head>
+  
+<body>
+  <canvas id="mycanvas" width="200" height="200"></canvas>
+
+  <script type="text/javascript">
+  var cx = document.getElementById('mycanvas').getContext('2d');
+  cx.beginPath();
+  cx.rect(10, 10, 50, 50);
+  cx.clip();
+  cx.beginPath();
+  cx.rect(0, 0, 50, 50);
+  cx.shadowColor = "black";
+  cx.shadowOffsetX = 10;
+  cx.shadowOffsetY = 10;
+  cx.fill();
+  </script>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/726951-shadow-clips.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<head>
+  
+<body>
+  <canvas id="mycanvas" width="200" height="600"></canvas>
+
+  <script type="text/javascript">
+  var cx = document.getElementById('mycanvas').getContext('2d');
+  cx.beginPath();
+  cx.rect(10, 10, 50, 50);
+  cx.clip();
+  cx.beginPath();
+  cx.rect(0, 0, 50, 50);
+  cx.shadowColor = "black";
+  cx.shadowOffsetX = 10;
+  cx.shadowOffsetY = 10;
+  cx.fill();
+  </script>
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -70,9 +70,11 @@ random-if(Android) == dash-1.html dash-1
 fails == ctm-singular-sanity.html data:text/html,<body>Pass  # Bug 612033
 == ctm-1.html ctm-1-ref.html
 
 fails-if(/Mac\x20OS\x20X\x2010\.[56]/.test(http.oscpu)) == 672646-alpha-radial-gradient.html 672646-alpha-radial-gradient-ref.html # Bug 673333
 == 674003-alpha-radial-gradient-superlum.html 674003-alpha-radial-gradient-superlum-ref.html
 
 != 693610-1.html 693610-1-notref.html # bug 693610: multiple glyph runs should not be overprinted
 
+== 726951-shadow-clips.html 726951-shadow-clips-ref.html
+
 == transformed-clip.html transformed-clip-ref.html
copy from layout/reftests/transform-3d/backface-visibility-1b.html
copy to layout/reftests/transform-3d/backface-visibility-1c.html
--- a/layout/reftests/transform-3d/backface-visibility-1b.html
+++ b/layout/reftests/transform-3d/backface-visibility-1c.html
@@ -1,9 +1,9 @@
 <html>
 <head>
 </head>
 <body>
-  <div style="-moz-transform: rotatex(180deg); -moz-backface-visibility: hidden; width: 100px; height: 100px;">
+  <div style="-moz-transform: rotatex(180deg); -moz-backface-visibility: hidden; width: 100px; height: 100px; display: table">
     Test Text
   </div>
 </body>
 </html>
--- a/layout/reftests/transform-3d/reftest.list
+++ b/layout/reftests/transform-3d/reftest.list
@@ -26,16 +26,17 @@ fails-if(/^Windows\x20NT\x206\.1/.test(h
 != translatez-1b.html translatez-1-ref.html
 == translate3d-1a.html translate3d-1-ref.html
 == matrix3d-1a.html matrix3d-1-ref.html
 == matrix3d-2a.html matrix3d-2-ref.html
 == rotate3d-1a.html rotatex-1-ref.html
 == rotate3d-2a.html rotatey-1-ref.html
 != backface-visibility-1a.html about:blank
 == backface-visibility-1b.html about:blank
+== backface-visibility-1c.html about:blank
 != perspective-origin-1a.html rotatex-perspective-1a.html
 == perspective-origin-1b.html perspective-origin-1a.html
 == perspective-origin-2a.html perspective-origin-2-ref.html
 != sorting-1a.html sorting-1-ref.html
 # Parallel planes, different z depth
 == sorting-2a.html sorting-2-ref.html
 # Parallel planes, same z depth (shouldn't be sorted!)
 == sorting-2b.html sorting-2-ref.html
--- a/layout/reftests/transform/descendant-1.html
+++ b/layout/reftests/transform/descendant-1.html
@@ -4,20 +4,20 @@
     #div1 {
       background: green;
       height: 100px;
       width: 100px;
     }
     span {
       background: yellow;
     }
-    #div1 span {-moz-transform: translate(20px, 150px);
-                -moz-transform-origin: 0% 0%;
+    #div1 div {-moz-transform: translate(20px, 150px);
+               -moz-transform-origin: 0% 0%;
     }
   </style>
 </head>
 <body>
   <div id="div1">
-    <span>span 1</span>
+    <div><span>span 1</span></div>
   </div>
   <span>span 2</span>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/inline-1-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+This is some text<br>that is not transformed
new file mode 100644
--- /dev/null
+++ b/layout/reftests/transform/inline-1a.html
@@ -0,0 +1,3 @@
+<!doctype html>
+This is some <span style="-moz-transform:rotate(180deg)">text<br>
+that is</span> not transformed
--- a/layout/reftests/transform/reftest.list
+++ b/layout/reftests/transform/reftest.list
@@ -113,8 +113,10 @@ fails-if(Android) == stresstest-1.html s
 == 601894-1.html 601894-ref.html
 == 601894-2.html 601894-ref.html
 # Bug 722777
 == table-1a.html table-1-ref.html
 == table-1b.html table-1-ref.html
 == table-1c.html table-1-ref.html
 == table-2a.html table-2-ref.html
 == table-2b.html table-2-ref.html
+# Bug 722463
+== inline-1a.html inline-1-ref.html
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -44,16 +44,17 @@
 #include "mozilla/css/Loader.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIPrincipal.h"
 #include "nsIURI.h"
 #include "nsNodeUtils.h"
+#include "nsGenericElement.h"
 
 namespace css = mozilla::css;
 namespace dom = mozilla::dom;
 
 nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(dom::Element* aElement,
                                                            bool aIsSMILOverride)
   : mElement(aElement)
   , mIsSMILOverride(aIsSMILOverride)
@@ -63,18 +64,36 @@ nsDOMCSSAttributeDeclaration::nsDOMCSSAt
   NS_ASSERTION(aElement, "Inline style for a NULL element?");
 }
 
 nsDOMCSSAttributeDeclaration::~nsDOMCSSAttributeDeclaration()
 {
   MOZ_COUNT_DTOR(nsDOMCSSAttributeDeclaration);
 }
 
+// If nsDOMCSSAttributeDeclaration is changed so that any additional
+// fields are traversed by the cycle collector (for instance, if
+// wrapper cache handling is changed) then CAN_SKIP must be updated.
 NS_IMPL_CYCLE_COLLECTION_1(nsDOMCSSAttributeDeclaration, mElement)
 
+// nsDOMCSSAttributeDeclaration has only one cycle collected field, so
+// if mElement is going to be skipped, the attribute declaration can't
+// be part of a garbage cycle.
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMCSSAttributeDeclaration)
+  return !tmp->mElement || nsGenericElement::CanSkip(tmp->mElement, true);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
+
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMCSSAttributeDeclaration)
+  return !tmp->mElement || nsGenericElement::CanSkipInCC(tmp->mElement);
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
+
+// CanSkipThis returns false to avoid problems with incomplete unlinking.
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMCSSAttributeDeclaration)
+NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
+
 NS_INTERFACE_MAP_BEGIN(nsDOMCSSAttributeDeclaration)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMCSSAttributeDeclaration)
 NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSAttributeDeclaration)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCSSAttributeDeclaration)
 
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -61,18 +61,18 @@ class nsDOMCSSAttributeDeclaration : pub
                                      public nsWrapperCache
 {
 public:
   typedef mozilla::dom::Element Element;
   nsDOMCSSAttributeDeclaration(Element* aContent, bool aIsSMILOverride);
   ~nsDOMCSSAttributeDeclaration();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
-                                           nsICSSDeclaration)
+  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
+                                                     nsICSSDeclaration)
 
   // If GetCSSDeclaration returns non-null, then the decl it returns
   // is owned by our current style rule.
   virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate);
   virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv);
   NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent);
 
   virtual nsINode* GetParentObject();
--- a/layout/style/test/test_priority_preservation.html
+++ b/layout/style/test/test_priority_preservation.html
@@ -83,17 +83,18 @@ is(s.getPropertyValue("text-decoration")
 is(s.getPropertyPriority("text-decoration"), "important",
    "text-decoration priority still stored");
 is(s.getPropertyValue("z-index"), "3",
    "z-index still stored");
 is(s.getPropertyPriority("z-index"), "",
    "z-index priority still stored");
 
   // and overriding one element of that shorthand with some longhand
-s.setProperty("font-style", "normal", "");
+  // test omitting the third argument to setProperty too (bug 655478)
+s.setProperty("font-style", "normal");
 
 is(s.getPropertyValue("font-style"), "normal", "font-style overridden");
 is(s.getPropertyPriority("font-style"), "", "font-style priority overridden");
 
 is(s.getPropertyValue("font-weight"), "bold", "font-weight unchanged");
 is(s.getPropertyPriority("font-weight"), "important",
    "font-weight priority unchanged");
 is(s.getPropertyValue("font-size"), "12px", "font-size unchanged");
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -72,16 +72,18 @@
   z-index: inherit;
   page-break-before: inherit;
   page-break-after: inherit;
   vertical-align: inherit; /* needed for inline-table */
   line-height: inherit; /* needed for vertical-align on inline-table */
   /* Bug 722777 */
   -moz-transform: inherit;
   -moz-transform-origin: inherit;
+  /* Bug 724750 */
+  -moz-backface-visibility: inherit;
 }
 
 *|*::-moz-table-row {
   display: table-row !important;
 }
 
 /* The ::-moz-table-column pseudo-element is for extra columns at the end 
    of a table. */
--- a/media/libjpeg/MOZCHANGES
+++ b/media/libjpeg/MOZCHANGES
@@ -1,19 +1,25 @@
 To upgrade to a new revision of libjpeg-turbo, do the following:
 
 * Check out libjpeg-turbo from SVN:
 
     $ svn co https://libjpeg-turbo.svn.sourceforge.net/svnroot/libjpeg-turbo/trunk libjpeg-turbo
 
 * In a clean clone of mozilla-central, run the following commands
 
-    $ rm -rf jpeg
-    $ svn export --ignore-externals /path/to/libjpeg-turbo jpeg
-    $ cd jpeg
+    $ rm -rf media/libjpeg
+    $ svn export --ignore-externals /path/to/libjpeg-turbo media/libjpeg
+    $ cd media/libjpeg
+
+* Copy win/jsimdcfg.inc to simd/.
+
+* Since libjpeg-turbo normally creates config.h and jconfig.h at build time and
+  we use pre-generated versions, changes to jconfig.h.in and win/config.h.in
+  should be looked for and noted for later inclusion.
 
 * Now look through the new files and rm any which are npotb.  When I upgraded
   to libjpeg-turbo 1.1.0, the only files I kept which didn't match
 
     *.c  *.h *.asm *.inc
 
   were README and README-turbo.
 
@@ -27,31 +33,49 @@ To upgrade to a new revision of libjpeg-
 
     $ hg status -nu | grep -v '\(c\|h\|asm\|inc\)$' | xargs rm
 
   A helpful command for finding the *.c files which aren't *currently* part of
   the build is
 
     diff <(ls *.c | sort) <(grep -o '\w*\.c' Makefile.in | sort)
 
-  of course, libjpeg-turbo might have added some new source files, so you'll
+  Of course, libjpeg-turbo might have added some new source files, so you'll
   have to look though and figure out which of these files to keep.
 
 * Restore files modified in the Mozilla repository.
 
-    $ hg revert --no-backup Makefile.in jconfig.h jmorecfg.h simd/Makefile.in \
-      simd/jsimdcfg.inc jchuff.c jdhuff.c jdhuff.h MOZCHANGES
+    $ hg revert --no-backup config.h jconfig.h Makefile.in MOZCHANGES \
+      mozilla.diff simd/Makefile.in
+
+* Update config.h and jconfig.h as noted previously.
+
+* Apply Mozilla-specific changes to upstream files.
+
+    $ patch -p0 -i mozilla.diff
 
 * Update Makefile.in to build any new files.
 
 * Finally, tell hg that we've added or removed some files:
 
     $ hg addremove
 
 
+== February 10, 2012 (libjpeg-turbo v1.2.0 r807 2012-02-10) ==
+
+* Imported jchuff.c, jdhuff.c, jdhuff.h under new licensing.
+
+* Created mozilla.diff for the required jmorecfg.h changes and to allow for any
+  future changes made by Mozilla to upstream files.
+
+* Removed the following files which are unused by the Mozilla build:
+
+    cderror.h, cdjpeg.h, jconfig.h.in, transupp.h, simd/jsimdcfg.inc.h
+
+
 == March 28, 2011 (initial commit, libjpeg-turbo v1.1.0 r469 2011-02-27) ==
 
 * Modified jmorecfg.h to define UINT8, UINT16, INT16, and INT32 in terms of
   prtypes to fix a build error on Windows.
 
 * Defined INLINE as NS_ALWAYS_INLINE in jconfig.h.
 
 * Removed the following files which are licensed under the wxWindows license:
--- a/media/libjpeg/Makefile.in
+++ b/media/libjpeg/Makefile.in
@@ -98,36 +98,43 @@ CSRCS		+= \
 		jcinit.c \
 		jcmainct.c \
 		jcmarker.c \
 		jcmaster.c \
 		jcparam.c \
 		jcphuff.c \
 		jcprepct.c \
 		jcsample.c \
+		jctrans.c \
 		$(NULL)
 
 AS=$(LIBJPEG_TURBO_AS)
 ASM_SUFFIX=asm
 ASFLAGS=$(LIBJPEG_TURBO_ASFLAGS) -I$(topsrcdir)/media/libjpeg/simd/
 
 ifeq ($(AS),yasm)
   # yasm doesn't like -c
   AS_DASH_C_FLAG=
 endif
 
 # No SIMD support?
-ifeq (,$(LIBJPEG_TURBO_X86_ASM)$(LIBJPEG_TURBO_X64_ASM))
+ifeq (,$(LIBJPEG_TURBO_X86_ASM)$(LIBJPEG_TURBO_X64_ASM)$(LIBJPEG_TURBO_ARM_ASM))
   CSRCS += jsimd_none.c
 endif
 
+ifeq (1,$(LIBJPEG_TURBO_ARM_ASM))
+  CSRCS += simd/jsimd_arm.c
+  SSRCS += simd/jsimd_arm_neon.S
+endif
+
 ifeq (1,$(LIBJPEG_TURBO_X64_ASM))
   CSRCS   += simd/jsimd_x86_64.c
   ASFILES += \
 	simd/jccolss2-64.asm \
+	simd/jcgrass2-64.asm \
 	simd/jcqnts2f-64.asm \
 	simd/jcqnts2i-64.asm \
 	simd/jcsamss2-64.asm \
 	simd/jdcolss2-64.asm \
 	simd/jdmerss2-64.asm \
 	simd/jdsamss2-64.asm \
 	simd/jfss2fst-64.asm \
 	simd/jfss2int-64.asm \
@@ -139,16 +146,18 @@ ifeq (1,$(LIBJPEG_TURBO_X64_ASM))
 	$(NULL)
 endif
 
 ifeq (1,$(LIBJPEG_TURBO_X86_ASM))
   CSRCS   +=simd/jsimd_i386.c
   ASFILES += \
 	simd/jccolmmx.asm \
 	simd/jccolss2.asm \
+	simd/jcgrammx.asm \
+	simd/jcgrass2.asm \
 	simd/jcqnt3dn.asm \
 	simd/jcqntmmx.asm \
 	simd/jcqnts2f.asm \
 	simd/jcqnts2i.asm \
 	simd/jcqntsse.asm \
 	simd/jcsammmx.asm \
 	simd/jcsamss2.asm \
 	simd/jdcolmmx.asm \
@@ -171,21 +180,21 @@ ifeq (1,$(LIBJPEG_TURBO_X86_ASM))
 	simd/jiss2fst.asm \
 	simd/jiss2int.asm \
 	simd/jiss2red.asm \
 	simd/jisseflt.asm \
 	simd/jsimdcpu.asm \
 	$(NULL)
 endif
 
-EXPORTS		= \
-		jconfig.h \
-		jerror.h \
-		jinclude.h \
-		jmorecfg.h \
-		jpegint.h \
-		jpeglib.h \
-		$(NULL)
+EXPORTS	= \
+	jconfig.h \
+	jerror.h \
+	jinclude.h \
+	jmorecfg.h \
+	jpegint.h \
+	jpeglib.h \
+	$(NULL)
 
 # need static lib for some of the libimg componentry to link properly
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
--- a/media/libjpeg/README
+++ b/media/libjpeg/README
@@ -1,12 +1,13 @@
-libjpeg-turbo note:  This file is mostly taken from the libjpeg v8b README
-file, and it is included only for reference.  Some parts of it may not apply to
-libjpeg-turbo.  Please see README-turbo.txt for information specific to the
-turbo version.
+libjpeg-turbo note:  This file contains portions of the libjpeg v6b and v8
+README files, with additional wordsmithing by The libjpeg-turbo Project.
+It is included only for reference, as some parts of it may not apply to
+libjpeg-turbo.  Please see README-turbo.txt for information specific to
+libjpeg-turbo.
 
 
 The Independent JPEG Group's JPEG software
 ==========================================
 
 This distribution contains a release of the Independent JPEG Group's free JPEG
 software.  You are welcome to redistribute this software and to use it for any
 purpose, subject to the conditions under LEGAL ISSUES, below.
@@ -57,17 +58,17 @@ the order listed) before diving into the
 
 
 OVERVIEW
 ========
 
 This package contains C software to implement JPEG image encoding, decoding,
 and transcoding.  JPEG (pronounced "jay-peg") is a standardized compression
 method for full-color and gray-scale images.  JPEG's strong suit is compressing
-photographic images or other types of images which have smooth color and
+photographic images or other types of images that have smooth color and
 brightness transitions between neighboring pixels.  Images with sharp lines or
 other abrupt features may not compress well with JPEG, and a higher JPEG
 quality may have to be used to avoid visible compression artifacts with such
 images.
 
 JPEG is lossy, meaning that the output pixels are not necessarily identical to
 the input pixels.  However, on photographic content and other "smooth" images,
 very good compression ratios can be obtained with no visible compression
@@ -251,39 +252,39 @@ uses our library to implement TIFF/JPEG 
 
 
 ARCHIVE LOCATIONS
 =================
 
 The "official" archive site for this software is www.ijg.org.
 The most recent released version can always be found there in
 directory "files".  This particular version will be archived as
-http://www.ijg.org/files/jpegsrc.v8b.tar.gz, and in Windows-compatible
-"zip" archive format as http://www.ijg.org/files/jpegsr8b.zip.
+http://www.ijg.org/files/jpegsrc.v8d.tar.gz, and in Windows-compatible
+"zip" archive format as http://www.ijg.org/files/jpegsr8d.zip.
 
 The JPEG FAQ (Frequently Asked Questions) article is a source of some
 general information about JPEG.
 It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
 and other news.answers archive sites, including the official news.answers
 archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
 If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
 with body
 	send usenet/news.answers/jpeg-faq/part1
 	send usenet/news.answers/jpeg-faq/part2
 
 
 FILE FORMAT WARS
 ================
 
 The ISO JPEG standards committee actually promotes different formats like
-"JPEG 2000" or "JPEG XR" which are incompatible with original DCT-based
+"JPEG 2000" or "JPEG XR", which are incompatible with original DCT-based
 JPEG.  IJG therefore does not support these formats (see REFERENCES).  Indeed,
 one of the original reasons for developing this free software was to help
 force convergence on common, interoperable format standards for JPEG files.
 Don't use an incompatible file format!
 (In any case, our decoder will remain capable of reading existing JPEG
 image files indefinitely.)
 
 
 TO DO
 =====
 
-Please send bug reports, offers of help, etc. to jpeg-info@uc.ag.
+Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.
--- a/media/libjpeg/README-turbo.txt
+++ b/media/libjpeg/README-turbo.txt
@@ -1,57 +1,86 @@
 *******************************************************************************
 **     Background
 *******************************************************************************
 
-libjpeg-turbo is a derivative of libjpeg which uses SIMD instructions (MMX,
-SSE2, etc.) to accelerate baseline JPEG compression and decompression on x86
-and x86-64 systems.  On such systems, libjpeg-turbo is generally 2-4x as fast
-as the unmodified version of libjpeg, all else being equal.
+libjpeg-turbo is a derivative of libjpeg that uses SIMD instructions (MMX,
+SSE2, NEON) to accelerate baseline JPEG compression and decompression on x86,
+x86-64, and ARM systems.  On such systems, libjpeg-turbo is generally 2-4x as
+fast as the unmodified version of libjpeg, all else being equal.
 
 libjpeg-turbo was originally based on libjpeg/SIMD by Miyasaka Masaru, but
 the TigerVNC and VirtualGL projects made numerous enhancements to the codec in
 2009, including improved support for Mac OS X, 64-bit support, support for
-32-bit and big endian pixel formats (RGBX, XBGR, etc.), accelerated Huffman
-encoding/decoding, and various bug fixes.  The goal was to produce a fully open
-source codec that could replace the partially closed source TurboJPEG/IPP codec
-used by VirtualGL and TurboVNC.  libjpeg-turbo generally performs in the range
-of 80-120% of TurboJPEG/IPP.  It is faster in some areas but slower in others.
+32-bit and big-endian pixel formats (RGBX, XBGR, etc.), accelerated Huffman
+encoding/decoding, and various bug fixes.  The goal was to produce a fully
+open-source codec that could replace the partially closed-source TurboJPEG/IPP
+codec used by VirtualGL and TurboVNC.  libjpeg-turbo generally achieves 80-120%
+of the performance of TurboJPEG/IPP.  It is faster in some areas but slower in
+others.
 
 In early 2010, libjpeg-turbo spun off into its own independent project, with
 the goal of making high-speed JPEG compression/decompression technology
-available to a broader range of users and developers.  The libjpeg-turbo shared
-libraries can be used as drop-in replacements for libjpeg on most systems.
+available to a broader range of users and developers.
 
 
 *******************************************************************************
 **     License
 *******************************************************************************
 
-The TurboJPEG/OSS wrapper, as well as some of the optimizations to the Huffman
-encoder (jchuff.c) and decoder (jdhuff.c), were borrowed from VirtualGL, and
-thus any distribution of libjpeg-turbo which includes those files must, as a
-whole, be subject to the terms of the wxWindows Library Licence, Version 3.1.
-A copy of this license can be found in this directory under LICENSE.txt.  The
-wxWindows Library License is based on the LGPL but includes provisions which
-allow the Library to be statically linked into proprietary libraries and
-applications without requiring the resulting binaries to be distributed under
-the terms of the LGPL.
+Most of libjpeg-turbo inherits the non-restrictive, BSD-style license used by
+libjpeg (see README.)  The TurboJPEG/OSS wrapper (both C and Java versions) and
+associated test programs bear a similar license, which is reproduced below:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
 
-The rest of the source code, apart from TurboJPEG/OSS and the Huffman codec
-optimizations, falls under a less restrictive, BSD-style license (see README.)
-You can choose to distribute libjpeg-turbo, as a whole, under this BSD-style
-license by simply removing TurboJPEG/OSS and replacing the optimized jchuff.c
-and jdhuff.c with their unoptimized counterparts from the libjpeg v6b source.
+- Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+- Neither the name of the libjpeg-turbo Project nor the names of its
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
 
 
 *******************************************************************************
 **     Using libjpeg-turbo
 *******************************************************************************
 
+libjpeg-turbo includes two APIs that can be used to compress and decompress
+JPEG images:
+
+  TurboJPEG API:  This API provides an easy-to-use interface for compressing
+  and decompressing JPEG images in memory.  It also provides some functionality
+  that would not be straightforward to achieve using the underlying libjpeg
+  API, such as generating planar YUV images and performing multiple
+  simultaneous lossless transforms on an image.  The Java interface for
+  libjpeg-turbo is written on top of the TurboJPEG API.
+
+  libjpeg API:  This is the de facto industry-standard API for compressing and
+  decompressing JPEG images.  It is more difficult to use than the TurboJPEG
+  API but also more powerful.  libjpeg-turbo is both API/ABI-compatible and
+  mathematically compatible with libjpeg v6b.  It can also optionally be
+  configured to be API/ABI-compatible with libjpeg v7 and v8 (see below.)
+
+
 =============================
 Replacing libjpeg at Run Time
 =============================
 
 If a Unix application is dynamically linked with libjpeg, then you can replace
 libjpeg with libjpeg-turbo at run time by manipulating LD_LIBRARY_PATH.
 For instance:
 
@@ -67,42 +96,42 @@ For instance:
   real  0m0.109s
   user  0m0.029s
   sys   0m0.010s
 
 NOTE: {lib} can be lib, lib32, lib64, or lib/64, depending on the O/S and
 architecture.
 
 System administrators can also replace the libjpeg sym links in /usr/{lib} with
-links to the libjpeg dynamic library located in /opt/libjpeg-turbo/{lib}.  This
-will effectively accelerate every dynamically linked libjpeg application on the
-system.
+links to the libjpeg-turbo dynamic library located in /opt/libjpeg-turbo/{lib}.
+This will effectively accelerate every application that uses the libjpeg
+dynamic library on the system.
 
 The libjpeg-turbo SDK for Visual C++ installs the libjpeg-turbo DLL
-(jpeg62.dll, jpeg7.dll, or jpeg8.dll, depending on whether libjpeg v6b, v7, or
-v8 emulation is enabled) into c:\libjpeg-turbo[64]\bin, and the PATH
+(jpeg62.dll, jpeg7.dll, or jpeg8.dll, depending on whether it was built with
+libjpeg v6b, v7, or v8 emulation) into c:\libjpeg-turbo[64]\bin, and the PATH
 environment variable can be modified such that this directory is searched
 before any others that might contain a libjpeg DLL.  However, if a libjpeg
 DLL exists in an application's install directory, then Windows will load this
 DLL first whenever the application is launched.  Thus, if an application ships
 with jpeg62.dll, jpeg7.dll, or jpeg8.dll, then back up the application's
 version of this DLL and copy c:\libjpeg-turbo[64]\bin\jpeg*.dll into the
 application's install directory to accelerate it.
 
 The version of the libjpeg-turbo DLL distributed in the libjpeg-turbo SDK for
-Visual C++ requires the Visual C++ 2008 C run time DLL (msvcr90.dll).
+Visual C++ requires the Visual C++ 2008 C run-time DLL (msvcr90.dll).
 msvcr90.dll ships with more recent versions of Windows, but users of older
 Windows releases can obtain it from the Visual C++ 2008 Redistributable
 Package, which is available as a free download from Microsoft's web site.
 
-NOTE:  Features of libjpeg which require passing a C run time structure, such
+NOTE:  Features of libjpeg that require passing a C run-time structure, such
 as a file handle, from an application to libjpeg will probably not work with
 the version of the libjpeg-turbo DLL distributed in the libjpeg-turbo SDK for
 Visual C++, unless the application is also built to use the Visual C++ 2008 C
-run time DLL.  In particular, this affects jpeg_stdio_dest() and
+run-time DLL.  In particular, this affects jpeg_stdio_dest() and
 jpeg_stdio_src().
 
 Mac applications typically embed their own copies of the libjpeg dylib inside
 the (hidden) application bundle, so it is not possible to globally replace
 libjpeg on OS X systems.  If an application uses a shared library version of
 libjpeg, then it may be possible to replace the application's version of it.
 This would generally involve copying libjpeg.*.dylib from libjpeg-turbo into
 the appropriate place in the application bundle and using install_name_tool to
@@ -112,28 +141,28 @@ Thus, it is not recommended for most use
 
 =======================
 Replacing TurboJPEG/IPP
 =======================
 
 libjpeg-turbo is a drop-in replacement for the TurboJPEG/IPP SDK used by
 VirtualGL 2.1.x and TurboVNC 0.6 (and prior.)  libjpeg-turbo contains a wrapper
 library (TurboJPEG/OSS) that emulates the TurboJPEG API using libjpeg-turbo
-instead of the closed source Intel Performance Primitives.  You can replace the
+instead of the closed-source Intel Performance Primitives.  You can replace the
 TurboJPEG/IPP package on Linux systems with the libjpeg-turbo package in order
 to make existing releases of VirtualGL 2.1.x and TurboVNC 0.x use the new codec
 at run time.  Note that the 64-bit libjpeg-turbo packages contain only 64-bit
 binaries, whereas the TurboJPEG/IPP 64-bit packages contained both 64-bit and
 32-bit binaries.  Thus, to replace a TurboJPEG/IPP 64-bit package, install
 both the 64-bit and 32-bit versions of libjpeg-turbo.
 
 You can also build the VirtualGL 2.1.x and TurboVNC 0.6 source code with
 the libjpeg-turbo SDK instead of TurboJPEG/IPP.  It should work identically.
 libjpeg-turbo also includes static library versions of TurboJPEG/OSS, which
-are used to build TurboVNC 1.0 and later.
+are used to build VirtualGL 2.2 and TurboVNC 1.0 and later.
 
 ========================================
 Using libjpeg-turbo in Your Own Programs
 ========================================
 
 For the most part, libjpeg-turbo should work identically to libjpeg, so in
 most cases, an application can be built against libjpeg and then run against
 libjpeg-turbo.  On Unix systems (including Cygwin), you can build against
@@ -174,68 +203,80 @@ c:\libjpeg-turbo[64]\include to the syst
 variable and c:\libjpeg-turbo[64]\lib to the system or user LIB environment
 variable, and then link against either jpeg.lib (to use the DLL version of
 libjpeg-turbo) or jpeg-static.lib (to use the static version of libjpeg-turbo.)
 
 =====================
 Colorspace Extensions
 =====================
 
-libjpeg-turbo includes extensions which allow JPEG images to be compressed
-directly from (and decompressed directly to) buffers which use BGR, BGRX,
-RGBX, XBGR, and XRGB pixel ordering.  This is implemented with six new
+libjpeg-turbo includes extensions that allow JPEG images to be compressed
+directly from (and decompressed directly to) buffers that use BGR, BGRX,
+RGBX, XBGR, and XRGB pixel ordering.  This is implemented with ten new
 colorspace constants:
 
   JCS_EXT_RGB   /* red/green/blue */
   JCS_EXT_RGBX  /* red/green/blue/x */
   JCS_EXT_BGR   /* blue/green/red */
   JCS_EXT_BGRX  /* blue/green/red/x */
   JCS_EXT_XBGR  /* x/blue/green/red */
   JCS_EXT_XRGB  /* x/red/green/blue */
+  JCS_EXT_RGBA  /* red/green/blue/alpha */
+  JCS_EXT_BGRA  /* blue/green/red/alpha */
+  JCS_EXT_ABGR  /* alpha/blue/green/red */
+  JCS_EXT_ARGB  /* alpha/red/green/blue */
 
 Setting cinfo.in_color_space (compression) or cinfo.out_color_space
 (decompression) to one of these values will cause libjpeg-turbo to read the
 red, green, and blue values from (or write them to) the appropriate position in
-the pixel when YUV conversion is performed.
+the pixel when compressing from/decompressing to an RGB buffer.
 
 Your application can check for the existence of these extensions at compile
 time with:
 
   #ifdef JCS_EXTENSIONS
 
 At run time, attempting to use these extensions with a version of libjpeg
 that doesn't support them will result in a "Bogus input colorspace" error.
 
+When using the RGBX, BGRX, XBGR, and XRGB colorspaces during decompression, the
+X byte is undefined, and in order to ensure the best performance, libjpeg-turbo
+can set that byte to whatever value it wishes.  If an application expects the X
+byte to be used as an alpha channel, then it should specify JCS_EXT_RGBA,
+JCS_EXT_BGRA, JCS_EXT_ABGR, or JCS_EXT_ARGB.  When these colorspace constants
+are used, the X byte is guaranteed to be 0xFF, which is interpreted as opaque.
+
+Your application can check for the existence of the alpha channel colorspace
+extensions at compile time with:
+
+  #ifdef JCS_ALPHA_EXTENSIONS
+
+jcstest.c, located in the libjpeg-turbo source tree, demonstrates how to check
+for the existence of the colorspace extensions at compile time and run time.
+
 =================================
 libjpeg v7 and v8 API/ABI support
 =================================
 
-libjpeg v7 and v8 added new features to the API/ABI, and, unfortunately, the
-compression and decompression structures were extended in a backward-
-incompatible manner to accommodate these features.  Thus, programs which are
+With libjpeg v7 and v8, new features were added that necessitated extending the
+compression and decompression structures.  Unfortunately, due to the exposed
+nature of those structures, extending them also necessitated breaking backward
+ABI compatibility with previous libjpeg releases.  Thus, programs that are
 built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is
 based on the libjpeg v6b code base.  Although libjpeg v7 and v8 are still not
 as widely used as v6b, enough programs (including a few Linux distros) have
 made the switch that it was desirable to provide support for the libjpeg v7/v8
-API/ABI in libjpeg-turbo.
-
-Some of the libjpeg v7 and v8 features -- DCT scaling, to name one -- involve
-deep modifications to the code which cannot be accommodated by libjpeg-turbo
-without either breaking compatibility with libjpeg v6b or producing an
-unsupportable mess.  In order to fully support libjpeg v8 with all of its
-features, we would have to essentially port the SIMD extensions to the libjpeg
-v8 code base and maintain two separate code trees.  We are hesitant to do this
-until/unless the newer libjpeg code bases garner more community support and
-involvement and until/unless we have some notion of whether future libjpeg
-releases will also be backward-incompatible.
+API/ABI in libjpeg-turbo.  Although libjpeg-turbo can now be configured as a
+drop-in replacement for libjpeg v7 or v8, it should be noted that not all of
+the features in libjpeg v7 and v8 are supported (see below.)
 
 By passing an argument of --with-jpeg7 or --with-jpeg8 to configure, or an
 argument of -DWITH_JPEG7=1 or -DWITH_JPEG8=1 to cmake, you can build a version
-of libjpeg-turbo which emulates the libjpeg v7 or v8 API/ABI, so that programs
-which are built against libjpeg v7 or v8 can be run with libjpeg-turbo.  The
+of libjpeg-turbo that emulates the libjpeg v7 or v8 API/ABI, so that programs
+that are built against libjpeg v7 or v8 can be run with libjpeg-turbo.  The
 following section describes which libjpeg v7+ features are supported and which
 aren't.
 
 libjpeg v7 and v8 Features:
 ---------------------------
 
 Fully supported:
 
@@ -259,43 +300,59 @@ Fully supported when using libjpeg v7/v8
 
 -- libjpeg: In-memory source and destination managers
 
 
 Not supported:
 
 -- libjpeg: DCT scaling in compressor
    cinfo.scale_num and cinfo.scale_denom are silently ignored.
+   There is no technical reason why DCT scaling cannot be supported, but
+   without the SmartScale extension (see below), it would only be able to
+   down-scale using ratios of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and 8/9,
+   which is of limited usefulness.
+
+-- libjpeg: SmartScale
+   cinfo.block_size is silently ignored.
+   SmartScale is an extension to the JPEG format that allows for DCT block
+   sizes other than 8x8.  It would be difficult to support this feature while
+   retaining backward compatibility with libjpeg v6b.
 
 -- libjpeg: IDCT scaling extensions in decompressor
    libjpeg-turbo still supports IDCT scaling with scaling factors of 1/2, 1/4,
    and 1/8 (same as libjpeg v6b.)
 
 -- libjpeg: Fancy downsampling in compressor
    cinfo.do_fancy_downsampling is silently ignored.
+   This requires the DCT scaling feature, which is not supported.
 
 -- jpegtran: Scaling
-   Seems to depend on the DCT scaling feature, which isn't supported.
+   This requires both the DCT scaling and SmartScale features, which are not
+   supported.
+
+-- Lossless RGB JPEG files
+   This requires the SmartScale feature, which is not supported.
 
 
 *******************************************************************************
 **     Performance pitfalls
 *******************************************************************************
 
 ===============
 Restart Markers
 ===============
 
 The optimized Huffman decoder in libjpeg-turbo does not handle restart markers
-in a way that makes libjpeg happy, so it is necessary to use the slow Huffman
-decoder when decompressing a JPEG image that has restart markers.  This can
-cause the decompression performance to drop by as much as 20%, but the
-performance will still be much much greater than that of libjpeg v6b.  Many
-consumer packages, such as PhotoShop, use restart markers when generating JPEG
-images, so images generated by those programs will experience this issue.
+in a way that makes the rest of the libjpeg infrastructure happy, so it is
+necessary to use the slow Huffman decoder when decompressing a JPEG image that
+has restart markers.  This can cause the decompression performance to drop by
+as much as 20%, but the performance will still be much greater than that of
+libjpeg.  Many consumer packages, such as PhotoShop, use restart markers when
+generating JPEG images, so images generated by those programs will experience
+this issue.
 
 ===============================================
 Fast Integer Forward DCT at High Quality Levels
 ===============================================
 
 The algorithm used by the SIMD-accelerated quantization function cannot produce
 correct results whenever the fast integer forward DCT is used along with a JPEG
 quality of 98-100.  Thus, libjpeg-turbo must use the non-SIMD quantization
deleted file mode 100644
--- a/media/libjpeg/cderror.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * cderror.h
- *
- * Copyright (C) 1994-1997, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
- * This file is part of the Independent JPEG Group's software.
- * For conditions of distribution and use, see the accompanying README file.
- *
- * This file defines the error and message codes for the cjpeg/djpeg
- * applications.  These strings are not needed as part of the JPEG library
- * proper.
- * Edit this file to add new codes, or to translate the message strings to
- * some other language.
- */
-
-/*
- * To define the enum list of message codes, include this file without
- * defining macro JMESSAGE.  To create a message string table, include it
- * again with a suitable JMESSAGE definition (see jerror.c for an example).
- */
-#ifndef JMESSAGE
-#ifndef CDERROR_H
-#define CDERROR_H
-/* First time through, define the enum list */
-#define JMAKE_ENUM_LIST
-#else
-/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
-#define JMESSAGE(code,string)
-#endif /* CDERROR_H */
-#endif /* JMESSAGE */
-
-#ifdef JMAKE_ENUM_LIST
-
-typedef enum {
-
-#define JMESSAGE(code,string)	code ,
-
-#endif /* JMAKE_ENUM_LIST */
-
-JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
-
-#ifdef BMP_SUPPORTED
-JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
-JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
-JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
-JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
-JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
-JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
-JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
-JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
-JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
-JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
-JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
-JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
-#endif /* BMP_SUPPORTED */
-
-#ifdef GIF_SUPPORTED
-JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
-JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
-JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
-JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
-JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
-JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
-JMESSAGE(JTRC_GIF_BADVERSION,
-	 "Warning: unexpected GIF version number '%c%c%c'")
-JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x")
-JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input")
-JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file")
-JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
-JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
-JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
-#endif /* GIF_SUPPORTED */
-
-#ifdef PPM_SUPPORTED
-JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
-JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
-JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
-JMESSAGE(JTRC_PGM, "%ux%u PGM image")
-JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
-JMESSAGE(JTRC_PPM, "%ux%u PPM image")
-JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
-#endif /* PPM_SUPPORTED */
-
-#ifdef RLE_SUPPORTED
-JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
-JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
-JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
-JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
-JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
-JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
-JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
-JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
-JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
-JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
-JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
-JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
-JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
-JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
-#endif /* RLE_SUPPORTED */
-
-#ifdef TARGA_SUPPORTED
-JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
-JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
-JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB")
-JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image")
-JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image")
-JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image")
-#else
-JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled")
-#endif /* TARGA_SUPPORTED */
-
-JMESSAGE(JERR_BAD_CMAP_FILE,
-	 "Color map file is invalid or of unsupported format")
-JMESSAGE(JERR_TOO_MANY_COLORS,
-	 "Output file format cannot handle %d colormap entries")
-JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed")
-#ifdef TARGA_SUPPORTED
-JMESSAGE(JERR_UNKNOWN_FORMAT,
-	 "Unrecognized input file format --- perhaps you need -targa")
-#else
-JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
-#endif
-JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
-
-#ifdef JMAKE_ENUM_LIST
-
-  JMSG_LASTADDONCODE
-} ADDON_MESSAGE_CODE;
-
-#undef JMAKE_ENUM_LIST
-#endif /* JMAKE_ENUM_LIST */
-
-/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
-#undef JMESSAGE
deleted file mode 100644
--- a/media/libjpeg/cdjpeg.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * cdjpeg.h
- *
- * Copyright (C) 1994-1997, Thomas G. Lane.
- * This file is part of the Independent JPEG Group's software.
- * For conditions of distribution and use, see the accompanying README file.
- *
- * This file contains common declarations for the sample applications
- * cjpeg and djpeg.  It is NOT used by the core JPEG library.
- */
-
-#define JPEG_CJPEG_DJPEG	/* define proper options in jconfig.h */
-#define JPEG_INTERNAL_OPTIONS	/* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */
-#include "jinclude.h"
-#include "jpeglib.h"
-#include "jerror.h"		/* get library error codes too */
-#include "cderror.h"		/* get application-specific error codes */
-
-
-/*
- * Object interface for cjpeg's source file decoding modules
- */
-
-typedef struct cjpeg_source_struct * cjpeg_source_ptr;
-
-struct cjpeg_source_struct {
-  JMETHOD(void, start_input, (j_compress_ptr cinfo,
-			      cjpeg_source_ptr sinfo));
-  JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo,
-				       cjpeg_source_ptr sinfo));
-  JMETHOD(void, finish_input, (j_compress_ptr cinfo,
-			       cjpeg_source_ptr sinfo));
-
-  FILE *input_file;
-
-  JSAMPARRAY buffer;
-  JDIMENSION buffer_height;
-};
-
-
-/*
- * Object interface for djpeg's output file encoding modules
- */
-
-typedef struct djpeg_dest_struct * djpeg_dest_ptr;
-
-struct djpeg_dest_struct {
-  /* start_output is called after jpeg_start_decompress finishes.
-   * The color map will be ready at this time, if one is needed.
-   */
-  JMETHOD(void, start_output, (j_decompress_ptr cinfo,
-			       djpeg_dest_ptr dinfo));
-  /* Emit the specified number of pixel rows from the buffer. */
-  JMETHOD(void, put_pixel_rows, (j_decompress_ptr cinfo,
-				 djpeg_dest_ptr dinfo,
-				 JDIMENSION rows_supplied));
-  /* Finish up at the end of the image. */
-  JMETHOD(void, finish_output, (j_decompress_ptr cinfo,
-				djpeg_dest_ptr dinfo));
-
-  /* Target file spec; filled in by djpeg.c after object is created. */
-  FILE * output_file;
-
-  /* Output pixel-row buffer.  Created by module init or start_output.
-   * Width is cinfo->output_width * cinfo->output_components;
-   * height is buffer_height.
-   */
-  JSAMPARRAY buffer;
-  JDIMENSION buffer_height;
-};
-
-
-/*
- * cjpeg/djpeg may need to perform extra passes to convert to or from
- * the source/destination file format.  The JPEG library does not know
- * about these passes, but we'd like them to be counted by the progress
- * monitor.  We use an expanded progress monitor object to hold the
- * additional pass count.
- */
-
-struct cdjpeg_progress_mgr {
-  struct jpeg_progress_mgr pub;	/* fields known to JPEG library */
-  int completed_extra_passes;	/* extra passes completed */
-  int total_extra_passes;	/* total extra */
-  /* last printed percentage stored here to avoid multiple printouts */
-  int percent_done;
-};
-
-typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
-
-
-/* Short forms of external names for systems with brain-damaged linkers. */
-
-#ifdef NEED_SHORT_EXTERNAL_NAMES
-#define jinit_read_bmp		jIRdBMP
-#define jinit_write_bmp		jIWrBMP
-#define jinit_read_gif		jIRdGIF
-#define jinit_write_gif		jIWrGIF
-#define jinit_read_ppm		jIRdPPM
-#define jinit_write_ppm		jIWrPPM
-#define jinit_read_rle		jIRdRLE
-#define jinit_write_rle		jIWrRLE
-#define jinit_read_targa	jIRdTarga
-#define jinit_write_targa	jIWrTarga
-#define read_quant_tables	RdQTables
-#define read_scan_script	RdScnScript
-#define set_quality_ratings     SetQRates
-#define set_quant_slots		SetQSlots
-#define set_sample_factors	SetSFacts
-#define read_color_map		RdCMap
-#define enable_signal_catcher	EnSigCatcher
-#define start_progress_monitor	StProgMon
-#define end_progress_monitor	EnProgMon
-#define read_stdin		RdStdin
-#define write_stdout		WrStdout
-#endif /* NEED_SHORT_EXTERNAL_NAMES */
-
-/* Module selection routines for I/O modules. */
-
-EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo));
-EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo,
-					    boolean is_os2));
-EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
-EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
-EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
-EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
-EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));
-EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo));
-EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo));
-EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
-
-/* cjpeg support routines (in rdswitch.c) */
-
-EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
-				       boolean force_baseline));
-EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
-EXTERN(boolean) set_quality_ratings JPP((j_compress_ptr cinfo, char *arg,
-					 boolean force_baseline));
-EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
-EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
-
-/* djpeg support routines (in rdcolmap.c) */
-
-EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile));
-
-/* common support routines (in cdjpeg.c) */
-
-EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo));
-EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo,
-					 cd_progress_ptr progress));
-EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo));
-EXTERN(boolean) keymatch JPP((char * arg, const char * keyword, int minchars));
-EXTERN(FILE *) read_stdin JPP((void));
-EXTERN(FILE *) write_stdout JPP((void));
-
-/* miscellaneous useful macros */
-
-#ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
-#define READ_BINARY	"r"
-#define WRITE_BINARY	"w"
-#else
-#ifdef VMS			/* VMS is very nonstandard */
-#define READ_BINARY	"rb", "ctx=stm"
-#define WRITE_BINARY	"wb", "ctx=stm"
-#else				/* standard ANSI-compliant case */
-#define READ_BINARY	"rb"
-#define WRITE_BINARY	"wb"
-#endif
-#endif
-
-#ifndef EXIT_FAILURE		/* define exit() codes if not provided */
-#define EXIT_FAILURE  1
-#endif
-#ifndef EXIT_SUCCESS
-#ifdef VMS
-#define EXIT_SUCCESS  1		/* VMS is very nonstandard */
-#else
-#define EXIT_SUCCESS  0
-#endif
-#endif
-#ifndef EXIT_WARNING
-#ifdef VMS
-#define EXIT_WARNING  1		/* VMS is very nonstandard */
-#else
-#define EXIT_WARNING  2
-#endif
-#endif
new file mode 100644
--- /dev/null
+++ b/media/libjpeg/config.h
@@ -0,0 +1,6 @@
+#define VERSION "1.2.0"
+#define BUILD "2012-02-10"
+#define PACKAGE_NAME "libjpeg-turbo"
+
+/* Need to use Mozilla-specific function inlining. */
+#define INLINE NS_ALWAYS_INLINE
--- a/media/libjpeg/jaricom.c
+++ b/media/libjpeg/jaricom.c
@@ -145,8 +145,9 @@ const INT32 jpeg_aritab[113+1] = {
   V( 110, 0x5a10, 110, 111, 1 ),
   V( 111, 0x5522, 112, 109, 0 ),
   V( 112, 0x59eb, 112, 111, 1 ),
 /*
  * This last entry is used for fixed probability estimate of 0.5
  * as recommended in Section 10.3 Table 5 of ITU-T Rec. T.851.
  */
   V( 113, 0x5a1d, 113, 113, 0 )
+};
new file mode 100644
--- /dev/null
+++ b/media/libjpeg/jccolext.c
@@ -0,0 +1,114 @@
+/*
+ * jccolext.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input colorspace conversion routines.
+ */
+
+
+/* This file is included by jccolor.c */
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ *
+ * Note that we change from the application's interleaved-pixel format
+ * to our internal noninterleaved, one-plane-per-component format.
+ * The input buffer is therefore three times as wide as the output buffer.
+ *
+ * A starting row offset is provided only for the output buffer.  The caller
+ * can easily adjust the passed input_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+INLINE
+LOCAL(void)
+rgb_ycc_convert_internal (j_compress_ptr cinfo,
+                          JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+                          JDIMENSION output_row, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int r, g, b;
+  register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register JSAMPROW inptr;
+  register JSAMPROW outptr0, outptr1, outptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr0 = output_buf[0][output_row];
+    outptr1 = output_buf[1][output_row];
+    outptr2 = output_buf[2][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr[RGB_RED]);
+      g = GETJSAMPLE(inptr[RGB_GREEN]);
+      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      inptr += RGB_PIXELSIZE;
+      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+       * must be too; we do not need an explicit range-limiting operation.
+       * Hence the value being shifted is never negative, and we don't
+       * need the general RIGHT_SHIFT macro.
+       */
+      /* Y */
+      outptr0[col] = (JSAMPLE)
+		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+		 >> SCALEBITS);
+      /* Cb */
+      outptr1[col] = (JSAMPLE)
+		((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+		 >> SCALEBITS);
+      /* Cr */
+      outptr2[col] = (JSAMPLE)
+		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+		 >> SCALEBITS);
+    }
+  }
+}
+
+
+/**************** Cases other than RGB -> YCbCr **************/
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles RGB->grayscale conversion, which is the same
+ * as the RGB->Y portion of RGB->YCbCr.
+ * We assume rgb_ycc_start has been called (we only use the Y tables).
+ */
+
+INLINE
+LOCAL(void)
+rgb_gray_convert_internal (j_compress_ptr cinfo,
+                           JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+                           JDIMENSION output_row, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int r, g, b;
+  register INT32 * ctab = cconvert->rgb_ycc_tab;
+  register JSAMPROW inptr;
+  register JSAMPROW outptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->image_width;
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr = output_buf[0][output_row];
+    output_row++;
+    for (col = 0; col < num_cols; col++) {
+      r = GETJSAMPLE(inptr[RGB_RED]);
+      g = GETJSAMPLE(inptr[RGB_GREEN]);
+      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      inptr += RGB_PIXELSIZE;
+      /* Y */
+      outptr[col] = (JSAMPLE)
+		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+		 >> SCALEBITS);
+    }
+  }
+}
--- a/media/libjpeg/jccolor.c
+++ b/media/libjpeg/jccolor.c
@@ -1,24 +1,25 @@
 /*
  * jccolor.c
  *
  * Copyright (C) 1991-1996, Thomas G. Lane.
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright 2009 D. R. Commander
+ * Copyright (C) 2009-2011, D. R. Commander.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains input colorspace conversion routines.
  */
 
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
 #include "jsimd.h"
+#include "config.h"
 
 
 /* Private subobject */
 
 typedef struct {
   struct jpeg_color_converter pub; /* public fields */
 
   /* Private state for RGB->YCC conversion */
@@ -76,82 +77,107 @@ typedef my_color_converter * my_cconvert
 #define G_CB_OFF	(4*(MAXJSAMPLE+1))
 #define B_CB_OFF	(5*(MAXJSAMPLE+1))
 #define R_CR_OFF	B_CB_OFF		/* B=>Cb, R=>Cr are the same */
 #define G_CR_OFF	(6*(MAXJSAMPLE+1))
 #define B_CR_OFF	(7*(MAXJSAMPLE+1))
 #define TABLE_SIZE	(8*(MAXJSAMPLE+1))
 
 
-#if BITS_IN_JSAMPLE == 8
+/* Include inline routines for colorspace extensions */
+
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
 
-static const unsigned char red_lut[256] = {
-  0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 4 ,
-  5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 ,
-  10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
-  14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19,
-  19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24,
-  24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28,
-  29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33,
-  33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38,
-  38, 39, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
-  43, 43, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48,
-  48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52,
-  53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57,
-  57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62,
-  62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67,
-  67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71,
-  72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76
-};
+#define RGB_RED EXT_RGB_RED
+#define RGB_GREEN EXT_RGB_GREEN
+#define RGB_BLUE EXT_RGB_BLUE
+#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
+#define rgb_ycc_convert_internal extrgb_ycc_convert_internal
+#define rgb_gray_convert_internal extrgb_gray_convert_internal
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_RGBX_RED
+#define RGB_GREEN EXT_RGBX_GREEN
+#define RGB_BLUE EXT_RGBX_BLUE
+#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
+#define rgb_ycc_convert_internal extrgbx_ycc_convert_internal
+#define rgb_gray_convert_internal extrgbx_gray_convert_internal
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
 
-static const unsigned char green_lut[256] = {
-  0  , 1  , 1  , 2  , 2  , 3  , 4  , 4  , 5  , 5  , 6  , 6  ,
-  7  , 8  , 8  , 9  , 9  , 10 , 11 , 11 , 12 , 12 , 13 , 14 ,
-  14 , 15 , 15 , 16 , 16 , 17 , 18 , 18 , 19 , 19 , 20 , 21 ,
-  21 , 22 , 22 , 23 , 23 , 24 , 25 , 25 , 26 , 26 , 27 , 28 ,
-  28 , 29 , 29 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 35 ,
-  35 , 36 , 36 , 37 , 38 , 38 , 39 , 39 , 40 , 41 , 41 , 42 ,
-  42 , 43 , 43 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 ,
-  49 , 50 , 50 , 51 , 52 , 52 , 53 , 53 , 54 , 55 , 55 , 56 ,
-  56 , 57 , 58 , 58 , 59 , 59 , 60 , 60 , 61 , 62 , 62 , 63 ,
-  63 , 64 , 65 , 65 , 66 , 66 , 67 , 68 , 68 , 69 , 69 , 70 ,
-  70 , 71 , 72 , 72 , 73 , 73 , 74 , 75 , 75 , 76 , 76 , 77 ,
-  77 , 78 , 79 , 79 , 80 , 80 , 81 , 82 , 82 , 83 , 83 , 84 ,
-  85 , 85 , 86 , 86 , 87 , 87 , 88 , 89 , 89 , 90 , 90 , 91 ,
-  92 , 92 , 93 , 93 , 94 , 95 , 95 , 96 , 96 , 97 , 97 , 98 ,
-  99 , 99 , 100, 100, 101, 102, 102, 103, 103, 104, 104, 105,
-  106, 106, 107, 107, 108, 109, 109, 110, 110, 111, 112, 112,
-  113, 113, 114, 114, 115, 116, 116, 117, 117, 118, 119, 119,
-  120, 120, 121, 122, 122, 123, 123, 124, 124, 125, 126, 126,
-  127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 133, 133,
-  134, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140,
-  141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147,
-  148, 149, 149, 150
-};
+#define RGB_RED EXT_BGR_RED
+#define RGB_GREEN EXT_BGR_GREEN
+#define RGB_BLUE EXT_BGR_BLUE
+#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
+#define rgb_ycc_convert_internal extbgr_ycc_convert_internal
+#define rgb_gray_convert_internal extbgr_gray_convert_internal
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_BGRX_RED
+#define RGB_GREEN EXT_BGRX_GREEN
+#define RGB_BLUE EXT_BGRX_BLUE
+#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
+#define rgb_ycc_convert_internal extbgrx_ycc_convert_internal
+#define rgb_gray_convert_internal extbgrx_gray_convert_internal
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
 
-static const unsigned char blue_lut[256] = {
-  0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ,
-  2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 ,
-  4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
-  5 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 ,
-  7 , 7 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 ,
-  9 , 9 , 9 , 9 , 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
-  11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
-  18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
-  20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
-  22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24,
-  24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-  26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27,
-  27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29
-};
+#define RGB_RED EXT_XBGR_RED
+#define RGB_GREEN EXT_XBGR_GREEN
+#define RGB_BLUE EXT_XBGR_BLUE
+#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
+#define rgb_ycc_convert_internal extxbgr_ycc_convert_internal
+#define rgb_gray_convert_internal extxbgr_gray_convert_internal
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
 
-#endif
+#define RGB_RED EXT_XRGB_RED
+#define RGB_GREEN EXT_XRGB_GREEN
+#define RGB_BLUE EXT_XRGB_BLUE
+#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
+#define rgb_ycc_convert_internal extxrgb_ycc_convert_internal
+#define rgb_gray_convert_internal extxrgb_gray_convert_internal
+#include "jccolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
 
 
 /*
  * Initialize for RGB->YCC colorspace conversion.
  */
 
 METHODDEF(void)
 rgb_ycc_start (j_compress_ptr cinfo)
@@ -182,117 +208,105 @@ rgb_ycc_start (j_compress_ptr cinfo)
     rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
     rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
   }
 }
 
 
 /*
  * Convert some rows of samples to the JPEG colorspace.
- *
- * Note that we change from the application's interleaved-pixel format
- * to our internal noninterleaved, one-plane-per-component format.
- * The input buffer is therefore three times as wide as the output buffer.
- *
- * A starting row offset is provided only for the output buffer.  The caller
- * can easily adjust the passed input_buf value to accommodate any row
- * offset required on that side.
  */
 
 METHODDEF(void)
 rgb_ycc_convert (j_compress_ptr cinfo,
 		 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 		 JDIMENSION output_row, int num_rows)
 {
-  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
-  register int r, g, b;
-  register INT32 * ctab = cconvert->rgb_ycc_tab;
-  register JSAMPROW inptr;
-  register JSAMPROW outptr0, outptr1, outptr2;
-  register JDIMENSION col;
-  JDIMENSION num_cols = cinfo->image_width;
-
-  while (--num_rows >= 0) {
-    inptr = *input_buf++;
-    outptr0 = output_buf[0][output_row];
-    outptr1 = output_buf[1][output_row];
-    outptr2 = output_buf[2][output_row];
-    output_row++;
-    for (col = 0; col < num_cols; col++) {
-      r = GETJSAMPLE(inptr[rgb_red[cinfo->in_color_space]]);
-      g = GETJSAMPLE(inptr[rgb_green[cinfo->in_color_space]]);
-      b = GETJSAMPLE(inptr[rgb_blue[cinfo->in_color_space]]);
-      inptr += rgb_pixelsize[cinfo->in_color_space];
-      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
-       * must be too; we do not need an explicit range-limiting operation.
-       * Hence the value being shifted is never negative, and we don't
-       * need the general RIGHT_SHIFT macro.
-       */
-      /* Y */
-      outptr0[col] = (JSAMPLE)
-		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
-		 >> SCALEBITS);
-      /* Cb */
-      outptr1[col] = (JSAMPLE)
-		((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
-		 >> SCALEBITS);
-      /* Cr */
-      outptr2[col] = (JSAMPLE)
-		((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
-		 >> SCALEBITS);
-    }
+  switch (cinfo->in_color_space) {
+    case JCS_EXT_RGB:
+      extrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                  num_rows);
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      extrgbx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                   num_rows);
+      break;
+    case JCS_EXT_BGR:
+      extbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                  num_rows);
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      extbgrx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                   num_rows);
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      extxbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                   num_rows);
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      extxrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                   num_rows);
+      break;
+    default:
+      rgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+                               num_rows);
+      break;
   }
 }
 
 
 /**************** Cases other than RGB -> YCbCr **************/
 
 
 /*
  * Convert some rows of samples to the JPEG colorspace.
- * This version handles RGB->grayscale conversion, which is the same
- * as the RGB->Y portion of RGB->YCbCr.
- * We assume rgb_ycc_start has been called (we only use the Y tables).
  */
 
 METHODDEF(void)
 rgb_gray_convert (j_compress_ptr cinfo,
 		  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 		  JDIMENSION output_row, int num_rows)
 {
-  #if BITS_IN_JSAMPLE != 8
-  register INT32 * ctab = cconvert->rgb_ycc_tab;
-  #endif
-  register JSAMPROW inptr;
-  register JSAMPROW outptr;
-  JSAMPLE *maxoutptr;
-  JDIMENSION num_cols = cinfo->image_width;
-  int rindex = rgb_red[cinfo->in_color_space];
-  int gindex = rgb_green[cinfo->in_color_space];
-  int bindex = rgb_blue[cinfo->in_color_space];
-  int rgbstride = rgb_pixelsize[cinfo->in_color_space];
-
-  while (--num_rows >= 0) {
-    inptr = *input_buf++;
-    outptr = output_buf[0][output_row];
-    maxoutptr = &outptr[num_cols];
-    output_row++;
-    for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
-      /* Y */
-      #if BITS_IN_JSAMPLE == 8
-      *outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
-	    + blue_lut[inptr[bindex]];
-      #else
-      *outptr = (JSAMPLE)
-	    ((ctab[GETJSAMPLE(inptr[rindex])+R_Y_OFF]
-	     + ctab[GETJSAMPLE(inptr[gindex])+G_Y_OFF]
-	     + ctab[GETJSAMPLE(inptr[bindex])+B_Y_OFF])
-	     >> SCALEBITS);
-      #endif
-    }
+  switch (cinfo->in_color_space) {
+    case JCS_EXT_RGB:
+      extrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                   num_rows);
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      extrgbx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                    num_rows);
+      break;
+    case JCS_EXT_BGR:
+      extbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                   num_rows);
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      extbgrx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                    num_rows);
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      extxbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                    num_rows);
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      extxrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                    num_rows);
+      break;
+    default:
+      rgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+                                num_rows);
+      break;
   }
 }
 
 
 /*
  * Convert some rows of samples to the JPEG colorspace.
  * This version handles Adobe-style CMYK->YCCK conversion,
  * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
@@ -448,16 +462,20 @@ jinit_color_converter (j_compress_ptr ci
 
   case JCS_RGB:
   case JCS_EXT_RGB:
   case JCS_EXT_RGBX:
   case JCS_EXT_BGR:
   case JCS_EXT_BGRX:
   case JCS_EXT_XBGR:
   case JCS_EXT_XRGB:
+  case JCS_EXT_RGBA:
+  case JCS_EXT_BGRA:
+  case JCS_EXT_ABGR:
+  case JCS_EXT_ARGB:
     if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
     break;
 
   case JCS_YCbCr:
     if (cinfo->input_components != 3)
       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
     break;
@@ -482,32 +500,44 @@ jinit_color_converter (j_compress_ptr ci
     if (cinfo->in_color_space == JCS_GRAYSCALE)
       cconvert->pub.color_convert = grayscale_convert;
     else if (cinfo->in_color_space == JCS_RGB ||
              cinfo->in_color_space == JCS_EXT_RGB ||
              cinfo->in_color_space == JCS_EXT_RGBX ||
              cinfo->in_color_space == JCS_EXT_BGR ||
              cinfo->in_color_space == JCS_EXT_BGRX ||
              cinfo->in_color_space == JCS_EXT_XBGR ||
-             cinfo->in_color_space == JCS_EXT_XRGB) {
-      cconvert->pub.start_pass = rgb_ycc_start;
-      cconvert->pub.color_convert = rgb_gray_convert;
+             cinfo->in_color_space == JCS_EXT_XRGB ||
+             cinfo->in_color_space == JCS_EXT_RGBA ||
+             cinfo->in_color_space == JCS_EXT_BGRA ||
+             cinfo->in_color_space == JCS_EXT_ABGR ||
+             cinfo->in_color_space == JCS_EXT_ARGB) {
+      if (jsimd_can_rgb_gray())
+        cconvert->pub.color_convert = jsimd_rgb_gray_convert;
+      else {
+        cconvert->pub.start_pass = rgb_ycc_start;
+        cconvert->pub.color_convert = rgb_gray_convert;
+      }
     } else if (cinfo->in_color_space == JCS_YCbCr)
       cconvert->pub.color_convert = grayscale_convert;
     else
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     break;
 
   case JCS_RGB:
   case JCS_EXT_RGB:
   case JCS_EXT_RGBX:
   case JCS_EXT_BGR:
   case JCS_EXT_BGRX:
   case JCS_EXT_XBGR:
   case JCS_EXT_XRGB:
+  case JCS_EXT_RGBA:
+  case JCS_EXT_BGRA:
+  case JCS_EXT_ABGR:
+  case JCS_EXT_ARGB:
     if (cinfo->num_components != 3)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     if (cinfo->in_color_space == cinfo->jpeg_color_space &&
       rgb_pixelsize[cinfo->in_color_space] == 3)
       cconvert->pub.color_convert = null_convert;
     else
       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     break;
@@ -516,17 +546,21 @@ jinit_color_converter (j_compress_ptr ci
     if (cinfo->num_components != 3)
       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     if (cinfo->in_color_space == JCS_RGB ||
         cinfo->in_color_space == JCS_EXT_RGB ||
         cinfo->in_color_space == JCS_EXT_RGBX ||
         cinfo->in_color_space == JCS_EXT_BGR ||
         cinfo->in_color_space == JCS_EXT_BGRX ||
         cinfo->in_color_space == JCS_EXT_XBGR ||
-        cinfo->in_color_space == JCS_EXT_XRGB) {
+        cinfo->in_color_space == JCS_EXT_XRGB ||
+        cinfo->in_color_space == JCS_EXT_RGBA ||
+        cinfo->in_color_space == JCS_EXT_BGRA ||
+        cinfo->in_color_space == JCS_EXT_ABGR ||
+        cinfo->in_color_space == JCS_EXT_ARGB) {
       if (jsimd_can_rgb_ycc())
         cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
       else {
         cconvert->pub.start_pass = rgb_ycc_start;
         cconvert->pub.color_convert = rgb_ycc_convert;
       }
     } else if (cinfo->in_color_space == JCS_YCbCr)
       cconvert->pub.color_convert = null_convert;
--- a/media/libjpeg/jcdctmgr.c
+++ b/media/libjpeg/jcdctmgr.c
@@ -177,17 +177,17 @@ compute_reciprocal (UINT16 divisor, DCTE
   fr = ((UDCTELEM2)1 << r) % divisor;
 
   c = divisor / 2; /* for rounding */
 
   if (fr == 0) { /* divisor is power of two */
     /* fq will be one bit too large to fit in DCTELEM, so adjust */
     fq >>= 1;
     r--;
-  } else if (fr <= (divisor / 2)) { /* fractional part is < 0.5 */
+  } else if (fr <= (divisor / 2U)) { /* fractional part is < 0.5 */
     c++;
   } else { /* fractional part is > 0.5 */
     fq++;
   }
 
   dtbl[DCTSIZE2 * 0] = (DCTELEM) fq;      /* reciprocal */
   dtbl[DCTSIZE2 * 1] = (DCTELEM) c;       /* correction + roundfactor */
   dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r));  /* scale */
--- a/media/libjpeg/jchuff.c
+++ b/media/libjpeg/jchuff.c
@@ -1,37 +1,47 @@
 /*
  * jchuff.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains Huffman entropy encoding routines.
  *
  * Much of the complexity here has to do with supporting output suspension.
  * If the data destination module demands suspension, we want to be able to
  * back up to the start of the current MCU.  To do this, we copy state
  * variables into local working storage, and update them back to the
  * permanent JPEG objects only upon successful completion of an MCU.
  */
 
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
 #include "jchuff.h"		/* Declarations shared with jcphuff.c */
+#include <limits.h>
+
+static unsigned char jpeg_nbits_table[65536];
+static int jpeg_nbits_table_init = 0;
+
+#ifndef min
+ #define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
 
 /* Expanded entropy encoder object for Huffman encoding.
  *
  * The savable_state subrecord contains fields that change within an MCU,
  * but must not be updated permanently until we complete the MCU.
  */
 
 typedef struct {
-  INT32 put_buffer;		/* current bit-accumulation buffer */
+  size_t put_buffer;		/* current bit-accumulation buffer */
   int put_bits;			/* # of bits now in it */
   int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
 } savable_state;
 
 /* This macro is to work around compilers with missing or broken
  * structure assignment.  You'll need to fix this code if you have
  * such a compiler and you change MAX_COMPS_IN_SCAN.
  */
@@ -255,16 +265,25 @@ jpeg_make_c_derived_tbl (j_compress_ptr 
 
   for (p = 0; p < lastp; p++) {
     i = htbl->huffval[p];
     if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
     dtbl->ehufco[i] = huffcode[p];
     dtbl->ehufsi[i] = huffsize[p];
   }
+
+  if(!jpeg_nbits_table_init) {
+    for(i = 0; i < 65536; i++) {
+      int nbits = 0, temp = i;
+      while (temp) {temp >>= 1;  nbits++;}
+      jpeg_nbits_table[i] = nbits;
+    }
+    jpeg_nbits_table_init = 1;
+  }
 }
 
 
 /* Outputting bytes to the file */
 
 /* Emit a byte, taking 'action' if must suspend. */
 #define emit_byte(state,val,action)  \
 	{ *(state)->next_output_byte++ = (JOCTET) (val);  \
@@ -274,174 +293,273 @@ jpeg_make_c_derived_tbl (j_compress_ptr 
 
 
 LOCAL(boolean)
 dump_buffer (working_state * state)
 /* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
 {
   struct jpeg_destination_mgr * dest = state->cinfo->dest;
 
+  dest->free_in_buffer = state->free_in_buffer;
+
   if (! (*dest->empty_output_buffer) (state->cinfo))
     return FALSE;
   /* After a successful buffer dump, must reset buffer pointers */
   state->next_output_byte = dest->next_output_byte;
   state->free_in_buffer = dest->free_in_buffer;
   return TRUE;
 }
 
 
 /* Outputting bits to the file */
 
-/* Only the right 24 bits of put_buffer are used; the valid bits are
- * left-justified in this part.  At most 16 bits can be passed to emit_bits
- * in one call, and we never retain more than 7 bits in put_buffer
- * between calls, so 24 bits are sufficient.
+/* These macros perform the same task as the emit_bits() function in the
+ * original libjpeg code.  In addition to reducing overhead by explicitly
+ * inlining the code, additional performance is achieved by taking into
+ * account the size of the bit buffer and waiting until it is almost full
+ * before emptying it.  This mostly benefits 64-bit platforms, since 6
+ * bytes can be stored in a 64-bit bit buffer before it has to be emptied.
  */
 
-INLINE
-LOCAL(boolean)
-emit_bits (working_state * state, unsigned int code, int size)
-/* Emit some bits; return TRUE if successful, FALSE if must suspend */
-{
-  /* This routine is heavily used, so it's worth coding tightly. */
-  register INT32 put_buffer = (INT32) code;
-  register int put_bits = state->cur.put_bits;
+#define EMIT_BYTE() { \
+  JOCTET c; \
+  put_bits -= 8; \
+  c = (JOCTET)GETJOCTET(put_buffer >> put_bits); \
+  *buffer++ = c; \
+  if (c == 0xFF)  /* need to stuff a zero byte? */ \
+    *buffer++ = 0; \
+ }
+
+#define PUT_BITS(code, size) { \
+  put_bits += size; \
+  put_buffer = (put_buffer << size) | code; \
+}
+
+#define CHECKBUF15() { \
+  if (put_bits > 15) { \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+  } \
+}
 
-  /* if size is 0, caller used an invalid Huffman table entry */
-  if (size == 0)
-    ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
+#define CHECKBUF31() { \
+  if (put_bits > 31) { \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+  } \
+}
 
-  put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
-  
-  put_bits += size;		/* new number of bits in buffer */
-  
-  put_buffer <<= 24 - put_bits; /* align incoming bits */
+#define CHECKBUF47() { \
+  if (put_bits > 47) { \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+    EMIT_BYTE() \
+  } \
+}
+
+#if __WORDSIZE==64 || defined(_WIN64)
+
+#define EMIT_BITS(code, size) { \
+  CHECKBUF47() \
+  PUT_BITS(code, size) \
+}
 
-  put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
-  
-  while (put_bits >= 8) {
-    int c = (int) ((put_buffer >> 16) & 0xFF);
-    
-    emit_byte(state, c, return FALSE);
-    if (c == 0xFF) {		/* need to stuff a zero byte? */
-      emit_byte(state, 0, return FALSE);
-    }
-    put_buffer <<= 8;
-    put_bits -= 8;
-  }
+#define EMIT_CODE(code, size) { \
+  temp2 &= (((INT32) 1)<<nbits) - 1; \
+  CHECKBUF31() \
+  PUT_BITS(code, size) \
+  PUT_BITS(temp2, nbits) \
+ }
+
+#else
+
+#define EMIT_BITS(code, size) { \
+  PUT_BITS(code, size) \
+  CHECKBUF15() \
+}
+
+#define EMIT_CODE(code, size) { \
+  temp2 &= (((INT32) 1)<<nbits) - 1; \
+  PUT_BITS(code, size) \
+  CHECKBUF15() \
+  PUT_BITS(temp2, nbits) \
+  CHECKBUF15() \
+ }
+
+#endif
+
+
+#define BUFSIZE (DCTSIZE2 * 2)
 
-  state->cur.put_buffer = put_buffer; /* update state variables */
-  state->cur.put_bits = put_bits;
+#define LOAD_BUFFER() { \
+  if (state->free_in_buffer < BUFSIZE) { \
+    localbuf = 1; \
+    buffer = _buffer; \
+  } \
+  else buffer = state->next_output_byte; \
+ }
 
-  return TRUE;
-}
+#define STORE_BUFFER() { \
+  if (localbuf) { \
+    bytes = buffer - _buffer; \
+    buffer = _buffer; \
+    while (bytes > 0) { \
+      bytestocopy = min(bytes, state->free_in_buffer); \
+      MEMCOPY(state->next_output_byte, buffer, bytestocopy); \
+      state->next_output_byte += bytestocopy; \
+      buffer += bytestocopy; \
+      state->free_in_buffer -= bytestocopy; \
+      if (state->free_in_buffer == 0) \
+        if (! dump_buffer(state)) return FALSE; \
+      bytes -= bytestocopy; \
+    } \
+  } \
+  else { \
+    state->free_in_buffer -= (buffer - state->next_output_byte); \
+    state->next_output_byte = buffer; \
+  } \
+ }
 
 
 LOCAL(boolean)
 flush_bits (working_state * state)
 {
-  if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
-    return FALSE;
+  JOCTET _buffer[BUFSIZE], *buffer;
+  size_t put_buffer;  int put_bits;
+  size_t bytes, bytestocopy;  int localbuf = 0;
+
+  put_buffer = state->cur.put_buffer;
+  put_bits = state->cur.put_bits;
+  LOAD_BUFFER()
+
+  /* fill any partial byte with ones */
+  PUT_BITS(0x7F, 7)
+  while (put_bits >= 8) EMIT_BYTE()
+
   state->cur.put_buffer = 0;	/* and reset bit-buffer to empty */
   state->cur.put_bits = 0;
+  STORE_BUFFER()
+
   return TRUE;
 }
 
 
 /* Encode a single block's worth of coefficients */
 
 LOCAL(boolean)
 encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
 		  c_derived_tbl *dctbl, c_derived_tbl *actbl)
 {
-  register int temp, temp2;
-  register int nbits;
-  register int k, r, i;
-  
+  int temp, temp2, temp3;
+  int nbits;
+  int r, code, size;
+  JOCTET _buffer[BUFSIZE], *buffer;
+  size_t put_buffer;  int put_bits;
+  int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
+  size_t bytes, bytestocopy;  int localbuf = 0;
+
+  put_buffer = state->cur.put_buffer;
+  put_bits = state->cur.put_bits;
+  LOAD_BUFFER()
+
   /* Encode the DC coefficient difference per section F.1.2.1 */
   
   temp = temp2 = block[0] - last_dc_val;
 
-  if (temp < 0) {
-    temp = -temp;		/* temp is abs value of input */
-    /* For a negative input, want temp2 = bitwise complement of abs(input) */
-    /* This code assumes we are on a two's complement machine */
-    temp2--;
-  }
-  
+ /* This is a well-known technique for obtaining the absolute value without a
+  * branch.  It is derived from an assembly language technique presented in
+  * "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by
+  * Agner Fog.
+  */
+  temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
+  temp ^= temp3;
+  temp -= temp3;
+
+  /* For a negative input, want temp2 = bitwise complement of abs(input) */
+  /* This code assumes we are on a two's complement machine */
+  temp2 += temp3;
+
   /* Find the number of bits needed for the magnitude of the coefficient */
-  nbits = 0;
-  while (temp) {
-    nbits++;
-    temp >>= 1;
-  }
-  /* Check for out-of-range coefficient values.
-   * Since we're encoding a difference, the range limit is twice as much.
-   */
-  if (nbits > MAX_COEF_BITS+1)
-    ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
-  
+  nbits = jpeg_nbits_table[temp];
+
   /* Emit the Huffman-coded symbol for the number of bits */
-  if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
-    return FALSE;
+  code = dctbl->ehufco[nbits];
+  size = dctbl->ehufsi[nbits];
+  PUT_BITS(code, size)
+  CHECKBUF15()
+
+  /* Mask off any extra bits in code */
+  temp2 &= (((INT32) 1)<<nbits) - 1;
 
   /* Emit that number of bits of the value, if positive, */
   /* or the complement of its magnitude, if negative. */
-  if (nbits)			/* emit_bits rejects calls with size 0 */
-    if (! emit_bits(state, (unsigned int) temp2, nbits))
-      return FALSE;
+  PUT_BITS(temp2, nbits)
+  CHECKBUF15()
 
   /* Encode the AC coefficients per section F.1.2.2 */
   
   r = 0;			/* r = run length of zeros */
-  
-  for (k = 1; k < DCTSIZE2; k++) {
-    if ((temp = block[jpeg_natural_order[k]]) == 0) {
-      r++;
-    } else {
-      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
-      while (r > 15) {
-	if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
-	  return FALSE;
-	r -= 16;
-      }
 
-      temp2 = temp;
-      if (temp < 0) {
-	temp = -temp;		/* temp is abs value of input */
-	/* This code assumes we are on a two's complement machine */
-	temp2--;
-      }
-      
-      /* Find the number of bits needed for the magnitude of the coefficient */
-      nbits = 1;		/* there must be at least one 1 bit */
-      while ((temp >>= 1))
-	nbits++;
-      /* Check for out-of-range coefficient values */
-      if (nbits > MAX_COEF_BITS)
-	ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
-      
-      /* Emit Huffman symbol for run length / number of bits */
-      i = (r << 4) + nbits;
-      if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
-	return FALSE;
+/* Manually unroll the k loop to eliminate the counter variable.  This
+ * improves performance greatly on systems with a limited number of
+ * registers (such as x86.)
+ */
+#define kloop(jpeg_natural_order_of_k) {  \
+  if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
+    r++; \
+  } else { \
+    temp2 = temp; \
+    /* Branch-less absolute value, bitwise complement, etc., same as above */ \
+    temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
+    temp ^= temp3; \
+    temp -= temp3; \
+    temp2 += temp3; \
+    nbits = jpeg_nbits_table[temp]; \
+    /* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
+    while (r > 15) { \
+      EMIT_BITS(code_0xf0, size_0xf0) \
+      r -= 16; \
+    } \
+    /* Emit Huffman symbol for run length / number of bits */ \
+    temp3 = (r << 4) + nbits;  \
+    code = actbl->ehufco[temp3]; \
+    size = actbl->ehufsi[temp3]; \
+    EMIT_CODE(code, size) \
+    r = 0;  \
+  } \
+}
 
-      /* Emit that number of bits of the value, if positive, */
-      /* or the complement of its magnitude, if negative. */
-      if (! emit_bits(state, (unsigned int) temp2, nbits))
-	return FALSE;
-      
-      r = 0;
-    }
+  /* One iteration for each value in jpeg_natural_order[] */
+  kloop(1);   kloop(8);   kloop(16);  kloop(9);   kloop(2);   kloop(3);
+  kloop(10);  kloop(17);  kloop(24);  kloop(32);  kloop(25);  kloop(18);
+  kloop(11);  kloop(4);   kloop(5);   kloop(12);  kloop(19);  kloop(26);
+  kloop(33);  kloop(40);  kloop(48);  kloop(41);  kloop(34);  kloop(27);
+  kloop(20);  kloop(13);  kloop(6);   kloop(7);   kloop(14);  kloop(21);
+  kloop(28);  kloop(35);  kloop(42);  kloop(49);  kloop(56);  kloop(57);
+  kloop(50);  kloop(43);  kloop(36);  kloop(29);  kloop(22);  kloop(15);
+  kloop(23);  kloop(30);  kloop(37);  kloop(44);  kloop(51);  kloop(58);
+  kloop(59);  kloop(52);  kloop(45);  kloop(38);  kloop(31);  kloop(39);
+  kloop(46);  kloop(53);  kloop(60);  kloop(61);  kloop(54);  kloop(47);
+  kloop(55);  kloop(62);  kloop(63);
+
+  /* If the last coef(s) were zero, emit an end-of-block code */
+  if (r > 0) {
+    code = actbl->ehufco[0];
+    size = actbl->ehufsi[0];
+    EMIT_BITS(code, size)
   }
 
-  /* If the last coef(s) were zero, emit an end-of-block code */
-  if (r > 0)
-    if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
-      return FALSE;
+  state->cur.put_buffer = put_buffer;
+  state->cur.put_bits = put_bits;
+  STORE_BUFFER()
 
   return TRUE;
 }
 
 
 /*
  * Emit a restart marker & resynchronize predictions.
  */
--- a/media/libjpeg/jcmainct.c
+++ b/media/libjpeg/jcmainct.c
@@ -63,42 +63,42 @@ METHODDEF(void) process_data_buffer_main
 
 /*
  * Initialize for a processing pass.
  */
 
 METHODDEF(void)
 start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
 
   /* Do nothing in raw-data mode. */
   if (cinfo->raw_data_in)
     return;
 
-  main->cur_iMCU_row = 0;	/* initialize counters */
-  main->rowgroup_ctr = 0;
-  main->suspended = FALSE;
-  main->pass_mode = pass_mode;	/* save mode for use by process_data */
+  main_ptr->cur_iMCU_row = 0;	/* initialize counters */
+  main_ptr->rowgroup_ctr = 0;
+  main_ptr->suspended = FALSE;
+  main_ptr->pass_mode = pass_mode;	/* save mode for use by process_data */
 
   switch (pass_mode) {
   case JBUF_PASS_THRU:
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
-    if (main->whole_image[0] != NULL)
+    if (main_ptr->whole_image[0] != NULL)
       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 #endif
-    main->pub.process_data = process_data_simple_main;
+    main_ptr->pub.process_data = process_data_simple_main;
     break;
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
   case JBUF_SAVE_SOURCE:
   case JBUF_CRANK_DEST:
   case JBUF_SAVE_AND_PASS:
-    if (main->whole_image[0] == NULL)
+    if (main_ptr->whole_image[0] == NULL)
       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
-    main->pub.process_data = process_data_buffer_main;
+    main_ptr->pub.process_data = process_data_buffer_main;
     break;
 #endif
   default:
     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
     break;
   }
 }
 
@@ -109,56 +109,56 @@ start_pass_main (j_compress_ptr cinfo, J
  * where we have only a strip buffer.
  */
 
 METHODDEF(void)
 process_data_simple_main (j_compress_ptr cinfo,
 			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 			  JDIMENSION in_rows_avail)
 {
-  my_main_ptr main = (my_main_ptr) cinfo->main;
+  my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
 
-  while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
+  while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
     /* Read input data if we haven't filled the main buffer yet */
-    if (main->rowgroup_ctr < DCTSIZE)
+    if (main_ptr->rowgroup_ctr < DCTSIZE)
       (*cinfo->prep->pre_process_data) (cinfo,
 					input_buf, in_row_ctr, in_rows_avail,
-					main->buffer, &main->rowgroup_ctr,
+					main_ptr->buffer, &main_ptr->rowgroup_ctr,
 					(JDIMENSION) DCTSIZE);
 
     /* If we don't have a full iMCU row buffered, return to application for
      * more data.  Note that preprocessor will always pad to fill the iMCU row
      * at the bottom of the image.
      */
-    if (main->rowgroup_ctr != DCTSIZE)
+    if (main_ptr->rowgroup_ctr != DCTSIZE)
       return;
 
     /* Send the completed row to the compressor */
-    if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
+    if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
       /* If compressor did not consume the whole row, then we must need to
        * suspend processing and return to the application.  In this situation
        * we pretend we didn't yet consume the last input row; otherwise, if
        * it happened to be the last row of the image, the application would
        * think we were done.
        */
-      if (! main->suspended) {
+      if (! main_ptr->suspended) {
 	(*in_row_ctr)--;
-	main->suspended = TRUE;
+	main_ptr->suspended = TRUE;
       }
       return;
     }
     /* We did finish the row.  Undo our little suspension hack if a previous
      * call suspended; then mark the main buffer empty.
      */
-    if (main->suspended) {
+    if (main_ptr->suspended) {
       (*in_row_ctr)++;
-      main->suspended = FALSE;
+      main_ptr->suspended = FALSE;
     }
-    main->rowgroup_ctr = 0;
-    main->cur_iMCU_row++;
+    main_ptr->rowgroup_ctr = 0;
+    main_ptr->cur_iMCU_row++;
   }
 }
 
 
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
 
 /*
  * Process some data.
@@ -168,126 +168,126 @@ process_data_simple_main (j_compress_ptr
 METHODDEF(void)
 process_data_buffer_main (j_compress_ptr cinfo,
 			  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
 			  JDIMENSION in_rows_avail)
 {
   my_main_ptr main = (my_main_ptr) cinfo->main;
   int ci;
   jpeg_component_info *compptr;
-  boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
+  boolean writing = (main_ptr->pass_mode != JBUF_CRANK_DEST);
 
-  while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
+  while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
     /* Realign the virtual buffers if at the start of an iMCU row. */
-    if (main->rowgroup_ctr == 0) {
+    if (main_ptr->rowgroup_ctr == 0) {
       for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	   ci++, compptr++) {
-	main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
-	  ((j_common_ptr) cinfo, main->whole_image[ci],
-	   main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
+	main_ptr->buffer[ci] = (*cinfo->mem->access_virt_sarray)
+	  ((j_common_ptr) cinfo, main_ptr->whole_image[ci],
+	   main_ptr->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
 	   (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
       }
       /* In a read pass, pretend we just read some source data. */
       if (! writing) {
 	*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
-	main->rowgroup_ctr = DCTSIZE;
+	main_ptr->rowgroup_ctr = DCTSIZE;
       }
     }
 
     /* If a write pass, read input data until the current iMCU row is full. */
     /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
     if (writing) {
       (*cinfo->prep->pre_process_data) (cinfo,
 					input_buf, in_row_ctr, in_rows_avail,
-					main->buffer, &main->rowgroup_ctr,
+					main_ptr->buffer, &main_ptr->rowgroup_ctr,
 					(JDIMENSION) DCTSIZE);
       /* Return to application if we need more data to fill the iMCU row. */
-      if (main->rowgroup_ctr < DCTSIZE)
+      if (main_ptr->rowgroup_ctr < DCTSIZE)
 	return;
     }
 
     /* Emit data, unless this is a sink-only pass. */
-    if (main->pass_mode != JBUF_SAVE_SOURCE) {
-      if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
+    if (main_ptr->pass_mode != JBUF_SAVE_SOURCE) {
+      if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
 	/* If compressor did not consume the whole row, then we must need to
 	 * suspend processing and return to the application.  In this situation
 	 * we pretend we didn't yet consume the last input row; otherwise, if
 	 * it happened to be the last row of the image, the application would
 	 * think we were done.
 	 */
-	if (! main->suspended) {
+	if (! main_ptr->suspended) {
 	  (*in_row_ctr)--;
-	  main->suspended = TRUE;
+	  main_ptr->suspended = TRUE;
 	}
 	return;
       }
       /* We did finish the row.  Undo our little suspension hack if a previous
        * call suspended; then mark the main buffer empty.
        */
-      if (main->suspended) {
+      if (main_ptr->suspended) {
 	(*in_row_ctr)++;
-	main->suspended = FALSE;
+	main_ptr->suspended = FALSE;
       }
     }
 
     /* If get here, we are done with this iMCU row.  Mark buffer empty. */
-    main->rowgroup_ctr = 0;
-    main->cur_iMCU_row++;
+    main_ptr->rowgroup_ctr = 0;
+    main_ptr->cur_iMCU_row++;
   }
 }
 
 #endif /* FULL_MAIN_BUFFER_SUPPORTED */
 
 
 /*
  * Initialize main buffer controller.
  */
 
 GLOBAL(void)
 jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
 {
-  my_main_ptr main;
+  my_main_ptr main_ptr;
   int ci;
   jpeg_component_info *compptr;
 
-  main = (my_main_ptr)
+  main_ptr = (my_main_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_main_controller));
-  cinfo->main = (struct jpeg_c_main_controller *) main;
-  main->pub.start_pass = start_pass_main;
+  cinfo->main = (struct jpeg_c_main_controller *) main_ptr;
+  main_ptr->pub.start_pass = start_pass_main;
 
   /* We don't need to create a buffer in raw-data mode. */
   if (cinfo->raw_data_in)
     return;
 
   /* Create the buffer.  It holds downsampled data, so each component
    * may be of a different size.
    */
   if (need_full_buffer) {
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
     /* Allocate a full-image virtual array for each component */
     /* Note we pad the bottom to a multiple of the iMCU height */
     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	 ci++, compptr++) {
-      main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
+      main_ptr->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
 	((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
 	 compptr->width_in_blocks * DCTSIZE,
 	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
 				(long) compptr->v_samp_factor) * DCTSIZE,
 	 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
     }
 #else
     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 #endif
   } else {
 #ifdef FULL_MAIN_BUFFER_SUPPORTED
-    main->whole_image[0] = NULL; /* flag for no virtual arrays */
+    main_ptr->whole_image[0] = NULL; /* flag for no virtual arrays */
 #endif
     /* Allocate a strip buffer for each component */
     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 	 ci++, compptr++) {
-      main->buffer[ci] = (*cinfo->mem->alloc_sarray)
+      main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
 	((j_common_ptr) cinfo, JPOOL_IMAGE,
 	 compptr->width_in_blocks * DCTSIZE,
 	 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
     }
   }
 }
--- a/media/libjpeg/jcmaster.c
+++ b/media/libjpeg/jcmaster.c
@@ -70,17 +70,19 @@ initial_setup (j_compress_ptr cinfo, boo
 /* Do computations that are needed before master selection phase */
 {
   int ci;
   jpeg_component_info *compptr;
   long samplesperrow;
   JDIMENSION jd_samplesperrow;
 
 #if JPEG_LIB_VERSION >= 70
+#if JPEG_LIB_VERSION >= 80
   if (!transcode_only)
+#endif
     jpeg_calc_jpeg_dimensions(cinfo);
 #endif
 
   /* Sanity check on image dimensions */
   if (cinfo->_jpeg_height <= 0 || cinfo->_jpeg_width <= 0
       || cinfo->num_components <= 0 || cinfo->input_components <= 0)
     ERREXIT(cinfo, JERR_EMPTY_IMAGE);
 
--- a/media/libjpeg/jconfig.h
+++ b/media/libjpeg/jconfig.h
@@ -1,59 +1,52 @@
 /* jconfig.h.  Generated from jconfig.h.in by configure, then manually edited
    for Mozilla. */
 
 /* Export libjpeg v6.2's ABI. */
 #define JPEG_LIB_VERSION 62
 
-/* Define if your compiler supports prototypes */
+/* libjpeg-turbo version */
+#define LIBJPEG_TURBO_VERSION 1.2.0
+
+/* Compiler supports function prototypes. */
 #define HAVE_PROTOTYPES 1
 
 /* Define to 1 if you have the <stddef.h> header file. */
 #define HAVE_STDDEF_H 1
 
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
-/* Define to 1 if the system has the type `unsigned char'. */
+/* Compiler supports 'unsigned char'. */
 #define HAVE_UNSIGNED_CHAR 1
 
-/* Define to 1 if the system has the type `unsigned short'. */
+/* Compiler supports 'unsigned short'. */
 #define HAVE_UNSIGNED_SHORT 1
 
-/* Define if you want use complete types */
+/* Compiler does not support pointers to unspecified structures. */
 /* #define INCOMPLETE_TYPES_BROKEN 1 */
 
-/* Define if you have BSD-like bzero and bcopy */
+/* Compiler has <strings.h> rather than standard <string.h>. */
 /* #undef NEED_BSD_STRINGS */
 
-/* Define if you need short function names */
+/* Linker requires that global names be unique in first 15 characters. */
 /* #undef NEED_SHORT_EXTERNAL_NAMES */
 
-/* Define if you have sys/types.h */
+/* Need to include <sys/types.h> in order to obtain size_t. */
 #define NEED_SYS_TYPES_H 1
 
-/* Define if shift is unsigned */
+/* Broken compiler shifts signed values as an unsigned shift. */
 /* #undef RIGHT_SHIFT_IS_UNSIGNED */
 
 /* Use accelerated SIMD routines. */
 #define WITH_SIMD 1
 
 /* Define to 1 if type `char' is unsigned and you are not using gcc.  */
 #ifndef __CHAR_UNSIGNED__
 /* # undef __CHAR_UNSIGNED__ */
 #endif
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
 
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 /* #undef size_t */
-
-/* MOZILLA CHANGE: libjpeg-turbo doesn't define INLINE in its config file, so
- * we define it here. */
-#define INLINE NS_ALWAYS_INLINE
deleted file mode 100644
--- a/media/libjpeg/jconfig.h.in
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Version ID for the JPEG library.
- * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
- */
-#define JPEG_LIB_VERSION  62	/* Version 6b */
-
-/* Support arithmetic encoding */
-#undef C_ARITH_CODING_SUPPORTED
-
-/* Support arithmetic decoding */
-#undef D_ARITH_CODING_SUPPORTED
-
-/* Define if your compiler supports prototypes */
-#undef HAVE_PROTOTYPES
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#undef HAVE_STDDEF_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if the system has the type `unsigned char'. */
-#undef HAVE_UNSIGNED_CHAR
-
-/* Define to 1 if the system has the type `unsigned short'. */
-#undef HAVE_UNSIGNED_SHORT
-
-/* Define if you want use complete types */
-#undef INCOMPLETE_TYPES_BROKEN
-
-/* Define if you have BSD-like bzero and bcopy */
-#undef NEED_BSD_STRINGS
-
-/* Define if you need short function names */
-#undef NEED_SHORT_EXTERNAL_NAMES
-
-/* Define if you have sys/types.h */
-#undef NEED_SYS_TYPES_H
-
-/* Define if shift is unsigned */
-#undef RIGHT_SHIFT_IS_UNSIGNED
-
-/* Use accelerated SIMD routines. */
-#undef WITH_SIMD
-
-/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
-#ifndef __CHAR_UNSIGNED__
-# undef __CHAR_UNSIGNED__
-#endif
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
--- a/media/libjpeg/jcparam.c
+++ b/media/libjpeg/jcparam.c
@@ -1,14 +1,14 @@
 /*
  * jcparam.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
  * Modified 2003-2008 by Guido Vollbeding.
- * Copyright (C) 2009-2010, D. R. Commander.
+ * Copyright (C) 2009-2011, D. R. Commander.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains optional default-setting code for the JPEG compressor.
  * Applications do not have to use this file, but those that don't use it
  * must know a lot more about the innards of the JPEG code.
  */
 
@@ -393,16 +393,20 @@ jpeg_default_colorspace (j_compress_ptr 
     break;
   case JCS_RGB:
   case JCS_EXT_RGB:
   case JCS_EXT_RGBX:
   case JCS_EXT_BGR:
   case JCS_EXT_BGRX:
   case JCS_EXT_XBGR:
   case JCS_EXT_XRGB:
+  case JCS_EXT_RGBA:
+  case JCS_EXT_BGRA:
+  case JCS_EXT_ABGR:
+  case JCS_EXT_ARGB:
     jpeg_set_colorspace(cinfo, JCS_YCbCr);
     break;
   case JCS_YCbCr:
     jpeg_set_colorspace(cinfo, JCS_YCbCr);
     break;
   case JCS_CMYK:
     jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
     break;
new file mode 100644
--- /dev/null
+++ b/media/libjpeg/jctrans.c
@@ -0,0 +1,399 @@
+/*
+ * jctrans.c
+ *
+ * Copyright (C) 1995-1998, Thomas G. Lane.
+ * Modified 2000-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains library routines for transcoding compression,
+ * that is, writing raw DCT coefficient arrays to an output JPEG file.
+ * The routines in jcapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transencode_master_selection
+	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+LOCAL(void) transencode_coef_controller
+	JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+
+
+/*
+ * Compression initialization for writing raw-coefficient data.
+ * Before calling this, all parameters and a data destination must be set up.
+ * Call jpeg_finish_compress() to actually write the data.
+ *
+ * The number of passed virtual arrays must match cinfo->num_components.
+ * Note that the virtual arrays need not be filled or even realized at
+ * the time write_coefficients is called; indeed, if the virtual arrays
+ * were requested from this compression object's memory manager, they
+ * typically will be realized during this routine and filled afterwards.
+ */
+
+GLOBAL(void)
+jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
+{
+  if (cinfo->global_state != CSTATE_START)
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  /* Mark all tables to be written */
+  jpeg_suppress_tables(cinfo, FALSE);
+  /* (Re)initialize error mgr and destination modules */
+  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+  (*cinfo->dest->init_destination) (cinfo);
+  /* Perform master selection of active modules */
+  transencode_master_selection(cinfo, coef_arrays);
+  /* Wait for jpeg_finish_compress() call */
+  cinfo->next_scanline = 0;	/* so jpeg_write_marker works */
+  cinfo->global_state = CSTATE_WRCOEFS;
+}
+
+
+/*
+ * Initialize the compression object with default parameters,
+ * then copy from the source object all parameters needed for lossless
+ * transcoding.  Parameters that can be varied without loss (such as
+ * scan script and Huffman optimization) are left in their default states.
+ */
+
+GLOBAL(void)
+jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
+			       j_compress_ptr dstinfo)
+{
+  JQUANT_TBL ** qtblptr;
+  jpeg_component_info *incomp, *outcomp;
+  JQUANT_TBL *c_quant, *slot_quant;
+  int tblno, ci, coefi;
+
+  /* Safety check to ensure start_compress not called yet. */
+  if (dstinfo->global_state != CSTATE_START)
+    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
+  /* Copy fundamental image dimensions */
+  dstinfo->image_width = srcinfo->image_width;
+  dstinfo->image_height = srcinfo->image_height;
+  dstinfo->input_components = srcinfo->num_components;
+  dstinfo->in_color_space = srcinfo->jpeg_color_space;
+#if JPEG_LIB_VERSION >= 70
+  dstinfo->jpeg_width = srcinfo->output_width;
+  dstinfo->jpeg_height = srcinfo->output_height;
+  dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
+  dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
+#endif
+  /* Initialize all parameters to default values */
+  jpeg_set_defaults(dstinfo);
+  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
+   * Fix it to get the right header markers for the image colorspace.
+   */
+  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
+  dstinfo->data_precision = srcinfo->data_precision;
+  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
+  /* Copy the source's quantization tables. */
+  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
+    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
+      qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
+      if (*qtblptr == NULL)
+	*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
+      MEMCOPY((*qtblptr)->quantval,
+	      srcinfo->quant_tbl_ptrs[tblno]->quantval,
+	      SIZEOF((*qtblptr)->quantval));
+      (*qtblptr)->sent_table = FALSE;
+    }
+  }
+  /* Copy the source's per-component info.
+   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
+   */
+  dstinfo->num_components = srcinfo->num_components;
+  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
+    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
+	     MAX_COMPONENTS);
+  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
+       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
+    outcomp->component_id = incomp->component_id;
+    outcomp->h_samp_factor = incomp->h_samp_factor;
+    outcomp->v_samp_factor = incomp->v_samp_factor;
+    outcomp->quant_tbl_no = incomp->quant_tbl_no;
+    /* Make sure saved quantization table for component matches the qtable
+     * slot.  If not, the input file re-used this qtable slot.
+     * IJG encoder currently cannot duplicate this.
+     */
+    tblno = outcomp->quant_tbl_no;
+    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
+	srcinfo->quant_tbl_ptrs[tblno] == NULL)
+      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
+    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
+    c_quant = incomp->quant_table;
+    if (c_quant != NULL) {
+      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
+	if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
+	  ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
+      }
+    }
+    /* Note: we do not copy the source's Huffman table assignments;
+     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
+     */
+  }
+  /* Also copy JFIF version and resolution information, if available.
+   * Strictly speaking this isn't "critical" info, but it's nearly
+   * always appropriate to copy it if available.  In particular,
+   * if the application chooses to copy JFIF 1.02 extension markers from
+   * the source file, we need to copy the version to make sure we don't
+   * emit a file that has 1.02 extensions but a claimed version of 1.01.
+   * We will *not*, however, copy version info from mislabeled "2.01" files.
+   */
+  if (srcinfo->saw_JFIF_marker) {
+    if (srcinfo->JFIF_major_version == 1) {
+      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
+      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
+    }
+    dstinfo->density_unit = srcinfo->density_unit;
+    dstinfo->X_density = srcinfo->X_density;
+    dstinfo->Y_density = srcinfo->Y_density;
+  }
+}
+
+
+/*
+ * Master selection of compression modules for transcoding.
+ * This substitutes for jcinit.c's initialization of the full compressor.
+ */
+
+LOCAL(void)
+transencode_master_selection (j_compress_ptr cinfo,
+			      jvirt_barray_ptr * coef_arrays)
+{
+  /* Although we don't actually use input_components for transcoding,
+   * jcmaster.c's initial_setup will complain if input_components is 0.
+   */
+  cinfo->input_components = 1;
+  /* Initialize master control (includes parameter checking/processing) */
+  jinit_c_master_control(cinfo, TRUE /* transcode only */);
+
+  /* Entropy encoding: either Huffman or arithmetic coding. */
+  if (cinfo->arith_code) {
+#ifdef C_ARITH_CODING_SUPPORTED
+    jinit_arith_encoder(cinfo);
+#else
+    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+#endif
+  } else {
+    if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+      jinit_phuff_encoder(cinfo);
+#else
+      ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+    } else
+      jinit_huff_encoder(cinfo);
+  }
+
+  /* We need a special coefficient buffer controller. */
+  transencode_coef_controller(cinfo, coef_arrays);
+
+  jinit_marker_writer(cinfo);
+
+  /* We can now tell the memory manager to allocate virtual arrays. */
+  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+  /* Write the datastream header (SOI, JFIF) immediately.
+   * Frame and scan headers are postponed till later.
+   * This lets application insert special markers after the SOI.
+   */
+  (*cinfo->marker->write_file_header) (cinfo);
+}
+
+
+/*
+ * The rest of this file is a special implementation of the coefficient
+ * buffer controller.  This is similar to jccoefct.c, but it handles only
+ * output from presupplied virtual arrays.  Furthermore, we generate any
+ * dummy padding blocks on-the-fly rather than expecting them to be present
+ * in the arrays.
+ */
+
+/* Private buffer controller object */
+
+typedef struct {
+  struct jpeg_c_coef_controller pub; /* public fields */
+
+  JDIMENSION iMCU_row_num;	/* iMCU row # within image */
+  JDIMENSION mcu_ctr;		/* counts MCUs processed in current row */
+  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
+  int MCU_rows_per_iMCU_row;	/* number of such rows needed */
+
+  /* Virtual block array for each component. */
+  jvirt_barray_ptr * whole_image;
+
+  /* Workspace for constructing dummy blocks at right/bottom edges. */
+  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  /* In an interleaved scan, an MCU row is the same as an iMCU row.
+   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+   * But at the bottom of the image, process only what's left.
+   */
+  if (cinfo->comps_in_scan > 1) {
+    coef->MCU_rows_per_iMCU_row = 1;
+  } else {
+    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+    else
+      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+  }
+
+  coef->mcu_ctr = 0;
+  coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+  if (pass_mode != JBUF_CRANK_DEST)
+    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+  coef->iMCU_row_num = 0;
+  start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Process some data.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+  JDIMENSION MCU_col_num;	/* index of current MCU within row */
+  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+  int blkn, ci, xindex, yindex, yoffset, blockcnt;
+  JDIMENSION start_col;
+  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+  JBLOCKROW buffer_ptr;
+  jpeg_component_info *compptr;
+
+  /* Align the virtual buffers for the components used in this scan. */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    buffer[ci] = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+       coef->iMCU_row_num * compptr->v_samp_factor,
+       (JDIMENSION) compptr->v_samp_factor, FALSE);
+  }
+
+  /* Loop to process one whole iMCU row */
+  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+       yoffset++) {
+    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+	 MCU_col_num++) {
+      /* Construct list of pointers to DCT blocks belonging to this MCU */
+      blkn = 0;			/* index of current DCT block within MCU */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+	compptr = cinfo->cur_comp_info[ci];
+	start_col = MCU_col_num * compptr->MCU_width;
+	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+						: compptr->last_col_width;
+	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+	  if (coef->iMCU_row_num < last_iMCU_row ||
+	      yindex+yoffset < compptr->last_row_height) {
+	    /* Fill in pointers to real blocks in this row */
+	    buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+	    for (xindex = 0; xindex < blockcnt; xindex++)
+	      MCU_buffer[blkn++] = buffer_ptr++;
+	  } else {
+	    /* At bottom of image, need a whole row of dummy blocks */
+	    xindex = 0;
+	  }
+	  /* Fill in any dummy blocks needed in this row.
+	   * Dummy blocks are filled in the same way as in jccoefct.c:
+	   * all zeroes in the AC entries, DC entries equal to previous
+	   * block's DC value.  The init routine has already zeroed the
+	   * AC entries, so we need only set the DC entries correctly.
+	   */
+	  for (; xindex < compptr->MCU_width; xindex++) {
+	    MCU_buffer[blkn] = coef->dummy_buffer[blkn];
+	    MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
+	    blkn++;
+	  }
+	}
+      }
+      /* Try to write the MCU. */
+      if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
+	/* Suspension forced; update state counters and exit */
+	coef->MCU_vert_offset = yoffset;
+	coef->mcu_ctr = MCU_col_num;
+	return FALSE;
+      }
+    }
+    /* Completed an MCU row, but perhaps not an iMCU row */
+    coef->mcu_ctr = 0;
+  }
+  /* Completed the iMCU row, advance counters for next one */
+  coef->iMCU_row_num++;
+  start_iMCU_row(cinfo);
+  return TRUE;
+}
+
+
+/*
+ * Initialize coefficient buffer controller.
+ *
+ * Each passed coefficient array must be the right size for that
+ * coefficient: width_in_blocks wide and height_in_blocks high,
+ * with unitheight at least v_samp_factor.
+ */
+
+LOCAL(void)
+transencode_coef_controller (j_compress_ptr cinfo,
+			     jvirt_barray_ptr * coef_arrays)
+{
+  my_coef_ptr coef;
+  JBLOCKROW buffer;
+  int i;
+
+  coef = (my_coef_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				SIZEOF(my_coef_controller));
+  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+  coef->pub.start_pass = start_pass_coef;
+  coef->pub.compress_data = compress_output;
+
+  /* Save pointer to virtual arrays */
+  coef->whole_image = coef_arrays;
+
+  /* Allocate and pre-zero space for dummy DCT blocks. */
+  buffer = (JBLOCKROW)
+    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+    coef->dummy_buffer[i] = buffer + i;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/media/libjpeg/jdcolext.c
@@ -0,0 +1,104 @@
+/*
+ * jdcolext.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009, 2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains output colorspace conversion routines.
+ */
+
+
+/* This file is included by jdcolor.c */
+
+
+/*
+ * Convert some rows of samples to the output colorspace.
+ *
+ * Note that we change from noninterleaved, one-plane-per-component format
+ * to interleaved-pixel format.  The output buffer is therefore three times
+ * as wide as the input buffer.
+ * A starting row offset is provided only for the input buffer.  The caller
+ * can easily adjust the passed output_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+INLINE
+LOCAL(void)
+ycc_rgb_convert_internal (j_decompress_ptr cinfo,
+                          JSAMPIMAGE input_buf, JDIMENSION input_row,
+                          JSAMPARRAY output_buf, int num_rows)
+{
+  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+  register int y, cb, cr;
+  register JSAMPROW outptr;
+  register JSAMPROW inptr0, inptr1, inptr2;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+  /* copy these pointers into registers if possible */
+  register JSAMPLE * range_limit = cinfo->sample_range_limit;
+  register int * Crrtab = cconvert->Cr_r_tab;
+  register int * Cbbtab = cconvert->Cb_b_tab;
+  register INT32 * Crgtab = cconvert->Cr_g_tab;
+  register INT32 * Cbgtab = cconvert->Cb_g_tab;
+  SHIFT_TEMPS
+
+  while (--num_rows >= 0) {
+    inptr0 = input_buf[0][input_row];
+    inptr1 = input_buf[1][input_row];
+    inptr2 = input_buf[2][input_row];
+    input_row++;
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      y  = GETJSAMPLE(inptr0[col]);
+      cb = GETJSAMPLE(inptr1[col]);
+      cr = GETJSAMPLE(inptr2[col]);
+      /* Range-limiting is essential due to noise introduced by DCT losses. */
+      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
+      outptr[RGB_GREEN] = range_limit[y +
+			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+						 SCALEBITS))];
+      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
+      /* Set unused byte to 0xFF so it can be interpreted as an opaque */
+      /* alpha channel value */
+#ifdef RGB_ALPHA
+      outptr[RGB_ALPHA] = 0xFF;
+#endif
+      outptr += RGB_PIXELSIZE;
+    }
+  }
+}
+
+
+/*
+ * Convert grayscale to RGB: just duplicate the graylevel three times.
+ * This is provided to support applications that don't want to cope
+ * with grayscale as a separate case.
+ */
+
+INLINE
+LOCAL(void)
+gray_rgb_convert_internal (j_decompress_ptr cinfo,
+                           JSAMPIMAGE input_buf, JDIMENSION input_row,
+                           JSAMPARRAY output_buf, int num_rows)
+{
+  register JSAMPROW inptr, outptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+
+  while (--num_rows >= 0) {
+    inptr = input_buf[0][input_row++];
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      /* We can dispense with GETJSAMPLE() here */
+      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
+      /* Set unused byte to 0xFF so it can be interpreted as an opaque */
+      /* alpha channel value */
+#ifdef RGB_ALPHA
+      outptr[RGB_ALPHA] = 0xFF;
+#endif
+      outptr += RGB_PIXELSIZE;
+    }
+  }
+}
--- a/media/libjpeg/jdcolor.c
+++ b/media/libjpeg/jdcolor.c
@@ -1,24 +1,25 @@
 /*
  * jdcolor.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2009, D. R. Commander.
+ * Copyright (C) 2009, 2011, D. R. Commander.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains output colorspace conversion routines.
  */
 
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
 #include "jsimd.h"
+#include "config.h"
 
 
 /* Private subobject */
 
 typedef struct {
   struct jpeg_color_deconverter pub; /* public fields */
 
   /* Private state for YCC->RGB conversion */
@@ -60,16 +61,117 @@ typedef my_color_deconverter * my_cconve
  * together before rounding.
  */
 
 #define SCALEBITS	16	/* speediest right-shift on some machines */
 #define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
 #define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
 
 
+/* Include inline routines for colorspace extensions */
+
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED EXT_RGB_RED
+#define RGB_GREEN EXT_RGB_GREEN
+#define RGB_BLUE EXT_RGB_BLUE
+#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extrgb_convert_internal
+#define gray_rgb_convert_internal gray_extrgb_convert_internal
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_RGBX_RED
+#define RGB_GREEN EXT_RGBX_GREEN
+#define RGB_BLUE EXT_RGBX_BLUE
+#define RGB_ALPHA 3
+#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extrgbx_convert_internal
+#define gray_rgb_convert_internal gray_extrgbx_convert_internal
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_BGR_RED
+#define RGB_GREEN EXT_BGR_GREEN
+#define RGB_BLUE EXT_BGR_BLUE
+#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extbgr_convert_internal
+#define gray_rgb_convert_internal gray_extbgr_convert_internal
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_BGRX_RED
+#define RGB_GREEN EXT_BGRX_GREEN
+#define RGB_BLUE EXT_BGRX_BLUE
+#define RGB_ALPHA 3
+#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extbgrx_convert_internal
+#define gray_rgb_convert_internal gray_extbgrx_convert_internal
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_XBGR_RED
+#define RGB_GREEN EXT_XBGR_GREEN
+#define RGB_BLUE EXT_XBGR_BLUE
+#define RGB_ALPHA 0
+#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extxbgr_convert_internal
+#define gray_rgb_convert_internal gray_extxbgr_convert_internal
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_XRGB_RED
+#define RGB_GREEN EXT_XRGB_GREEN
+#define RGB_BLUE EXT_XRGB_BLUE
+#define RGB_ALPHA 0
+#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extxrgb_convert_internal
+#define gray_rgb_convert_internal gray_extxrgb_convert_internal
+#include "jdcolext.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+
 /*
  * Initialize tables for YCC->RGB colorspace conversion.
  */
 
 LOCAL(void)
 build_ycc_rgb_table (j_decompress_ptr cinfo)
 {
   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
@@ -105,62 +207,56 @@ build_ycc_rgb_table (j_decompress_ptr ci
     /* We also add in ONE_HALF so that need not do it in inner loop */
     cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
   }
 }
 
 
 /*
  * Convert some rows of samples to the output colorspace.
- *
- * Note that we change from noninterleaved, one-plane-per-component format
- * to interleaved-pixel format.  The output buffer is therefore three times
- * as wide as the input buffer.
- * A starting row offset is provided only for the input buffer.  The caller
- * can easily adjust the passed output_buf value to accommodate any row
- * offset required on that side.
  */
 
 METHODDEF(void)
 ycc_rgb_convert (j_decompress_ptr cinfo,
 		 JSAMPIMAGE input_buf, JDIMENSION input_row,
 		 JSAMPARRAY output_buf, int num_rows)
 {
-  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
-  register int y, cb, cr;
-  register JSAMPROW outptr;
-  register JSAMPROW inptr0, inptr1, inptr2;
-  register JDIMENSION col;
-  JDIMENSION num_cols = cinfo->output_width;
-  /* copy these pointers into registers if possible */
-  register JSAMPLE * range_limit = cinfo->sample_range_limit;
-  register int * Crrtab = cconvert->Cr_r_tab;
-  register int * Cbbtab = cconvert->Cb_b_tab;
-  register INT32 * Crgtab = cconvert->Cr_g_tab;
-  register INT32 * Cbgtab = cconvert->Cb_g_tab;
-  SHIFT_TEMPS
-
-  while (--num_rows >= 0) {
-    inptr0 = input_buf[0][input_row];
-    inptr1 = input_buf[1][input_row];
-    inptr2 = input_buf[2][input_row];
-    input_row++;
-    outptr = *output_buf++;
-    for (col = 0; col < num_cols; col++) {
-      y  = GETJSAMPLE(inptr0[col]);
-      cb = GETJSAMPLE(inptr1[col]);
-      cr = GETJSAMPLE(inptr2[col]);
-      /* Range-limiting is essential due to noise introduced by DCT losses. */
-      outptr[rgb_red[cinfo->out_color_space]] =   range_limit[y + Crrtab[cr]];
-      outptr[rgb_green[cinfo->out_color_space]] = range_limit[y +
-			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
-						 SCALEBITS))];
-      outptr[rgb_blue[cinfo->out_color_space]] =  range_limit[y + Cbbtab[cb]];
-      outptr += rgb_pixelsize[cinfo->out_color_space];
-    }
+  switch (cinfo->out_color_space) {
+    case JCS_EXT_RGB:
+      ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                  num_rows);
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                   num_rows);
+      break;
+    case JCS_EXT_BGR:
+      ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                  num_rows);
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                   num_rows);
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                   num_rows);
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                   num_rows);
+      break;
+    default:
+      ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+                               num_rows);
+      break;
   }
 }
 
 
 /**************** Cases other than YCbCr -> RGB **************/
 
 
 /*
@@ -206,42 +302,57 @@ grayscale_convert (j_decompress_ptr cinf
 		   JSAMPARRAY output_buf, int num_rows)
 {
   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
 		    num_rows, cinfo->output_width);
 }
 
 
 /*
- * Convert grayscale to RGB: just duplicate the graylevel three times.
- * This is provided to support applications that don't want to cope
- * with grayscale as a separate case.
+ * Convert grayscale to RGB
  */
 
 METHODDEF(void)
 gray_rgb_convert (j_decompress_ptr cinfo,
 		  JSAMPIMAGE input_buf, JDIMENSION input_row,
 		  JSAMPARRAY output_buf, int num_rows)
 {
-  register JSAMPROW inptr, outptr;
-  JSAMPLE *maxinptr;
-  JDIMENSION num_cols = cinfo->output_width;
-  int rindex = rgb_red[cinfo->out_color_space];
-  int gindex = rgb_green[cinfo->out_color_space];
-  int bindex = rgb_blue[cinfo->out_color_space];
-  int rgbstride = rgb_pixelsize[cinfo->out_color_space];
-
-  while (--num_rows >= 0) {
-    inptr = input_buf[0][input_row++];
-    maxinptr = &inptr[num_cols];
-    outptr = *output_buf++;
-    for (; inptr < maxinptr; inptr++, outptr += rgbstride) {
-      /* We can dispense with GETJSAMPLE() here */
-      outptr[rindex] = outptr[gindex] = outptr[bindex] = *inptr;
-    }
+  switch (cinfo->out_color_space) {
+    case JCS_EXT_RGB:
+      gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                   num_rows);
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                    num_rows);
+      break;
+    case JCS_EXT_BGR:
+      gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                   num_rows);
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                    num_rows);
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                    num_rows);
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                    num_rows);
+      break;
+    default:
+      gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+                                num_rows);
+      break;
   }
 }
 
 
 /*
  * Adobe-style YCCK->CMYK conversion.
  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
  * conversion as above, while passing K (black) unchanged.
@@ -364,16 +475,20 @@ jinit_color_deconverter (j_decompress_pt
 
   case JCS_RGB:
   case JCS_EXT_RGB:
   case JCS_EXT_RGBX:
   case JCS_EXT_BGR:
   case JCS_EXT_BGRX:
   case JCS_EXT_XBGR:
   case JCS_EXT_XRGB:
+  case JCS_EXT_RGBA:
+  case JCS_EXT_BGRA:
+  case JCS_EXT_ABGR:
+  case JCS_EXT_ARGB:
     cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
     if (cinfo->jpeg_color_space == JCS_YCbCr) {
       if (jsimd_can_ycc_rgb())
         cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
       else {
         cconvert->pub.color_convert = ycc_rgb_convert;
         build_ycc_rgb_table(cinfo);
       }
--- a/media/libjpeg/jdhuff.c
+++ b/media/libjpeg/jdhuff.c
@@ -1,28 +1,30 @@
 /*
  * jdhuff.c
  *
  * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains Huffman entropy decoding routines.
  *
  * Much of the complexity here has to do with supporting input suspension.
  * If the data source module demands suspension, we want to be able to back
  * up to the start of the current MCU.  To do this, we copy state variables
  * into local working storage, and update them back to the permanent
  * storage only upon successful completion of an MCU.
  */
 
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
 #include "jdhuff.h"		/* Declarations shared with jdphuff.c */
+#include "jpegcomp.h"
 
 
 /*
  * Expanded entropy decoder object for Huffman decoding.
  *
  * The savable_state subrecord contains fields that change within an MCU,
  * but must not be updated permanently until we complete the MCU.
  */
@@ -117,17 +119,17 @@ start_pass_huff_decoder (j_decompress_pt
     compptr = cinfo->cur_comp_info[ci];
     /* Precalculate which table to use for each block */
     entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
     entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
     /* Decide whether we really care about the coefficient values */
     if (compptr->component_needed) {
       entropy->dc_needed[blkn] = TRUE;
       /* we don't need the ACs if producing a 1/8th-size image */
-      entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
+      entropy->ac_needed[blkn] = (compptr->_DCT_scaled_size > 1);
     } else {
       entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
     }
   }
 
   /* Initialize bitread state variables */
   entropy->bitstate.bits_left = 0;
   entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
@@ -220,36 +222,37 @@ jpeg_make_d_derived_tbl (j_decompress_pt
        */
       dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
       p += htbl->bits[l];
       dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
     } else {
       dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */
     }
   }
+  dtbl->valoffset[17] = 0;
   dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
 
   /* Compute lookahead tables to speed up decoding.
    * First we set all the table entries to 0, indicating "too long";
    * then we iterate through the Huffman codes that are short enough and
    * fill in all the entries that correspond to bit sequences starting
    * with that code.
    */
 
-  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
+   for (i = 0; i < (1 << HUFF_LOOKAHEAD); i++)
+     dtbl->lookup[i] = (HUFF_LOOKAHEAD + 1) << HUFF_LOOKAHEAD;
 
   p = 0;
   for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
     for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
       /* l = current code's length, p = its index in huffcode[] & huffval[]. */
       /* Generate left-justified code followed by all possible bit sequences */
       lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
       for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
-	dtbl->look_nbits[lookbits] = l;
-	dtbl->look_sym[lookbits] = htbl->huffval[p];
+	dtbl->lookup[lookbits] = (l << HUFF_LOOKAHEAD) | htbl->huffval[p];
 	lookbits++;
       }
     }
   }
 
   /* Validate symbols as being reasonable.
    * For AC tables, we make no check, but accept all byte values 0..255.
    * For DC tables, we require the symbols to be in range 0..15.
@@ -384,16 +387,60 @@ jpeg_fill_bit_buffer (bitread_working_st
   state->bytes_in_buffer = bytes_in_buffer;
   state->get_buffer = get_buffer;
   state->bits_left = bits_left;
 
   return TRUE;
 }
 
 
+/* Macro version of the above, which performs much better but does not
+   handle markers.  We have to hand off any blocks with markers to the
+   slower routines. */
+
+#define GET_BYTE \
+{ \
+  register int c0, c1; \
+  c0 = GETJOCTET(*buffer++); \
+  c1 = GETJOCTET(*buffer); \
+  /* Pre-execute most common case */ \
+  get_buffer = (get_buffer << 8) | c0; \
+  bits_left += 8; \
+  if (c0 == 0xFF) { \
+    /* Pre-execute case of FF/00, which represents an FF data byte */ \
+    buffer++; \
+    if (c1 != 0) { \
+      /* Oops, it's actually a marker indicating end of compressed data. */ \