Merge mozilla-central into holly
authorMike Conley <mconley@mozilla.com>
Thu, 05 Dec 2013 13:54:05 -0500
changeset 174520 8a631d00cf5dd3abacf5368f3e6d27e72643bfb2
parent 174466 2bcfb7046e72eb3b620ead5e8405726790e63bf3 (current diff)
parent 174519 056164bcce96df11121687fd95fa2e149774773a (diff)
child 174541 7be54d06d846aa5ef581efbec0244b78b0cddd49
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
Merge mozilla-central into holly
widget/cocoa/nsChildView.mm
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1216,16 +1216,20 @@ HyperTextAccessible::TextBounds(int32_t 
     return nsIntRect();
 
   nsIntRect bounds;
   int32_t prevOffset = GetChildOffset(childIdx);
   int32_t offset1 = startOffset - prevOffset;
 
   while (childIdx < ChildCount()) {
     nsIFrame* frame = GetChildAt(childIdx)->GetFrame();
+    if (!frame) {
+      NS_NOTREACHED("No frame for a child!");
+      continue;
+    }
 
     childIdx++;
     int32_t nextOffset = GetChildOffset(childIdx);
     if (nextOffset >= endOffset) {
       bounds.UnionRect(bounds, GetBoundsInFrame(frame, offset1,
                                                 endOffset - prevOffset));
       break;
     }
--- a/browser/modules/test/browser.ini
+++ b/browser/modules/test/browser.ini
@@ -1,6 +1,6 @@
 [DEFAULT]
 
 [browser_NetworkPrioritizer.js]
 [browser_SignInToWebsite.js]
 [browser_UITour.js]
-support-files = uitour.*
\ No newline at end of file
+support-files = uitour.*
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -157,20 +157,20 @@ case "$target" in
         CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
     fi
     LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
     AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
     RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
     STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
     OBJCOPY="$android_toolchain"/bin/"$android_tool_prefix"-objcopy
 
-    CPPFLAGS="-isystem $android_platform/usr/include $CPPFLAGS"
+    CPPFLAGS="-idirafter $android_platform/usr/include $CPPFLAGS"
     CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS"
-    ASFLAGS="-isystem $android_platform/usr/include -DANDROID $ASFLAGS"
+    ASFLAGS="-idirafter $android_platform/usr/include -DANDROID $ASFLAGS"
 
     dnl Add -llog by default, since we use it all over the place.
     dnl Add --allow-shlib-undefined, because libGLESv2 links to an
     dnl undefined symbol (present on the hardware, just not in the
     dnl NDK.)
     LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS"
     dnl prevent cross compile section from using these flags as host flags
     if test -z "$HOST_CPPFLAGS" ; then
@@ -235,17 +235,17 @@ if test "$OS_TARGET" = "Android" -a -z "
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a"; then
                 # android-ndk-r5c, android-ndk-r6, android-ndk-r6b
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
                 STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/ -lstdc++"
             else
                 AC_MSG_ERROR([Couldn't find path to gnu-libstdc++ in the android ndk])
             fi
         else
-            STLPORT_CPPFLAGS="-I$_topsrcdir/build/stlport/stlport -I$android_ndk/sources/cxx-stl/system/include"
+            STLPORT_CPPFLAGS="-isystem $_topsrcdir/build/stlport/stlport -isystem $android_ndk/sources/cxx-stl/system/include"
             STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
         fi
     fi
     CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
 fi
 AC_SUBST([MOZ_ANDROID_LIBSTDCXX])
 AC_SUBST([STLPORT_LIBS])
 
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1845,16 +1845,22 @@ nsScriptSecurityManager::CanCreateWrappe
 {
 // XXX Special case for nsIXPCException ?
     ClassInfoData objClassInfo = ClassInfoData(aClassInfo, nullptr);
     if (objClassInfo.IsDOMClass())
     {
         return NS_OK;
     }
 
+    // We give remote-XUL whitelisted domains a free pass here. See bug 932906.
+    if (!xpc::AllowXBLScope(js::GetContextCompartment(cx)))
+    {
+        return NS_OK;
+    }
+
     //--See if the object advertises a non-default level of access
     //  using nsISecurityCheckedComponent
     nsCOMPtr<nsISecurityCheckedComponent> checkedComponent =
         do_QueryInterface(aObj);
 
     nsXPIDLCString objectSecurityLevel;
     if (checkedComponent)
         checkedComponent->CanCreateWrapper((nsIID *)&aIID, getter_Copies(objectSecurityLevel));
--- a/configure.in
+++ b/configure.in
@@ -46,17 +46,17 @@ dnl ====================================
 _SUBDIR_HOST_CFLAGS="$HOST_CFLAGS"
 _SUBDIR_HOST_CXXFLAGS="$HOST_CXXFLAGS"
 _SUBDIR_HOST_LDFLAGS="$HOST_LDFLAGS"
 _SUBDIR_CONFIG_ARGS="$ac_configure_args"
 
 dnl Set the version number of the libs included with mozilla
 dnl ========================================================
 MOZJPEG=62
-MOZPNG=10606
+MOZPNG=10607
 NSPR_VERSION=4
 NSS_VERSION=3
 
 dnl Set the minimum version of toolkit libs used by mozilla
 dnl ========================================================
 GLIB_VERSION=1.2.0
 PERL_VERSION=5.006
 CAIRO_VERSION=1.10
@@ -3780,16 +3780,18 @@ if test "$MOZ_NATIVE_ZLIB" != 1; then
     MOZ_ZLIB_CFLAGS=
     MOZ_ZLIB_LIBS='$(call EXPAND_LIBNAME_PATH,mozz,'"$MOZ_BUILD_ROOT"'/modules/zlib/src)'
 fi
 
 if test "$MOZ_LINKER" = 1 -a "$MOZ_NATIVE_ZLIB" != 1; then
     AC_MSG_ERROR([Custom dynamic linker requires --with-system-zlib])
 fi
 
+MOZ_PNG_ARM_NEON=
+
 if test -z "$SKIP_LIBRARY_CHECKS"; then
 dnl system BZIP2 Support
 dnl ========================================================
 MOZ_ARG_WITH_STRING(system-bz2,
 [  --with-system-bz2[=PFX]
                           Use system libbz2 [installed at prefix PFX]],
     BZ2_DIR=$withval)
 
@@ -3854,24 +3856,20 @@ CFLAGS=$_SAVE_CFLAGS
 LDFLAGS=$_SAVE_LDFLAGS
 LIBS=$_SAVE_LIBS
 
 if test "${PNG_DIR}" -a -d "${PNG_DIR}" -a "$MOZ_NATIVE_PNG" = 1; then
     MOZ_PNG_CFLAGS="-I${PNG_DIR}/include"
     MOZ_PNG_LIBS="-L${PNG_DIR}/lib ${MOZ_PNG_LIBS}"
 fi
 
-MOZ_PNG_ARM_NEON=
-if test "$MOZ_NATIVE_PNG" != 1 -a "$CPU_ARCH" = "arm" ; then
-    MOZ_PNG_ARM_NEON=1
-fi
+fi # SKIP_LIBRARY_CHECKS
+
 AC_SUBST(MOZ_PNG_ARM_NEON)
 
-fi # SKIP_LIBRARY_CHECKS
-
 dnl system HunSpell Support
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(system-hunspell,
 [  --enable-system-hunspell
                           Use system hunspell (located with pkgconfig)],
     MOZ_NATIVE_HUNSPELL=1 )
 
 if test -n "$MOZ_NATIVE_HUNSPELL"; then
@@ -9122,16 +9120,19 @@ if test -z "$MOZ_NATIVE_NSPR"; then
       export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
     fi
     export LDFLAGS="$LDFLAGS $NSPR_LDFLAGS"
     export CFLAGS="$CFLAGS $MOZ_FRAMEPTR_FLAGS"
 
     AC_OUTPUT_SUBDIRS(nsprpub)
 
     # .. and restore them
+    unset CFLAGS
+    unset CPPFLAGS
+    unset LDFLAGS
     CFLAGS="$_SAVE_CFLAGS"
     CPPFLAGS="$_SAVE_CPPFLAGS"
     LDFLAGS="$_SAVE_LDFLAGS"
 
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 fi
 
 dnl ========================================================
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -643,19 +643,17 @@ nsDOMMemoryFile::DataOwner::sDataOwners;
 nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
 
 class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
   : public MemoryMultiReporter
 {
 public:
-  nsDOMMemoryFileDataOwnerMemoryReporter()
-    : MemoryMultiReporter("dom-memory-file-data-owner")
-  {}
+  nsDOMMemoryFileDataOwnerMemoryReporter() {}
 
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
                             nsISupports *aClosure)
   {
     typedef nsDOMMemoryFile::DataOwner DataOwner;
 
     StaticMutexAutoLock lock(DataOwner::sDataOwnerMutex);
 
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -1128,19 +1128,17 @@ struct MessageManagerReferentCount
 } // anonymous namespace
 
 namespace mozilla {
 namespace dom {
 
 class MessageManagerReporter MOZ_FINAL : public MemoryMultiReporter
 {
 public:
-  MessageManagerReporter()
-    : MemoryMultiReporter("message-manager")
-  {}
+  MessageManagerReporter() {}
 
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
                             nsISupports* aData);
 
   static const size_t kSuspectReferentCount = 300;
 protected:
   void CountReferents(nsFrameMessageManager* aMessageManager,
                       MessageManagerReferentCount* aReferentCount);
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -3994,17 +3994,20 @@ CanvasRenderingContext2D::GetCanvasLayer
   }
 
   mTarget->Flush();
 
   if (!mResetLayer && aOldLayer) {
     CanvasRenderingContext2DUserData* userData =
       static_cast<CanvasRenderingContext2DUserData*>(
         aOldLayer->GetUserData(&g2DContextLayerUserData));
-    if (userData && userData->IsForContext(this)) {
+
+    CanvasLayer::Data data;
+    data.mGLContext = static_cast<GLContext*>(mTarget->GetGLContext());
+    if (userData && userData->IsForContext(this) && aOldLayer->IsDataValid(data)) {
       nsRefPtr<CanvasLayer> ret = aOldLayer;
       return ret.forget();
     }
   }
 
   nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
   if (!canvasLayer) {
     NS_WARNING("CreateCanvasLayer returned null!");
--- a/content/canvas/src/WebGLContextReporter.cpp
+++ b/content/canvas/src/WebGLContextReporter.cpp
@@ -94,17 +94,16 @@ WebGLMemoryTracker* WebGLMemoryTracker::
     if (!sUniqueInstance) {
         sUniqueInstance = new WebGLMemoryTracker;
         sUniqueInstance->InitMemoryReporter();
     }
     return sUniqueInstance;
 }
 
 WebGLMemoryTracker::WebGLMemoryTracker()
-    : MemoryMultiReporter("webgl")
 {
 }
 
 void
 WebGLMemoryTracker::InitMemoryReporter()
 {
     RegisterWeakMemoryReporter(this);
 }
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -754,17 +754,17 @@ nsEventListenerManager::RemoveEventHandl
 
   uint32_t eventType = nsContentUtils::GetEventId(aName);
   nsListenerStruct* ls = FindEventHandler(eventType, aName, aTypeString);
 
   if (ls) {
     mListeners.RemoveElementAt(uint32_t(ls - &mListeners.ElementAt(0)));
     mNoListenerForEvent = NS_EVENT_NULL;
     mNoListenerForEventAtom = nullptr;
-    if (mTarget) {
+    if (mTarget && aName) {
       mTarget->EventListenerRemoved(aName);
     }
   }
 }
 
 nsresult
 nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerStruct,
                                                     nsCxPusher& aPusher,
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -1853,17 +1853,16 @@ MediaMemoryTracker::CollectReports(nsIHa
 MediaDecoderOwner*
 MediaDecoder::GetOwner()
 {
   MOZ_ASSERT(NS_IsMainThread());
   return mOwner;
 }
 
 MediaMemoryTracker::MediaMemoryTracker()
-  : MemoryMultiReporter("media")
 {
 }
 
 void
 MediaMemoryTracker::InitMemoryReporter()
 {
   RegisterWeakMemoryReporter(this);
 }
--- a/content/media/plugins/moz.build
+++ b/content/media/plugins/moz.build
@@ -7,17 +7,17 @@
 EXPORTS += [
     'MediaPluginDecoder.h',
     'MediaPluginHost.h',
     'MediaPluginReader.h',
     'MediaResourceServer.h',
     'MPAPI.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'MediaPluginDecoder.cpp',
     'MediaPluginHost.cpp',
     'MediaPluginReader.cpp',
     'MediaResourceServer.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/content/base/src',
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -10,17 +10,17 @@
 #include "nsCxPusher.h"
 #include "nsThreadUtils.h"
 #include "DOMCursor.h"
 #include "nsIDOMEvent.h"
 
 using mozilla::dom::DOMRequest;
 using mozilla::dom::DOMRequestService;
 using mozilla::dom::DOMCursor;
-using mozilla::AutoPushJSContext;
+using mozilla::AutoSafeJSContext;
 
 DOMRequest::DOMRequest(nsIDOMWindow* aWindow)
   : mResult(JSVAL_VOID)
   , mDone(false)
 {
   SetIsDOMBinding();
   Init(aWindow);
 }
@@ -252,44 +252,34 @@ class FireSuccessAsyncTask : public nsRu
     mReq(aRequest),
     mResult(aResult),
     mIsSetup(false)
   {
   }
 
 public:
 
-  nsresult
+  void
   Setup()
   {
-    nsresult rv;
-    nsIScriptContext* sc = mReq->GetContextForEventHandlers(&rv);
-    if (!NS_SUCCEEDED(rv)) {
-      return rv;
-    }
-    AutoPushJSContext cx(sc->GetNativeContext());
-    if (!cx) {
-      return NS_ERROR_FAILURE;
-    }
+    AutoSafeJSContext cx;
     JS_AddValueRoot(cx, &mResult);
     mIsSetup = true;
-    return NS_OK;
   }
 
   // Due to the fact that initialization can fail during shutdown (since we
   // can't fetch a js context), set up an initiatization function to make sure
   // we can return the failure appropriately
   static nsresult
   Dispatch(DOMRequest* aRequest,
            const JS::Value& aResult)
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     nsRefPtr<FireSuccessAsyncTask> asyncTask = new FireSuccessAsyncTask(aRequest, aResult);
-    nsresult rv = asyncTask->Setup();
-    NS_ENSURE_SUCCESS(rv, rv);
+    asyncTask->Setup();
     if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
       NS_WARNING("Failed to dispatch to main thread!");
       return NS_ERROR_FAILURE;
     }
     return NS_OK;
   }
 
   NS_IMETHODIMP
@@ -301,22 +291,18 @@ public:
 
   ~FireSuccessAsyncTask()
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     if(!mIsSetup) {
       // If we never set up, no reason to unroot
       return;
     }
-    nsresult rv;
-    nsIScriptContext* sc = mReq->GetContextForEventHandlers(&rv);
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
-    AutoPushJSContext cx(sc->GetNativeContext());
-    MOZ_ASSERT(cx);
 
+    AutoSafeJSContext cx;
     JS_RemoveValueRoot(cx, &mResult);
   }
 private:
   nsRefPtr<DOMRequest> mReq;
   JS::Value mResult;
   bool mIsSetup;
 };
 
--- a/dom/base/ObjectWrapper.jsm
+++ b/dom/base/ObjectWrapper.jsm
@@ -7,44 +7,63 @@
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 this.EXPORTED_SYMBOLS = ["ObjectWrapper"];
 
 // Makes sure that we expose correctly chrome JS objects to content.
 
+const TypedArrayThings = [
+  "Int8Array",
+  "Uint8Array",
+  "Uint8ClampedArray",
+  "Int16Array",
+  "Uint16Array",
+  "Int32Array",
+  "Uint32Array",
+  "Float32Array",
+  "Float64Array",
+];
+
 this.ObjectWrapper = {
   getObjectKind: function objWrapper_getObjectKind(aObject) {
     if (aObject === null || aObject === undefined) {
       return "primitive";
     } else if (Array.isArray(aObject)) {
       return "array";
     } else if (aObject instanceof Ci.nsIDOMFile) {
       return "file";
     } else if (aObject instanceof Ci.nsIDOMBlob) {
       return "blob";
     } else if (aObject instanceof Date) {
       return "date";
+    } else if (TypedArrayThings.indexOf(aObject.constructor.name) !== -1) {
+      return aObject.constructor.name;
     } else if (typeof aObject == "object") {
       return "object";
     } else {
       return "primitive";
     }
   },
 
   wrap: function objWrapper_wrap(aObject, aCtxt) {
     // First check wich kind of object we have.
     let kind = this.getObjectKind(aObject);
     if (kind == "array") {
       let res = Cu.createArrayIn(aCtxt);
       aObject.forEach(function(aObj) {
         res.push(this.wrap(aObj, aCtxt));
       }, this);
       return res;
+    } else if (TypedArrayThings.indexOf(kind) !== -1) {
+      // This is slow, because from the perspective of the constructor in aCtxt
+      // aObject is a CCW, and it gets the indexed properties one by one rather
+      // instead of realizing that this is already a typed array thing.
+      return new aCtxt[kind](aObject);
     } else if (kind == "file") {
       return new aCtxt.File(aObject,
                             { name: aObject.name,
                               type: aObject.type });
     } else if (kind == "blob") {
       return new aCtxt.Blob([aObject], { type: aObject.type });
     } else if (kind == "date") {
       return Cu.createDateIn(aCtxt, aObject.getTime());
--- a/dom/devicestorage/moz.build
+++ b/dom/devicestorage/moz.build
@@ -13,17 +13,17 @@ EXPORTS += [
     'nsDeviceStorage.h',
 ]
 
 EXPORTS.mozilla.dom.devicestorage += [
     'DeviceStorageRequestChild.h',
     'DeviceStorageRequestParent.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'DeviceStorageRequestChild.cpp',
     'DeviceStorageRequestParent.cpp',
     'nsDeviceStorage.cpp',
 ]
 
 IPDL_SOURCES += [
     'PDeviceStorageRequest.ipdl',
 ]
--- a/dom/encoding/moz.build
+++ b/dom/encoding/moz.build
@@ -8,22 +8,19 @@ TEST_DIRS += ['test']
 
 EXPORTS.mozilla.dom += [
     'EncodingUtils.h',
     'FallbackEncoding.h',
     'TextDecoder.h',
     'TextEncoder.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'EncodingUtils.cpp',
     'FallbackEncoding.cpp',
-]
-
-UNIFIED_SOURCES += [
     'TextDecoder.cpp',
     'TextEncoder.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -191,19 +191,17 @@ MemoryReportRequestParent::~MemoryReport
 {
     MOZ_COUNT_DTOR(MemoryReportRequestParent);
 }
 
 // A memory reporter for ContentParent objects themselves.
 class ContentParentsMemoryReporter MOZ_FINAL : public MemoryMultiReporter
 {
 public:
-    ContentParentsMemoryReporter()
-      : MemoryMultiReporter("content-parents")
-    {}
+    ContentParentsMemoryReporter() {}
 
     NS_IMETHOD CollectReports(nsIMemoryReporterCallback* cb,
                               nsISupports* aClosure);
 };
 
 NS_IMETHODIMP
 ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
                                              nsISupports* aClosure)
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -174,17 +174,21 @@ private:
     void CloseFile()
     {
         // It's possible for this to happen on the main thread if the dispatch
         // to the stream service fails after we've already opened the file so
         // we can't assert the thread we're running on.
 
         MOZ_ASSERT(mFD);
 
-        PR_Close(mFD);
+        PRStatus prrc;
+        prrc = PR_Close(mFD);
+        if (prrc != PR_SUCCESS) {
+          NS_ERROR("PR_Close() failed.");
+        }
         mFD = nullptr;
     }
 };
 
 namespace mozilla {
 namespace dom {
 
 TabParent* sEventCapturer;
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -76,16 +76,17 @@ nsPluginTag::nsPluginTag(nsPluginInfo* a
     mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
     mCachedBlocklistStateValid(false)
 {
   InitMime(aPluginInfo->fMimeTypeArray,
            aPluginInfo->fMimeDescriptionArray,
            aPluginInfo->fExtensionArray,
            aPluginInfo->fVariantCount);
   EnsureMembersAreUTF8();
+  FixupVersion();
 }
 
 nsPluginTag::nsPluginTag(const char* aName,
                          const char* aDescription,
                          const char* aFileName,
                          const char* aFullPath,
                          const char* aVersion,
                          const char* const* aMimeTypes,
@@ -106,16 +107,17 @@ nsPluginTag::nsPluginTag(const char* aNa
     mNiceFileName(),
     mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
     mCachedBlocklistStateValid(false)
 {
   InitMime(aMimeTypes, aMimeDescriptions, aExtensions,
            static_cast<uint32_t>(aVariants));
   if (!aArgsAreUTF8)
     EnsureMembersAreUTF8();
+  FixupVersion();
 }
 
 nsPluginTag::~nsPluginTag()
 {
   NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
 }
 
 NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
@@ -245,16 +247,25 @@ nsresult nsPluginTag::EnsureMembersAreUT
     for (uint32_t i = 0; i < mMimeDescriptions.Length(); ++i) {
       ConvertToUTF8(decoder, mMimeDescriptions[i]);
     }
   }
   return NS_OK;
 #endif
 }
 
+void nsPluginTag::FixupVersion()
+{
+#if defined(XP_LINUX)
+  if (mIsFlashPlugin) {
+    mVersion.ReplaceChar(',', '.');
+  }
+#endif
+}
+
 NS_IMETHODIMP
 nsPluginTag::GetDescription(nsACString& aDescription)
 {
   aDescription = mDescription;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/plugins/base/nsPluginTags.h
+++ b/dom/plugins/base/nsPluginTags.h
@@ -93,11 +93,12 @@ private:
   uint16_t      mCachedBlocklistState;
   bool          mCachedBlocklistStateValid;
 
   void InitMime(const char* const* aMimeTypes,
                 const char* const* aMimeDescriptions,
                 const char* const* aExtensions,
                 uint32_t aVariantCount);
   nsresult EnsureMembersAreUTF8();
+  void FixupVersion();
 };
 
 #endif // nsPluginTags_h_
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -1555,22 +1555,24 @@ PluginModuleParent::AllocPCrashReporterP
 #else
     return nullptr;
 #endif
 }
 
 bool
 PluginModuleParent::DeallocPCrashReporterParent(PCrashReporterParent* actor)
 {
+#ifdef MOZ_CRASHREPORTER
 #ifdef XP_WIN
     mozilla::MutexAutoLock lock(mCrashReporterMutex);
     if (actor == static_cast<PCrashReporterParent*>(mCrashReporter)) {
         mCrashReporter = nullptr;
     }
 #endif
+#endif
     delete actor;
     return true;
 }
 
 bool
 PluginModuleParent::RecvSetCursor(const NSCursorInfo& aCursorInfo)
 {
     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
--- a/dom/telephony/moz.build
+++ b/dom/telephony/moz.build
@@ -20,17 +20,17 @@ EXPORTS.mozilla.dom += [
 
 EXPORTS.mozilla.dom.telephony += [
     'ipc/TelephonyChild.h',
     'ipc/TelephonyParent.h',
     'TelephonyCommon.h',
     'TelephonyFactory.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'CallEvent.cpp',
     'CallsList.cpp',
     'ipc/TelephonyChild.cpp',
     'ipc/TelephonyIPCProvider.cpp',
     'ipc/TelephonyParent.cpp',
     'Telephony.cpp',
     'TelephonyCall.cpp',
     'TelephonyCallGroup.cpp',
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -62,16 +62,17 @@ interface PeerConnectionImpl  {
    */
   [Throws]
   void addIceCandidate(DOMString candidate, DOMString mid, unsigned short level);
 
   /* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
   void close();
 
   /* Attributes */
+  readonly attribute DOMString fingerprint;
   readonly attribute DOMString localDescription;
   readonly attribute DOMString remoteDescription;
 
   readonly attribute PCImplIceConnectionState iceConnectionState;
   readonly attribute PCImplIceGatheringState iceGatheringState;
   readonly attribute PCImplReadyState readyState;
   readonly attribute PCImplSignalingState signalingState;
   readonly attribute PCImplSipccState sipccState;
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2014,18 +2014,17 @@ class WorkerPrivate::MemoryReporter MOZ_
 
   SharedMutex mMutex;
   WorkerPrivate* mWorkerPrivate;
   nsCString mRtPath;
   bool mAlreadyMappedToAddon;
 
 public:
   MemoryReporter(WorkerPrivate* aWorkerPrivate)
-  : MemoryMultiReporter("workers"),
-    mMutex(aWorkerPrivate->mMutex), mWorkerPrivate(aWorkerPrivate),
+  : mMutex(aWorkerPrivate->mMutex), mWorkerPrivate(aWorkerPrivate),
     mAlreadyMappedToAddon(false)
   {
     aWorkerPrivate->AssertIsOnWorkerThread();
 
     nsCString escapedDomain(aWorkerPrivate->Domain());
     escapedDomain.ReplaceChar('/', '\\');
 
     NS_ConvertUTF16toUTF8 escapedURL(aWorkerPrivate->ScriptURL());
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -64,16 +64,22 @@ CopyableCanvasLayer::Initialize(const Da
     mNeedsYFlip = false;
   } else {
     NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
   }
 
   mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
 }
 
+bool
+CopyableCanvasLayer::IsDataValid(const Data& aData)
+{
+  return mGLContext == aData.mGLContext;
+}
+
 void
 CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
 {
   if (!IsDirty())
     return;
   Painted();
 
   if (mDrawTarget) {
--- a/gfx/layers/CopyableCanvasLayer.h
+++ b/gfx/layers/CopyableCanvasLayer.h
@@ -35,17 +35,18 @@ class CanvasClientWebGL;
  */
 class CopyableCanvasLayer : public CanvasLayer
 {
 public:
   CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData);
   virtual ~CopyableCanvasLayer();
 
   virtual void Initialize(const Data& aData);
-  
+
+  virtual bool IsDataValid(const Data& aData);
 
 protected:
   void PaintWithOpacity(gfxContext* aContext,
                         float aOpacity,
                         Layer* aMaskLayer,
                         gfxContext::GraphicsOperator aOperator = gfxContext::OPERATOR_OVER);
 
   void UpdateSurface(gfxASurface* aDestSurface = nullptr, Layer* aMaskLayer = nullptr);
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1729,16 +1729,21 @@ public:
    * have either mSurface or mGLContext initialized (but not both), as
    * well as mSize.
    *
    * This must only be called once.
    */
   virtual void Initialize(const Data& aData) = 0;
 
   /**
+   * Check the data is owned by this layer is still valid for rendering
+   */
+  virtual bool IsDataValid(const Data& aData) { return true; }
+
+  /**
    * Notify this CanvasLayer that the canvas surface contents have
    * changed (or will change) before the next transaction.
    */
   void Updated() { mDirty = true; SetInvalidRectToVisibleRegion(); }
 
   /**
    * Notify this CanvasLayer that the canvas surface contents have
    * been painted since the last change.
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -139,17 +139,27 @@ void CompositorParent::ShutDown()
 bool CompositorParent::CreateThread()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
   if (sCompositorThread || sCompositorLoop) {
     return true;
   }
   sCompositorThreadRefCount = 1;
   sCompositorThread = new Thread("Compositor");
-  if (!sCompositorThread->Start()) {
+
+  Thread::Options options;
+  /* Timeout values are powers-of-two to enable us get better data.
+     128ms is chosen for transient hangs because 8Hz should be the minimally
+     acceptable goal for Compositor responsiveness (normal goal is 60Hz). */
+  options.transient_hang_timeout = 128; // milliseconds
+  /* 8192ms is chosen for permanent hangs because it's several seconds longer
+     than the default hang timeout on major platforms (about 5 seconds). */
+  options.permanent_hang_timeout = 8192; // milliseconds
+
+  if (!sCompositorThread->StartWithOptions(options)) {
     delete sCompositorThread;
     sCompositorThread = nullptr;
     return false;
   }
   return true;
 }
 
 void CompositorParent::DestroyThread()
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -629,19 +629,17 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_
 
 /* Surface size memory reporting */
 
 static int64_t gSurfaceMemoryUsed[gfxSurfaceTypeMax] = { 0 };
 
 class SurfaceMemoryReporter MOZ_FINAL : public MemoryMultiReporter
 {
 public:
-    SurfaceMemoryReporter()
-        : MemoryMultiReporter("gfx-surface")
-    { }
+    SurfaceMemoryReporter() { }
 
     NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
                               nsISupports *aClosure)
     {
         size_t len = NS_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs);
         for (size_t i = 0; i < len; i++) {
             int64_t amount = gSurfaceMemoryUsed[i];
 
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -949,19 +949,17 @@ public:
                                 FontCacheSizes* aSizes) const;
     void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                                 FontCacheSizes* aSizes) const;
 
 protected:
     class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter
     {
     public:
-        MemoryReporter()
-            : MemoryMultiReporter("font-cache")
-        {}
+        MemoryReporter() {}
 
         NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
                                   nsISupports* aClosure);
     };
 
     // Observer for notifications that the font cache cares about
     class Observer MOZ_FINAL
         : public nsIObserver
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -69,17 +69,16 @@ gfxFontListPrefObserver::Observe(nsISupp
     gfxPlatformFontList::PlatformFontList()->ClearPrefFonts();
     gfxFontCache::GetCache()->AgeAllGenerations();
     return NS_OK;
 }
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
 
 gfxPlatformFontList::MemoryReporter::MemoryReporter()
-    : MemoryMultiReporter("font-list")
 {}
 
 NS_IMETHODIMP
 gfxPlatformFontList::MemoryReporter::CollectReports
     (nsIMemoryReporterCallback* aCb,
      nsISupports* aClosure)
 {
     FontListSizes sizes;
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -224,19 +224,17 @@ class GPUAdapterReporter : public Memory
                 DXGIDevice->Release();
             }
         }
 
         return result;
     }
 
 public:
-    GPUAdapterReporter()
-      : MemoryMultiReporter("gpu-adapter")
-    {}
+    GPUAdapterReporter() {}
 
     NS_IMETHOD
     CollectReports(nsIMemoryReporterCallback* aCb,
                    nsISupports* aClosure)
     {
         HANDLE ProcessHandle = GetCurrentProcess();
 
         int64_t dedicatedBytesUsed = 0;
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -800,21 +800,21 @@ nsPNGDecoder::row_callback(png_structp p
       // Only do incremental image display for the first frame
       // XXXbholley - this check should be handled in the superclass
       nsIntRect r(0, row_num, width, 1);
       decoder->PostInvalidation(r);
     }
   }
 }
 
+#ifdef PNG_APNG_SUPPORTED
 // got the header of a new frame that's coming
 void
 nsPNGDecoder::frame_info_callback(png_structp png_ptr, png_uint_32 frame_num)
 {
-#ifdef PNG_APNG_SUPPORTED
   png_uint_32 x_offset, y_offset;
   int32_t width, height;
 
   nsPNGDecoder *decoder =
                static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
 
   // old frame is done
   decoder->EndImageFrame();
@@ -830,18 +830,18 @@ nsPNGDecoder::frame_info_callback(png_st
   decoder->CreateFrame(x_offset, y_offset, width, height, decoder->format);
 
   if (decoder->NeedsNewFrame()) {
     /* We know that we need a new frame, so pause input so the decoder
      * infrastructure can give it to us.
      */
     png_process_data_pause(png_ptr, /* save = */ 1);
   }
+}
 #endif
-}
 
 void
 nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
 {
   /* libpng comments:
    *
    * this function is called when the whole image has been read,
    * including any chunks after the image (up to and including
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -48,19 +48,17 @@
 using namespace mozilla;
 using namespace mozilla::image;
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
 
 class imgMemoryReporter MOZ_FINAL : public MemoryMultiReporter
 {
 public:
-  imgMemoryReporter()
-    : MemoryMultiReporter("images")
-  {}
+  imgMemoryReporter() {}
 
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback *callback,
                             nsISupports *closure)
   {
     AllSizes chrome;
     AllSizes content;
 
     for (uint32_t i = 0; i < mKnownLoaders.Length(); i++) {
--- a/intl/chardet/src/moz.build
+++ b/intl/chardet/src/moz.build
@@ -1,12 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'nsChardetModule.cpp',
     'nsCyrillicDetector.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/intl/hyphenation/src/moz.build
+++ b/intl/hyphenation/src/moz.build
@@ -1,15 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'hnjstdio.cpp',
     'nsHyphenationManager.cpp',
     'nsHyphenator.cpp',
 ]
 
 SOURCES += [
     'hyphen.c',
 ]
--- a/intl/locale/src/mac/moz.build
+++ b/intl/locale/src/mac/moz.build
@@ -1,15 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'nsCollationMacUC.cpp',
     'nsDateTimeFormatMac.cpp',
     'nsMacCharset.cpp',
 ]
 
 FINAL_LIBRARY = 'i18n'
 LOCAL_INCLUDES += [
     '..',
--- a/intl/locale/src/moz.build
+++ b/intl/locale/src/moz.build
@@ -12,17 +12,17 @@ elif toolkit == 'cocoa':
     DIRS += ['mac']
 else:
     DIRS += ['unix']
 
 EXPORTS += [
     'nsCollation.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'nsCharsetAlias.cpp',
     'nsCollation.cpp',
     'nsLanguageAtomService.cpp',
     'nsLocale.cpp',
     'nsLocaleService.cpp',
     'nsScriptableDateFormat.cpp',
     'nsUConvPropertySearch.cpp',
 ]
--- a/intl/lwbrk/src/moz.build
+++ b/intl/lwbrk/src/moz.build
@@ -1,30 +1,30 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'nsJISx4051LineBreaker.cpp',
     'nsSampleWordBreaker.cpp',
     'nsSemanticUnitScanner.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_GTK']:
     SOURCES += [
         'nsPangoBreaker.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'nsUniscribeBreaker.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'nsCarbonBreaker.cpp',
     ]
 else:
     SOURCES += [
         'nsRuleBreaker.cpp',
     ]
     SOURCES += [
         'rulebrk.c',
--- a/intl/strres/src/moz.build
+++ b/intl/strres/src/moz.build
@@ -1,14 +1,14 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'nsStringBundle.cpp',
     'nsStringBundleTextOverride.cpp',
 ]
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'i18n'
--- a/intl/strres/src/nsStringBundle.cpp
+++ b/intl/strres/src/nsStringBundle.cpp
@@ -26,17 +26,16 @@
 #ifdef ASYNC_LOADING
 #include "nsIBinaryInputStream.h"
 #include "nsIStringStream.h"
 #endif
 
 using namespace mozilla;
 
 static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
-static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
 
 nsStringBundle::~nsStringBundle()
 {
 }
 
 nsStringBundle::nsStringBundle(const char* aURLSpec,
                                nsIStringBundleOverride* aOverrideStrings) :
   mPropertiesURL(aURLSpec),
@@ -79,17 +78,18 @@ nsStringBundle::LoadProperties()
   channel->SetContentType(NS_LITERAL_CSTRING("text/plain"));
   
   nsCOMPtr<nsIInputStream> in;
   rv = channel->Open(getter_AddRefs(in));
   if (NS_FAILED(rv)) return rv;
 
   NS_ASSERTION(NS_SUCCEEDED(rv) && in, "Error in OpenBlockingStream");
   NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && in, NS_ERROR_FAILURE);
-    
+
+  static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
   mProps = do_CreateInstance(kPersistentPropertiesCID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   
   mAttemptedLoad = mLoaded = true;
   rv = mProps->Load(in);
 
   mLoaded = NS_SUCCEEDED(rv);
   
--- a/intl/strres/src/nsStringBundleTextOverride.cpp
+++ b/intl/strres/src/nsStringBundleTextOverride.cpp
@@ -5,19 +5,16 @@
 
 
 #include "nsStringBundleTextOverride.h"
 #include "nsString.h"
 
 #include "nsNetUtil.h"
 #include "nsAppDirectoryServiceDefs.h"
 
-static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
-
-
 // first we need a simple class which wraps a nsIPropertyElement and
 // cuts out the leading URL from the key
 class URLPropertyElement : public nsIPropertyElement
 {
 public:
     URLPropertyElement(nsIPropertyElement *aRealElement, uint32_t aURLLength) :
         mRealElement(aRealElement),
         mURLLength(aURLLength)
@@ -147,16 +144,17 @@ nsStringBundleTextOverride::Init()
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), customStringsURLSpec);
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIInputStream> in;
     rv = NS_OpenURI(getter_AddRefs(in), uri);
     if (NS_FAILED(rv)) return rv;
 
+    static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
     mValues = do_CreateInstance(kPersistentPropertiesCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
     rv = mValues->Load(in);
 
     // turn this on to see the contents of custom-strings.txt
 #ifdef DEBUG_alecf
     nsCOMPtr<nsISimpleEnumerator> enumerator;
--- a/ipc/chromium/src/base/message_loop.cc
+++ b/ipc/chromium/src/base/message_loop.cc
@@ -94,16 +94,18 @@ MessageLoop::MessageLoop(Type type)
       id_(++message_loop_id_seq),
       nestable_tasks_allowed_(true),
       exception_restoration_(false),
       state_(NULL),
       run_depth_base_(1),
 #ifdef OS_WIN
       os_modal_loop_(false),
 #endif  // OS_WIN
+      transient_hang_timeout_(0),
+      permanent_hang_timeout_(0),
       next_sequence_num_(0) {
   DCHECK(!current()) << "should only have one message loop per thread";
   lazy_tls_ptr.Pointer()->Set(this);
   if (type_ == TYPE_MOZILLA_UI) {
     pump_ = new mozilla::ipc::MessagePump();
     return;
   }
   if (type_ == TYPE_MOZILLA_CHILD) {
--- a/ipc/chromium/src/base/message_loop.h
+++ b/ipc/chromium/src/base/message_loop.h
@@ -264,16 +264,30 @@ public:
     os_modal_loop_ = os_modal_loop;
   }
 
   bool & os_modal_loop() {
     return os_modal_loop_;
   }
 #endif  // OS_WIN
 
+  // Set the timeouts for background hang monitoring.
+  // A value of 0 indicates there is no timeout.
+  void set_hang_timeouts(uint32_t transient_timeout_ms,
+                         uint32_t permanent_timeout_ms) {
+    transient_hang_timeout_ = transient_timeout_ms;
+    permanent_hang_timeout_ = permanent_timeout_ms;
+  }
+  uint32_t transient_hang_timeout() const {
+    return transient_hang_timeout_;
+  }
+  uint32_t permanent_hang_timeout() const {
+    return permanent_hang_timeout_;
+  }
+
   //----------------------------------------------------------------------------
  protected:
   struct RunState {
     // Used to count how many Run() invocations are on the stack.
     int run_depth;
 
     // Used to record that Quit() was called, or that we should quit the pump
     // once it becomes idle.
@@ -415,16 +429,20 @@ public:
   int run_depth_base_;
 
 #if defined(OS_WIN)
   // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
   // which enter a modal message loop.
   bool os_modal_loop_;
 #endif
 
+  // Timeout values for hang monitoring
+  uint32_t transient_hang_timeout_;
+  uint32_t permanent_hang_timeout_;
+
   // The next sequence number to use for delayed tasks.
   int next_sequence_num_;
 
   DISALLOW_COPY_AND_ASSIGN(MessageLoop);
 };
 
 //-----------------------------------------------------------------------------
 // MessageLoopForUI extends MessageLoop with methods that are particular to a
--- a/ipc/chromium/src/base/message_pump_default.cc
+++ b/ipc/chromium/src/base/message_pump_default.cc
@@ -1,55 +1,69 @@
 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "base/message_pump_default.h"
 
 #include "base/logging.h"
+#include "base/message_loop.h"
 #include "base/scoped_nsautorelease_pool.h"
 #include "GeckoProfiler.h"
 
+#include "mozilla/BackgroundHangMonitor.h"
+
 namespace base {
 
 MessagePumpDefault::MessagePumpDefault()
     : keep_running_(true),
       event_(false, false) {
 }
 
 void MessagePumpDefault::Run(Delegate* delegate) {
   DCHECK(keep_running_) << "Quit must have been called outside of Run!";
 
+  const MessageLoop* const loop = MessageLoop::current();
+  mozilla::BackgroundHangMonitor hangMonitor(
+    loop->thread_name().c_str(),
+    loop->transient_hang_timeout(),
+    loop->permanent_hang_timeout());
+
   for (;;) {
     ScopedNSAutoreleasePool autorelease_pool;
 
+    hangMonitor.NotifyActivity();
     bool did_work = delegate->DoWork();
     if (!keep_running_)
       break;
 
+    hangMonitor.NotifyActivity();
     did_work |= delegate->DoDelayedWork(&delayed_work_time_);
     if (!keep_running_)
       break;
 
     if (did_work)
       continue;
 
+    hangMonitor.NotifyActivity();
     did_work = delegate->DoIdleWork();
     if (!keep_running_)
       break;
 
     if (did_work)
       continue;
 
     if (delayed_work_time_.is_null()) {
+      hangMonitor.NotifyWait();
       PROFILER_LABEL("MessagePump", "Wait");
       event_.Wait();
     } else {
       TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
       if (delay > TimeDelta()) {
+        hangMonitor.NotifyWait();
         PROFILER_LABEL("MessagePump", "Wait");
         event_.TimedWait(delay);
       } else {
         // It looks like delayed_work_time_ indicates a time in the past, so we
         // need to call DoDelayedWork now.
         delayed_work_time_ = TimeTicks();
       }
     }
--- a/ipc/chromium/src/base/thread.cc
+++ b/ipc/chromium/src/base/thread.cc
@@ -142,16 +142,18 @@ void Thread::ThreadMain() {
 
   // The message loop for this thread.
   MessageLoop message_loop(startup_data_->options.message_loop_type);
 
   // Complete the initialization of our Thread object.
   thread_id_ = PlatformThread::CurrentId();
   PlatformThread::SetName(name_.c_str());
   message_loop.set_thread_name(name_);
+  message_loop.set_hang_timeouts(startup_data_->options.transient_hang_timeout,
+                                 startup_data_->options.permanent_hang_timeout);
   message_loop_ = &message_loop;
 
   // Let the thread do extra initialization.
   // Let's do this before signaling we are started.
   Init();
 
   startup_data_->event.Signal();
   // startup_data_ can't be touched anymore since the starting thread is now
--- a/ipc/chromium/src/base/thread.h
+++ b/ipc/chromium/src/base/thread.h
@@ -1,15 +1,16 @@
 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef BASE_THREAD_H_
 #define BASE_THREAD_H_
 
+#include <stdint.h>
 #include <string>
 
 #include "base/message_loop.h"
 #include "base/platform_thread.h"
 
 namespace base {
 
 // A simple thread abstraction that establishes a MessageLoop on a new thread.
@@ -23,19 +24,31 @@ class Thread : PlatformThread::Delegate 
     // Specifies the type of message loop that will be allocated on the thread.
     MessageLoop::Type message_loop_type;
 
     // Specifies the maximum stack size that the thread is allowed to use.
     // This does not necessarily correspond to the thread's initial stack size.
     // A value of 0 indicates that the default maximum should be used.
     size_t stack_size;
 
-    Options() : message_loop_type(MessageLoop::TYPE_DEFAULT), stack_size(0) {}
+    // Specifies the transient and permanent hang timeouts for background hang
+    // monitoring. A value of 0 indicates there is no timeout.
+    uint32_t transient_hang_timeout;
+    uint32_t permanent_hang_timeout;
+
+    Options()
+        : message_loop_type(MessageLoop::TYPE_DEFAULT)
+        , stack_size(0)
+        , transient_hang_timeout(0)
+        , permanent_hang_timeout(0) {}
     Options(MessageLoop::Type type, size_t size)
-        : message_loop_type(type), stack_size(size) {}
+        : message_loop_type(type)
+        , stack_size(size)
+        , transient_hang_timeout(0)
+        , permanent_hang_timeout(0) {}
   };
 
   // Constructor.
   // name is a display string to identify the thread.
   explicit Thread(const char *name);
 
   // Destroys the thread, stopping it if necessary.
   //
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -206,65 +206,55 @@ struct CodeSizes
     FOR_EACH_SIZE(DECL_SIZE)
     int dummy;  // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
 
 #undef FOR_EACH_SIZE
 };
 
 // This class holds information about the memory taken up by identical copies of
 // a particular string.  Multiple JSStrings may have their sizes aggregated
-// together into one StringInfo object.
+// together into one StringInfo object.  Note that two strings with identical
+// chars will not be aggregated together if one is a short string and the other
+// is not.
 struct StringInfo
 {
     StringInfo()
-      : length(0), numCopies(0), shortGCHeap(0), normalGCHeap(0), normalMallocHeap(0)
+      : numCopies(0),
+        isShort(0),
+        gcHeap(0),
+        mallocHeap(0)
     {}
 
-    StringInfo(size_t len, size_t shorts, size_t normals, size_t chars)
-      : length(len),
-        numCopies(1),
-        shortGCHeap(shorts),
-        normalGCHeap(normals),
-        normalMallocHeap(chars)
+    StringInfo(bool isShort, size_t gcSize, size_t mallocSize)
+      : numCopies(1),
+        isShort(isShort),
+        gcHeap(gcSize),
+        mallocHeap(mallocSize)
     {}
 
-    void add(size_t shorts, size_t normals, size_t chars) {
-        shortGCHeap += shorts;
-        normalGCHeap += normals;
-        normalMallocHeap += chars;
+    void add(bool isShort, size_t gcSize, size_t mallocSize) {
         numCopies++;
+        MOZ_ASSERT(isShort == this->isShort);
+        gcHeap += gcSize;
+        mallocHeap += mallocSize;
     }
 
     void add(const StringInfo& info) {
-        MOZ_ASSERT(length == info.length);
-
-        shortGCHeap += info.shortGCHeap;
-        normalGCHeap += info.normalGCHeap;
-        normalMallocHeap += info.normalMallocHeap;
         numCopies += info.numCopies;
-    }
-
-    size_t totalSizeOf() const {
-        return shortGCHeap + normalGCHeap + normalMallocHeap;
+        MOZ_ASSERT(info.isShort == isShort);
+        gcHeap += info.gcHeap;
+        mallocHeap += info.mallocHeap;
     }
 
-    size_t totalGCHeapSizeOf() const {
-        return shortGCHeap + normalGCHeap;
-    }
-
-    // The string's length, excluding the null-terminator.
-    size_t length;
-
-    // How many copies of the string have we seen?
-    size_t numCopies;
+    uint32_t numCopies:31;  // How many copies of the string have we seen?
+    uint32_t isShort:1;     // Is it a short string?
 
     // These are all totals across all copies of the string we've seen.
-    size_t shortGCHeap;
-    size_t normalGCHeap;
-    size_t normalMallocHeap;
+    size_t gcHeap;
+    size_t mallocHeap;
 };
 
 // Holds data about a notable string (one which uses more than
 // NotableStringInfo::notableSize() bytes of memory), so we can report it
 // individually.
 //
 // Essentially the only difference between this class and StringInfo is that
 // NotableStringInfo holds a copy of the string's chars.
@@ -281,16 +271,17 @@ struct NotableStringInfo : public String
 
     // A string needs to take up this many bytes of storage before we consider
     // it to be "notable".
     static size_t notableSize() {
         return js::MemoryReportingSundriesThreshold();
     }
 
     char *buffer;
+    size_t length;
 
   private:
     NotableStringInfo(const NotableStringInfo& info) MOZ_DELETE;
 };
 
 // These measurements relate directly to the JSRuntime, and not to zones and
 // compartments within it.
 struct RuntimeSizes
@@ -316,64 +307,70 @@ struct RuntimeSizes
     FOR_EACH_SIZE(DECL_SIZE)
     CodeSizes code;
 
 #undef FOR_EACH_SIZE
 };
 
 struct ZoneStats : js::ZoneStatsPod
 {
-    ZoneStats() {
-        strings.init();
-    }
+    ZoneStats()
+      : strings(nullptr)
+    {}
 
     ZoneStats(ZoneStats &&other)
       : ZoneStatsPod(mozilla::Move(other)),
-        strings(mozilla::Move(other.strings)),
+        strings(other.strings),
         notableStrings(mozilla::Move(other.notableStrings))
-    {}
+    {
+        other.strings = nullptr;
+    }
+
+    bool initStrings(JSRuntime *rt);
 
-    // Add other's numbers to this object's numbers.  Both objects'
-    // notableStrings vectors must be empty at this point, because we can't
-    // merge them.  (A NotableStringInfo contains only a prefix of the string,
-    // so we can't tell whether two NotableStringInfo objects correspond to the
-    // same string.)
-    void add(const ZoneStats &other) {
+    // Add |other|'s numbers to this object's numbers.  The strings data isn't
+    // touched.
+    void addIgnoringStrings(const ZoneStats &other) {
         ZoneStatsPod::add(other);
+    }
 
-        MOZ_ASSERT(notableStrings.empty());
-        MOZ_ASSERT(other.notableStrings.empty());
-
-        for (StringsHashMap::Range r = other.strings.all(); !r.empty(); r.popFront()) {
-            StringsHashMap::AddPtr p = strings.lookupForAdd(r.front().key());
+    // Add |other|'s strings data to this object's strings data.  (We don't do
+    // anything with notableStrings.)
+    void addStrings(const ZoneStats &other) {
+        for (StringsHashMap::Range r = other.strings->all(); !r.empty(); r.popFront()) {
+            StringsHashMap::AddPtr p = strings->lookupForAdd(r.front().key());
             if (p) {
                 // We've seen this string before; add its size to our tally.
                 p->value().add(r.front().value());
             } else {
                 // We haven't seen this string before; add it to the hashtable.
-                strings.add(p, r.front().key(), r.front().value());
+                strings->add(p, r.front().key(), r.front().value());
             }
         }
     }
 
     size_t sizeOfLiveGCThings() const {
         size_t n = ZoneStatsPod::sizeOfLiveGCThings();
         for (size_t i = 0; i < notableStrings.length(); i++) {
             const JS::NotableStringInfo& info = notableStrings[i];
-            n += info.totalGCHeapSizeOf();
+            n += info.gcHeap;
         }
         return n;
     }
 
     typedef js::HashMap<JSString*,
                         StringInfo,
                         js::InefficientNonFlatteningStringHashPolicy,
                         js::SystemAllocPolicy> StringsHashMap;
 
-    StringsHashMap strings;
+    // |strings| is only used transiently.  During the zone traversal it is
+    // filled with info about every string in the zone.  It's then used to fill
+    // in |notableStrings| (which actually gets reported), and immediately
+    // discarded afterwards.
+    StringsHashMap *strings;
     js::Vector<NotableStringInfo, 0, js::SystemAllocPolicy> notableStrings;
 };
 
 struct CompartmentStats
 {
 #define FOR_EACH_SIZE(macro) \
     macro(Objects, IsLiveGCThing,  objectsGCHeapOrdinary) \
     macro(Objects, IsLiveGCThing,  objectsGCHeapFunction) \
@@ -439,16 +436,19 @@ struct CompartmentStats
 
     FOR_EACH_SIZE(DECL_SIZE)
     ObjectsExtraSizes  objectsExtra;
     void               *extra;  // This field can be used by embedders.
 
 #undef FOR_EACH_SIZE
 };
 
+typedef js::Vector<CompartmentStats, 0, js::SystemAllocPolicy> CompartmentStatsVector;
+typedef js::Vector<ZoneStats, 0, js::SystemAllocPolicy> ZoneStatsVector;
+
 struct RuntimeStats
 {
 #define FOR_EACH_SIZE(macro) \
     macro(_, _, gcHeapChunkTotal) \
     macro(_, _, gcHeapDecommittedArenas) \
     macro(_, _, gcHeapUnusedChunks) \
     macro(_, _, gcHeapUnusedArenas) \
     macro(_, _, gcHeapChunkAdmin) \
@@ -487,18 +487,18 @@ struct RuntimeStats
 
     FOR_EACH_SIZE(DECL_SIZE)
 
     RuntimeSizes runtime;
 
     CompartmentStats cTotals;   // The sum of this runtime's compartments' measurements.
     ZoneStats zTotals;          // The sum of this runtime's zones' measurements.
 
-    js::Vector<CompartmentStats, 0, js::SystemAllocPolicy> compartmentStatsVector;
-    js::Vector<ZoneStats, 0, js::SystemAllocPolicy> zoneStatsVector;
+    CompartmentStatsVector compartmentStatsVector;
+    ZoneStatsVector zoneStatsVector;
 
     ZoneStats *currZoneStats;
 
     mozilla::MallocSizeOf mallocSizeOf_;
 
     virtual void initExtraCompartmentStats(JSCompartment *c, CompartmentStats *cstats) = 0;
     virtual void initExtraZoneStats(JS::Zone *zone, ZoneStats *zstats) = 0;
 
--- a/js/src/build/autoconf/android.m4
+++ b/js/src/build/autoconf/android.m4
@@ -157,20 +157,20 @@ case "$target" in
         CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
     fi
     LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
     AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
     RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
     STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
     OBJCOPY="$android_toolchain"/bin/"$android_tool_prefix"-objcopy
 
-    CPPFLAGS="-isystem $android_platform/usr/include $CPPFLAGS"
+    CPPFLAGS="-idirafter $android_platform/usr/include $CPPFLAGS"
     CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
     CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS"
-    ASFLAGS="-isystem $android_platform/usr/include -DANDROID $ASFLAGS"
+    ASFLAGS="-idirafter $android_platform/usr/include -DANDROID $ASFLAGS"
 
     dnl Add -llog by default, since we use it all over the place.
     dnl Add --allow-shlib-undefined, because libGLESv2 links to an
     dnl undefined symbol (present on the hardware, just not in the
     dnl NDK.)
     LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS"
     dnl prevent cross compile section from using these flags as host flags
     if test -z "$HOST_CPPFLAGS" ; then
@@ -235,17 +235,17 @@ if test "$OS_TARGET" = "Android" -a -z "
             elif test -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a"; then
                 # android-ndk-r5c, android-ndk-r6, android-ndk-r6b
                 STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include"
                 STLPORT_LIBS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/ -lstdc++"
             else
                 AC_MSG_ERROR([Couldn't find path to gnu-libstdc++ in the android ndk])
             fi
         else
-            STLPORT_CPPFLAGS="-I$_topsrcdir/build/stlport/stlport -I$android_ndk/sources/cxx-stl/system/include"
+            STLPORT_CPPFLAGS="-isystem $_topsrcdir/build/stlport/stlport -isystem $android_ndk/sources/cxx-stl/system/include"
             STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
         fi
     fi
     CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
 fi
 AC_SUBST([MOZ_ANDROID_LIBSTDCXX])
 AC_SUBST([STLPORT_LIBS])
 
--- a/js/src/jit-test/tests/asm.js/testExpressions.js
+++ b/js/src/jit-test/tests/asm.js/testExpressions.js
@@ -326,8 +326,35 @@ var f = asmLink(asmCompile(USE_ASM + "fu
 for (let i = 0; i < 31; i++) {
     assertEq(f(Math.pow(2,i)), (Math.pow(2,i) * 2)|0);
     assertEq(f(Math.pow(2,i) - 1), ((Math.pow(2,i) - 1) * 2)|0);
     assertEq(f(-Math.pow(2,i)), (-Math.pow(2,i) * 2)|0);
     assertEq(f(-Math.pow(2,i) - 1), ((-Math.pow(2,i) - 1) * 2)|0);
 }
 assertEq(f(INT32_MIN), (INT32_MIN * 2)|0);
 assertEq(f(INT32_MAX), (INT32_MAX * 2)|0);
+
+// Signed integer division by a power of two - with a non-negative numerator!
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/1)|0; } return f;"));
+for (let i = 0; i < 31; i++) {
+    assertEq(f(Math.pow(2,i)), Math.pow(2,i));
+    assertEq(f(Math.pow(2,i+1)-1), Math.pow(2,i+1)-1);
+}
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/2)|0; } return f;"));
+for (let i = 0; i < 31; i++) {
+    assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/2)|0);
+    assertEq(f(Math.pow(2,i+1)-1), ((Math.pow(2,i+1)-1)/2)|0);
+}
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/4)|0; } return f;"));
+for (let i = 0; i < 31; i++) {
+    assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/4)|0);
+    assertEq(f(Math.pow(2,i+1)-1), ((Math.pow(2,i+1)-1)/4)|0);
+}
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/1073741824)|0; } return f;"));
+for (let i = 0; i < 31; i++) {
+    assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/Math.pow(2,30))|0);
+    assertEq(f(Math.pow(2,i+1)-1), ((Math.pow(2,i+1)-1)/Math.pow(2,30))|0);
+}
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((((i|0)/1)|0)+i)|0; } return f;"));
+for (let i = 0; i < 31; i++) {
+    assertEq(f(Math.pow(2,i)), (Math.pow(2,i) * 2)|0);
+    assertEq(f(Math.pow(2,i+1) - 1), ((Math.pow(2,i+1) - 1) * 2)|0);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug944080.js
@@ -0,0 +1,17 @@
+
+function intLength (a, l) {
+    var res = 0;
+    for (var i = 0; i < l; i++)
+	res += a.length;
+}
+intLength([0,1,2,3,4,5,6,7,8,9], 10)
+intLength(new Uint8Array(10), 10)
+function test() {
+    var a = "abc".split("");
+    var res = 0;
+    for (var i=0; i<20; i++)
+	res += a.length;
+    return res;
+}
+Object.prototype.length = function(){};
+assertEq(test(), 60);
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -5981,16 +5981,22 @@ ClassHasEffectlessLookup(const Class *cl
         return true;
     }
     return clasp->isNative() && !clasp->ops.lookupGeneric;
 }
 
 static bool
 ClassHasResolveHook(CompileCompartment *comp, const Class *clasp, PropertyName *name)
 {
+    // While arrays do not have resolve hooks, the types of their |length|
+    // properties are not reflected in type information, so pretend there is a
+    // resolve hook for this property.
+    if (clasp == &ArrayObject::class_)
+        return name = comp->runtime()->names().length;
+
     if (clasp->resolve == JS_ResolveStub)
         return false;
 
     if (clasp->resolve == (JSResolveOp)str_resolve) {
         // str_resolve only resolves integers, not names.
         return false;
     }
 
@@ -6097,16 +6103,19 @@ IonBuilder::testSingletonPropertyTypes(M
         // has the singleton property, the access will not be on a missing property.
         for (unsigned i = 0; i < types->getObjectCount(); i++) {
             types::TypeObjectKey *object = types->getObject(i);
             if (!object)
                 continue;
             if (analysisContext)
                 object->ensureTrackedProperty(analysisContext, NameToId(name));
 
+            const Class *clasp = object->clasp();
+            if (!ClassHasEffectlessLookup(clasp, name) || ClassHasResolveHook(compartment, clasp, name))
+                return false;
             if (object->unknownProperties())
                 return false;
             types::HeapTypeSetKey property = object->property(NameToId(name));
             if (property.isOwnProperty(constraints()))
                 return false;
 
             if (JSObject *proto = object->proto().toObjectOrNull()) {
                 // Test this type.
@@ -7996,16 +8005,20 @@ IonBuilder::annotateGetPropertyCache(MDe
     for (unsigned int i = 0; i < objCount; i++) {
         types::TypeObject *baseTypeObj = objTypes->getTypeObject(i);
         if (!baseTypeObj)
             continue;
         types::TypeObjectKey *typeObj = types::TypeObjectKey::get(baseTypeObj);
         if (typeObj->unknownProperties() || !typeObj->proto().isObject())
             continue;
 
+        const Class *clasp = typeObj->clasp();
+        if (!ClassHasEffectlessLookup(clasp, name) || ClassHasResolveHook(compartment, clasp, name))
+            continue;
+
         types::HeapTypeSetKey ownTypes = typeObj->property(NameToId(name));
         if (ownTypes.isOwnProperty(constraints()))
             continue;
 
         JSObject *singleton = testSingletonProperty(typeObj->proto().toObject(), name);
         if (!singleton || !singleton->is<JSFunction>())
             continue;
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -4090,23 +4090,25 @@ class MMul : public MBinaryArithInstruct
     Mode mode() { return mode_; }
 };
 
 class MDiv : public MBinaryArithInstruction
 {
     bool canBeNegativeZero_;
     bool canBeNegativeOverflow_;
     bool canBeDivideByZero_;
+    bool canBeNegativeDividend_;
     bool unsigned_;
 
     MDiv(MDefinition *left, MDefinition *right, MIRType type)
       : MBinaryArithInstruction(left, right),
         canBeNegativeZero_(true),
         canBeNegativeOverflow_(true),
         canBeDivideByZero_(true),
+        canBeNegativeDividend_(true),
         unsigned_(false)
     {
         if (type != MIRType_Value)
             specialization_ = type;
         setResultType(type);
     }
 
   public:
@@ -4145,25 +4147,30 @@ class MDiv : public MBinaryArithInstruct
     bool canBeNegativeOverflow() const {
         return canBeNegativeOverflow_;
     }
 
     bool canBeDivideByZero() const {
         return canBeDivideByZero_;
     }
 
+    bool canBeNegativeDividend() const {
+        return canBeNegativeDividend_;
+    }
+
     bool isUnsigned() const {
         return unsigned_;
     }
 
     bool isFloat32Commutative() const { return true; }
 
     void computeRange();
     bool fallible() const;
     bool truncate();
+    void collectRangeInfoPreTrunc();
 };
 
 class MMod : public MBinaryArithInstruction
 {
     bool unsigned_;
     bool canBeNegativeDividend_;
 
     MMod(MDefinition *left, MDefinition *right, MIRType type)
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -2492,16 +2492,24 @@ void
 MLoadElementHole::collectRangeInfoPreTrunc()
 {
     Range indexRange(index());
     if (indexRange.isFiniteNonNegative())
         needsNegativeIntCheck_ = false;
 }
 
 void
+MDiv::collectRangeInfoPreTrunc()
+{
+    Range lhsRange(lhs());
+    if (lhsRange.isFiniteNonNegative())
+        canBeNegativeDividend_ = false;
+}
+
+void
 MMod::collectRangeInfoPreTrunc()
 {
     Range lhsRange(lhs());
     if (lhsRange.isFiniteNonNegative())
         canBeNegativeDividend_ = false;
 }
 
 void
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -649,28 +649,33 @@ CodeGeneratorARM::visitSoftDivI(LSoftDiv
 bool
 CodeGeneratorARM::visitDivPowTwoI(LDivPowTwoI *ins)
 {
     Register lhs = ToRegister(ins->numerator());
     Register output = ToRegister(ins->output());
     int32_t shift = ins->shift();
 
     if (shift != 0) {
-        if (!ins->mir()->isTruncated()) {
+        MDiv *mir = ins->mir();
+        if (!mir->isTruncated()) {
             // If the remainder is != 0, bailout since this must be a double.
             masm.as_mov(ScratchRegister, lsl(lhs, 32 - shift), SetCond);
             if (!bailoutIf(Assembler::NonZero, ins->snapshot()))
                 return false;
         }
 
+        if (!mir->canBeNegativeDividend()) {
+            // Numerator is unsigned, so needs no adjusting. Do the shift.
+            masm.as_mov(output, asr(lhs, shift));
+            return true;
+        }
+
         // Adjust the value so that shifting produces a correctly rounded result
         // when the numerator is negative. See 10-1 "Signed Division by a Known
         // Power of 2" in Henry S. Warren, Jr.'s Hacker's Delight.
-        // Note that we wouldn't need to do this adjustment if we could use
-        // Range Analysis to find cases when the value is never negative.
         if (shift > 1) {
             masm.as_mov(ScratchRegister, asr(lhs, 31));
             masm.as_add(ScratchRegister, lhs, lsr(ScratchRegister, 32 - shift));
         } else
             masm.as_add(ScratchRegister, lhs, lsr(lhs, 32 - shift));
 
         // Do the shift.
         masm.as_mov(output, asr(ScratchRegister, shift));
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -848,38 +848,43 @@ CodeGeneratorX86Shared::visitMulNegative
     masm.jmp(ool->rejoin());
     return true;
 }
 
 bool
 CodeGeneratorX86Shared::visitDivPowTwoI(LDivPowTwoI *ins)
 {
     Register lhs = ToRegister(ins->numerator());
-    Register lhsCopy = ToRegister(ins->numeratorCopy());
     mozilla::DebugOnly<Register> output = ToRegister(ins->output());
     int32_t shift = ins->shift();
 
     // We use defineReuseInput so these should always be the same, which is
     // convenient since all of our instructions here are two-address.
     JS_ASSERT(lhs == output);
 
     if (shift != 0) {
-        if (!ins->mir()->isTruncated()) {
+        MDiv *mir = ins->mir();
+        if (!mir->isTruncated()) {
             // If the remainder is != 0, bailout since this must be a double.
             masm.testl(lhs, Imm32(UINT32_MAX >> (32 - shift)));
             if (!bailoutIf(Assembler::NonZero, ins->snapshot()))
                 return false;
         }
 
+        if (!mir->canBeNegativeDividend()) {
+            // Numerator is unsigned, so needs no adjusting. Do the shift.
+            masm.sarl(Imm32(shift), lhs);
+            return true;
+        }
+
         // Adjust the value so that shifting produces a correctly rounded result
         // when the numerator is negative. See 10-1 "Signed Division by a Known
         // Power of 2" in Henry S. Warren, Jr.'s Hacker's Delight.
-        // Note that we wouldn't need to do this adjustment if we could use
-        // Range Analysis to find cases when the value is never negative. We
-        // wouldn't even need the lhsCopy either in that case.
+        Register lhsCopy = ToRegister(ins->numeratorCopy());
+        JS_ASSERT(lhsCopy != lhs);
         if (shift > 1)
             masm.sarl(Imm32(31), lhs);
         masm.shrl(Imm32(32 - shift), lhs);
         masm.addl(lhsCopy, lhs);
 
         // Do the shift.
         masm.sarl(Imm32(shift), lhs);
     }
--- a/js/src/jit/shared/LIR-x86-shared.h
+++ b/js/src/jit/shared/LIR-x86-shared.h
@@ -53,16 +53,22 @@ class LDivPowTwoI : public LBinaryMath<0
 
     LDivPowTwoI(const LAllocation &lhs, const LAllocation &lhsCopy, int32_t shift)
       : shift_(shift)
     {
         setOperand(0, lhs);
         setOperand(1, lhsCopy);
     }
 
+    LDivPowTwoI(const LAllocation &lhs, int32_t shift)
+      : shift_(shift)
+    {
+        setOperand(0, lhs);
+    }
+
     const LAllocation *numerator() {
         return getOperand(0);
     }
     const LAllocation *numeratorCopy() {
         return getOperand(1);
     }
     int32_t shift() const {
         return shift_;
--- a/js/src/jit/shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/shared/Lowering-x86-shared.cpp
@@ -139,17 +139,26 @@ LIRGeneratorX86Shared::lowerDivI(MDiv *d
 
         // Check for division by a positive power of two, which is an easy and
         // important case to optimize. Note that other optimizations are also
         // possible; division by negative powers of two can be optimized in a
         // similar manner as positive powers of two, and division by other
         // constants can be optimized by a reciprocal multiplication technique.
         int32_t shift = FloorLog2(rhs);
         if (rhs > 0 && 1 << shift == rhs) {
-            LDivPowTwoI *lir = new LDivPowTwoI(useRegisterAtStart(div->lhs()), useRegister(div->lhs()), shift);
+            LAllocation lhs = useRegisterAtStart(div->lhs());
+            LDivPowTwoI *lir;
+            if (!div->canBeNegativeDividend()) {
+                // Numerator is unsigned, so does not need adjusting.
+                lir = new LDivPowTwoI(lhs, shift);
+            } else {
+                // Numerator is signed, and needs adjusting, and an extra
+                // lhs copy register is needed.
+                lir = new LDivPowTwoI(lhs, useRegister(div->lhs()), shift);
+            }
             if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
                 return false;
             return defineReuseInput(lir, div, 0);
         }
     }
 
     // Optimize x/x. This is quaint, but it also protects the LDivI code below.
     // Since LDivI requires lhs to be in %eax, and since the register allocator
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -546,18 +546,16 @@ TypeSet::unionSets(TypeSet *a, TypeSet *
 static LifoAlloc *IonAlloc() {
 #ifdef JS_ION
     return jit::GetIonContext()->temp->lifoAlloc();
 #else
     MOZ_CRASH();
 #endif
 }
 
-namespace {
-
 // Superclass of all constraints generated during Ion compilation. These may
 // be allocated off the main thread, using the current Ion context's allocator.
 class CompilerConstraint
 {
   public:
     // Property being queried by the compiler.
     HeapTypeSetKey property;
 
@@ -571,18 +569,16 @@ class CompilerConstraint
         expected(property.maybeTypes() ? property.maybeTypes()->clone(IonAlloc()) : nullptr)
     {}
 
     // Generate the type constraint recording the assumption made by this
     // compilation. Returns true if the assumption originally made still holds.
     virtual bool generateTypeConstraint(JSContext *cx, RecompileInfo recompileInfo) = 0;
 };
 
-} // anonymous namespace
-
 class types::CompilerConstraintList
 {
   public:
     struct FrozenScript
     {
         JSScript *script;
         TemporaryTypeSet *thisTypes;
         TemporaryTypeSet *argTypes;
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -947,16 +947,19 @@ struct TypeObject : gc::BarrieredCell<Ty
      *    There is an exception for properties of global JS objects which
      *    are undefined at the point where the property was (lazily) generated.
      *    In such cases the property type set will remain empty, and the
      *    'undefined' type will only be added after a subsequent assignment or
      *    deletion. After these properties have been assigned a defined value,
      *    the only way they can become undefined again is after such an assign
      *    or deletion.
      *
+     *    There is another exception for array lengths, which are special cased
+     *    by the compiler and VM and are not reflected in property types.
+     *
      * We establish these by using write barriers on calls to setProperty and
      * defineProperty which are on native properties, and on any jitcode which
      * might update the property with a new type.
      */
     Property **propertySet;
 
     /* If this is an interpreted function, the function object. */
     HeapPtrFunction interpretedFunction;
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1451,16 +1451,17 @@ GetBlockChainAtPC(JSContext *cx, JSScrip
             break;
         if (offset <= note->start + note->length)
             blockChain = script->getObject(note->index);
     }
 
     return blockChain;
 }
 
+namespace {
 /*
  * The expression decompiler is invoked by error handling code to produce a
  * string representation of the erroring expression. As it's only a debugging
  * tool, it only supports basic expressions. For anything complicated, it simply
  * puts "(intermediate value)" into the error result.
  *
  * Here's the basic algorithm:
  *
@@ -1760,16 +1761,18 @@ ExpressionDecompiler::getOutput(char **r
     *res = cx->pod_malloc<char>(len + 1);
     if (!*res)
         return false;
     js_memcpy(*res, sprinter.stringAt(0), len);
     (*res)[len] = 0;
     return true;
 }
 
+}  // anonymous namespace
+
 static bool
 FindStartPC(JSContext *cx, ScriptFrameIter &iter, int spindex, int skipStackHits, Value v,
             jsbytecode **valuepc)
 {
     jsbytecode *current = *valuepc;
 
     if (spindex == JSDVG_IGNORE_STACK)
         return true;
--- a/js/src/vm/MemoryMetrics.cpp
+++ b/js/src/vm/MemoryMetrics.cpp
@@ -51,26 +51,38 @@ InefficientNonFlatteningStringHashPolicy
         chars = l->pureChars();
     } else {
         // Slowest hash function evar!
         if (!l->copyNonPureChars(/* tcx */ nullptr, ownedChars))
             MOZ_CRASH("oom");
         chars = ownedChars;
     }
 
-    return mozilla::HashString(chars, l->length());
+    // We include the result of isShort() in the hash.  This is because it is
+    // possible for a particular string (i.e. unique char sequence) to have one
+    // or more copies as short strings and one or more copies as non-short
+    // strings, and treating them separately for the purposes of notable string
+    // detection makes things simpler.  In practice, although such collisions
+    // do happen, they are sufficiently rare that they are unlikely to have a
+    // significant effect on which strings are considered notable.
+    return mozilla::AddToHash(mozilla::HashString(chars, l->length()),
+                              l->isShort());
 }
 
 /* static */ bool
 InefficientNonFlatteningStringHashPolicy::match(const JSString *const &k, const Lookup &l)
 {
     // We can't use js::EqualStrings, because that flattens our strings.
     if (k->length() != l->length())
         return false;
 
+    // Just like in hash(), we must consider isShort() for the two strings.
+    if (k->isShort() != l->isShort())
+        return false;
+
     const jschar *c1;
     ScopedJSFreePtr<jschar> ownedChars1;
     if (k->hasPureChars()) {
         c1 = k->pureChars();
     } else {
         if (!k->copyNonPureChars(/* tcx */ nullptr, ownedChars1))
             MOZ_CRASH("oom");
         c1 = ownedChars1;
@@ -89,21 +101,24 @@ InefficientNonFlatteningStringHashPolicy
     return PodEqual(c1, c2, k->length());
 }
 
 } // namespace js
 
 namespace JS {
 
 NotableStringInfo::NotableStringInfo()
-  : buffer(0)
-{}
+  : buffer(0),
+    length(0)
+{
+}
 
 NotableStringInfo::NotableStringInfo(JSString *str, const StringInfo &info)
-  : StringInfo(info)
+  : StringInfo(info),
+    length(str->length())
 {
     size_t bufferSize = Min(str->length() + 1, size_t(4096));
     buffer = js_pod_malloc<char>(bufferSize);
     if (!buffer) {
         MOZ_CRASH("oom");
     }
 
     const jschar* chars;
@@ -118,17 +133,18 @@ NotableStringInfo::NotableStringInfo(JSS
 
     // We might truncate |str| even if it's much shorter than 4096 chars, if
     // |str| contains unicode chars.  Since this is just for a memory reporter,
     // we don't care.
     PutEscapedString(buffer, bufferSize, chars, str->length(), /* quote */ 0);
 }
 
 NotableStringInfo::NotableStringInfo(NotableStringInfo &&info)
-  : StringInfo(Move(info))
+  : StringInfo(Move(info)),
+    length(info.length)
 {
     buffer = info.buffer;
     info.buffer = nullptr;
 }
 
 NotableStringInfo &NotableStringInfo::operator=(NotableStringInfo &&info)
 {
     MOZ_ASSERT(this != &info, "self-move assignment is prohibited");
@@ -172,16 +188,17 @@ static void
 StatsZoneCallback(JSRuntime *rt, void *data, Zone *zone)
 {
     // Append a new CompartmentStats to the vector.
     RuntimeStats *rtStats = static_cast<StatsClosure *>(data)->rtStats;
 
     // CollectRuntimeStats reserves enough space.
     MOZ_ALWAYS_TRUE(rtStats->zoneStatsVector.growBy(1));
     ZoneStats &zStats = rtStats->zoneStatsVector.back();
+    zStats.initStrings(rt);
     rtStats->initExtraZoneStats(zone, &zStats);
     rtStats->currZoneStats = &zStats;
 
     zone->addSizeOfIncludingThis(rtStats->mallocSizeOf_, &zStats.typePool);
 }
 
 static void
 StatsCompartmentCallback(JSRuntime *rt, void *data, JSCompartment *compartment)
@@ -268,40 +285,41 @@ StatsCellCallback(JSRuntime *rt, void *d
                 cStats->objectsPrivate += opv->sizeOfIncludingThis(iface);
         }
         break;
       }
 
       case JSTRACE_STRING: {
         JSString *str = static_cast<JSString *>(thing);
 
+        bool isShort = str->isShort();
         size_t strCharsSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf_);
-        MOZ_ASSERT_IF(str->isShort(), strCharsSize == 0);
+
 
-        size_t shortStringThingSize  =  str->isShort() ? thingSize : 0;
-        size_t normalStringThingSize = !str->isShort() ? thingSize : 0;
+        if (isShort) {
+            zStats->stringsShortGCHeap += thingSize;
+            MOZ_ASSERT(strCharsSize == 0);
+        } else {
+            zStats->stringsNormalGCHeap += thingSize;
+            zStats->stringsNormalMallocHeap += strCharsSize;
+        }
 
         // This string hashing is expensive.  Its results are unused when doing
         // coarse-grained measurements, and skipping it more than doubles the
         // profile speed for complex pages such as gmail.com.
         if (granularity == FineGrained) {
-            ZoneStats::StringsHashMap::AddPtr p = zStats->strings.lookupForAdd(str);
+            ZoneStats::StringsHashMap::AddPtr p = zStats->strings->lookupForAdd(str);
             if (!p) {
-                JS::StringInfo info(str->length(), shortStringThingSize,
-                                    normalStringThingSize, strCharsSize);
-                zStats->strings.add(p, str, info);
+                JS::StringInfo info(isShort, thingSize, strCharsSize);
+                zStats->strings->add(p, str, info);
             } else {
-                p->value().add(shortStringThingSize, normalStringThingSize, strCharsSize);
+                p->value().add(isShort, thingSize, strCharsSize);
             }
         }
 
-        zStats->stringsShortGCHeap += shortStringThingSize;
-        zStats->stringsNormalGCHeap += normalStringThingSize;
-        zStats->stringsNormalMallocHeap += strCharsSize;
-
         break;
       }
 
       case JSTRACE_SHAPE: {
         Shape *shape = static_cast<Shape *>(thing);
         CompartmentStats *cStats = GetCompartmentStats(shape->compartment());
         if (shape->inDictionary()) {
             cStats->shapesGCHeapDict += thingSize;
@@ -386,42 +404,56 @@ FindNotableStrings(ZoneStats &zStats)
 {
     using namespace JS;
 
     // You should only run FindNotableStrings once per ZoneStats object
     // (although it's not going to break anything if you run it more than once,
     // unless you add to |strings| in the meantime).
     MOZ_ASSERT(zStats.notableStrings.empty());
 
-    for (ZoneStats::StringsHashMap::Range r = zStats.strings.all(); !r.empty(); r.popFront()) {
+    for (ZoneStats::StringsHashMap::Range r = zStats.strings->all(); !r.empty(); r.popFront()) {
 
         JSString *str = r.front().key();
         StringInfo &info = r.front().value();
 
         // If this string is too small, or if we can't grow the notableStrings
         // vector, skip this string.
-        if (info.totalSizeOf() < NotableStringInfo::notableSize() ||
+        if (info.gcHeap + info.mallocHeap < NotableStringInfo::notableSize() ||
             !zStats.notableStrings.growBy(1))
             continue;
 
         zStats.notableStrings.back() = NotableStringInfo(str, info);
 
         // We're moving this string from a non-notable to a notable bucket, so
         // subtract it out of the non-notable tallies.
-        MOZ_ASSERT(zStats.stringsShortGCHeap >= info.shortGCHeap);
-        MOZ_ASSERT(zStats.stringsNormalGCHeap >= info.normalGCHeap);
-        MOZ_ASSERT(zStats.stringsNormalMallocHeap >= info.normalMallocHeap);
-        zStats.stringsShortGCHeap -= info.shortGCHeap;
-        zStats.stringsNormalGCHeap -= info.normalGCHeap;
-        zStats.stringsNormalMallocHeap -= info.normalMallocHeap;
+        if (info.isShort) {
+            MOZ_ASSERT(zStats.stringsShortGCHeap >= info.gcHeap);
+            zStats.stringsShortGCHeap -= info.gcHeap;
+            MOZ_ASSERT(info.mallocHeap == 0);
+        } else {
+            MOZ_ASSERT(zStats.stringsNormalGCHeap >= info.gcHeap);
+            MOZ_ASSERT(zStats.stringsNormalMallocHeap >= info.mallocHeap);
+            zStats.stringsNormalGCHeap -= info.gcHeap;
+            zStats.stringsNormalMallocHeap -= info.mallocHeap;
+        }
     }
+}
 
-    // zStats.strings holds unrooted JSString pointers, which we don't want to
-    // expose out into the dangerous land where we might GC.
-    zStats.strings.clear();
+bool
+ZoneStats::initStrings(JSRuntime *rt)
+{
+    strings = rt->new_<StringsHashMap>();
+    if (!strings)
+        return false;
+    if (!strings->init()) {
+        js_delete(strings);
+        strings = nullptr;
+        return false;
+    }
+    return true;
 }
 
 JS_PUBLIC_API(bool)
 JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *opv)
 {
     if (!rtStats->compartmentStatsVector.reserve(rt->numCompartments))
         return false;
 
@@ -442,27 +474,54 @@ JS::CollectRuntimeStats(JSRuntime *rt, R
     if (!closure.init())
         return false;
     IterateZonesCompartmentsArenasCells(rt, &closure, StatsZoneCallback, StatsCompartmentCallback,
                                         StatsArenaCallback, StatsCellCallback<FineGrained>);
 
     // Take the "explicit/js/runtime/" measurements.
     rt->addSizeOfIncludingThis(rtStats->mallocSizeOf_, &rtStats->runtime);
 
-    for (size_t i = 0; i < rtStats->zoneStatsVector.length(); i++) {
-        ZoneStats &zStats = rtStats->zoneStatsVector[i];
+    ZoneStatsVector &zs = rtStats->zoneStatsVector;
+    ZoneStats &zTotals = rtStats->zTotals;
 
-        rtStats->zTotals.add(zStats);
-
-        // Move any strings which take up more than the sundries threshold
-        // (counting all of their copies together) into notableStrings.
-        FindNotableStrings(zStats);
+    // For each zone:
+    // - sum everything except its strings data into zTotals, and
+    // - find its notable strings.
+    // Also, record which zone had the biggest |strings| hashtable -- to save
+    // time and memory, we will re-use that hashtable to find the notable
+    // strings for zTotals.
+    size_t iMax = 0;
+    for (size_t i = 0; i < zs.length(); i++) {
+        zTotals.addIgnoringStrings(zs[i]);
+        FindNotableStrings(zs[i]);
+        if (zs[i].strings->count() > zs[iMax].strings->count())
+            iMax = i;
     }
 
-    FindNotableStrings(rtStats->zTotals);
+    // Transfer the biggest strings table to zTotals.  We can do this because:
+    // (a) we've found the notable strings for zs[IMax], and so don't need it
+    //     any more for zs, and
+    // (b) zs[iMax].strings contains a subset of the values that will end up in
+    //     zTotals.strings.
+    MOZ_ASSERT(!zTotals.strings);
+    zTotals.strings = zs[iMax].strings;
+    zs[iMax].strings = nullptr;
+
+    // Add the remaining strings hashtables to zTotals, and then get the
+    // notable strings for zTotals.
+    for (size_t i = 0; i < zs.length(); i++) {
+        if (i != iMax) {
+            zTotals.addStrings(zs[i]);
+            js_delete(zs[i].strings);
+            zs[i].strings = nullptr;
+        }
+    }
+    FindNotableStrings(zTotals);
+    js_delete(zTotals.strings);
+    zTotals.strings = nullptr;
 
     for (size_t i = 0; i < rtStats->compartmentStatsVector.length(); i++) {
         CompartmentStats &cStats = rtStats->compartmentStatsVector[i];
         rtStats->cTotals.add(cStats);
     }
 
     rtStats->gcHeapGCThings = rtStats->zTotals.sizeOfLiveGCThings() +
                               rtStats->cTotals.sizeOfLiveGCThings();
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1859,18 +1859,18 @@ ReportZoneStats(const JS::ZoneStats &zSt
         // even more notable strings the next time we open about:memory (unless
         // there's a GC in the meantime), and so on ad infinitum.
         //
         // To avoid cluttering up about:memory like this, we stick notable
         // strings which contain "strings/notable/string(length=" into their own
         // bucket.
 #       define STRING_LENGTH "string(length="
         if (FindInReadable(NS_LITERAL_CSTRING(STRING_LENGTH), notableString)) {
-            stringsNotableAboutMemoryGCHeap += info.totalGCHeapSizeOf();
-            stringsNotableAboutMemoryMallocHeap += info.normalMallocHeap;
+            stringsNotableAboutMemoryGCHeap += info.gcHeap;
+            stringsNotableAboutMemoryMallocHeap += info.mallocHeap;
             continue;
         }
 
         // Escape / to \ before we put notableString into the memory reporter
         // path, because we don't want any forward slashes in the string to
         // count as path separators.
         nsCString escapedString(notableString);
         escapedString.ReplaceSubstring("/", "\\");
@@ -1879,31 +1879,31 @@ ReportZoneStats(const JS::ZoneStats &zSt
 
         nsCString path = pathPrefix +
             nsPrintfCString("strings/notable/" STRING_LENGTH "%d, copies=%d, \"%s\"%s)/",
                             info.length, info.numCopies, escapedString.get(),
                             truncated ? " (truncated)" : "");
 
         REPORT_BYTES2(path + NS_LITERAL_CSTRING("gc-heap"),
             KIND_NONHEAP,
-            info.totalGCHeapSizeOf(),
+            info.gcHeap,
             nsPrintfCString("Memory allocated to hold headers for copies of "
             "the given notable string.  A string is notable if all of its copies "
             "together use more than %d bytes total of JS GC heap and malloc heap "
             "memory.\n\n"
             "These headers may contain the string data itself, if the string "
             "is short enough.  If so, the string won't have any memory reported "
             "under 'string-chars'.",
             JS::NotableStringInfo::notableSize()));
-        gcTotal += info.totalGCHeapSizeOf();
-
-        if (info.normalMallocHeap > 0) {
+        gcTotal += info.gcHeap;
+
+        if (info.mallocHeap > 0) {
             REPORT_BYTES2(path + NS_LITERAL_CSTRING("malloc-heap"),
                 KIND_HEAP,
-                info.normalMallocHeap,
+                info.mallocHeap,
                 nsPrintfCString("Memory allocated on the malloc heap to hold "
                 "string data for copies of the given notable string.  A string is "
                 "notable if all of its copies together use more than %d bytes "
                 "total of JS GC heap and malloc heap memory.",
                 JS::NotableStringInfo::notableSize()));
         }
     }
 
@@ -2392,19 +2392,17 @@ ReportJSRuntimeExplicitTreeStats(const J
 }
 
 
 } // namespace xpc
 
 class JSMainRuntimeCompartmentsReporter MOZ_FINAL : public MemoryMultiReporter
 {
   public:
-    JSMainRuntimeCompartmentsReporter()
-      : MemoryMultiReporter("js-main-runtime-compartments")
-    {}
+    JSMainRuntimeCompartmentsReporter() {}
 
     typedef js::Vector<nsCString, 0, js::SystemAllocPolicy> Paths;
 
     static void CompartmentCallback(JSRuntime *rt, void* data, JSCompartment *c) {
         // silently ignore OOM errors
         Paths *paths = static_cast<Paths *>(data);
         nsCString path;
         GetCompartmentName(c, path, true);
--- a/js/xpconnect/tests/chrome/chrome.ini
+++ b/js/xpconnect/tests/chrome/chrome.ini
@@ -45,16 +45,17 @@ support-files =
 [test_bug801241.xul]
 [test_bug812415.xul]
 [test_bug853283.xul]
 [test_bug853571.xul]
 [test_bug858101.xul]
 [test_bug860494.xul]
 [test_bug866823.xul]
 [test_bug895340.xul]
+[test_bug932906.xul]
 [test_xrayToJS.xul]
 [test_chrometoSource.xul]
 [test_cows.xul]
 [test_documentdomain.xul]
 [test_doublewrappedcompartments.xul]
 [test_evalInSandbox.xul]
 [test_evalInWindow.xul]
 [test_exnstack.xul]
--- a/js/xpconnect/tests/chrome/test_bug361111.xul
+++ b/js/xpconnect/tests/chrome/test_bug361111.xul
@@ -17,12 +17,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
 
     /** Test for Bug 361111 **/
     window.onerror = null;
     SimpleTest.waitForExplicitFinish();
     document.documentElement.setAttribute("onclick", "%");
     is(1, 1, "Good, setting a bogus onclick did not throw.");
-    SimpleTest.finish();
+
+    // Bonus test - make sure that flushPrefEnv is appropriately
+    // called at the end of the test. It would be nice if there were
+    // somewhere in the harness that this could live, but there isn't.
+    SpecialPowers.pushPrefEnv({set: [['testing.some_arbitrary_pref', true]]},
+                              function() { SimpleTest.finish(); });
 
   ]]></script>
 </window>
--- a/js/xpconnect/tests/chrome/test_bug448587.xul
+++ b/js/xpconnect/tests/chrome/test_bug448587.xul
@@ -14,16 +14,22 @@ https://bugzilla.mozilla.org/show_bug.cg
   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=448587"
      target="_blank">Mozilla Bug 448587</a>
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript">
   <![CDATA[
 
+  // Bonus test - collaborate with test_bug361111.xul to make sure that
+  // flushPrefEnv is appropriately called.
+  ok(!SpecialPowers.Services.prefs.prefHasUserValue('testing.some_arbitrary_pref'),
+     "Pref shouldn't carry over from previous test!");
+
+
   /** Test for Bug 448587 **/
   const Cu = Components.utils;
   var sandbox = new Cu.Sandbox("about:blank");
   var fwrapper = Cu.evalInSandbox("function f() {} f", sandbox);
   is(fwrapper.prototype, Cu.evalInSandbox("f.prototype", sandbox),
      "we don't censor .prototype through .wrappedJSObject");
   ]]>
   </script>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_bug932906.xul
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=932906
+-->
+<window title="Mozilla Bug 932906"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=932906"
+     target="_blank">Mozilla Bug 932906</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  const Cu = Components.utils;
+  Cu.import('resource://gre/modules/Services.jsm');
+
+  /** Test for Bug 932906 **/
+  SimpleTest.waitForExplicitFinish();
+
+  function passToContent(shouldThrow) {
+    try {
+      $('ifr').contentWindow.obs = Services.obs;
+      ok(!shouldThrow, "Didn't throw when passing non-DOM XPCWN to content");
+    } catch (e) {
+      ok(shouldThrow, "Threw when passing non-DOM XPCWN to content");
+      ok(/denied/.test(e), "Threw correct exception: " + e);
+    }
+  }
+
+  var gLoadCount = 0;
+  function loaded() {
+    ++gLoadCount;
+    if (gLoadCount == 1)
+      part1();
+    else if (gLoadCount == 2)
+      part2();
+    else
+      ok(false, "Didn't expect three loads");
+  }
+
+  function part1() {
+
+    // Make sure that the pref is what we expect for mochitests.
+    is(Services.prefs.getBoolPref('dom.use_xbl_scopes_for_remote_xul'), true,
+       "Test harness set up like we expect");
+
+
+    // First, test that we can't normally pass non-DOM XPCWNs to content.
+    passToContent(/* shouldThrow = */ true);
+
+    // Now, make sure we _can_ for the remote xul case. We use SpecialPowers
+    // for the pref munging because it cleans up after us.
+    SpecialPowers.pushPrefEnv({set: [['dom.use_xbl_scopes_for_remote_xul', false]]}, function() {
+      $('ifr').contentWindow.location.reload();
+    });
+  }
+
+  function part2() {
+      passToContent(/* shouldThrow = */ false);
+      SimpleTest.finish();
+  }
+
+  ]]>
+  </script>
+  <iframe id="ifr" onload="loaded();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" />
+</window>
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -677,24 +677,29 @@ nsDocumentViewer::InitPresentationStuff(
     // to avoid bogus notifications.
 
     mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
   }
 
   mPresShell->BeginObservingDocument();
 
   // Initialize our view manager
-  nscoord width = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.width;
-  nscoord height = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel() * mBounds.height;
+  int32_t p2a = mPresContext->AppUnitsPerDevPixel();
+  MOZ_ASSERT(p2a == mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel());
+  nscoord width = p2a * mBounds.width;
+  nscoord height = p2a * mBounds.height;
 
   mViewManager->SetWindowDimensions(width, height);
   mPresContext->SetTextZoom(mTextZoom);
   mPresContext->SetFullZoom(mPageZoom);
   mPresContext->SetMinFontSize(mMinFontSize);
 
+  p2a = mPresContext->AppUnitsPerDevPixel();  // zoom may have changed it
+  width = p2a * mBounds.width;
+  height = p2a * mBounds.height;
   if (aDoInitialReflow) {
     nsCOMPtr<nsIPresShell> shellGrip = mPresShell;
     // Initial reflow
     mPresShell->Initialize(width, height);
   } else {
     // Store the visible area so it's available for other callers of
     // Initialize, like nsContentSink::StartLayout.
     mPresContext->SetVisibleArea(nsRect(0, 0, width, height));
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2473,55 +2473,57 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFram
 {
   while (aFrame) {
     AddBoxesForFrame(aFrame, aCallback);
     aFrame = nsLayoutUtils::GetNextContinuationOrSpecialSibling(aFrame);
   }
 }
 
 struct BoxToRect : public nsLayoutUtils::BoxCallback {
-  typedef nsSize (*GetRectFromFrameFun)(nsIFrame*);
-
   nsIFrame* mRelativeTo;
   nsLayoutUtils::RectCallback* mCallback;
   uint32_t mFlags;
-  GetRectFromFrameFun mRectFromFrame;
 
   BoxToRect(nsIFrame* aRelativeTo, nsLayoutUtils::RectCallback* aCallback,
-            uint32_t aFlags, GetRectFromFrameFun aRectFromFrame)
-    : mRelativeTo(aRelativeTo), mCallback(aCallback), mFlags(aFlags),
-      mRectFromFrame(aRectFromFrame) {}
+            uint32_t aFlags)
+    : mRelativeTo(aRelativeTo), mCallback(aCallback), mFlags(aFlags) {}
 
   virtual void AddBox(nsIFrame* aFrame) {
     nsRect r;
     nsIFrame* outer = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(aFrame, &r);
     if (!outer) {
       outer = aFrame;
-      r = nsRect(nsPoint(0, 0), mRectFromFrame(aFrame));
+      switch (mFlags & nsLayoutUtils::RECTS_WHICH_BOX_MASK) {
+        case nsLayoutUtils::RECTS_USE_CONTENT_BOX:
+          r = aFrame->GetContentRectRelativeToSelf();
+          break;
+        case nsLayoutUtils::RECTS_USE_PADDING_BOX:
+          r = aFrame->GetPaddingRectRelativeToSelf();
+          break;
+        case nsLayoutUtils::RECTS_USE_MARGIN_BOX:
+          r = aFrame->GetMarginRectRelativeToSelf();
+          break;
+        default: // Use the border box
+          r = aFrame->GetRectRelativeToSelf();
+      }
     }
     if (mFlags & nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS) {
       r = nsLayoutUtils::TransformFrameRectToAncestor(outer, r, mRelativeTo);
     } else {
       r += outer->GetOffsetTo(mRelativeTo);
     }
     mCallback->AddRect(r);
   }
 };
 
-static nsSize
-GetFrameBorderSize(nsIFrame* aFrame)
-{
-  return aFrame->GetSize();
-}
-
 void
 nsLayoutUtils::GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo,
                                  RectCallback* aCallback, uint32_t aFlags)
 {
-  BoxToRect converter(aRelativeTo, aCallback, aFlags, &GetFrameBorderSize);
+  BoxToRect converter(aRelativeTo, aCallback, aFlags);
   GetAllInFlowBoxes(aFrame, &converter);
 }
 
 nsLayoutUtils::RectAccumulator::RectAccumulator() : mSeenFirstRect(false) {}
 
 void nsLayoutUtils::RectAccumulator::AddRect(const nsRect& aRect) {
   mResultRect.UnionRect(mResultRect, aRect);
   if (!mSeenFirstRect) {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -867,39 +867,51 @@ public:
 
     RectListBuilder(DOMRectList* aList);
     virtual void AddRect(const nsRect& aRect);
   };
 
   static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame);
 
   enum {
-    RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01
+    RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01,
+    // Two bits for specifying which box type to use.
+    // With neither bit set (default), use the border box.
+    RECTS_USE_CONTENT_BOX = 0x02,
+    RECTS_USE_PADDING_BOX = 0x04,
+    RECTS_USE_MARGIN_BOX = 0x06, // both bits set
+    RECTS_WHICH_BOX_MASK = 0x06 // bitmask for these two bits
   };
   /**
-   * Collect all CSS border-boxes associated with aFrame and its
-   * continuations, "drilling down" through outer table frames and
-   * some anonymous blocks since they're not real CSS boxes.
+   * Collect all CSS boxes (content, padding, border, or margin) associated
+   * with aFrame and its continuations, "drilling down" through outer table
+   * frames and some anonymous blocks since they're not real CSS boxes.
    * The boxes are positioned relative to aRelativeTo (taking scrolling
    * into account) and passed to the callback in frame-tree order.
    * If aFrame is null, no boxes are returned.
    * For SVG frames, returns one rectangle, the bounding box.
    * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
    * the boxes into aRelativeTo coordinates, transforms (including CSS
    * and SVG transforms) are taken into account.
+   * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
+   * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
+   * Otherwise (by default), the border box is used.
    */
   static void GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo,
                                 RectCallback* aCallback, uint32_t aFlags = 0);
 
   /**
    * Computes the union of all rects returned by GetAllInFlowRects. If
    * the union is empty, returns the first rect.
    * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
    * the boxes into aRelativeTo coordinates, transforms (including CSS
    * and SVG transforms) are taken into account.
+   * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
+   * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
+   * Otherwise (by default), the border box is used.
    */
   static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo,
                                        uint32_t aFlags = 0);
 
   enum {
     EXCLUDE_BLUR_SHADOWS = 0x01
   };
   /**
--- a/layout/generic/StickyScrollContainer.cpp
+++ b/layout/generic/StickyScrollContainer.cpp
@@ -187,26 +187,35 @@ StickyScrollContainer::ComputeStickyLimi
   nsIFrame* cbFrame = aFrame->GetContainingBlock();
   NS_ASSERTION(cbFrame == scrolledFrame ||
     nsLayoutUtils::IsProperAncestorFrame(scrolledFrame, cbFrame),
     "Scroll frame should be an ancestor of the containing block");
 
   nsRect rect =
     nsLayoutUtils::GetAllInFlowRectsUnion(aFrame, aFrame->GetParent());
 
-  // Containing block limits
+  // Containing block limits for the position of aFrame relative to its parent.
+  // The margin box of the sticky element stays within the content box of the
+  // contaning-block element.
   if (cbFrame != scrolledFrame) {
-    *aContain = nsLayoutUtils::GetAllInFlowRectsUnion(cbFrame, cbFrame);
-    aContain->MoveBy(-aFrame->GetParent()->GetOffsetTo(cbFrame));
-    // FIXME (Bug 920688): GetUsedBorderAndPadding / GetUsedMargin
-    // consider skip-sides, which doesn't quite mesh with the use of
-    // GetAllInFlowRectsUnion here.  This probably needs to do that
-    // computation *inside* the accumuation function over the in-flows.
-    aContain->Deflate(cbFrame->GetUsedBorderAndPadding());
-    aContain->Deflate(aFrame->GetUsedMargin());
+    *aContain = nsLayoutUtils::
+      GetAllInFlowRectsUnion(cbFrame, aFrame->GetParent(),
+                             nsLayoutUtils::RECTS_USE_CONTENT_BOX);
+    nsRect marginRect = nsLayoutUtils::
+      GetAllInFlowRectsUnion(aFrame, aFrame->GetParent(),
+                             nsLayoutUtils::RECTS_USE_MARGIN_BOX);
+
+    // Deflate aContain by the difference between the union of aFrame's
+    // continuations' margin boxes and the union of their border boxes, so that
+    // by keeping aFrame within aContain, we keep the union of the margin boxes
+    // within the containing block's content box.
+    aContain->Deflate(marginRect - rect);
+
+    // Deflate aContain by the border-box size, to form a constraint on the
+    // upper-left corner of aFrame and continuations.
     aContain->Deflate(nsMargin(0, rect.width, rect.height, 0));
   }
 
   nsMargin sfPadding = scrolledFrame->GetUsedPadding();
   nsPoint sfOffset = aFrame->GetParent()->GetOffsetTo(scrolledFrame);
 
   // Top
   if (computedOffsets->top != NS_AUTOOFFSET) {
@@ -241,17 +250,19 @@ StickyScrollContainer::ComputeStickyLimi
        direction == NS_STYLE_DIRECTION_RTL ||
        rect.width <= sfSize.width - computedOffsets->LeftRight())) {
     aStick->SetRightEdge(mScrollPosition.x + sfPadding.left + sfSize.width -
                          computedOffsets->right - rect.width - sfOffset.x);
   }
 
   // These limits are for the bounding box of aFrame's continuations. Convert
   // to limits for aFrame itself.
-  aStick->MoveBy(aFrame->GetPosition() - rect.TopLeft());
+  nsPoint frameOffset = aFrame->GetPosition() - rect.TopLeft();
+  aStick->MoveBy(frameOffset);
+  aContain->MoveBy(frameOffset);
 }
 
 nsPoint
 StickyScrollContainer::ComputePosition(nsIFrame* aFrame) const
 {
   nsRect stick;
   nsRect contain;
   ComputeStickyLimits(aFrame, &stick, &contain);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -988,16 +988,26 @@ nsIFrame::GetPaddingRectRelativeToSelf()
 }
 
 nsRect
 nsIFrame::GetPaddingRect() const
 {
   return GetPaddingRectRelativeToSelf() + GetPosition();
 }
 
+nsRect
+nsIFrame::GetMarginRectRelativeToSelf() const
+{
+  nsMargin m = GetUsedMargin();
+  ApplySkipSides(m);
+  nsRect r(0, 0, mRect.width, mRect.height);
+  r.Inflate(m);
+  return r;
+}
+
 bool
 nsIFrame::IsTransformed() const
 {
   return ((mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
           (StyleDisplay()->HasTransform(this) ||
            IsSVGTransformed() ||
            (mContent &&
             nsLayoutUtils::HasAnimationsForCompositor(mContent,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -876,16 +876,19 @@ public:
    * content area, borders, and padding.
    *
    * Note: moving or sizing the frame does not affect the view's size or
    * position.
    */
   nsRect GetRect() const { return mRect; }
   nsPoint GetPosition() const { return mRect.TopLeft(); }
   nsSize GetSize() const { return mRect.Size(); }
+  nsRect GetRectRelativeToSelf() const {
+    return nsRect(nsPoint(0, 0), mRect.Size());
+  }
 
   /**
    * When we change the size of the frame's border-box rect, we may need to
    * reset the overflow rect if it was previously stored as deltas.
    * (If it is currently a "large" overflow and could be re-packed as deltas,
    * we don't bother as the cost of the allocation has already been paid.)
    */
   void SetRect(const nsRect& aRect) {
@@ -1063,16 +1066,17 @@ public:
   /**
    * Like the frame's rect (see |GetRect|), which is the border rect,
    * other rectangles of the frame, in app units, relative to the parent.
    */
   nsRect GetPaddingRect() const;
   nsRect GetPaddingRectRelativeToSelf() const;
   nsRect GetContentRect() const;
   nsRect GetContentRectRelativeToSelf() const;
+  nsRect GetMarginRectRelativeToSelf() const;
 
   /**
    * The area to paint box-shadows around.  The default is the border rect.
    * (nsFieldSetFrame overrides this).
    */
   virtual nsRect VisualBorderRectRelativeToSelf() const {
     return nsRect(0, 0, mRect.width, mRect.height);
   }
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -34,17 +34,18 @@ fails-if(winWidget) == mfenced-10.html m
 == mi-mathvariant-1.xhtml mi-mathvariant-1-ref.xhtml
 == mi-mathvariant-2.xhtml mi-mathvariant-2-ref.xhtml
 != non-spacing-accent-1.xhtml non-spacing-accent-1-ref.xhtml
 == overbar-width-1.xhtml overbar-width-1-ref.xhtml
 skip-if(B2G) == quotes-1.xhtml quotes-1-ref.xhtml
 != stretchy-underbar-1.xhtml stretchy-underbar-1-ref.xhtml 
 == table-width-1.xhtml table-width-1-ref.xhtml
 == table-width-2.html table-width-2-ref.html
-fails-if(OSX||/^Windows\x20NT\x206\.[12]/.test(http.oscpu)||Android) == table-width-3.html table-width-3-ref.html
+fails-if(OSX||/^Windows\x20NT\x206\.[^0]/.test(http.oscpu)||Android) == table-width-3.html table-width-3-ref.html
+fails-if((OSX&&(OSX<10.8))||/^Windows\x20NT\x206\.[^0]/.test(http.oscpu)||Android) == table-width-4.html table-width-4-ref.html
 == underbar-width-1.xhtml underbar-width-1-ref.xhtml
 == mathml-type-supported.xhtml mathml-type-supported-ref.xml
 == mtable-align-negative-rownumber.html mtable-align-negative-rownumber-ref.html
 != embellished-op-1-1.html embellished-op-1-1-ref.html
 != embellished-op-1-2.html embellished-op-1-2-ref.html
 != embellished-op-1-3.html embellished-op-1-3-ref.html
 != embellished-op-1-4.html embellished-op-1-4-ref.html
 != embellished-op-1-5.html embellished-op-1-5-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/table-width-4-ref.html
@@ -0,0 +1,53 @@
+<!doctype>
+<html>
+  <head>
+    <title>table-width-4</title>
+    <meta charset="utf-8"/>
+    <style type="text/css">
+      html { background-color: grey; }
+      td { border: 1px solid white;
+      padding: 0;
+      background-color: black;
+      color: black; }
+    </style>
+  </head>
+  <body>
+
+    <table>
+      <tr>
+        <td>
+          <math><mphantom><mi>ℓ</mi><mi>i</mi></mphantom></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mphantom><mtext>ℓ</mtext><mi>i</mi></mphantom></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mphantom><mtext style="font-style: italic">ℓ</mtext><mi>i</mi></mphantom></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mphantom><mtext mathvariant="script">l</mtext><mi>i</mi></mphantom></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mphantom><mi mathvariant="script">l</mi><mi>i</mi></mphantom></math>
+        </td>
+      </tr>
+    </table>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/table-width-4.html
@@ -0,0 +1,53 @@
+<!doctype>
+<html>
+  <head>
+    <title>table-width-4</title>
+    <meta charset="utf-8"/>
+    <style type="text/css">
+      html { background-color: grey; }
+      td { border: 1px solid white;
+      padding: 0;
+      background-color: black;
+      color: black; }
+    </style>
+  </head>
+  <body>
+
+    <table>
+      <tr>
+        <td>
+          <math><mi>ℓ</mi><mi>i</mi></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mtext>ℓ</mtext><mi>i</mi></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mtext style="font-style: italic">ℓ</mtext><mi>i</mi></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mtext mathvariant="script">l</mtext><mi>i</mi></math>
+        </td>
+      </tr>
+    </table>
+    <table>
+      <tr>
+        <td>
+          <math><mi mathvariant="script">l</mi><mi>i</mi></math>
+        </td>
+      </tr>
+    </table>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/position-sticky/column-contain-2-ref.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+  <head>
+    <link rel="author" title="Corey Ford" href="mailto:corey@coreyford.name">
+    <style>
+      #scroll {
+        overflow: hidden;
+        height: 200px;
+        line-height: 1;
+      }
+      #columns {
+        -moz-column-count: 2;
+        column-count: 2;
+        -moz-column-rule: 1px solid black;
+        column-rule: 1px solid black;
+        height: 200px;
+        width: 200px;
+      }
+      #contain {
+        padding-bottom: 10px;
+        border-bottom: 10px solid gray;
+      }
+      #fill {
+        height: 370px;
+        background: blue;
+      }
+      #sticky {
+        position: relative;
+        top: 190px;
+        width: 10px;
+        height: 10px;
+        background: black;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="scroll">
+      <div id="columns">
+        <div id="contain">
+          <div id="sticky"></div>
+          <div id="fill"></div>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/position-sticky/column-contain-2.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+  <head>
+    <title>CSS Test: Sticky Positioning - multiframe containing-block element</title>
+    <link rel="author" title="Corey Ford" href="mailto:corey@coreyford.name">
+    <link rel="match" href="column-contain-2-ref.html">
+    <meta name="assert" content="Sticky positioning where the containing-block element has multiple frames and border/padding should stay contained within the union of the content boxes of all frames">
+    <style>
+      #scroll {
+        overflow: hidden;
+        height: 200px;
+        line-height: 1;
+      }
+      #columns {
+        -moz-column-count: 2;
+        column-count: 2;
+        -moz-column-rule: 1px solid black;
+        column-rule: 1px solid black;
+        height: 200px;
+        width: 200px;
+      }
+      #contain {
+        padding-bottom: 10px;
+        border-bottom: 10px solid gray;
+      }
+      #fill {
+        height: 370px;
+        background: blue;
+      }
+      #sticky {
+        position: sticky;
+        top: 195px;
+        width: 10px;
+        height: 10px;
+        background: black;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="scroll">
+      <div id="columns">
+        <div id="contain">
+          <div id="sticky"></div>
+          <div id="fill"></div>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>
--- a/layout/reftests/position-sticky/inline-3-ref.html
+++ b/layout/reftests/position-sticky/inline-3-ref.html
@@ -1,36 +1,30 @@
 <!DOCTYPE html>
 <!-- Any copyright is dedicated to the Public Domain.
    - http://creativecommons.org/publicdomain/zero/1.0/ -->
 <html>
   <head>
-    <link rel="author" title="Corey Ford" href="mailto:cford@mozilla.com">
+    <link rel="author" title="Corey Ford" href="mailto:corey@coreyford.name">
     <link rel="stylesheet" type="text/css" href="ahem.css">
     <style>
       #scroll {
         overflow: hidden;
         height: 200px;
         position: relative;
         font: 10px/1 Ahem;
       }
       #sticky {
         position: absolute;
-        top: 20px;
+        top: 0;
         left: 10px;
       }
       #hidden {
         visibility: hidden;
       }
-      b {
-        display: inline-block;
-        width: 40px;
-        height: 10px;
-        background: black;
-      }
     </style>
   </head>
   <body>
     <div id="scroll">
-      <b></b><span id="sticky"><b id="hidden"></b><b></b><br><b></b></span>
+      test <span id="sticky"><span id="hidden">test </span>test<br>test</span>
     </div>
   </body>
 </html>
--- a/layout/reftests/position-sticky/inline-3.html
+++ b/layout/reftests/position-sticky/inline-3.html
@@ -1,42 +1,34 @@
 <!DOCTYPE html>
 <!-- Any copyright is dedicated to the Public Domain.
    - http://creativecommons.org/publicdomain/zero/1.0/ -->
 <html>
   <head>
     <title>CSS Test: Sticky Positioning - inline with margins</title>
-    <link rel="author" title="Corey Ford" href="mailto:cford@mozilla.com">
+    <link rel="author" title="Corey Ford" href="mailto:corey@coreyford.name">
     <link rel="match" href="inline-3-ref.html">
     <meta name="assert" content="Sticky positioning on inline elements should keep the bounding box of all continuations' margin boxes contained">
     <link rel="stylesheet" type="text/css" href="ahem.css">
     <style>
       #scroll {
         overflow: hidden;
         height: 200px;
         font: 10px/1 Ahem;
       }
       #sticky {
         position: sticky;
-        top: 20px;
         left: 20px;
         margin-right: 10px;
       }
       #contain {
-        width: 90px;
-        font-size: 10px;
-      }
-      b {
-        display: inline-block;
-        width: 40px;
-        height: 10px;
-        background: black;
+        width: 100px;
       }
     </style>
   </head>
   <body>
     <div id="scroll">
       <div id="contain">
-        <b></b><span id="sticky"><b></b><br><b></b></span>
+        test <span id="sticky">test<br>test</span>
       </div>
     </div>
   </body>
 </html>
--- a/layout/reftests/position-sticky/reftest.list
+++ b/layout/reftests/position-sticky/reftest.list
@@ -38,15 +38,16 @@ fuzzy-if(Android,2,3) == stacking-contex
 == left-right-2.html left-right-2-ref.html
 == left-right-3.html left-right-3-ref.html
 fuzzy-if(Android,4,810) == containing-block-1.html containing-block-1-ref.html
 == overconstrained-1.html overconstrained-1-ref.html
 == overconstrained-2.html overconstrained-2-ref.html
 == overconstrained-3.html overconstrained-3-ref.html
 == inline-1.html inline-1-ref.html
 == inline-2.html inline-2-ref.html
-fails == inline-3.html inline-3-ref.html # bug 916302
+fuzzy-if(OSX==10.6||OSX==10.7,64,100) fuzzy-if(OSX==10.8,99,210) == inline-3.html inline-3-ref.html
 fails == column-contain-1a.html column-contain-1-ref.html
 == column-contain-1b.html column-contain-1-ref.html
+== column-contain-2.html column-contain-2-ref.html
 == block-in-inline-1.html block-in-inline-1-ref.html
 fuzzy-if(Android,8,1533) == block-in-inline-2.html block-in-inline-2-ref.html
 fuzzy-if(Android,8,630) fuzzy-if(OSX==10.8,1,11) == block-in-inline-3.html block-in-inline-3-ref.html
 == inner-table-1.html inner-table-1-ref.html
--- a/media/libpng/CHANGES
+++ b/media/libpng/CHANGES
@@ -4632,19 +4632,92 @@ Version 1.6.4rc01 [September 5, 2013]
   No changes.
 
 Version 1.6.4 [September 12, 2013]
   No changes.
 
 Version 1.6.5 [September 14, 2013]
   Removed two stray lines of code from arm/arm_init.c.
 
-Version 1.6.6beta01 [September 16, 2013]
+Version 1.6.6 [September 16, 2013]
   Removed two stray lines of code from arm/arm_init.c, again.
 
+Version 1.6.7beta01 [September 30, 2013]
+  Revised unknown chunk code to correct several bugs in the NO_SAVE_/NO_WRITE
+    combination
+  Allow HANDLE_AS_UNKNOWN to work when other options are configured off. Also
+    fixed the pngminim makefiles to work when $(MAKEFLAGS) contains stuff
+    which terminates the make options (as by default in recent versions of
+    Gentoo).
+  Avoid up-cast warnings in pngvalid.c. On ARM the alignment requirements of
+    png_modifier are greater than that of png_store and as a consequence
+    compilation of pngvalid.c results in a warning about increased alignment
+    requirements because of the bare cast to (png_modifier*). The code is safe,
+    because the pointer is known to point to a stack allocated png_modifier,
+    but this change avoids the warning.
+  Fixed default behavior of ARM_NEON_API. If the ARM NEON API option was
+    compiled without the CHECK option it defaulted to on, not off.
+  Check user callback behavior in pngunknown.c. Previous versions compiled
+    if SAVE_UNKNOWN was not available but did nothing since the callback
+    was never implemented.
+  Merged pngunknown.c with 1.7 version and back ported 1.7 improvements/fixes
+
+Version 1.6.7beta02 [October 12, 2013]
+  Made changes for compatibility with automake 1.14:
+    1) Added the 'compile' program to the list of programs that must be cleaned
+       in autogen.sh
+    2) Added 'subdir-objects' which causes .c files in sub-directories to be
+       compiled such that the corresponding .o files are also in the
+       sub-directory.  This is because automake 1.14 warns that the
+       current behavior of compiling to the top level directory may be removed
+       in the future.
+    3) Updated dependencies on pnglibconf.h to match the new .o locations and
+       added all the files in contrib/libtests and contrib/tools that depend
+       on pnglibconf.h
+    4) Added 'BUILD_SOURCES = pnglibconf.h'; this is the automake recommended
+       way of handling the dependencies of sources that are machine generated;
+       unfortunately it only works if the user does 'make all' or 'make check',
+       so the dependencies (3) are still required.
+  Cleaned up (char*) casts of zlib messages. The latest version of the Intel C
+    compiler complains about casting a string literal as (char*), so copied the
+    treatment of z_const from the library code into pngfix.c
+  Simplified error message code in pngunknown. The simplification has the
+    useful side effect of avoiding a bogus warning generated by the latest
+    version of the Intel C compiler (it objects to
+    condition ? string-literal : string-literal).
+  Make autogen.sh work with automake 1.13 as well as 1.14. Do this by always
+    removing the 1.14 'compile' script but never checking for it.
+
+Version 1.6.7beta03 [October 19, 2013]
+  Added ARMv8 support (James Yu <james.yu at linaro.org>).  Added file
+    arm/filter_neon_intrinsics.c; enable with -mfpu=neon.
+  Revised pngvalid to generate size images with as many filters as it can
+    manage, limited by the number of rows.
+  Cleaned up ARM NEON compilation handling. The tests are now in pngpriv.h
+    and detect the broken GCC compilers.
+
+Version 1.6.7beta04 [October 26, 2013]
+  Allow clang derived from older GCC versions to use ARM intrinsics. This
+    causes all clang builds that use -mfpu=neon to use the intrinsics code,
+    not the assembler code.  This has only been tested on iOS 7. It may be
+    necessary to exclude some earlier clang versions but this seems unlikely.
+  Changed NEON implementation selection mechanism. This allows assembler
+    or intrinsics to be turned on at compile time during the build by defining
+    PNG_ARM_NEON_IMPLEMENTATION to the correct value (2 or 1).  This macro
+    is undefined by default and the build type is selected in pngpriv.h.
+
+Version 1.6.7rc01 [November 2, 2013]
+  No changes.
+
+Version 1.6.7rc02 [November 7, 2013]
+  Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char
+    checking macros take an unsigned char argument, not a signed char.
+
+Version 1.6.7 [November 14, 2013]
+
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
 to subscribe)
 or to glennrp at users.sourceforge.net
 
 Glenn R-P
 #endif
--- a/media/libpng/LICENSE
+++ b/media/libpng/LICENSE
@@ -5,17 +5,17 @@ included in the libpng distribution, the
 
 COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
 
 If you modify libpng you may insert additional notices immediately following
 this sentence.
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.6.6, September 16, 2013, are
+libpng versions 1.2.6, August 15, 2004, through 1.6.7, November 14, 2013, are
 Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
 distributed according to the same disclaimer and license as libpng-1.2.5
 with the following individual added to the list of Contributing Authors
 
    Cosmin Truta
 
 libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
 Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
@@ -103,9 +103,9 @@ boxes and the like:
 Also, the PNG logo (in PNG format, of course) is supplied in the
 files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
 
 Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
 certification mark of the Open Source Initiative.
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-September 16, 2013
+November 14, 2013
--- a/media/libpng/MOZCHANGES
+++ b/media/libpng/MOZCHANGES
@@ -1,11 +1,13 @@
 
 Changes made to pristine png source by mozilla.org developers.
 
+2013/11/17  -- Synced with libpng-1.6.7 (bug #938740).
+
 2013/09/21  -- Synced with libpng-1.6.6 (bug #886499).
 
 2013/07/17  -- Synced with libpng-1.5.17 (bug #886499).
 
 2013/06/06  -- Synced with libpng-1.5.16 (bug #873001).
 
 2013/04/11  -- Synced with libpng-1.5.15 (bug #858578).
 
--- a/media/libpng/README
+++ b/media/libpng/README
@@ -1,9 +1,9 @@
-README for libpng version 1.6.6 - September 16, 2013 (shared library 16.0)
+README for libpng version 1.6.7 - November 14, 2013 (shared library 16.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
 
 Libpng comes in several distribution formats.  Get libpng-*.tar.gz or
 libpng-*.tar.xz or if you want UNIX-style line endings in the text files,
 or lpng*.7z or lpng*.zip if you want DOS-style line endings.
 
--- a/media/libpng/apng.patch
+++ b/media/libpng/apng.patch
@@ -273,28 +273,28 @@ Index: pngget.c
 +    return 0;
 +}
 +#endif /* PNG_APNG_SUPPORTED */
  #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
 Index: png.h
 ===================================================================
 --- png.h
 +++ png.h
-@@ -443,6 +443,10 @@
+@@ -448,6 +448,10 @@
  #   include "pnglibconf.h"
  #endif
  
 +#define PNG_APNG_SUPPORTED
 +#define PNG_READ_APNG_SUPPORTED
 +#define PNG_WRITE_APNG_SUPPORTED
 +
  #ifndef PNG_VERSION_INFO_ONLY
     /* Machine specific configuration. */
  #  include "pngconf.h"
-@@ -533,6 +537,17 @@
+@@ -538,6 +542,17 @@
   * See pngconf.h for base types that vary by machine/system
   */
  
 +#ifdef PNG_APNG_SUPPORTED
 +/* dispose_op flags from inside fcTL */
 +#define PNG_DISPOSE_OP_NONE        0x00
 +#define PNG_DISPOSE_OP_BACKGROUND  0x01
 +#define PNG_DISPOSE_OP_PREVIOUS    0x02
@@ -302,39 +302,39 @@ Index: png.h
 +/* blend_op flags from inside fcTL */
 +#define PNG_BLEND_OP_SOURCE        0x00
 +#define PNG_BLEND_OP_OVER          0x01
 +#endif /* PNG_APNG_SUPPORTED */
 +
  /* This triggers a compiler error in png.c, if png.c and png.h
   * do not agree upon the version number.
   */
-@@ -852,6 +867,10 @@
+@@ -858,6 +873,10 @@
  #define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
  #define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
  #define PNG_INFO_IDAT 0x8000   /* ESR, 1.0.6 */
 +#ifdef PNG_APNG_SUPPORTED
 +#define PNG_INFO_acTL 0x10000
 +#define PNG_INFO_fcTL 0x20000
 +#endif
  
  /* This is used for the transformation routines, as some of them
   * change these values for the row.  It also should enable using
-@@ -889,6 +908,10 @@
+@@ -895,6 +914,10 @@
  #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
  typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
 +#ifdef PNG_APNG_SUPPORTED
 +typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp,
 +    png_uint_32));
 +#endif
  
  /* The following callback receives png_uint_32 row_number, int pass for the
   * png_bytep data of the row.  When transforming an interlaced image the
-@@ -3292,6 +3315,75 @@
+@@ -3298,6 +3321,75 @@
   *  END OF HARDWARE OPTIONS
   ******************************************************************************/
  
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_EXPORT(245, png_uint_32, png_get_acTL, (png_structp png_ptr,
 +   png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
 +
 +PNG_EXPORT(246, png_uint_32, png_set_acTL, (png_structp png_ptr,
@@ -400,61 +400,61 @@ Index: png.h
 +PNG_EXPORT(264, void, png_write_frame_tail, (png_structp png_ptr,
 +   png_infop info_ptr));
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +#endif /* PNG_APNG_SUPPORTED */
 +
  /* Maintainer: Put new public prototypes here ^, in libpng.3, and project
   * defs, scripts/pnglibconf.h, and scripts/pnglibconf.h.prebuilt
   */
-@@ -3301,7 +3393,11 @@
+@@ -3307,7 +3399,11 @@
   * scripts/symbols.def as well.
   */
  #ifdef PNG_EXPORT_LAST_ORDINAL
 +#ifdef PNG_APNG_SUPPORTED
 +  PNG_EXPORT_LAST_ORDINAL(264);
 +#else
    PNG_EXPORT_LAST_ORDINAL(244);
 +#endif /* PNG_APNG_SUPPORTED */
  #endif
  
  #ifdef __cplusplus
 Index: pngpriv.h
 ===================================================================
 --- pngpriv.h
 +++ pngpriv.h
-@@ -502,6 +502,10 @@
+@@ -544,6 +544,10 @@
  #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
                     /*             0x4000 (unused) */
  #define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */
 +#ifdef PNG_APNG_SUPPORTED
 +#define PNG_HAVE_acTL            0x10000
 +#define PNG_HAVE_fcTL            0x20000
 +#endif
  
  /* Flags for the transformations the PNG library does on the image data */
  #define PNG_BGR                 0x0001
-@@ -723,6 +727,16 @@
+@@ -765,6 +769,16 @@
  #define png_tRNS PNG_U32(116,  82,  78,  83)
  #define png_zTXt PNG_U32(122,  84,  88, 116)
  
 +#ifdef PNG_APNG_SUPPORTED
 +#define png_acTL PNG_U32( 97,  99,  84,  76)
 +#define png_fcTL PNG_U32(102,  99,  84,  76)
 +#define png_fdAT PNG_U32(102, 100,  65,  84)
 +
 +/* For png_struct.apng_flags: */
 +#define PNG_FIRST_FRAME_HIDDEN       0x0001
 +#define PNG_APNG_APP                 0x0002
 +#endif
 +
  /* The following will work on (signed char*) strings, whereas the get_uint_32
   * macro will fail on top-bit-set values because of the sign extension.
   */
-@@ -1516,6 +1530,49 @@
+@@ -1559,6 +1573,49 @@
      png_bytep row),PNG_EMPTY);
  #endif
  
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_INTERNAL_FUNCTION(void,png_ensure_fcTL_is_valid,(png_structp png_ptr,
 +   png_uint_32 width, png_uint_32 height,
 +   png_uint_32 x_offset, png_uint_32 y_offset,
 +   png_uint_16 delay_num, png_uint_16 delay_den,
@@ -1246,17 +1246,17 @@ Index: pngrutil.c
 +
 +    png_ptr->next_seq_num++;
 +}
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
  #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
  static int
-@@ -3952,6 +4130,38 @@
+@@ -3953,6 +4131,38 @@
           uInt avail_in;
           png_bytep buffer;
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_uint_32 bytes_to_skip = 0;
 +
 +         while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
 +         {
@@ -1285,35 +1285,35 @@ Index: pngrutil.c
 +
 +               png_ptr->idat_size -= 4;
 +            }
 +         }
 +#else
           while (png_ptr->idat_size == 0)
           {
              png_crc_finish(png_ptr, 0);
-@@ -3963,6 +4173,7 @@
+@@ -3964,6 +4174,7 @@
              if (png_ptr->chunk_name != png_IDAT)
                 png_error(png_ptr, "Not enough image data");
           }
 +#endif /* PNG_READ_APNG_SUPPORTED */
  
           avail_in = png_ptr->IDAT_read_size;
  
-@@ -4026,6 +4237,9 @@
+@@ -4027,6 +4238,9 @@
  
           png_ptr->mode |= PNG_AFTER_IDAT;
           png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_ptr->num_frames_read++;
 +#endif
  
           if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
              png_chunk_benign_error(png_ptr, "Extra compressed data");
-@@ -4471,4 +4685,80 @@
+@@ -4472,4 +4686,80 @@
  
     png_ptr->flags |= PNG_FLAG_ROW_INIT;
  }
 +
 +#ifdef PNG_READ_APNG_SUPPORTED
 +/* This function is to be called after the main IDAT set has been read and
 + * before a new IDAT is read. It resets some parts of png_ptr
 + * to make them usable by the read functions again */
--- a/media/libpng/arm/arm_init.c
+++ b/media/libpng/arm/arm_init.c
@@ -1,14 +1,14 @@
 
 /* arm_init.c - NEON optimised filter functions
  *
  * Copyright (c) 2013 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.5 [September 16, 2013]
+ * Last changed in libpng 1.6.6 [September 16, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
  * called.
  */
@@ -149,16 +149,26 @@ png_have_neon(png_structp png_ptr)
 
 #ifndef PNG_ALIGNED_MEMORY_SUPPORTED
 #  error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
 #endif
 
 void
 png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
 {
+   /* The switch statement is compiled in for ARM_NEON_API, the call to
+    * png_have_neon is compiled in for ARM_NEON_CHECK.  If both are defined
+    * the check is only performed if the API has not set the NEON option on
+    * or off explicitly.  In this case the check controls what happens.
+    *
+    * If the CHECK is not compiled in and the option is UNSET the behavior prior
+    * to 1.6.7 was to use the NEON code - this was a bug caused by having the
+    * wrong order of the 'ON' and 'default' cases.  UNSET now defaults to OFF,
+    * as documented in png.h
+    */
 #ifdef PNG_ARM_NEON_API_SUPPORTED
    switch ((pp->options >> PNG_ARM_NEON) & 3)
    {
       case PNG_OPTION_UNSET:
          /* Allow the run-time check to execute if it has been enabled -
           * thus both API and CHECK can be turned on.  If it isn't supported
           * this case will fall through to the 'default' below, which just
           * returns.
@@ -173,23 +183,24 @@ png_init_filter_functions_neon(png_struc
 
             if (no_neon)
                return;
          }
 #ifdef PNG_ARM_NEON_API_SUPPORTED
          break;
 #endif
 #endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
+
 #ifdef PNG_ARM_NEON_API_SUPPORTED
+      default: /* OFF or INVALID */
+         return;
+
       case PNG_OPTION_ON:
          /* Option turned on */
          break;
-
-      default: /* OFF or INVALID */
-         return;
    }
 #endif
 
    /* IMPORTANT: any new external functions used here must be declared using
     * PNG_INTERNAL_FUNCTION in ../pngpriv.h.  This is required so that the
     * 'prefix' option to configure works:
     *
     *    ./configure --with-libpng-prefix=foobar_
--- a/media/libpng/arm/filter_neon.S
+++ b/media/libpng/arm/filter_neon.S
@@ -1,30 +1,37 @@
 
 /* filter_neon.S - NEON optimised filter functions
  *
  * Copyright (c) 2013 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.5.17 [July 18, 2013]
+ * Last changed in libpng 1.6.7 [November 14, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 /* This is required to get the symbol renames, which are #defines, and also
  * includes the definition (or not) of PNG_ARM_NEON_OPT.
  */
 #define PNG_VERSION_INFO_ONLY
 #include "../pngpriv.h"
 
 #if defined(__linux__) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 #endif
 
+/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
+ * ARM64).  The code in arm/filter_neon_intrinsics.c supports ARM64, however it
+ * only works if -mfpu=neon is specified on the GCC command line.  See pngpriv.h
+ * for the logic which sets PNG_USE_ARM_NEON_ASM:
+ */
+#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
+
 #ifdef PNG_READ_SUPPORTED
 #if PNG_ARM_NEON_OPT > 0
 
 #ifdef __ELF__
 #   define ELF
 #else
 #   define ELF @
 #endif
@@ -230,8 +237,9 @@ 1:
         vst1.32         {d3[0]},  [r1], r4
         subs            r12, r12, #12
         bgt             1b
 
         pop             {r4,pc}
 endfunc
 #endif /* PNG_ARM_NEON_OPT > 0 */
 #endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
new file mode 100644
--- /dev/null
+++ b/media/libpng/arm/filter_neon_intrinsics.c
@@ -0,0 +1,372 @@
+
+/* filter_neon_intrinsics.c - NEON optimised filter functions
+ *
+ * Copyright (c) 2013 Glenn Randers-Pehrson
+ * Written by James Yu <james.yu at linaro.org>, October 2013.
+ * Based on filter_neon.S, written by Mans Rullgard, 2011.
+ *
+ * Last changed in libpng 1.6.7 [November 14, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+/* This code requires -mfpu=neon on the command line: */
+#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code */
+
+#include <arm_neon.h>
+
+/* libpng row pointers are not necessarily aligned to any particular boundary,
+ * however this code will only work with appropriate alignment.  arm/arm_init.c
+ * checks for this (and will not compile unless it is done), this code uses
+ * variants of png_aligncast to avoid compiler warnings.
+ */
+#define png_ptr(type,pointer) png_aligncast(type *,pointer)
+#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
+
+/* The following relies on a variable 'temp_pointer' being declared with type
+ * 'type'.  This is written this way just to hide the GCC strict aliasing
+ * warning; note that the code is safe because there never is an alias between
+ * the input and output pointers.
+ */
+#define png_ldr(type,pointer)\
+   (temp_pointer = png_ptr(type,pointer), *temp_pointer)
+
+#ifdef PNG_READ_SUPPORTED
+#if PNG_ARM_NEON_OPT > 0
+
+void
+png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+   png_const_bytep pp = prev_row;
+
+   for (; rp < rp_stop; rp += 16, pp += 16)
+   {
+      uint8x16_t qrp, qpp;
+
+      qrp = vld1q_u8(rp);
+      qpp = vld1q_u8(pp);
+      qrp = vaddq_u8(qrp, qpp);
+      vst1q_u8(rp, qrp);
+   }
+}
+
+void
+png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x16_t vtmp = vld1q_u8(rp);
+   uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
+   uint8x8x2_t vrp = *vrpt;
+
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   for (; rp < rp_stop;)
+   {
+      uint8x8_t vtmp1, vtmp2;
+      uint32x2_t *temp_pointer;
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+      vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+      vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
+      vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
+
+      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+      vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
+      vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
+
+      vtmp = vld1q_u8(rp + 12);
+      vrpt = png_ptr(uint8x8x2_t, &vtmp);
+      vrp = *vrpt;
+
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+      rp += 3;
+   }
+
+   PNG_UNUSED(prev_row)
+}
+
+void
+png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   for (; rp < rp_stop; rp += 16)
+   {
+      uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
+      uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
+      uint8x8x4_t vrp = *vrpt;
+      uint32x2x4_t *temp_pointer;
+
+      vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+      vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
+      vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
+      vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
+      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+   }
+
+   PNG_UNUSED(prev_row)
+}
+
+void
+png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x16_t vtmp;
+   uint8x8x2_t *vrpt;
+   uint8x8x2_t vrp;
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   vtmp = vld1q_u8(rp);
+   vrpt = png_ptr(uint8x8x2_t,&vtmp);
+   vrp = *vrpt;
+
+   for (; rp < rp_stop; pp += 12)
+   {
+      uint8x8_t vtmp1, vtmp2, vtmp3;
+
+      uint8x8x2_t *vppt;
+      uint8x8x2_t vpp;
+
+      uint32x2_t *temp_pointer;
+
+      vtmp = vld1q_u8(pp);
+      vppt = png_ptr(uint8x8x2_t,&vtmp);
+      vpp = *vppt;
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+      vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+      vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
+      vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
+      vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
+      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+
+      vtmp = vld1q_u8(rp + 12);
+      vrpt = png_ptr(uint8x8x2_t,&vtmp);
+      vrp = *vrpt;
+
+      vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
+      vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
+
+      vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+      vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
+      vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+      rp += 3;
+   }
+}
+
+void
+png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+   png_const_bytep pp = prev_row;
+
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   for (; rp < rp_stop; rp += 16, pp += 16)
+   {
+      uint32x2x4_t vtmp;
+      uint8x8x4_t *vrpt, *vppt;
+      uint8x8x4_t vrp, vpp;
+      uint32x2x4_t *temp_pointer;
+
+      vtmp = vld4_u32(png_ptr(uint32_t,rp));
+      vrpt = png_ptr(uint8x8x4_t,&vtmp);
+      vrp = *vrpt;
+      vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+      vppt = png_ptr(uint8x8x4_t,&vtmp);
+      vpp = *vppt;
+
+      vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+      vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
+      vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+      vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
+      vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+      vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
+      vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+   }
+}
+
+static uint8x8_t
+paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)
+{
+   uint8x8_t d, e;
+   uint16x8_t p1, pa, pb, pc;
+
+   p1 = vaddl_u8(a, b); /* a + b */
+   pc = vaddl_u8(c, c); /* c * 2 */
+   pa = vabdl_u8(b, c); /* pa */
+   pb = vabdl_u8(a, c); /* pb */
+   pc = vabdq_u16(p1, pc); /* pc */
+
+   p1 = vcleq_u16(pa, pb); /* pa <= pb */
+   pa = vcleq_u16(pa, pc); /* pa <= pc */
+   pb = vcleq_u16(pb, pc); /* pb <= pc */
+
+   p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
+
+   d = vmovn_u16(pb);
+   e = vmovn_u16(p1);
+
+   d = vbsl_u8(d, b, c);
+   e = vbsl_u8(e, a, d);
+
+   return e;
+}
+
+void
+png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x16_t vtmp;
+   uint8x8x2_t *vrpt;
+   uint8x8x2_t vrp;
+   uint8x8_t vlast = vdup_n_u8(0);
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   vtmp = vld1q_u8(rp);
+   vrpt = png_ptr(uint8x8x2_t,&vtmp);
+   vrp = *vrpt;
+
+   for (; rp < rp_stop; pp += 12)
+   {
+      uint8x8x2_t *vppt;
+      uint8x8x2_t vpp;
+      uint8x8_t vtmp1, vtmp2, vtmp3;
+      uint32x2_t *temp_pointer;
+
+      vtmp = vld1q_u8(pp);
+      vppt = png_ptr(uint8x8x2_t,&vtmp);
+      vpp = *vppt;
+
+      vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+      vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);
+      vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
+      vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
+      vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);
+      vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
+
+      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+      vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+      vtmp = vld1q_u8(rp + 12);
+      vrpt = png_ptr(uint8x8x2_t,&vtmp);
+      vrp = *vrpt;
+
+      vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);
+      vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+      vlast = vtmp2;
+
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+      rp += 3;
+   }
+}
+
+void
+png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+   png_const_bytep pp = prev_row;
+
+   uint8x8_t vlast = vdup_n_u8(0);
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   for (; rp < rp_stop; rp += 16, pp += 16)
+   {
+      uint32x2x4_t vtmp;
+      uint8x8x4_t *vrpt, *vppt;
+      uint8x8x4_t vrp, vpp;
+      uint32x2x4_t *temp_pointer;
+
+      vtmp = vld4_u32(png_ptr(uint32_t,rp));
+      vrpt = png_ptr(uint8x8x4_t,&vtmp);
+      vrp = *vrpt;
+      vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+      vppt = png_ptr(uint8x8x4_t,&vtmp);
+      vpp = *vppt;
+
+      vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+      vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);
+      vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+      vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);
+      vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+      vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);
+      vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+      vlast = vpp.val[3];
+
+      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+   }
+}
+
+#endif /* PNG_ARM_NEON_OPT > 0 */
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */
--- a/media/libpng/libpng-manual.txt
+++ b/media/libpng/libpng-manual.txt
@@ -1,22 +1,22 @@
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.6 - September 16, 2013
+ libpng version 1.6.7 - November 14, 2013
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
  Copyright (c) 1998-2013 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
  and license in png.h
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.6 - September 16, 2013
+ libpng versions 0.97, January 1998, through 1.6.7 - November 14, 2013
  Updated and distributed by Glenn Randers-Pehrson
  Copyright (c) 1998-2013 Glenn Randers-Pehrson
 
  libpng 1.0 beta 6  version 0.96 May 28, 1997
  Updated and distributed by Andreas Dilger
  Copyright (c) 1996, 1997 Andreas Dilger
 
  libpng 1.0 beta 2 - version 0.88  January 26, 1996
@@ -5010,29 +5010,32 @@ The following have been removed:
 
 The signatures of many exported functions were changed, such that
    png_structp became png_structrp or png_const_structrp
    png_infop became png_inforp or png_const_inforp
 where "rp" indicates a "restricted pointer".
 
 Error detection in some chunks has improved; in particular the iCCP chunk
 reader now does pretty complete validation of the basic format.  Some bad
-profiles that were previously accepted are now rejected, in particular the
-very old broken Microsoft/HP sRGB profile.  The PNG spec requirement that
-only grayscale profiles may appear in images with color type 0 or 4 and that
-even if the image only contains gray pixels, only RGB profiles may appear
+profiles that were previously accepted are now accepted with a warning or
+rejected, depending upon the png_set_benign_errors() setting, in particular the
+very old broken Microsoft/HP 3144-byte sRGB profile.  The PNG spec requirement
+that only grayscale profiles may appear in images with color type 0 or 4 and
+that even if the image only contains gray pixels, only RGB profiles may appear
 in images with color type 2, 3, or 6, is now enforced.  The sRGB chunk
 is allowed to appear in images with any color type.
 
 Prior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained
 an empty language field or an empty translated keyword.  Both of these
 are allowed by the PNG specification, so these warnings are no longer issued.
 
 The library now issues an error if the application attempts to set a
-transform after it calls png_read_update_info().
+transform after it calls png_read_update_info() or if it attempts to call
+both png_read_update_info() and png_start_read_image() or to call either
+of them more than once.
 
 The default condition for benign_errors is now to treat benign errors as
 warnings while reading and as errors while writing.
 
 The library now issues a warning if both background processing and RGB to
 gray are used when gamma correction happens. As with previous versions of
 the library the results are numerically very incorrect in this case.
 
@@ -5224,23 +5227,23 @@ for a few type names that we inherit fro
 We do not use the TAB character for indentation in the C sources.
 
 Lines do not exceed 80 characters.
 
 Other rules can be inferred by inspecting the libpng source.
 
 XVI. Y2K Compliance in libpng
 
-September 16, 2013
+November 14, 2013
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.6 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.7 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 
 Libpng only has two year fields.  One is a 2-byte unsigned integer
 that will hold years up to 65535.  The other, which is deprecated,
 holds the date in text format, and will hold years up to 9999.
 
 The integer is
     "png_uint_16 year" in png_time_struct.
--- a/media/libpng/moz.build
+++ b/media/libpng/moz.build
@@ -19,27 +19,21 @@ UNIFIED_SOURCES += [
     'pngread.c',
     'pngrio.c',
     'pngrtran.c',
     'pngrutil.c',
     'pngset.c',
     'pngtrans.c',
     'pngwio.c',
     'pngwrite.c',
-    'pngwtran.c',
     'pngwutil.c',
 ]
 
 if CONFIG['MOZ_PNG_ARM_NEON']:
-    DIRS += [
-        'arm',
-    ]
-
-if CONFIG['MOZ_PNG_ARM_NEON']:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'arm/arm_init.c'
     ]
 
 if CONFIG['MOZ_PNG_ARM_NEON']:
     SOURCES += [
         'arm/filter_neon.S'
     ]
 
--- a/media/libpng/mozpngconf.h
+++ b/media/libpng/mozpngconf.h
@@ -17,17 +17,16 @@
 #define PNG_WEIGHT_SHIFT 8
 #define PNG_ZBUF_SIZE 8192
 #define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
 #define PNG_INFLATE_BUF_SIZE 1024
 #define PNG_Z_DEFAULT_COMPRESSION (-1)
 #define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
 #define PNG_Z_DEFAULT_STRATEGY 1
 
-
 #ifdef _MSC_VER
 /* The PNG_PEDANTIC_WARNINGS (attributes) fail to build with some MSC
  * compilers; we'll play it safe and disable them for all MSC compilers.
  */
 #define PNG_NO_PEDANTIC_WARNINGS
 #endif
 
 #undef PNG_ARM_NEON_OPT /* This may have been defined in pngpriv.h */
@@ -49,20 +48,20 @@
 #define PNG_READ_GAMMA_SUPPORTED
 #define PNG_READ_GRAY_TO_RGB_SUPPORTED
 #define PNG_READ_INTERLACING_SUPPORTED
 #define PNG_READ_SCALE_16_TO_8_SUPPORTED
 #define PNG_READ_TRANSFORMS_SUPPORTED
 
 /* necessary for boot animation code */
 #ifdef MOZ_WIDGET_GONK
-#define PNG_EASY_ACCESS_SUPPORTED
 #define PNG_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#define PNG_EASY_ACCESS_SUPPORTED
 #define PNG_READ_BGR_SUPPORTED
 #define PNG_BENIGN_READ_ERRORS_SUPPORTED
 #define PNG_READ_EXPAND_SUPPORTED
 #define PNG_READ_FILLER_SUPPORTED
 #define PNG_READ_GRAY_TO_RGB_SUPPORTED
 #define PNG_READ_STRIP_16_TO_8_SUPPORTED
 #define PNG_READ_STRIP_ALPHA_SUPPORTED
 #define PNG_READ_USER_TRANSFORM_SUPPORTED
@@ -486,16 +485,17 @@
 #define png_read_reinit                 MOZ_APNG_read_reinit
 #define png_read_reset                  MOZ_APNG_read_reset
 #define png_set_acTL                    MOZ_APNG_set_acTL
 #define png_set_first_frame_is_hidden   MOZ_APNG_set_first_frame_is_hidden
 #define png_set_next_frame_fcTL         MOZ_APNG_set_next_frame_fcTL
 #define png_set_progressive_frame_fn    MOZ_APNG_set_prog_frame_fn
 #define png_write_acTL                  MOZ_APNG_write_acTL
 #define png_write_fcTL                  MOZ_APNG_write_fcTL
+#define png_write_fdAT                  MOZ_APNG_write_fdAT
 #define png_write_frame_head            MOZ_APNG_write_frame_head
 #define png_write_frame_tail            MOZ_APNG_write_frame_tail
 #define png_write_reinit                MOZ_APNG_write_reinit
 #define png_write_reset                 MOZ_APNG_write_reset
 
 /* libpng-1.4.x additions */
 #define png_do_quantize                 MOZ_PNG_do_quantize
 #define png_get_chunk_cache_max         MOZ_PNG_get_chunk_cache_max
@@ -598,16 +598,44 @@
 #define png_XYZ_from_xy                           MOZ_PNG_XYZ_from_xy
 #define png_XYZ_from_xy_checked                   MOZ_PNG_XYZ_from_xy_checked
 #define png_zlib_claim                            MOZ_PNG_zlib_claim
 #define png_zlib_release                          MOZ_PNG_zlib_release
 #define convert_gamma_value                       MOZ_convert_gamma_value
 #define ppi_from_ppm                              MOZ_ppi_from_ppm
 #define translate_gamma_flags                     MOZ_translate_gamma_flags
 
+/* libpng-1.6.x additions */
+#define png_app_error                             MOZ_PNG_app_err
+#define png_app_warning                           MOZ_PNG_app_warn
+#define png_benign_error                          MOZ_PNG_benign_err
+#define png_chunk_benign_error                    MOZ_PNG_chunk_benign_err
+#define png_chunk_report                          MOZ_PNG_chunk_report
+#define png_colorspace_set_ICC                    MOZ_PNG_cs_set_ICC
+#define png_colorspace_set_chromaticities         MOZ_PNG_cs_set_chromats
+#define png_colorspace_set_endpoints              MOZ_PNG_cs_set_endpts
+#define png_colorspace_set_gamma                  MOZ_PNG_cs_set_gamma
+#define png_colorspace_set_sRGB                   MOZ_PNG_cs_set_sRGB
+#define png_colorspace_sync                       MOZ_PNG_cs_sync
+#define png_colorspace_sync_info                  MOZ_PNG_cs_sync_info
+#define png_compress_IDAT                         MOZ_PNG_compress_IDAT
+#define png_create_png_struct                     MOZ_PNG_create_png_struct
+#define png_destroy_png_struct                    MOZ_PNG_destroy_png_struct
+#define png_free_buffer_list                      MOZ_PNG_free_buffer_list
+#define png_free_jmpbuf                           MOZ_PNG_free_jmpbuf
+#define png_get_uint_31                           MOZ_PNG_get_uint_31
+#define png_icc_check_header                      MOZ_PNG_icc_check_header
+#define png_icc_check_length                      MOZ_PNG_icc_check_length
+#define png_icc_check_tag_table                   MOZ_PNG_icc_check_tags
+#define png_icc_set_sRGB                          MOZ_PNG_icc_set_sRGB
+#define png_malloc_array                          MOZ_PNG_malloc_array
+#define png_malloc_base                           MOZ_PNG_malloc_base
+#define png_realloc_array                         MOZ_PNG_realloc_array
+#define png_zstream_error                         MOZ_PNG_zstream_error
+
 #if defined(PR_LOGGING) && defined(PNG_WARNINGS_SUPPORTED)
 #define png_warning                     MOZ_PNG_warning
 #define png_error                       MOZ_PNG_error
 #define png_chunk_error                 MOZ_PNG_chunk_err
 #define png_fixed_error                 MOZ_PNG_fixed_err
 #define png_formatted_warning           MOZ_PNG_formatted_warning
 #define png_chunk_warning               MOZ_PNG_chunk_warn
 #define png_warning_parameter           MOZ_PNG_warn_param
--- a/media/libpng/png.c
+++ b/media/libpng/png.c
@@ -9,17 +9,17 @@
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_6 Your_png_h_is_not_version_1_6_6;
+typedef png_libpng_version_1_6_7 Your_png_h_is_not_version_1_6_7;
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
  * stream we can set num_bytes = 8 so that libpng will not attempt to read
  * or write any of the magic bytes before it starts on the IHDR.
  */
 
 #ifdef PNG_READ_SUPPORTED
@@ -763,23 +763,23 @@ png_const_charp PNGAPI
 png_get_copyright(png_const_structrp png_ptr)
 {
    PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
 #ifdef PNG_STRING_COPYRIGHT
    return PNG_STRING_COPYRIGHT
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-     "libpng version 1.6.6 - September 16, 2013" PNG_STRING_NEWLINE \
+     "libpng version 1.6.7 - November 14, 2013" PNG_STRING_NEWLINE \
      "Copyright (c) 1998-2013 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
      PNG_STRING_NEWLINE;
 #  else
-      return "libpng version 1.6.6 - September 16, 2013\
+      return "libpng version 1.6.7 - November 14, 2013\
       Copyright (c) 1998-2013 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
 #endif
 }
 
 /* The following return the library version as a short string in the
@@ -850,26 +850,27 @@ png_handle_as_unknown(png_const_structrp
    /* This means that known chunks should be processed and unknown chunks should
     * be handled according to the value of png_ptr->unknown_default; this can be
     * confusing because, as a result, there are two levels of defaulting for
     * unknown chunks.
     */
    return PNG_HANDLE_CHUNK_AS_DEFAULT;
 }
 
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
 int /* PRIVATE */
 png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
 {
    png_byte chunk_string[5];
 
    PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
    return png_handle_as_unknown(png_ptr, chunk_string);
 }
-#endif /* HANDLE_AS_UNKNOWN */
+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
 #endif /* SET_UNKNOWN_CHUNKS */
 
 #ifdef PNG_READ_SUPPORTED
 /* This function, added to libpng-1.0.6g, is untested. */
 int PNGAPI
 png_reset_zstream(png_structrp png_ptr)
 {
    if (png_ptr == NULL)
--- a/media/libpng/png.h
+++ b/media/libpng/png.h
@@ -1,22 +1,22 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.6.6 - September 16, 2013
+ * libpng version 1.6.7 - November 14, 2013
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license (See LICENSE, below)
  *
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.6 - September 16, 2013: Glenn
+ *   libpng versions 0.97, January 1998, through 1.6.7 - November 14, 2013: Glenn
  *   See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
  *
  *   Due to various miscommunications, unforeseen code incompatibilities
  *   and occasional factors outside the authors' control, version numbering
  *   on the library has not always been consistent and straightforward.
  *   The following table summarizes matters since version 0.89c, which was
@@ -178,16 +178,19 @@
  *    1.6.3beta01-11          16    10603  16.so.16.3[.0]
  *    1.6.3rc01               16    10603  16.so.16.3[.0]
  *    1.6.3                   16    10603  16.so.16.3[.0]
  *    1.6.4beta01-02          16    10604  16.so.16.4[.0]
  *    1.6.4rc01               16    10604  16.so.16.4[.0]
  *    1.6.4                   16    10604  16.so.16.4[.0]
  *    1.6.5                   16    10605  16.so.16.5[.0]
  *    1.6.6                   16    10606  16.so.16.6[.0]
+ *    1.6.7beta01-04          16    10607  16.so.16.7[.0]
+ *    1.6.7rc01-02            16    10607  16.so.16.7[.0]
+ *    1.6.7                   16    10607  16.so.16.7[.0]
  *
  *   Henceforth the source version will match the shared-library major
  *   and minor numbers; the shared-library major version number will be
  *   used for changes in backward compatibility, as it is intended.  The
  *   PNG_LIBPNG_VER macro, which is not used within libpng but is available
  *   for applications, is an unsigned integer of the form xyyzz corresponding
  *   to the source version x.y.z (leading zeros in y and z).  Beta versions
  *   were given the previous public release number plus a letter, until
@@ -209,17 +212,17 @@
 /*
  * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
  *
  * If you modify libpng you may insert additional notices immediately following
  * this sentence.
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.6.6, September 16, 2013, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.7, November 14, 2013, are
  * Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
  * distributed according to the same disclaimer and license as libpng-1.2.5
  * with the following individual added to the list of Contributing Authors:
  *
  *    Cosmin Truta
  *
  * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
  * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
@@ -321,23 +324,23 @@
  *
  * Thanks to Frank J. T. Wojcik for helping with the documentation.
  */
 
 /*
  * Y2K compliance in libpng:
  * =========================
  *
- *    September 16, 2013
+ *    November 14, 2013
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *
  *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.6 are Y2K compliant.  It is my belief that
+ *    upward through 1.6.7 are Y2K compliant.  It is my belief that
  *    earlier versions were also Y2K compliant.
  *
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
  *    that will hold years up to 65535.  The other, which is deprecated,
  *    holds the date in text format, and will hold years up to 9999.
  *
  *    The integer is
  *        "png_uint_16 year" in png_time_struct.
@@ -387,27 +390,27 @@
  * with some code on which to build.  This file is useful for looking
  * at the actual function definitions and structure components.
  *
  * If you just need to read a PNG file and don't want to read the documentation
  * skip to the end of this file and read the section entitled 'simplified API'.
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.6"
+#define PNG_LIBPNG_VER_STRING "1.6.7"
 #define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.6 - September 16, 2013\n"
+     " libpng version 1.6.7 - November 14, 2013\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
 
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 6
+#define PNG_LIBPNG_VER_RELEASE 7
 
 /* This should match the numeric part of the final component of
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
  */
 
 #define PNG_LIBPNG_VER_BUILD  0
 
 /* Release Status */
@@ -428,17 +431,17 @@
 #define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
 
 /* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
  * We must not include leading zeros.
  * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
  * version 1.0.0 was mis-numbered 100 instead of 10000).  From
  * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
  */
-#define PNG_LIBPNG_VER 10606 /* 1.6.6 */
+#define PNG_LIBPNG_VER 10607 /* 1.6.7 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
  */
 
 #ifndef PNG_VERSION_INFO_ONLY
    /* Machine specific configuration. */
 #  include "mozpngconf.h"
@@ -539,17 +542,17 @@ extern "C" {
 /* blend_op flags from inside fcTL */
 #define PNG_BLEND_OP_SOURCE        0x00
 #define PNG_BLEND_OP_OVER          0x01
 #endif /* PNG_APNG_SUPPORTED */
 
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_6;
+typedef char* png_libpng_version_1_6_7;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
  * png_struct is the cache of information used while reading or writing a single
  * PNG file.  One of these is always required, although the simplified API
  * (below) hides the creation and destruction of it.
  */
 typedef struct png_struct_def png_struct;
@@ -721,17 +724,18 @@ typedef struct png_time_struct
    png_byte hour;    /* hour of day, 0 - 23 */
    png_byte minute;  /* minute of hour, 0 - 59 */
    png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
 } png_time;
 typedef png_time * png_timep;
 typedef const png_time * png_const_timep;
 typedef png_time * * png_timepp;
 
-#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\
+   defined(PNG_USER_CHUNKS_SUPPORTED)
 /* png_unknown_chunk is a structure to hold queued chunks for which there is
  * no specific support.  The idea is that we can use this to queue
  * up private chunks for output even though the library doesn't actually
  * know about their semantics.
  *
  * The data in the structure is set by libpng on read and used on write.
  */
 typedef struct png_unknown_chunk_t
--- a/media/libpng/pngconf.h
+++ b/media/libpng/pngconf.h
@@ -1,12 +1,12 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.6.6 - September 16, 2013
+ * libpng version 1.6.7 - November 14, 2013
  *
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
--- a/media/libpng/pngpread.c
+++ b/media/libpng/pngpread.c
@@ -180,17 +180,17 @@ png_push_read_sig(png_structrp png_ptr, 
       }
    }
 }
 
 void /* PRIVATE */
 png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
 {
    png_uint_32 chunk_name;
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
    int keep; /* unknown handling method */
 #endif
 
    /* First we make sure we have enough data for the 4 byte chunk name
     * and the 4 byte chunk length before proceeding with decoding the
     * chunk data.  To fully decode each of these chunks, we also make
     * sure we have enough data in the buffer for the 4 byte CRC at the
     * end of every chunk (except IDAT, which is handled separately).
@@ -369,17 +369,17 @@ png_push_read_chunk(png_structrp png_ptr
       }
 
       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
 
       png_ptr->process_mode = PNG_READ_DONE_MODE;
       png_push_have_end(png_ptr, info_ptr);
    }
 
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
    else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
    {
       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       {
          png_push_save_buffer(png_ptr);
          return;
       }
 
@@ -653,18 +653,18 @@ png_push_read_chunk(png_structrp png_ptr
       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       {
          png_push_save_buffer(png_ptr);
          return;
       }
 
       png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
    }
+#endif /* PNG_READ_APNG_SUPPORTED */
 
-#endif /* PNG_READ_APNG_SUPPORTED */
    else
    {
       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       {
          png_push_save_buffer(png_ptr);
          return;
       }
       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
--- a/media/libpng/pngpriv.h
+++ b/media/libpng/pngpriv.h
@@ -1,17 +1,17 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng 1.6.3 [July 18, 2013]
+ * Last changed in libpng 1.6.7 [November 14, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 /* The symbols declared in this file (including the functions declared
  * as extern) are PRIVATE.  They are not part of the libpng public
@@ -123,17 +123,59 @@
 #  endif
 #endif
 
 #if PNG_ARM_NEON_OPT > 0
    /* NEON optimizations are to be at least considered by libpng, so enable the
     * callbacks to do this.
     */
 #  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
-#endif
+
+   /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
+    * if possible - if __ARM_NEON__ is set and the compiler version is not known
+    * to be broken.  This is control by PNG_ARM_NEON_IMPLEMENTATION which can
+    * be:
+    *
+    *    1  The intrinsics code (the default with __ARM_NEON__)
+    *    2  The hand coded assembler (the default without __ARM_NEON__)
+    *
+    * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
+    * this is *NOT* supported and may cease to work even after a minor revision
+    * to libpng.  It *is* valid to do this for testing purposes, e.g. speed
+    * testing or a new compiler, but the results should be communicated to the
+    * libpng implementation list for incorporation in the next minor release.
+    */
+#  ifndef PNG_ARM_NEON_IMPLEMENTATION
+#     ifdef __ARM_NEON__
+#        if defined(__clang__)
+            /* At present it is unknown by the libpng developers which versions
+             * of clang support the intrinsics, however some or perhaps all
+             * versions do not work with the assembler so this may be
+             * irrelevant, so just use the default (do nothing here.)
+             */
+#        elif defined(__GNUC__)
+            /* GCC 4.5.4 NEON support is known to be broken.  4.6.3 is known to
+             * work, so if this *is* GCC, or G++, look for a version >4.5
+             */
+#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)
+#              define PNG_ARM_NEON_IMPLEMENTATION 2
+#           endif /* no GNUC support */
+#        endif /* __GNUC__ */
+#     else /* !defined __ARM_NEON__ */
+         /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
+          */
+#        define PNG_ARM_NEON_IMPLEMENTATION 2
+#     endif /* __ARM_NEON__ */
+#  endif /* !defined PNG_ARM_NEON_IMPLEMENTATION */
+
+#  ifndef PNG_ARM_NEON_IMPLEMENTATION
+      /* Use the intrinsics code by default. */
+#     define PNG_ARM_NEON_IMPLEMENTATION 1
+#  endif
+#endif /* PNG_ARM_NEON_OPT > 0 */
 
 /* Is this a build of a DLL where compilation of the object modules requires
  * different preprocessor settings to those required for a simple library?  If
  * so PNG_BUILD_DLL must be set.
  *
  * If libpng is used inside a DLL but that DLL does not export the libpng APIs
  * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a
  * static library of libpng then link the DLL against that.
@@ -1433,33 +1475,34 @@ PNG_INTERNAL_FUNCTION(void,png_handle_tR
 #ifdef PNG_READ_zTXt_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 
 PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
     png_uint_32 chunk_name),PNG_EMPTY);
 
-#ifdef PNG_READ_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
    /* This is the function that gets called for unknown chunks.  The 'keep'
     * argument is either non-zero for a known chunk that has been set to be
     * handled as unknown or zero for an unknown chunk.  By default the function
     * just skips the chunk or errors out if it is critical.
     */
 
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
 PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
     (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
    /* Exactly as the API png_handle_as_unknown() except that the argument is a
     * 32-bit chunk name, not a string.
     */
-#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED */
+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+#endif /* PNG_SET_UNKNOWN_CHUNKS_SUPPORTED */
 
 /* Handle the transformations for reading and writing */
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
    png_row_infop row_info),PNG_EMPTY);
 #endif
 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
--- a/media/libpng/pngrtran.c
+++ b/media/libpng/pngrtran.c
@@ -1,12 +1,12 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.6.4 [September 16, 2013]
+ * Last changed in libpng 1.6.4 [August 21, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
--- a/media/libpng/pngrutil.c
+++ b/media/libpng/pngrutil.c
@@ -1,12 +1,12 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.6.4 [September 16, 2013]
+ * Last changed in libpng 1.6.7 [November 14, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
@@ -2937,36 +2937,38 @@ png_cache_unknown_chunk(png_structrp png
 void /* PRIVATE */
 png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
    png_uint_32 length, int keep)
 {
    int handled = 0; /* the chunk was handled */
 
    png_debug(1, "in png_handle_unknown");
 
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
    /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing
     * the bug which meant that setting a non-default behavior for a specific
     * chunk would be ignored (the default was always used unless a user
     * callback was installed).
     *
     * 'keep' is the value from the png_chunk_unknown_handling, the setting for
     * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it
     * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.
     * This is just an optimization to avoid multiple calls to the lookup
     * function.
     */
-#  ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-   keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
+#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#     ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+         keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
+#     endif
 #  endif
 
    /* One of the following methods will read the chunk or skip it (at least one
     * of these is always defined because this is the only way to switch on
     * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
     */
-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
 #  ifdef PNG_READ_USER_CHUNKS_SUPPORTED
       /* The user callback takes precedence over the chunk keep value, but the
        * keep value is still required to validate a save of a critical chunk.
        */
       if (png_ptr->read_user_chunk_fn != NULL)
       {
          if (png_cache_unknown_chunk(png_ptr, length))
          {
@@ -3064,17 +3066,17 @@ png_handle_unknown(png_structrp png_ptr,
           * the app has erroneously asked for unknown chunk saving when there
           * is no support.
           */
          if (keep > PNG_HANDLE_CHUNK_NEVER)
             png_app_error(png_ptr, "no unknown chunk support available");
 
          png_crc_finish(png_ptr, length);
       }
-#  endif /* PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED */
+#  endif
 
 #  ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
       /* Now store the chunk in the chunk list if appropriate, and if the limits
        * permit it.
        */
       if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
          (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
           PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
@@ -3103,19 +3105,18 @@ png_handle_unknown(png_structrp png_ptr,
                png_set_unknown_chunks(png_ptr, info_ptr,
                   &png_ptr->unknown_chunk, 1);
                handled = 1;
 #     ifdef PNG_USER_LIMITS_SUPPORTED
                break;
          }
 #     endif
       }
-#  else /* no store support! */
+#  else /* no store support: the chunk must be handled by the user callback */
       PNG_UNUSED(info_ptr)
-#     error untested code (reading unknown chunks with no store support)
 #  endif
 
    /* Regardless of the error handling below the cached data (if any) can be
     * freed now.  Notice that the data is not freed if there is a png_error, but
     * it will be freed by destroy_read_struct.
     */
    if (png_ptr->unknown_chunk.data != NULL)
       png_free(png_ptr, png_ptr->unknown_chunk.data);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -782,28 +782,28 @@ PeerConnectionImpl::Initialize(PeerConne
     CSFLogError(logTag, "%s: Generate returned NULL", __FUNCTION__);
     return NS_ERROR_FAILURE;
   }
 
   // Set the fingerprint. Right now assume we only have one
   // DTLS identity
   unsigned char fingerprint[DTLS_FINGERPRINT_LENGTH];
   size_t fingerprint_length;
-  res = mIdentity->ComputeFingerprint("sha-1",
+  res = mIdentity->ComputeFingerprint("sha-256",
                                       fingerprint,
                                       sizeof(fingerprint),
                                       &fingerprint_length);
 
   if (NS_FAILED(res)) {
     CSFLogError(logTag, "%s: ComputeFingerprint failed: %u",
       __FUNCTION__, static_cast<uint32_t>(res));
     return res;
   }
 
-  mFingerprint = "sha-1 " + mIdentity->FormatFingerprint(fingerprint,
+  mFingerprint = "sha-256 " + mIdentity->FormatFingerprint(fingerprint,
                                                          fingerprint_length);
   if (NS_FAILED(res)) {
     CSFLogError(logTag, "%s: do_GetService failed: %u",
       __FUNCTION__, static_cast<uint32_t>(res));
     return res;
   }
 
   return NS_OK;
@@ -987,25 +987,28 @@ PeerConnectionImpl::CreateDataChannel(co
 // do_QueryObjectReferent() - Helps get PeerConnectionObserver from nsWeakPtr.
 //
 // nsWeakPtr deals in XPCOM interfaces, while webidl bindings are concrete objs.
 // TODO: Turn this into a central (template) function somewhere (Bug 939178)
 //
 // Without it, each weak-ref call in this file would look like this:
 //
 //  nsCOMPtr<nsISupportsWeakReference> tmp = do_QueryReferent(mPCObserver);
+//  if (!tmp) {
+//    return;
+//  }
 //  nsRefPtr<nsSupportsWeakReference> tmp2 = do_QueryObject(tmp);
 //  nsRefPtr<PeerConnectionObserver> pco = static_cast<PeerConnectionObserver*>(&*tmp2);
-//  if (!pco) {
-//    return;
-//  }
 
 static already_AddRefed<PeerConnectionObserver>
 do_QueryObjectReferent(nsIWeakReference* aRawPtr) {
   nsCOMPtr<nsISupportsWeakReference> tmp = do_QueryReferent(aRawPtr);
+  if (!tmp) {
+    return nullptr;
+  }
   nsRefPtr<nsSupportsWeakReference> tmp2 = do_QueryObject(tmp);
   nsRefPtr<PeerConnectionObserver> tmp3 = static_cast<PeerConnectionObserver*>(&*tmp2);
   return tmp3.forget();
 }
 
 void
 PeerConnectionImpl::NotifyConnection()
 {
@@ -1332,16 +1335,17 @@ PeerConnectionImpl::SetRemoteFingerprint
     mRemoteFingerprint = std::string(fingerprint);
     CSFLogDebug(logTag, "Setting remote fingerprint to %s", mRemoteFingerprint.c_str());
     return NS_OK;
   } else {
     CSFLogError(logTag, "%s: Invalid Remote Finger Print", __FUNCTION__);
     return NS_ERROR_FAILURE;
   }
 }
+*/
 
 NS_IMETHODIMP
 PeerConnectionImpl::GetFingerprint(char** fingerprint)
 {
   MOZ_ASSERT(fingerprint);
 
   if (!mIdentity) {
     return NS_ERROR_FAILURE;
@@ -1349,17 +1353,16 @@ PeerConnectionImpl::GetFingerprint(char*
 
   char* tmp = new char[mFingerprint.size() + 1];
   std::copy(mFingerprint.begin(), mFingerprint.end(), tmp);
   tmp[mFingerprint.size()] = '\0';
 
   *fingerprint = tmp;
   return NS_OK;
 }
-*/
 
 NS_IMETHODIMP
 PeerConnectionImpl::GetLocalDescription(char** aSDP)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   MOZ_ASSERT(aSDP);
 
   char* tmp = new char[mLocalSDP.size() + 1];
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -341,16 +341,25 @@ public:
   }
 
   NS_IMETHODIMP_TO_ERRORRESULT(RemoveStream, ErrorResult &rv,
                                DOMMediaStream& aMediaStream)
   {
     rv = RemoveStream(aMediaStream);
   }
 
+  NS_IMETHODIMP GetFingerprint(char** fingerprint);
+  void GetFingerprint(nsAString& fingerprint)
+  {
+    char *tmp;
+    GetFingerprint(&tmp);
+    fingerprint.AssignASCII(tmp);
+    delete[] tmp;
+  }
+
   NS_IMETHODIMP GetLocalDescription(char** aSDP);
 
   void GetLocalDescription(nsAString& aSDP)
   {
     char *tmp;
     GetLocalDescription(&tmp);
     aSDP.AssignASCII(tmp);
     delete tmp;
--- a/modules/libpref/src/Preferences.cpp
+++ b/modules/libpref/src/Preferences.cpp
@@ -221,19 +221,17 @@ Preferences::SizeOfIncludingThisAndOther
   // DMD indicates they are not significant.
   n += pref_SizeOfPrivateData(aMallocSizeOf);
   return n;
 }
 
 class PreferenceServiceReporter MOZ_FINAL : public MemoryMultiReporter
 {
 public:
-  PreferenceServiceReporter()
-    : MemoryMultiReporter("preference-service")
-  {}
+  PreferenceServiceReporter() {}
 
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
                             nsISupports* aData);
 
 protected:
   static const uint32_t kSuspectReferentCount = 1000;
   static PLDHashOperator CountReferents(PrefCallback* aKey,
                                         nsAutoPtr<PrefCallback>& aCallback,
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -1070,18 +1070,17 @@ private:
  * nsCacheService
  *****************************************************************************/
 nsCacheService *   nsCacheService::gService = nullptr;
 
 NS_IMPL_ISUPPORTS_INHERITED2(nsCacheService, MemoryMultiReporter,
                              nsICacheService, nsICacheServiceInternal)
 
 nsCacheService::nsCacheService()
-    : MemoryMultiReporter("cache-service"),
-      mObserver(nullptr),
+    : mObserver(nullptr),
       mLock("nsCacheService.mLock"),
       mCondVar(mLock, "nsCacheService.mCondVar"),
       mTimeStampLock("nsCacheService.mTimeStampLock"),
       mInitialized(false),
       mClearingEntries(false),
       mEnableMemoryDevice(true),
       mEnableDiskDevice(true),
       mMemoryDevice(nullptr),
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_15_4_BETA6
+NSS_3_15_4_BETA7
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -13484,16 +13484,44 @@ END
 CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\005\071\021\105\020\224
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
+# Distrust "Distrusted AC DG Tresor SSL"
+# Issuer: CN=AC DGTPE Signature Authentification,O=DGTPE,C=FR
+# Serial Number: 204199 (0x31da7)
+# Subject: CN=AC DG Tr..sor SSL,O=DG Tr..sor,C=FR
+# Not Valid Before: Thu Jul 18 10:05:28 2013
+# Not Valid After : Fri Jul 18 10:05:28 2014
+# Fingerprint (MD5): 3A:EA:9E:FC:00:0C:E2:06:6C:E0:AC:39:C1:31:DE:C8
+# Fingerprint (SHA1): 5C:E3:39:46:5F:41:A1:E4:23:14:9F:65:54:40:95:40:4D:E6:EB:E2
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "Distrusted AC DG Tresor SSL"
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\016\060\014\006\003\125\004\012\023\005\104\107\124\120\105\061
+\054\060\052\006\003\125\004\003\023\043\101\103\040\104\107\124
+\120\105\040\123\151\147\156\141\164\165\162\145\040\101\165\164
+\150\145\156\164\151\146\151\143\141\164\151\157\156
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\003\003\035\247
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
 #
 # Certificate "Security Communication EV RootCA1"
 #
 # Issuer: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP
 # Serial Number: 0 (0x0)
 # Subject: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP
 # Not Valid Before: Wed Jun 06 02:12:32 2007
 # Not Valid After : Sat Jun 06 02:12:32 2037
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -978,16 +978,18 @@ size_t RNG_FileUpdate(const char *fileNa
 	/* Read from the underlying file descriptor directly to bypass stdio
 	 * buffering and avoid reading more bytes than we need from
 	 * /dev/urandom. NOTE: we can't use fread with unbuffered I/O because
 	 * fread may return EOF in unbuffered I/O mode on Android.
 	 *
 	 * Moreover, we read into a buffer of size BUFSIZ, so buffered I/O
 	 * has no performance advantage. */
 	fd = fileno(file);
+	/* 'file' was just opened, so this should not fail. */
+	PORT_Assert(fd != -1);
 	while (limit > fileBytes) {
 	    bytes = PR_MIN(sizeof buffer, limit - fileBytes);
 	    bytes = read(fd, buffer, bytes);
 	    if (bytes <= 0)
 		break;
 	    RNG_RandomUpdate(buffer, bytes);
 	    fileBytes      += bytes;
 	    totalFileBytes += bytes;
@@ -1145,16 +1147,18 @@ size_t RNG_SystemRNG(void *dest, size_t 
 	return rng_systemFromNoise(dest, maxLen);
     }
     /* Read from the underlying file descriptor directly to bypass stdio
      * buffering and avoid reading more bytes than we need from /dev/urandom.
      * NOTE: we can't use fread with unbuffered I/O because fread may return
      * EOF in unbuffered I/O mode on Android.
      */
     fd = fileno(file);
+    /* 'file' was just opened, so this should not fail. */
+    PORT_Assert(fd != -1);
     while (maxLen > fileBytes) {
 	bytes = maxLen - fileBytes;
 	bytes = read(fd, buffer, bytes);
 	if (bytes <= 0)
 	    break;
 	fileBytes += bytes;
 	buffer += bytes;
     }
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -121,18 +121,17 @@ StartupCache::InitSingleton()
 StaticRefPtr<StartupCache> StartupCache::gStartupCache;
 bool StartupCache::gShutdownInitiated;
 bool StartupCache::gIgnoreDiskCache;
 enum StartupCache::TelemetrifyAge StartupCache::gPostFlushAgeAction = StartupCache::IGNORE_AGE;
 
 NS_IMPL_ISUPPORTS_INHERITED0(StartupCache, MemoryMultiReporter)
 
 StartupCache::StartupCache()
-  : MemoryMultiReporter("startup-cache"),
-    mArchive(nullptr), mStartupWriteInitiated(false), mWriteThread(nullptr)
+  : mArchive(nullptr), mStartupWriteInitiated(false), mWriteThread(nullptr)
 { }
 
 StartupCache::~StartupCache()
 {
   if (mTimer) {
     mTimer->Cancel();
   }
 
--- a/storage/src/mozStorageService.cpp
+++ b/storage/src/mozStorageService.cpp
@@ -273,18 +273,17 @@ int32_t
 Service::getSynchronousPref()
 {
   return sSynchronousPref;
 }
 
 int32_t Service::sDefaultPageSize = PREF_TS_PAGESIZE_DEFAULT;
 
 Service::Service()
-: MemoryMultiReporter("storage-sqlite")
-, mMutex("Service::mMutex")
+: mMutex("Service::mMutex")
 , mSqliteVFS(nullptr)
 , mRegistrationMutex("Service::mRegistrationMutex")
 , mConnections()
 {
 }
 
 Service::~Service()
 {
--- a/testing/mochitest/harness.xul
+++ b/testing/mochitest/harness.xul
@@ -5,22 +5,16 @@
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Chrome Test Harness"
         directory="chrome">
 
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/LogController.js"/>
   <script type="text/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/>
-  <script type="text/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
-  <script type="text/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
-  <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/MemoryStats.js"/>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/TestRunner.js"/>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/MozillaLogger.js"/>
   <script type="application/javascript"
           src="chrome://mochikit/content/chrome-harness.js" />
   <script type="application/javascript"
--- a/testing/mochitest/tests/test_SpecialPowersExtension.html
+++ b/testing/mochitest/tests/test_SpecialPowersExtension.html
@@ -156,15 +156,20 @@ function starttest(){
   SpecialPowers.wrap(document).title = "foo";
   is(document.title, "foo", "Set property correctly on Xray-wrapped DOM object");
   is(SpecialPowers.wrap(document).URI, document.URI, "Got property correctly on Xray-wrapped DOM object");
 
   info("\nProfile::SpecialPowersRunTime: " + (new Date() - startTime) + "\n");
 
   // bug 855192
   ok(SpecialPowers.MockPermissionPrompt, "check mock permission prompt");
-  SimpleTest.finish();
+
+  // Set a pref using pushPrefEnv to make sure that flushPrefEnv is
+  // automatically called before we invoke
+  // test_SpecialPowersExtension2.html.
+  SpecialPowers.pushPrefEnv({set: [['testing.some_arbitrary_pref', true]]},
+                            function() { SimpleTest.finish(); });
 }
 </script>
 </pre>
 </body>
 </html>
 
--- a/testing/mochitest/tests/test_SpecialPowersExtension2.html
+++ b/testing/mochitest/tests/test_SpecialPowersExtension2.html
@@ -6,14 +6,16 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 
 <div id="content" class="testbody">
   <script type="text/javascript">
     dump("\nSPECIALPTEST2:::Loading test2 file now " + (new Date).getTime() + "\n");
     is(SpecialPowers.sanityCheck(), "foo", "Special Powers top level");
+    ok(!SpecialPowers.Services.prefs.prefHasUserValue('testing.some_arbitrary_pref'),
+       "should not retain pref from previous test");
   </script>
   <iframe id="frame1" src="file_SpecialPowersFrame1.html">
   </iframe>
 </div>
 </body>
 </html>
--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -442,18 +442,29 @@ function updateAboutMemoryFromJSONObject
                 "missing 'hasMozMallocUsableSize' property");
     assertInput(aObj.reports && aObj.reports instanceof Array,
                 "missing or non-array 'reports' property");
 
     let processMemoryReportsFromFile =
         function(aHandleReport, aDisplayReports) {
       for (let i = 0; i < aObj.reports.length; i++) {
         let r = aObj.reports[i];
-        aHandleReport(r.process, r.path, r.kind, r.units, r.amount,
-                      r.description, r._presence);
+
+        // A hack: for a brief time (late in the FF26 and early in the FF27
+        // cycle) we were dumping memory report files that contained reports
+        // whose path began with "redundant/".  Such reports were ignored by
+        // about:memory.  These reports are no longer produced, but some older
+        // builds are still floating around and producing files that contain
+        // them, so we need to still handle them (i.e. ignore them).  This hack
+        // can be removed once FF26 and associated products (e.g. B2G 1.2) are
+        // no longer in common use.
+        if (!r.path.startsWith("redundant/")) {
+          aHandleReport(r.process, r.path, r.kind, r.units, r.amount,
+                        r.description, r._presence);
+        }
       }
       aDisplayReports();
     }
     appendAboutMemoryMain(processMemoryReportsFromFile,
                           aObj.hasMozMallocUsableSize);
   } catch (ex) {
     handleException(ex);
   }
--- a/toolkit/components/aboutmemory/tests/memory-reports-good.json
+++ b/toolkit/components/aboutmemory/tests/memory-reports-good.json
@@ -9,15 +9,17 @@
 
     {"process": "Main Process (pid NNN)", "path": "size/a", "kind": 1, "units": 0, "amount": 1024, "description": "non-sentence"},
     {"process": "Main Process (pid NNN)", "path": "rss/a", "kind": 1, "units": 0, "amount": 1024, "description": "non-sentence"},
     {"process": "Main Process (pid NNN)", "path": "pss/a", "kind": 1, "units": 0, "amount": 1024, "description": "non-sentence"},
     {"process": "Main Process (pid NNN)", "path": "swap/a", "kind": 1, "units": 0, "amount": 1024, "description": "non-sentence"},
     {"process": "Main Process (pid NNN)", "path": "compartments/system/a", "kind": 1, "units": 0, "amount": 1024, "description": ""},
     {"process": "Main Process (pid NNN)", "path": "ghost-windows/a", "kind": 1, "units": 0, "amount": 1024, "description": ""},
 
+    {"process": "Main Process (pid NNN)", "path": "redundant/should-be-ignored", "kind": 1, "units": 0, "amount": 1024, "description": ""},
+
     {"process": "Explicit-only process", "path": "explicit/a/b", "kind": 1, "units": 0, "amount": 100000, "description": "A b."},
 
     {"process": "Other-only process", "path": "a/b", "kind": 1, "units": 0, "amount": 100000, "description": "A b."},
     {"process": "Other-only process", "path": "a/c", "kind": 1, "units": 0, "amount": 100000, "description": "A c."},
     {"process": "Other-only process", "path": "heap-allocated", "kind": 1, "units": 0, "amount": 500000, "description": "D."}
   ]
 }
--- a/toolkit/components/jsdownloads/test/unit/test_DownloadList.js
+++ b/toolkit/components/jsdownloads/test/unit/test_DownloadList.js
@@ -357,19 +357,18 @@ add_task(function test_history_expiratio
   yield promiseExpirableDownloadVisit();
   yield promiseExpirableDownloadVisit(httpUrl("interruptible.txt"));
 
   // After clearing history, we can add the downloads to be removed to the list.
   yield list.add(downloadOne);
   yield list.add(downloadTwo);
 
   // Force a history expiration.
-  let expire = Cc["@mozilla.org/places/expiration;1"]
-                 .getService(Ci.nsIObserver);
-  expire.observe(null, "places-debug-start-expiration", -1);
+  Cc["@mozilla.org/places/expiration;1"]
+    .getService(Ci.nsIObserver).observe(null, "places-debug-start-expiration", -1);
 
   // Wait for both downloads to be removed.
   yield deferred.promise;
 
   cleanup();
 });
 
 /**
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -906,17 +906,17 @@ NS_IMETHODIMP nsChildView::SetCursor(nsC
 
 // implement to fix "hidden virtual function" warning
 NS_IMETHODIMP nsChildView::SetCursor(imgIContainer* aCursor,
                                       uint32_t aHotspotX, uint32_t aHotspotY)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY);
-  return [[nsCursorManager sharedInstance] setCursorWithImage:aCursor hotSpotX:aHotspotX hotSpotY:aHotspotY];
+  return [[nsCursorManager sharedInstance] setCursorWithImage:aCursor hotSpotX:aHotspotX hotSpotY:aHotspotY scaleFactor:BackingScaleFactor()];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 #pragma mark -
 
 // Get this component dimension
 NS_IMETHODIMP nsChildView::GetBounds(nsIntRect &aRect)
--- a/widget/cocoa/nsCocoaUtils.h
+++ b/widget/cocoa/nsCocoaUtils.h
@@ -237,19 +237,20 @@ class nsCocoaUtils
    */
   static nsresult CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage **aResult);
 
   /** Creates a Cocoa <code>NSImage</code> from a frame of an <code>imgIContainer</code>.
       Combines the two methods above. The caller owns the <code>NSImage</code>.
       @param aImage the image to extract a frame from
       @param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
       @param aResult the resulting NSImage
+      @param scaleFactor the desired scale factor of the NSImage (2 for a retina display)
       @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
    */  
-  static nsresult CreateNSImageFromImageContainer(imgIContainer *aImage, uint32_t aWhichFrame, NSImage **aResult);
+  static nsresult CreateNSImageFromImageContainer(imgIContainer *aImage, uint32_t aWhichFrame, NSImage **aResult, CGFloat scaleFactor);
 
   /**
    * Returns nsAString for aSrc.
    */
   static void GetStringForNSString(const NSString *aSrc, nsAString& aDist);
 
   /**
    * Makes NSString instance for aString.
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -277,71 +277,132 @@ nsresult nsCocoaUtils::CreateCGImageFrom
                                                                   NULL);
   CGColorSpaceRef colorSpace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
   *aResult = ::CGImageCreate(width,
                              height,
                              8,
                              32,
                              stride,
                              colorSpace,
-                             kCGBitmapByteOrder32Host | kCGImageAlphaFirst,
+                             kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst,
                              dataProvider,
                              NULL,
                              0,
                              kCGRenderingIntentDefault);
   ::CGColorSpaceRelease(colorSpace);
   ::CGDataProviderRelease(dataProvider);
   return *aResult ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult nsCocoaUtils::CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage **aResult)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
+  // Be very careful when creating the NSImage that the backing NSImageRep is
+  // exactly 1:1 with the input image. On a retina display, both [NSImage
+  // lockFocus] and [NSImage initWithCGImage:size:] will create an image with a
+  // 2x backing NSImageRep. This prevents NSCursor from recognizing a retina
+  // cursor, which only occurs if pixelsWide and pixelsHigh are exactly 2x the
+  // size of the NSImage.
+  //
+  // For example, if a 32x32 SVG cursor is rendered on a retina display, then
+  // aInputImage will be 64x64. The resulting NSImage will be scaled back down
+  // to 32x32 so it stays the correct size on the screen by changing its size
+  // (resizing a NSImage only scales the image and doesn't resample the data).
+  // If aInputImage is converted using [NSImage initWithCGImage:size:] then the
+  // bitmap will be 128x128 and NSCursor won't recognize a retina cursor, since
+  // it will expect a 64x64 bitmap.
+
   int32_t width = ::CGImageGetWidth(aInputImage);
   int32_t height = ::CGImageGetHeight(aInputImage);
   NSRect imageRect = ::NSMakeRect(0.0, 0.0, width, height);
 
-  // Create a new image to receive the Quartz image data.
-  *aResult = [[NSImage alloc] initWithSize:imageRect.size];
+  NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc]
+    initWithBitmapDataPlanes:NULL
+    pixelsWide:width
+    pixelsHigh:height
+    bitsPerSample:8
+    samplesPerPixel:4
+    hasAlpha:YES
+    isPlanar:NO
+    colorSpaceName:NSDeviceRGBColorSpace
+    bitmapFormat:NSAlphaFirstBitmapFormat
+    bytesPerRow:0
+    bitsPerPixel:0];
 
-  [*aResult lockFocus];
+  NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep];
+  [NSGraphicsContext saveGraphicsState];
+  [NSGraphicsContext setCurrentContext:context];
 
   // Get the Quartz context and draw.
   CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
   ::CGContextDrawImage(imageContext, *(CGRect*)&imageRect, aInputImage);
 
-  [*aResult unlockFocus];
+  [NSGraphicsContext restoreGraphicsState];
+
+  *aResult = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
+  [*aResult addRepresentation:offscreenRep];
+  [offscreenRep release];
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
-nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, uint32_t aWhichFrame, NSImage **aResult)
+nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, uint32_t aWhichFrame, NSImage **aResult, CGFloat scaleFactor)
 {
-  nsRefPtr<gfxASurface> surface;
-  aImage->GetFrame(aWhichFrame,
-                   imgIContainer::FLAG_SYNC_DECODE,
-                   getter_AddRefs(surface));
-  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
+  nsRefPtr<gfxImageSurface> frame;
+  int32_t width = 0, height = 0;
+  aImage->GetWidth(&width);
+  aImage->GetHeight(&height);
+
+  // Render a vector image at the correct resolution on a retina display
+  if (aImage->GetType() == imgIContainer::TYPE_VECTOR && scaleFactor != 1.0f) {
+    int scaledWidth = (int)ceilf(width * scaleFactor);
+    int scaledHeight = (int)ceilf(height * scaleFactor);
+
+    frame = new gfxImageSurface(gfxIntSize(scaledWidth, scaledHeight), gfxImageFormatARGB32);
+    NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+
+    nsRefPtr<gfxContext> context = new gfxContext(frame);
+    NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
 
-  nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+    aImage->Draw(context, GraphicsFilter::FILTER_NEAREST, gfxMatrix(),
+      gfxRect(0.0f, 0.0f, scaledWidth, scaledHeight),
+      nsIntRect(0, 0, width, height),
+      nsIntSize(scaledWidth, scaledHeight),
+      nullptr, aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
+  }
+
+  else {
+    nsRefPtr<gfxASurface> surface;
+    aImage->GetFrame(aWhichFrame,
+                     imgIContainer::FLAG_SYNC_DECODE,
+                     getter_AddRefs(surface));
+    NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
+
+    frame = surface->GetAsReadableARGB32ImageSurface();
+    NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+  }
 
   CGImageRef imageRef = NULL;
   nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(frame, &imageRef);
   if (NS_FAILED(rv) || !imageRef) {
     return NS_ERROR_FAILURE;
   }
 
   rv = nsCocoaUtils::CreateNSImageFromCGImage(imageRef, aResult);
   if (NS_FAILED(rv) || !aResult) {
     return NS_ERROR_FAILURE;
   }
   ::CGImageRelease(imageRef);
+
+  // Ensure the image will be rendered the correct size on a retina display
+  NSSize size = NSMakeSize(width, height);
+  [*aResult setSize:size];
+  [[[*aResult representations] objectAtIndex:0] setSize:size];
   return NS_OK;
 }
 
 // static
 void
 nsCocoaUtils::GetStringForNSString(const NSString *aSrc, nsAString& aDist)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
--- a/widget/cocoa/nsCursorManager.h
+++ b/widget/cocoa/nsCursorManager.h
@@ -32,18 +32,19 @@
 
 /*! @method  setCursorWithImage:hotSpotX:hotSpotY:
  @abstract   Sets the current cursor to a custom image
  @discussion Sets the current cursor to the cursor given by the aCursorImage argument.
  Resources associated with the previous cursor are cleaned up.
  @param aCursorImage the cursor image to use
  @param aHotSpotX the x coordinate of the cursor's hotspot
  @param aHotSpotY the y coordinate of the cursor's hotspot
+ @param scaleFactor the scale factor of the target display (2 for a retina display)
  */
-- (nsresult) setCursorWithImage: (imgIContainer*) aCursorImage hotSpotX: (uint32_t) aHotspotX hotSpotY: (uint32_t) aHotspotY;
+- (nsresult) setCursorWithImage: (imgIContainer*) aCursorImage hotSpotX: (uint32_t) aHotspotX hotSpotY: (uint32_t) aHotspotY scaleFactor: (CGFloat) scaleFactor;
 
 
 /*! @method     sharedInstance
     @abstract   Get the Singleton instance of the cursor manager.
     @discussion Use this method to obtain a reference to the cursor manager.
     @result a reference to the cursor manager
 */
 + (nsCursorManager *) sharedInstance;
--- a/widget/cocoa/nsCursorManager.mm
+++ b/widget/cocoa/nsCursorManager.mm
@@ -4,16 +4,17 @@
 
 #include "imgIContainer.h"
 #include "nsCocoaUtils.h"
 #include "nsCursorManager.h"
 #include "nsObjCExceptions.h"
 #include <math.h>
 
 static nsCursorManager *gInstance;
+static CGFloat sCursorScaleFactor = 0.0f;
 static imgIContainer *sCursorImgContainer = nullptr;
 static const nsCursor sCustomCursor = eCursorCount;
 
 /*! @category nsCursorManager(PrivateMethods)
     Private methods for the cursor manager class.
 */
 @interface nsCursorManager(PrivateMethods)
 /*! @method     getCursor:
@@ -235,50 +236,51 @@ static const nsCursor sCustomCursor = eC
     mCurrentMacCursor = aMacCursor;
   }
 
   return NS_OK;
   
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
-- (nsresult) setCursorWithImage: (imgIContainer*) aCursorImage hotSpotX: (uint32_t) aHotspotX hotSpotY: (uint32_t) aHotspotY
+- (nsresult) setCursorWithImage: (imgIContainer*) aCursorImage hotSpotX: (uint32_t) aHotspotX hotSpotY: (uint32_t) aHotspotY scaleFactor: (CGFloat) scaleFactor
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
   // As the user moves the mouse, this gets called repeatedly with the same aCursorImage
-  if (sCursorImgContainer == aCursorImage && mCurrentMacCursor) {
+  if (sCursorImgContainer == aCursorImage && sCursorScaleFactor == scaleFactor && mCurrentMacCursor) {
     [self setMacCursor:mCurrentMacCursor];
     return NS_OK;
   }
   
   [[NSCursor currentCursor] set];
   int32_t width = 0, height = 0;
   aCursorImage->GetWidth(&width);
   aCursorImage->GetHeight(&height);
   // prevent DoS attacks
   if (width > 128 || height > 128) {
     return NS_OK;
   }
 
   NSImage *cursorImage;
-  nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(aCursorImage, imgIContainer::FRAME_FIRST, &cursorImage);
+  nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(aCursorImage, imgIContainer::FRAME_FIRST, &cursorImage, scaleFactor);
   if (NS_FAILED(rv) || !cursorImage) {
     return NS_ERROR_FAILURE;
   }
 
   // if the hotspot is nonsensical, make it 0,0
   aHotspotX = (aHotspotX > (uint32_t)width - 1) ? 0 : aHotspotX;
   aHotspotY = (aHotspotY > (uint32_t)height - 1) ? 0 : aHotspotY;
 
   NSPoint hotSpot = ::NSMakePoint(aHotspotX, aHotspotY);
   [self setMacCursor:[nsMacCursor cursorWithCursor:[[NSCursor alloc] initWithImage:cursorImage hotSpot:hotSpot] type:sCustomCursor]];
   [cursorImage release];
   
   NS_IF_RELEASE(sCursorImgContainer);
   sCursorImgContainer = aCursorImage;
+  sCursorScaleFactor = scaleFactor;
   NS_ADDREF(sCursorImgContainer);
   
   return NS_OK;
   
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 - (nsMacCursor *) getCursor: (enum nsCursor) aCursor
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -2560,17 +2560,16 @@ nsCycleCollector::CollectReports(nsIHand
 };
 
 
 ////////////////////////////////////////////////////////////////////////
 // Collector implementation
 ////////////////////////////////////////////////////////////////////////
 
 nsCycleCollector::nsCycleCollector() :
-    MemoryMultiReporter("cycle-collector"),
     mActivelyCollecting(false),
     mScanInProgress(false),
     mJSRuntime(nullptr),
     mIncrementalPhase(IdlePhase),
     mThread(NS_GetCurrentThread()),
     mWhiteNodeCount(0),
     mBeforeUnlinkCB(nullptr),
     mForgetSkippableCB(nullptr),
--- a/xpcom/base/nsIMemoryReporter.idl
+++ b/xpcom/base/nsIMemoryReporter.idl
@@ -495,61 +495,54 @@ void RunReporters();
   {                                                                           \
       return moz_malloc_size_of(aPtr);                                        \
   }
 
 namespace mozilla {
 
 // The following base class reduces the amount of boilerplate code required for
 // memory uni-reporters.  You just need to provide the following.
-// - The constant values: nameAndPath (which serves as both the reporters name,
-//   and the path in its single report), kind, units, and description.  They
-//   are arguments to the MemoryUniReporter constructor.
+// - The constant values: path, kind, units, and description.  They are
+//   arguments to the MemoryUniReporter constructor.
 // - A private Amount() or public GetAmount() method.  It can use the
 //   MallocSizeOf method if necessary.  (There is also
 //   MallocSizeOfOn{Alloc,Free}, which can be useful.)  Use Amount() if the
 //   reporter is infallible, and GetAmount() otherwise.  (If you fail to
 //   provide one or the other, you'll get assertion failures when the memory
 //   reporter runs.)
 //
-// The class name of subclasses should match the nameAndPath, minus the
-// "explicit" (if present), and with "Reporter" at the end.  For example:
-// - nameAndPath == "explicit/dom/xyzzy"     --> DOMXyzzyReporter
-// - nameAndPath == "js-compartments/system" --> JSCompartmentsSystemReporter
+// The class name of subclasses should match the path, minus the "explicit" (if
+// present), and with "Reporter" at the end.  For example:
+// - path == "explicit/dom/xyzzy"     --> DOMXyzzyReporter
+// - path == "js-compartments/system" --> JSCompartmentsSystemReporter
 //
 class MemoryUniReporter : public nsIMemoryReporter
 {
 public:
-  MemoryUniReporter(const char* aNameAndPath, int32_t aKind, int32_t aUnits,
+  MemoryUniReporter(const char* aPath, int32_t aKind, int32_t aUnits,
                     const char* aDescription)
-    : mNameAndPath(aNameAndPath)
+    : mPath(aPath)
     , mKind(aKind)
     , mUnits(aUnits)
     , mDescription(aDescription)
   {}
 
   virtual ~MemoryUniReporter() {}
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  NS_IMETHOD GetName(nsACString& aName)
-  {
-    aName.Assign(mNameAndPath);
-    return NS_OK;
-  }
-
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
                             nsISupports* aData)
   {
     int64_t amount;
     nsresult rv = GetAmount(&amount);
     if (NS_WARN_IF(NS_FAILED(rv)))
       return rv;
 
-    return aCallback->Callback(EmptyCString(), mNameAndPath, mKind, mUnits,
+    return aCallback->Callback(EmptyCString(), mPath, mKind, mUnits,
                                amount, mDescription, aData);
   }
 
 protected:
   NS_IMETHOD GetAmount(int64_t* aAmount)
   {
     *aAmount = Amount();
     return NS_OK;
@@ -561,17 +554,17 @@ protected:
     MOZ_ASSERT(false);
     return 0;
   }
 
   NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf)
   NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(MallocSizeOfOnAlloc)
   NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(MallocSizeOfOnFree)
 
-  const nsCString mNameAndPath;
+  const nsCString mPath;
   const int32_t   mKind;
   const int32_t   mUnits;
   const nsCString mDescription;
 };
 
 // The following base class reduces the amount of boilerplate code required for
 // memory multi-reporters.  You just need to provide the following.
 // - The constant value: name.  It is an argument to the MemoryMultiReporter
@@ -582,30 +575,26 @@ protected:
 //
 // The class name of subclasses should match the name, with "Reporter" at
 // the end.  For example:
 // - name == "foo" --> FooMultiReporter
 //
 class MemoryMultiReporter : public nsIMemoryReporter
 {
 public:
-  MemoryMultiReporter(const char* aName)
-    : mName(aName)
-  {}
+  MemoryMultiReporter() {}
 
   virtual ~MemoryMultiReporter() {}
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
                             nsISupports* aClosure) = 0;
 
 protected:
   NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf)
   NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(MallocSizeOfOnAlloc)
   NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(MallocSizeOfOnFree)
-
-  const nsCString mName;
 };
 
 } // namespace mozilla
 
 %}
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -794,19 +794,17 @@ private:
 #ifdef MOZ_DMD
 
 namespace mozilla {
 namespace dmd {
 
 class DMDReporter MOZ_FINAL : public MemoryMultiReporter
 {
 public:
-  DMDReporter()
-    : MemoryMultiReporter("dmd")
-  {}
+  DMDReporter() {}
 
   NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
                             nsISupports* aData)
   {
     dmd::Sizes sizes;
     dmd::SizeOf(&sizes);
 
 #define REPORT(_path, _amount, _desc)                                         \
--- a/xpcom/ds/nsObserverService.cpp
+++ b/xpcom/ds/nsObserverService.cpp
@@ -170,17 +170,16 @@ nsObserverService::CollectReports(nsIHan
 
 NS_IMPL_ISUPPORTS_INHERITED2(
     nsObserverService,
     MemoryMultiReporter,
     nsIObserverService,
     nsObserverService)
 
 nsObserverService::nsObserverService() :
-    MemoryMultiReporter("observer-service"),
     mShuttingDown(false)
 {
 }
 
 nsObserverService::~nsObserverService(void)
 {
     Shutdown();
 }
--- a/xpcom/threads/BackgroundHangMonitor.cpp
+++ b/xpcom/threads/BackgroundHangMonitor.cpp
@@ -296,18 +296,22 @@ BackgroundHangManager::RunMonitorThread(
 }
 
 
 BackgroundHangThread::BackgroundHangThread(const char* aName,
                                            uint32_t aTimeoutMs,
                                            uint32_t aMaxTimeoutMs)
   : mManager(BackgroundHangManager::sInstance)
   , mThreadID(PR_GetCurrentThread())
-  , mTimeout(PR_MillisecondsToInterval(aTimeoutMs))
-  , mMaxTimeout(PR_MillisecondsToInterval(aMaxTimeoutMs))
+  , mTimeout(aTimeoutMs == BackgroundHangMonitor::kNoTimeout
+             ? PR_INTERVAL_NO_TIMEOUT
+             : PR_MillisecondsToInterval(aTimeoutMs))
+  , mMaxTimeout(aMaxTimeoutMs == BackgroundHangMonitor::kNoTimeout
+                ? PR_INTERVAL_NO_TIMEOUT
+                : PR_MillisecondsToInterval(aMaxTimeoutMs))
   , mInterval(mManager->mIntervalNow)
   , mHangStart(mInterval)
   , mHanging(false)
   , mWaiting(true)
   , mStats(aName)
 {
   if (sTlsKey.initialized()) {
     sTlsKey.set(this);
--- a/xpcom/threads/BackgroundHangMonitor.h
+++ b/xpcom/threads/BackgroundHangMonitor.h
@@ -101,16 +101,18 @@ class BackgroundHangThread;
  *
  */
 class BackgroundHangMonitor
 {
 private:
   RefPtr<BackgroundHangThread> mThread;
 
 public:
+  static const uint32_t kNoTimeout = 0;
+
   /**
    * ThreadHangStatsIterator is used to iterate through the ThreadHangStats
    * associated with each active monitored thread. Because of an internal
    * lock while this object is alive, a thread must use only one instance
    * of this class at a time and must iterate through the list as fast as
    * possible. The following example shows using the iterator:
    *
    * {