merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 05 Nov 2013 15:52:56 +0100
changeset 153597 ebed32c70afaf16f03b07d1045826cf5a027b0c1
parent 153596 c80b984d7c5c8018473c0f172868844a2b27db14 (current diff)
parent 153551 48dbd532a004ff0df6b2c73a8a6ab39b6e79c8a5 (diff)
child 153598 ec8042ab407537bd0c5cdea49e65f05bb48c290c
push id25595
push userryanvm@gmail.com
push dateTue, 05 Nov 2013 20:19:27 +0000
treeherdermozilla-central@2ada3a06d5e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-central to fx-team
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "e9d3946c6e4c26c60f67b8efac40e14785b634d3", 
+    "revision": "9c89bc252dca005ec14f54d6d8524b44917322b2", 
     "repo_path": "/integration/gaia-central"
 }
--- a/configure.in
+++ b/configure.in
@@ -2074,18 +2074,21 @@ ia64*-hpux*)
         _USE_CPP_INCLUDE_FLAG=1
         _DEFINES_CFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
         _DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         if test "$_CC_SUITE" -ge "12"; then
             dnl VS2013+ requires -FS when parallel building by make -jN.
             dnl If nothing, compiler sometimes causes C1041 error.
-            CFLAGS="$CFLAGS -FS"
-            CXXFLAGS="$CXXFLAGS -FS"
+            dnl
+            dnl Visual Studio 2013 supports -Gw flags
+            dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx
+            CFLAGS="$CFLAGS -FS -Gw"
+            CXXFLAGS="$CXXFLAGS -FS -Gw"
         fi
         # khuey says we can safely ignore MSVC warning C4251
         # MSVC warning C4244 (implicit type conversion may lose data) warns
         # and requires workarounds for perfectly valid code.  Also, GCC/clang
         # don't warn about it by default. So for consistency/sanity, we turn
         # it off on MSVC, too.
         # MSVC warning C4345 warns of newly conformant behavior as of VS2003.
         # MSVC warning C4351 warns of newly conformant behavior as of VS2005.
@@ -3659,17 +3662,17 @@ dnl = If NSS was not detected in the sys
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
-    AM_PATH_NSS(3.15, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
+    AM_PATH_NSS(3.15.3, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_NATIVE_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS='-I$(LIBXUL_DIST)/include/nss'
 
    if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT" -o "$OS_ARCH" = "OS2"; then
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -1302,18 +1302,16 @@ nsresult MediaDecoderStateMachine::Init(
   }
   return mReader->Init(cloneReader);
 }
 
 void MediaDecoderStateMachine::StopPlayback()
 {
   LOG(PR_LOG_DEBUG, ("%p StopPlayback()", mDecoder.get()));
 
-  NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
-               "Should be on state machine thread or the decoder thread.");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   mDecoder->NotifyPlaybackStopped();
 
   if (IsPlaying()) {
     mPlayDuration += DurationToUsecs(TimeStamp::Now() - mPlayStartTime);
     mPlayStartTime = TimeStamp();
   }
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -498,23 +498,21 @@ private:
   nsresult StartAudioThread();
 
   // The main loop for the audio thread. Sent to the thread as
   // an nsRunnableMethod. This continually does blocking writes to
   // to audio stream to play audio data.
   void AudioLoop();
 
   // Sets internal state which causes playback of media to pause.
-  // The decoder monitor must be held. Called on the state machine,
-  // and decode threads.
+  // The decoder monitor must be held.
   void StopPlayback();
 
   // Sets internal state which causes playback of media to begin or resume.
-  // Must be called with the decode monitor held. Called on the state machine
-  // and decode threads.
+  // Must be called with the decode monitor held.
   void StartPlayback();
 
   // Moves the decoder into decoding state. Called on the state machine
   // thread. The decoder monitor must be held.
   void StartDecoding();
 
   void StartWaitForResources();
 
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -1408,52 +1408,30 @@ private:
   nsCOMPtr<nsIInputStream>  mInput;
 
   // Whether we've attempted to initialize mSize. Note that mSize can be -1
   // when mSizeInitialized is true if we tried and failed to get the size
   // of the file.
   bool mSizeInitialized;
 };
 
-class LoadedEvent : public nsRunnable
-{
-public:
-  LoadedEvent(MediaDecoder* aDecoder) :
-    mDecoder(aDecoder)
-  {
-    MOZ_COUNT_CTOR(LoadedEvent);
-  }
-  ~LoadedEvent()
-  {
-    MOZ_COUNT_DTOR(LoadedEvent);
-  }
-
-  NS_IMETHOD Run() {
-    mDecoder->NotifyDownloadEnded(NS_OK);
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<MediaDecoder> mDecoder;
-};
-
 void FileMediaResource::EnsureSizeInitialized()
 {
   mLock.AssertCurrentThreadOwns();
   NS_ASSERTION(mInput, "Must have file input stream");
   if (mSizeInitialized) {
     return;
   }
   mSizeInitialized = true;
   // Get the file size and inform the decoder.
   uint64_t size;
   nsresult res = mInput->Available(&size);
   if (NS_SUCCEEDED(res) && size <= INT64_MAX) {
     mSize = (int64_t)size;
-    nsCOMPtr<nsIRunnable> event = new LoadedEvent(mDecoder);
+    nsCOMPtr<nsIRunnable> event = new DataEnded(mDecoder, NS_OK);
     NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   }
 }
 
 nsresult FileMediaResource::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
 {
   MutexAutoLock lock(mLock);
 
new file mode 100644
--- /dev/null
+++ b/content/media/test/crashtests/933151.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+  var ac = new window.AudioContext();
+  var buffer = ac.createBuffer(1, 24313, 47250);
+  buffer.copyFromChannel(buffer.getChannelData(0), '');
+}
+
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -55,12 +55,13 @@ load 907986-1.html
 load 907986-2.html
 load 907986-3.html
 load 907986-4.html
 load 910171-1.html
 load 920987.html
 load 925619-1.html
 load 925619-2.html
 load 926619.html
+load 933151.html
 load offline-buffer-source-ended-1.html
 skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338
 skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338
 test-pref(media.mediasource.enabled,true) load 926665.html
--- a/content/media/webaudio/AudioBuffer.cpp
+++ b/content/media/webaudio/AudioBuffer.cpp
@@ -126,17 +126,17 @@ AudioBuffer::CopyFromChannel(const Float
     // The array was probably neutered
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return;
   }
 
   const float* sourceData = mSharedChannels ?
     mSharedChannels->GetData(aChannelNumber) :
     JS_GetFloat32ArrayData(mJSChannels[aChannelNumber]);
-  PodCopy(aDestination.Data(), sourceData + aStartInChannel, length);
+  PodMove(aDestination.Data(), sourceData + aStartInChannel, length);
 }
 
 void
 AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
                            uint32_t aChannelNumber, uint32_t aStartInChannel,
                            ErrorResult& aRv)
 {
   uint32_t length = aSource.Length();
@@ -154,17 +154,17 @@ AudioBuffer::CopyToChannel(JSContext* aJ
     return;
   }
 
   if (!RestoreJSChannelData(aJSContext)) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
-  PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannelNumber]) + aStartInChannel,
+  PodMove(JS_GetFloat32ArrayData(mJSChannels[aChannelNumber]) + aStartInChannel,
           aSource.Data(), length);
 }
 
 void
 AudioBuffer::SetRawChannelContents(JSContext* aJSContext, uint32_t aChannel,
                                    float* aContents)
 {
   PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannel]), aContents, mLength);
--- a/dom/messages/SystemMessageManager.js
+++ b/dom/messages/SystemMessageManager.js
@@ -131,17 +131,16 @@ SystemMessageManager.prototype = {
       delete dispatchers[aType];
       return;
     }
 
     // Last registered handler wins.
     dispatchers[aType] = { handler: aHandler, messages: [], isHandling: false };
 
     // Ask for the list of currently pending messages.
-    this.addMessageListeners("SystemMessageManager:GetPendingMessages:Return");
     cpmm.sendAsyncMessage("SystemMessageManager:GetPendingMessages",
                           { type: aType,
                             uri: this._uri,
                             manifest: this._manifest });
   },
 
   mozHasPendingMessage: function sysMessMgr_hasPendingMessage(aType) {
     debug("asking pending message for [" + aType + "]");
@@ -210,18 +209,16 @@ SystemMessageManager.prototype = {
     if (aMessage.name == "SystemMessageManager:Message") {
       // Send an acknowledgement to parent to clean up the pending message,
       // so a re-launched app won't handle it again, which is redundant.
       cpmm.sendAsyncMessage("SystemMessageManager:Message:Return:OK",
                             { type: msg.type,
                               manifest: this._manifest,
                               uri: this._uri,
                               msgID: msg.msgID });
-    } else if (aMessage.name == "SystemMessageManager:GetPendingMessages:Return") {
-      this.removeMessageListeners(aMessage.name);
     }
 
     let messages = (aMessage.name == "SystemMessageManager:Message")
                    ? [msg.msg]
                    : msg.msgQueue;
 
     // We only dispatch messages when a handler is registered.
     let dispatcher = this._dispatchers[msg.type];
@@ -246,17 +243,18 @@ SystemMessageManager.prototype = {
                                    "handle-system-messages-done",
                                    /* aData */ null);
     }
   },
 
   // nsIDOMGlobalPropertyInitializer implementation.
   init: function sysMessMgr_init(aWindow) {
     debug("init");
-    this.initDOMRequestHelper(aWindow, ["SystemMessageManager:Message"]);
+    this.initDOMRequestHelper(aWindow, ["SystemMessageManager:Message",
+                              "SystemMessageManager:GetPendingMessages:Return"]);
 
     let principal = aWindow.document.nodePrincipal;
     this._isInBrowserElement = principal.isInBrowserElement;
     this._uri = principal.URI.spec;
 
     let appsService = Cc["@mozilla.org/AppsService;1"]
                         .getService(Ci.nsIAppsService);
     this._manifest = appsService.getManifestURLByLocalId(principal.appId);
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -45,16 +45,37 @@ RotatedBuffer::GetQuadrantRectangle(XSid
   // quadrantTranslation is the amount we translate the top-left
   // of the quadrant by to get coordinates relative to the layer
   nsIntPoint quadrantTranslation = -mBufferRotation;
   quadrantTranslation.x += aXSide == LEFT ? mBufferRect.width : 0;
   quadrantTranslation.y += aYSide == TOP ? mBufferRect.height : 0;
   return mBufferRect + quadrantTranslation;
 }
 
+Rect
+RotatedBuffer::GetSourceRectangle(XSide aXSide, YSide aYSide) const
+{
+  Rect result;
+  if (aXSide == LEFT) {
+    result.x = 0;
+    result.width = mBufferRotation.x;
+  } else {
+    result.x = mBufferRotation.x;
+    result.width = mBufferRect.width - mBufferRotation.x;
+  }
+  if (aYSide == TOP) {
+    result.y = 0;
+    result.height = mBufferRotation.y;
+  } else {
+    result.y = mBufferRotation.y;
+    result.height = mBufferRect.height - mBufferRotation.y;
+  }
+  return result;
+}
+
 /**
  * @param aXSide LEFT means we draw from the left side of the buffer (which
  * is drawn on the right side of mBufferRect). RIGHT means we draw from
  * the right side of the buffer (which is drawn on the left side of
  * mBufferRect).
  * @param aYSide TOP means we draw from the top side of the buffer (which
  * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
  * the bottom side of the buffer (which is drawn on the top side of
@@ -173,51 +194,70 @@ RotatedBuffer::DrawBufferQuadrant(gfx::D
   // mBufferRect
   nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide);
   nsIntRect fillRect;
   if (!fillRect.IntersectRect(mBufferRect, quadrantRect))
     return;
 
   gfx::Point quadrantTranslation(quadrantRect.x, quadrantRect.y);
 
+  MOZ_ASSERT(aOperator == OP_OVER || aOperator == OP_SOURCE);
+  // direct2d is much slower when using OP_SOURCE so use OP_OVER and
+  // (maybe) a clear instead. Normally we need to draw in a single operation
+  // (to avoid flickering) but direct2d is ok since it defers rendering.
+  // We should try abstract this logic in a helper when we have other use
+  // cases.
+  if (aTarget->GetType() == BACKEND_DIRECT2D && aOperator == OP_SOURCE) {
+    aOperator = OP_OVER;
+    if (mDTBuffer->GetFormat() == FORMAT_B8G8R8A8) {
+      aTarget->ClearRect(ToRect(fillRect));
+    }
+  }
+
   RefPtr<SourceSurface> snapshot;
   if (aSource == BUFFER_BLACK) {
     snapshot = mDTBuffer->Snapshot();
   } else {
     MOZ_ASSERT(aSource == BUFFER_WHITE);
     snapshot = mDTBufferOnWhite->Snapshot();
   }
 
-  // Transform from user -> buffer space.
-  Matrix transform;
-  transform.Translate(quadrantTranslation.x, quadrantTranslation.y);
-
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-  SurfacePattern source(snapshot, EXTEND_CLAMP, transform, FILTER_POINT);
-#else
-  SurfacePattern source(snapshot, EXTEND_CLAMP, transform);
-#endif
-
   if (aOperator == OP_SOURCE) {
     // OP_SOURCE is unbounded in Azure, and we really don't want that behaviour here.
     // We also can't do a ClearRect+FillRect since we need the drawing to happen
     // as an atomic operation (to prevent flickering).
     aTarget->PushClipRect(gfx::Rect(fillRect.x, fillRect.y,
                                     fillRect.width, fillRect.height));
   }
 
   if (aMask) {
+    // Transform from user -> buffer space.
+    Matrix transform;
+    transform.Translate(quadrantTranslation.x, quadrantTranslation.y);
+
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+    SurfacePattern source(snapshot, EXTEND_CLAMP, transform, FILTER_POINT);
+#else
+    SurfacePattern source(snapshot, EXTEND_CLAMP, transform);
+#endif
+
     Matrix oldTransform = aTarget->GetTransform();
     aTarget->SetTransform(*aMaskTransform);
     aTarget->MaskSurface(source, aMask, Point(0, 0), DrawOptions(aOpacity, aOperator));
     aTarget->SetTransform(oldTransform);
   } else {
-    aTarget->FillRect(gfx::Rect(fillRect.x, fillRect.y,
-                                fillRect.width, fillRect.height),
-                      source, DrawOptions(aOpacity, aOperator));
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+    DrawSurfaceOptions options(FILTER_POINT);
+#else
+    DrawSurfaceOptions options;
+#endif
+    aTarget->DrawSurface(snapshot, ToRect(fillRect),
+                         GetSourceRectangle(aXSide, aYSide),
+                         options,
+                         DrawOptions(aOpacity, aOperator));
   }
 
   if (aOperator == OP_SOURCE) {
     aTarget->PopClip();
   }
 
   aTarget->Flush();
 }
--- a/gfx/layers/ThebesLayerBuffer.h
+++ b/gfx/layers/ThebesLayerBuffer.h
@@ -107,16 +107,18 @@ protected:
   enum XSide {
     LEFT, RIGHT
   };
   enum YSide {
     TOP, BOTTOM
   };
   nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const;
 
+  gfx::Rect GetSourceRectangle(XSide aXSide, YSide aYSide) const;
+
   /*
    * If aMask is non-null, then it is used as an alpha mask for rendering this
    * buffer. aMaskTransform must be non-null if aMask is non-null, and is used
    * to adjust the coordinate space of the mask.
    */
   void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide,
                           ContextSource aSource,
                           float aOpacity,
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -1527,16 +1527,20 @@ void AsyncPanZoomController::SendAsyncSc
     contentRect.MoveTo(mCurrentAsyncScrollOffset);
   }
 
   controller->SendAsyncScrollDOMEvent(scrollId, contentRect, scrollableSize);
 }
 
 void AsyncPanZoomController::UpdateScrollOffset(const CSSPoint& aScrollOffset)
 {
+  APZC_LOG("Updating scroll offset from (%f, %f) to (%f, %f)\n",
+    mFrameMetrics.mScrollOffset.x, mFrameMetrics.mScrollOffset.y,
+    aScrollOffset.x, aScrollOffset.y);
+
   ReentrantMonitorAutoEnter lock(mMonitor);
   mFrameMetrics.mScrollOffset = aScrollOffset;
 }
 
 bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid)
 {
   // TODO: also check the presShellId, once that is fully propagated
   // everywhere in RenderFrameParent and AndroidJNI.
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -10,35 +10,39 @@
 
 #include "mozilla/Util.h"
 
 #include "gfxFontUtils.h"
 
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
 
 #include "nsIUUIDGenerator.h"
 #include "nsICharsetConverterManager.h"
+#include "nsIObserverService.h"
+#include "nsCRT.h"
 
 #include "harfbuzz/hb.h"
 
 #include "plbase64.h"
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 
 #define LOG(log, args) PR_LOG(gfxPlatform::GetLog(log), \
                                PR_LOG_DEBUG, args)
 
 #endif // PR_LOGGING
 
 #define UNICODE_BMP_LIMIT 0x10000
 
 using namespace mozilla;
+using mozilla::services::GetObserverService;
 
 #pragma pack(1)
 
 typedef struct {
     AutoSwap_PRUint16 format;
     AutoSwap_PRUint16 reserved;
     AutoSwap_PRUint32 length;
     AutoSwap_PRUint32 language;
@@ -1420,8 +1424,112 @@ gfxFontUtils::IsCffFont(const uint8_t* a
 {
     // this is only called after aFontData has passed basic validation,
     // so we know there is enough data present to allow us to read the version!
     const SFNTHeader *sfntHeader = reinterpret_cast<const SFNTHeader*>(aFontData);
     return (sfntHeader->sfntVersion == TRUETYPE_TAG('O','T','T','O'));
 }
 
 #endif
+
+NS_IMPL_ISUPPORTS1(gfxFontInfoLoader::ShutdownObserver, nsIObserver)
+
+NS_IMETHODIMP
+gfxFontInfoLoader::ShutdownObserver::Observe(nsISupports *aSubject,
+                                             const char *aTopic,
+                                             const PRUnichar *someData)
+{
+    if (!nsCRT::strcmp(aTopic, "quit-application")) {
+        mLoader->CancelLoader();
+    } else {
+        NS_NOTREACHED("unexpected notification topic");
+    }
+    return NS_OK;
+}
+
+void
+gfxFontInfoLoader::StartLoader(uint32_t aDelay, uint32_t aInterval)
+{
+    mInterval = aInterval;
+
+    // sanity check
+    if (mState != stateInitial && mState != stateTimerOff) {
+        CancelLoader();
+    }
+
+    // set up timer
+    if (!mTimer) {
+        mTimer = do_CreateInstance("@mozilla.org/timer;1");
+        if (!mTimer) {
+            NS_WARNING("Failure to create font info loader timer");
+            return;
+        }
+    }
+
+    // need an initial delay?
+    uint32_t timerInterval;
+
+    if (aDelay) {
+        mState = stateTimerOnDelay;
+        timerInterval = aDelay;
+    } else {
+        mState = stateTimerOnInterval;
+        timerInterval = mInterval;
+    }
+
+    InitLoader();
+
+    // start timer
+    mTimer->InitWithFuncCallback(LoaderTimerCallback, this, timerInterval,
+                                 nsITimer::TYPE_REPEATING_SLACK);
+
+    nsCOMPtr<nsIObserverService> obs = GetObserverService();
+    if (obs) {
+        mObserver = new ShutdownObserver(this);
+        obs->AddObserver(mObserver, "quit-application", false);
+    }
+}
+
+void
+gfxFontInfoLoader::CancelLoader()
+{
+    if (mState == stateInitial) {
+        return;
+    }
+    mState = stateTimerOff;
+    if (mTimer) {
+        mTimer->Cancel();
+        mTimer = nullptr;
+    }
+    RemoveShutdownObserver();
+    FinishLoader();
+}
+
+void
+gfxFontInfoLoader::LoaderTimerFire()
+{
+    if (mState == stateTimerOnDelay) {
+        mState = stateTimerOnInterval;
+        mTimer->SetDelay(mInterval);
+    }
+
+    bool done = RunLoader();
+    if (done) {
+        CancelLoader();
+    }
+}
+
+gfxFontInfoLoader::~gfxFontInfoLoader()
+{
+    RemoveShutdownObserver();
+}
+
+void
+gfxFontInfoLoader::RemoveShutdownObserver()
+{
+    if (mObserver) {
+        nsCOMPtr<nsIObserverService> obs = GetObserverService();
+        if (obs) {
+            obs->RemoveObserver(mObserver, "quit-application");
+            mObserver = nullptr;
+        }
+    }
+}
--- a/gfx/thebes/gfxFontUtils.h
+++ b/gfx/thebes/gfxFontUtils.h
@@ -7,16 +7,17 @@
 #define GFX_FONT_UTILS_H
 
 #include "gfxPlatform.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
+#include "nsIObserver.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Endian.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "zlib.h"
 #include <algorithm>
 
 /* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
@@ -958,91 +959,60 @@ public:
         stateTimerOff
     } TimerState;
 
     gfxFontInfoLoader() :
         mInterval(0), mState(stateInitial)
     {
     }
 
-    virtual ~gfxFontInfoLoader() {}
+    virtual ~gfxFontInfoLoader();
 
     // start timer with an initial delay, then call Run method at regular intervals
-    void StartLoader(uint32_t aDelay, uint32_t aInterval) {
-        mInterval = aInterval;
-
-        // sanity check
-        if (mState != stateInitial && mState != stateTimerOff)
-            CancelLoader();
-
-        // set up timer
-        if (!mTimer) {
-            mTimer = do_CreateInstance("@mozilla.org/timer;1");
-            if (!mTimer) {
-                NS_WARNING("Failure to create font info loader timer");
-                return;
-            }
-        }
-
-        // need an initial delay?
-        uint32_t timerInterval;
-
-        if (aDelay) {
-            mState = stateTimerOnDelay;
-            timerInterval = aDelay;
-        } else {
-            mState = stateTimerOnInterval;
-            timerInterval = mInterval;
-        }
-
-        InitLoader();
-
-        // start timer
-        mTimer->InitWithFuncCallback(LoaderTimerCallback, this, timerInterval,
-                                     nsITimer::TYPE_REPEATING_SLACK);
-    }
+    void StartLoader(uint32_t aDelay, uint32_t aInterval);
 
     // cancel the timer and cleanup
-    void CancelLoader() {
-        if (mState == stateInitial)
-            return;
-        mState = stateTimerOff;
-        if (mTimer) {
-            mTimer->Cancel();
-        }
-        FinishLoader();
-    }
+    void CancelLoader();
 
 protected:
+    class ShutdownObserver : public nsIObserver
+    {
+    public:
+        NS_DECL_ISUPPORTS
+        NS_DECL_NSIOBSERVER
+
+        ShutdownObserver(gfxFontInfoLoader *aLoader)
+            : mLoader(aLoader)
+        { }
+
+        virtual ~ShutdownObserver()
+        { }
+
+    protected:
+        gfxFontInfoLoader *mLoader;
+    };
 
     // Init - initialization at start time after initial delay
     virtual void InitLoader() = 0;
 
     // Run - called at intervals, return true to indicate done
     virtual bool RunLoader() = 0;
 
     // Finish - cleanup after done
     virtual void FinishLoader() = 0;
 
+    // Timer interval callbacks
     static void LoaderTimerCallback(nsITimer *aTimer, void *aThis) {
         gfxFontInfoLoader *loader = static_cast<gfxFontInfoLoader*>(aThis);
         loader->LoaderTimerFire();
     }
 
-    // start the timer, interval callbacks
-    void LoaderTimerFire() {
-        if (mState == stateTimerOnDelay) {
-            mState = stateTimerOnInterval;
-            mTimer->SetDelay(mInterval);
-        }
+    void LoaderTimerFire();
 
-        bool done = RunLoader();
-        if (done) {
-            CancelLoader();
-        }
-    }
+    void RemoveShutdownObserver();
 
     nsCOMPtr<nsITimer> mTimer;
+    nsCOMPtr<nsIObserver> mObserver;
     uint32_t mInterval;
     TimerState mState;
 };
 
 #endif /* GFX_FONT_UTILS_H */
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -560,19 +560,16 @@ install:: $(LIBRARY_NAME).pc
 #          js/src/gc/* public headers
 #        mozilla/
 #          mfbt headers
 #
 
 install::
 	$(call py_action,process_install_manifest,--no-remove $(DESTDIR)$(includedir)/$(LIBRARY_NAME) _build_manifests/install/dist_include)
 
-install:: $(EXPORTS_mozilla)
-	$(SYSINSTALL) $^ $(DESTDIR)$(includedir)/$(LIBRARY_NAME)/mozilla
-
 #
 # END SpiderMonkey header installation
 #############################################
 
 install:: $(SCRIPTS)
 	$(SYSINSTALL) $^ $(DESTDIR)$(bindir)
 
 install:: $(REAL_LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1642,18 +1642,21 @@ ia64*-hpux*)
         _USE_CPP_INCLUDE_FLAG=1
         _DEFINES_CFLAGS='-FI $(DEPTH)/js-confdefs.h -DMOZILLA_CLIENT'
         _DEFINES_CXXFLAGS='-FI $(DEPTH)/js-confdefs.h -DMOZILLA_CLIENT'
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         if test "$_CC_SUITE" -ge "12"; then
             dnl VS2013+ requires -FS when parallel building by make -jN.
             dnl If nothing, compiler sometimes causes C1041 error.
-            CFLAGS="$CFLAGS -FS"
-            CXXFLAGS="$CXXFLAGS -FS"
+            dnl
+            dnl Visual Studio 2013 supports -Gw flags
+            dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx
+            CFLAGS="$CFLAGS -FS -Gw"
+            CXXFLAGS="$CXXFLAGS -FS -Gw"
         fi
         # khuey says we can safely ignore MSVC warning C4251
         # MSVC warning C4244 (implicit type conversion may lose data) warns
         # and requires workarounds for perfectly valid code.  Also, GCC/clang
         # don't warn about it by default. So for consistency/sanity, we turn
         # it off on MSVC, too.
         CFLAGS="$CFLAGS -wd4244"
         CXXFLAGS="$CXXFLAGS -wd4244 -wd4251"
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -286,19 +286,19 @@ GetObjectAllocKindForCopy(JSRuntime *rt,
         size_t nelements = obj->getDenseCapacity();
         return GetBackgroundAllocKind(GetGCArrayKind(nelements));
     }
 
     if (obj->is<JSFunction>())
         return obj->as<JSFunction>().getAllocKind();
 
     AllocKind kind = GetGCObjectFixedSlotsKind(obj->numFixedSlots());
-    if (CanBeFinalizedInBackground(kind, obj->getClass()))
-        kind = GetBackgroundAllocKind(kind);
-    return kind;
+    JS_ASSERT(!IsBackgroundFinalized(kind));
+    JS_ASSERT(CanBeFinalizedInBackground(kind, obj->getClass()));
+    return GetBackgroundAllocKind(kind);
 }
 
 void *
 js::Nursery::allocateFromTenured(Zone *zone, AllocKind thingKind)
 {
     void *t = zone->allocator.arenas.allocateFromFreeList(thingKind, Arena::thingSize(thingKind));
     if (t)
         return t;
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -855,17 +855,18 @@ class ModuleChars
             cursor = DeserializeVector(cx, cursor, &funCtorArgs_);
         return cursor;
     }
 
     bool matchUnparsedModule(const AsmJSParser &parser) const {
         uint32_t parseBeginOffset = parser.pc->maybeFunction->pn_pos.begin;
         const jschar *parseBegin = parser.tokenStream.rawBase() + parseBeginOffset;
         const jschar *parseLimit = parser.tokenStream.rawLimit();
-        if (parseLimit - parseBegin < length_)
+        JS_ASSERT(parseLimit >= parseBegin);
+        if (uint32_t(parseLimit - parseBegin) < length_)
             return false;
         if (!PodEqual(begin_, parseBegin, length_))
             return false;
         if (isFunCtor_ != parser.pc->isFunctionConstructorBody())
             return false;
         if (isFunCtor_) {
             // For function statements, the closing } is included as the last
             // character of the matched source. For Function constructor,
--- a/js/src/jit/Snapshots.cpp
+++ b/js/src/jit/Snapshots.cpp
@@ -357,17 +357,17 @@ SnapshotWriter::writeSlotHeader(JSValueT
 
     slotsWritten_++;
     JS_ASSERT(slotsWritten_ <= nslots_);
 }
 
 void
 SnapshotWriter::addSlot(const FloatRegister &reg)
 {
-    JS_ASSERT(reg.code() < MIN_REG_FIELD_ESC);
+    JS_ASSERT(uint32_t(reg.code()) < MIN_REG_FIELD_ESC);
     IonSpew(IonSpew_Snapshots, "    slot %u: double (reg %s)", slotsWritten_, reg.name());
 
     writeSlotHeader(JSVAL_TYPE_DOUBLE, reg.code());
 }
 
 static const char *
 ValTypeToString(JSValueType type)
 {
@@ -514,17 +514,17 @@ SnapshotWriter::addInt32Slot(int32_t val
         writeSlotHeader(JSVAL_TYPE_NULL, ESC_REG_FIELD_INDEX);
         writer_.writeSigned(value);
     }
 }
 
 void
 SnapshotWriter::addFloat32Slot(const FloatRegister &reg)
 {
-    JS_ASSERT(reg.code() < MIN_REG_FIELD_ESC);
+    JS_ASSERT(uint32_t(reg.code()) < MIN_REG_FIELD_ESC);
     IonSpew(IonSpew_Snapshots, "    slot %u: float32 (reg %s)", slotsWritten_, reg.name());
     writeSlotHeader(JSVAL_TYPE_NULL, ESC_REG_FIELD_FLOAT32_REG);
     writer_.writeUnsigned(reg.code());
 }
 
 void
 SnapshotWriter::addFloat32Slot(int32_t stackIndex)
 {
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -115,17 +115,17 @@ interface nsIXPCComponents_utils_Sandbox
 interface ScheduledGCCallback : nsISupports
 {
     void callback();
 };
 
 /**
 * interface of Components.utils
 */
-[scriptable, uuid(08a49c33-0704-4b88-bebb-9a0cf1309f30)]
+[scriptable, uuid(90019271-a0d1-439f-911c-967f8e85cd5b)]
 interface nsIXPCComponents_Utils : nsISupports
 {
 
     /* reportError is designed to be called from JavaScript only.
      *
      * It will report a JS Error object to the JS console, and return. It
      * is meant for use in exception handler blocks which want to "eat"
      * an exception, but still want to report it to the console.
@@ -303,22 +303,54 @@ interface nsIXPCComponents_Utils : nsISu
      *
      * @param obj The JavaScript object whose global is to be gotten.
      * @return the corresponding global.
      */
     [implicit_jscontext]
     jsval getGlobalForObject(in jsval obj);
 
     /*
+     * Similar to evalInSandbox except this one is used to eval a script in the
+     * scope of a window. Also note, that the return value and the possible exceptions
+     * in the script are structured cloned, unless they are natives (then they are just
+     * wrapped).
+     * Principal of the caller must subsume the target's.
+     */
+    [implicit_jscontext]
+    jsval evalInWindow(in AString source, in jsval window);
+
+    /*
+     * To be called from JS only.
+     *
+     * Instead of simply wrapping a function into another compartment,
+     * this helper function creates a native function in the target
+     * compartment and forwards the call to the original function.
+     * That call will be different than a regular JS function call in
+     * that, the |this| is left unbound, and all the non-native JS
+     * object arguments will be cloned using the structured clone
+     * algorithm.
+     * The return value is the new forwarder function, wrapped into
+     * the caller's compartment.
+     * The 3rd argument is the name of the property that will
+     * be set on the target scope, with the forwarder function as
+     * the value.
+     */
+    [implicit_jscontext]
+    jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname);
+
+    /*
      * To be called from JS only.
      *
      * Returns an object created in |vobj|'s compartment.
+     * If defineAs property on the options object is a non-null ID,
+     * the new object will be added to vobj as a property. Also, the
+     * returned new object is always automatically waived (see waiveXrays).
      */
     [implicit_jscontext]
-    jsval createObjectIn(in jsval vobj);
+    jsval createObjectIn(in jsval vobj, [optional] in jsval voptions);
 
     /*
      * To be called from JS only.
      *
      * Returns an array created in |vobj|'s compartment.
      */
     [implicit_jscontext]
     jsval createArrayIn(in jsval vobj);
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -210,54 +210,30 @@ CreateXMLHttpRequest(JSContext *cx, unsi
 
     rv = nsContentUtils::WrapNative(cx, global, xhr, args.rval());
     if (NS_FAILED(rv))
         return false;
 
     return true;
 }
 
-/*
- * Instead of simply wrapping a function into another compartment,
- * this helper function creates a native function in the target
- * compartment and forwards the call to the original function.
- * That call will be different than a regular JS function call in
- * that, the |this| is left unbound, and all the non-native JS
- * object arguments will be cloned using the structured clone
- * algorithm.
- * The return value is the new forwarder function, wrapped into
- * the caller's compartment.
- * The 3rd argument is the name of the property that will
- * be set on the target scope, with the forwarder function as
- * the value.
- * The principal of the caller must subsume that of the target.
- *
- * Expected type of the arguments and the return value:
- * function exportFunction(function funToExport,
- *                         object targetScope,
- *                         string name)
- */
-static bool
-ExportFunction(JSContext *cx, unsigned argc, jsval *vp)
+namespace xpc {
+
+bool
+ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleValue vname,
+               MutableHandleValue rval)
 {
-    MOZ_ASSERT(cx);
-    if (argc < 3) {
-        JS_ReportError(cx, "Function requires at least 3 arguments");
-        return false;
-    }
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (!args[0].isObject() || !args[1].isObject() || !args[2].isString()) {
+    if (!vscope.isObject() || !vfunction.isObject() || !vname.isString()) {
         JS_ReportError(cx, "Invalid argument");
         return false;
     }
 
-    RootedObject funObj(cx, &args[0].toObject());
-    RootedObject targetScope(cx, &args[1].toObject());
-    RootedString funName(cx, args[2].toString());
+    RootedObject funObj(cx, &vfunction.toObject());
+    RootedObject targetScope(cx, &vscope.toObject());
+    RootedString funName(cx, vname.toString());
 
     // We can only export functions to scopes those are transparent for us,
     // so if there is a security wrapper around targetScope we must throw.
     targetScope = CheckedUnwrap(targetScope);
     if (!targetScope) {
         JS_ReportError(cx, "Permission denied to export function into scope");
         return false;
     }
@@ -281,41 +257,61 @@ ExportFunction(JSContext *cx, unsigned a
 
         // The function forwarder will live in the target compartment. Since
         // this function will be referenced from its private slot, to avoid a
         // GC hazard, we must wrap it to the same compartment.
         if (!JS_WrapObject(cx, &funObj))
             return false;
 
         RootedId id(cx);
-        if (!JS_ValueToId(cx, args[2], id.address()))
+        if (!JS_ValueToId(cx, vname, id.address()))
             return false;
 
         // And now, let's create the forwarder function in the target compartment
         // for the function the be exported.
-        if (!NewFunctionForwarder(cx, id, funObj, /* doclone = */ true, args.rval())) {
+        if (!NewFunctionForwarder(cx, id, funObj, /* doclone = */ true, rval)) {
             JS_ReportError(cx, "Exporting function failed");
             return false;
         }
 
         // We have the forwarder function in the target compartment, now
         // we have to add it to the target scope as a property.
-        if (!JS_DefinePropertyById(cx, targetScope, id, args.rval(),
+        if (!JS_DefinePropertyById(cx, targetScope, id, rval,
                                    JS_PropertyStub, JS_StrictPropertyStub,
                                    JSPROP_ENUMERATE))
             return false;
     }
 
     // Finally we have to re-wrap the exported function back to the caller compartment.
-    if (!JS_WrapValue(cx, args.rval()))
+    if (!JS_WrapValue(cx, rval))
         return false;
 
     return true;
 }
 
+/*
+ * Expected type of the arguments and the return value:
+ * function exportFunction(function funToExport,
+ *                         object targetScope,
+ *                         string name)
+ */
+static bool
+ExportFunction(JSContext *cx, unsigned argc, jsval *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if (args.length() < 3) {
+        JS_ReportError(cx, "Function requires at least 3 arguments");
+        return false;
+    }
+
+    return ExportFunction(cx, args[0], args[1],
+                          args[2], args.rval());
+}
+} /* namespace xpc */
+
 static bool
 GetFilenameAndLineNumber(JSContext *cx, nsACString &filename, unsigned &lineno)
 {
     JS::RootedScript script(cx);
     if (JS_DescribeScriptedCaller(cx, &script, &lineno)) {
         if (const char *cfilename = JS_GetScriptFilename(cx, script)) {
             filename.Assign(nsDependentCString(cfilename));
             return true;
@@ -426,47 +422,23 @@ CloneNonReflectors(JSContext *cx, Mutabl
         &rootedReflectors))
     {
         return false;
     }
 
     return true;
 }
 
-/*
- * Similar to evalInSandbox except this one is used to eval a script in the
- * scope of a window. Also note, that the return value and the possible exceptions
- * in the script are structured cloned, unless they are natives (then they are just
- * wrapped).
- * Principal of the caller must subsume the target's.
- *
- * Expected type of the arguments:
- * value evalInWindow(string script,
- *                    object window)
- */
-static bool
-EvalInWindow(JSContext *cx, unsigned argc, jsval *vp)
+namespace xpc {
+
+bool
+EvalInWindow(JSContext *cx, const nsAString &source, HandleObject scope, MutableHandleValue rval)
 {
-    MOZ_ASSERT(cx);
-    if (argc < 2) {
-        JS_ReportError(cx, "Function requires two arguments");
-        return false;
-    }
-
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (!args[0].isString() || !args[1].isObject()) {
-        JS_ReportError(cx, "Invalid arguments");
-        return false;
-    }
-
-    RootedString srcString(cx, args[0].toString());
-    RootedObject targetScope(cx, &args[1].toObject());
-
     // If we cannot unwrap we must not eval in it.
-    targetScope = CheckedUnwrap(targetScope);
+    RootedObject targetScope(cx, CheckedUnwrap(scope));
     if (!targetScope) {
         JS_ReportError(cx, "Permission denied to eval in target scope");
         return false;
     }
 
     // Make sure that we have a window object.
     RootedObject inner(cx, CheckedUnwrap(targetScope, /* stopAtOuter = */ false));
     nsCOMPtr<nsIGlobalObject> global;
@@ -494,74 +466,101 @@ EvalInWindow(JSContext *cx, unsigned arg
     nsCString filename;
     unsigned lineNo;
     if (!GetFilenameAndLineNumber(cx, filename, lineNo)) {
         // Default values for non-scripted callers.
         filename.Assign("Unknown");
         lineNo = 0;
     }
 
-    nsDependentJSString srcDepString;
-    srcDepString.init(cx, srcString);
-
     {
         // CompileOptions must be created from the context
         // we will execute this script in.
         JSContext *wndCx = context->GetNativeContext();
         AutoCxPusher pusher(wndCx);
         JS::CompileOptions compileOptions(wndCx);
         compileOptions.setFileAndLine(filename.get(), lineNo);
 
         // We don't want the JS engine to automatically report
         // uncaught exceptions.
         nsJSUtils::EvaluateOptions evaluateOptions;
         evaluateOptions.setReportUncaught(false);
 
         nsresult rv = nsJSUtils::EvaluateString(wndCx,
-                                                srcDepString,
+                                                source,
                                                 targetScope,
                                                 compileOptions,
                                                 evaluateOptions,
-                                                args.rval().address());
+                                                rval.address());
 
         if (NS_FAILED(rv)) {
             // If there was an exception we get it as a return value, if
             // the evaluation failed for some other reason, then a default
             // exception is raised.
             MOZ_ASSERT(!JS_IsExceptionPending(wndCx),
                        "Exception should be delivered as return value.");
-            if (args.rval().isUndefined()) {
+            if (rval.isUndefined()) {
                 MOZ_ASSERT(rv == NS_ERROR_OUT_OF_MEMORY);
                 return false;
             }
 
             // If there was an exception thrown we should set it
             // on the calling context.
-            RootedValue exn(wndCx, args.rval());
+            RootedValue exn(wndCx, rval);
             // First we should reset the return value.
-            args.rval().set(UndefinedValue());
+            rval.set(UndefinedValue());
 
             // Then clone the exception.
             if (CloneNonReflectors(cx, &exn))
                 JS_SetPendingException(cx, exn);
 
             return false;
         }
     }
 
     // Let's clone the return value back to the callers compartment.
-    if (!CloneNonReflectors(cx, args.rval())) {
-        args.rval().set(UndefinedValue());
+    if (!CloneNonReflectors(cx, rval)) {
+        rval.set(UndefinedValue());
         return false;
     }
 
     return true;
 }
 
-namespace xpc {
+/*
+ * Expected type of the arguments:
+ * value evalInWindow(string script,
+ *                    object window)
+ */
+static bool
+EvalInWindow(JSContext *cx, unsigned argc, jsval *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if (args.length() < 2) {
+        JS_ReportError(cx, "Function requires two arguments");
+        return false;
+    }
+
+    if (!args[0].isString() || !args[1].isObject()) {
+        JS_ReportError(cx, "Invalid arguments");
+        return false;
+    }
+
+    RootedString srcString(cx, args[0].toString());
+    RootedObject targetScope(cx, &args[1].toObject());
+
+    nsDependentJSString srcDepString;
+    if (!srcDepString.init(cx, srcString)) {
+        JS_ReportError(cx, "Source string is invalid");
+        return false;
+    }
+
+    return EvalInWindow(cx, srcDepString, targetScope, args.rval());
+}
+
 static bool
 CreateObjectIn(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() < 1) {
         JS_ReportError(cx, "Function requires at least 1 argument");
         return false;
     }
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3020,42 +3020,84 @@ xpc::CreateObjectIn(JSContext *cx, Handl
         return false;
     }
 
     RootedObject scope(cx, js::CheckedUnwrap(&vobj.toObject()));
     if (!scope) {
         JS_ReportError(cx, "Permission denied to create object in the target scope");
         return false;
     }
+
     RootedObject obj(cx);
     {
         JSAutoCompartment ac(cx, scope);
         obj = JS_NewObject(cx, nullptr, nullptr, scope);
         if (!obj)
             return false;
 
         if (!JSID_IS_VOID(options.defineAs) &&
             !JS_DefinePropertyById(cx, scope, options.defineAs, ObjectValue(*obj),
-                                       JS_PropertyStub, JS_StrictPropertyStub,
-                                       JSPROP_ENUMERATE))
+                                   JS_PropertyStub, JS_StrictPropertyStub,
+                                   JSPROP_ENUMERATE))
             return false;
     }
 
-    if (!JS_WrapObject(cx, &obj))
-        return false;
-
     rval.setObject(*obj);
+    if (!WrapperFactory::WaiveXrayAndWrap(cx, rval))
+        return false;
+
     return true;
 }
 
-/* jsval createObjectIn(in jsval vobj); */
+/* jsval evalInWindow(in string source, in jsval window); */
+NS_IMETHODIMP
+nsXPCComponents_Utils::EvalInWindow(const nsAString &source, const Value &window,
+                                    JSContext *cx, Value *rval)
+{
+    if (!window.isObject())
+        return NS_ERROR_INVALID_ARG;
+
+    RootedObject rwindow(cx, &window.toObject());
+    RootedValue res(cx);
+    if (!xpc::EvalInWindow(cx, source, rwindow, &res))
+        return NS_ERROR_FAILURE;
+
+    *rval = res;
+    return NS_OK;
+}
+
+/* jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::ExportFunction(const Value &vfunction, const Value &vscope,
+                                      const Value &vname, JSContext *cx, Value *rval)
 {
-    CreateObjectInOptions options;
+    RootedValue rfunction(cx, vfunction);
+    RootedValue rscope(cx, vscope);
+    RootedValue rname(cx, vname);
+    RootedValue res(cx);
+    if (!xpc::ExportFunction(cx, rfunction, rscope, rname, &res))
+        return NS_ERROR_FAILURE;
+    *rval = res;
+    return NS_OK;
+}
+
+/* jsval createObjectIn(in jsval vobj, [optional] in jsval voptions); */
+NS_IMETHODIMP
+nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, const Value &voptions,
+                                      JSContext *cx, Value *rval)
+{
+    RootedObject optionsObject(cx, voptions.isObject() ? &voptions.toObject()
+                                                       : nullptr);
+    CreateObjectInOptions options(cx, optionsObject);
+    if (voptions.isObject() &&
+        !options.Parse())
+    {
+        return NS_ERROR_FAILURE;
+    }
+
     RootedValue rvobj(cx, vobj);
     RootedValue res(cx);
     if (!xpc::CreateObjectIn(cx, rvobj, options, &res))
         return NS_ERROR_FAILURE;
 
     *rval = res;
     return NS_OK;
 }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3720,16 +3720,24 @@ GetSandboxMetadata(JSContext *cx, JS::Ha
 nsresult
 SetSandboxMetadata(JSContext *cx, JS::HandleObject sandboxArg,
                    JS::HandleValue metadata);
 
 bool
 CreateObjectIn(JSContext *cx, JS::HandleValue vobj, CreateObjectInOptions &options,
                JS::MutableHandleValue rval);
 
+bool
+EvalInWindow(JSContext *cx, const nsAString &source, JS::HandleObject scope,
+             JS::MutableHandleValue rval);
+
+bool
+ExportFunction(JSContext *cx, JS::HandleValue vscope, JS::HandleValue vfunction,
+               JS::HandleValue vname, JS::MutableHandleValue rval);
+
 } /* namespace xpc */
 
 
 /***************************************************************************/
 // Inlined utilities.
 
 inline bool
 xpc_ForcePropertyResolve(JSContext* cx, JSObject* obj, jsid id);
--- a/js/xpconnect/tests/chrome/test_APIExposer.xul
+++ b/js/xpconnect/tests/chrome/test_APIExposer.xul
@@ -21,17 +21,18 @@ https://bugzilla.mozilla.org/show_bug.cg
       const Cu = Components.utils;
 
       var sandbox = new Cu.Sandbox("about:blank");
       sandbox.ok = ok;
       sandbox.is = is;
       Cu.evalInSandbox("Object.defineProperty(Object.prototype, 'getProp', { get: function() { throw 'FAIL: called getter' }, set: function() { throw 'FAIL: called setter'; } })", sandbox);
 
       var obj = Cu.createObjectIn(sandbox);
-      is(Object.getPrototypeOf(obj), Cu.evalInSandbox("Object.prototype", sandbox),
+      is(obj, Cu.waiveXrays(obj), "createObjectIn waives");
+      is(Object.getPrototypeOf(obj), Cu.waiveXrays(Cu.evalInSandbox("Object.prototype", sandbox)),
          "Object is a sandbox object");
 
       function genPropDesc(value) {
           return { enumerable: true, configurable: true, writable: true,
                    value: value };
       }
       const props = {
           'getProp': genPropDesc(function() { ok(true, "called prop that shadowed a getter"); }),
--- a/js/xpconnect/tests/chrome/test_evalInWindow.xul
+++ b/js/xpconnect/tests/chrome/test_evalInWindow.xul
@@ -46,16 +46,18 @@ https://bugzilla.mozilla.org/show_bug.cg
         is( executeIn(frame.contentWindow, "({a:{doc: document}})").a.doc, frame.contentWindow.document,
            "Deep cloning works.");
 
         executeIn(frame.contentWindow, "throw 42", function(e){is(e, 42,
                                                                   "Exception was thrown from script.")});
 
         executeIn(frame.contentDocument, "var a = 42;", function(e){ok(e.toString().indexOf("Second argument must be a window") > -1,
                                                                        "Passing non-window to evalInWindow should throw.");});
+        // evalInWindow is also available from Cu:
+        is(Cu.evalInWindow("document.str", frame.contentWindow), "foobar");
         testDone();
       }
 
       function testCrossOrigin(frame) {
         executeIn(frame.contentWindow, "var a = 42;", function(e){ok(e.toString().indexOf("Permission denied") > -1,
                                                                      "Executing script in a window from cross origin should throw.");});
         testDone();
       }
--- a/js/xpconnect/tests/components/native/Makefile.in
+++ b/js/xpconnect/tests/components/native/Makefile.in
@@ -1,28 +1,25 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE_NAME = xpconnect_test
 FORCE_SHARED_LIB = 1
 
-MANIFEST_FILE = xpctest.manifest
+componentdir = js/xpconnect/tests/components/native
+
+MANIFEST = xpctest.manifest
+MANIFEST_PATH = $(testxpcobjdir)/$(componentdir)
+PP_TARGETS += MANIFEST
 
 EXTRA_DSO_LDOPTS += \
   $(XPCOM_GLUE_LDOPTS) \
   $(MOZ_COMPONENT_LIBS) \
   $(MOZ_JS_LIBS) \
   $(NULL)
 
-include $(topsrcdir)/config/rules.mk
-
-
 DEFINES += -DLIBRARY_FILENAME="$(SHARED_LIBRARY)"
 
-componentdir = js/xpconnect/tests/components/native
-
-libs:: $(SHARED_LIBRARY)
-	$(INSTALL) $^ $(testxpcobjdir)/$(componentdir)
-
-libs:: $(MANIFEST_FILE)
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(componentdir)/$(<F)
+LIB_FILES = $(SHARED_LIBRARY)
+LIB_DEST = $(testxpcobjdir)/$(componentdir)
+INSTALL_TARGETS += LIB
--- a/js/xpconnect/tests/unit/test_exportFunction.js
+++ b/js/xpconnect/tests/unit/test_exportFunction.js
@@ -80,9 +80,20 @@ function run_test() {
 
   Cu.evalInSandbox("(" + function () {
     importedObject.privMethod(42, tobecloned, native, mixed);
   }.toSource() + ")()", subsb);
 
   Cu.evalInSandbox("(" + function() {
     checkIfCalled();
   }.toSource() + ")()", epsb);
+
+  // exportFunction and createObjectIn should be available from Cu too.
+  var newContentObject = Cu.createObjectIn(subsb, {defineAs:"importedObject2"});
+  var wasCalled = false;
+  Cu.exportFunction(function(arg){wasCalled = arg.wasCalled;}, newContentObject, "privMethod");
+
+  Cu.evalInSandbox("(" + function () {
+    importedObject2.privMethod({wasCalled: true});
+  }.toSource() + ")()", subsb);
+
+  do_check_true(wasCalled, true);
 }
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -676,44 +676,37 @@ static void RecordFrameMetrics(nsIFrame*
   }
   else {
     nsRect contentBounds = aForFrame->GetRect();
     metrics.mScrollableRect = CSSRect::FromAppUnits(contentBounds);
   }
 
   metrics.mScrollId = aScrollId;
 
+  // Only the root scrollable frame for a given presShell should pick up
+  // the presShell's resolution. All the other frames are 1.0.
   nsIPresShell* presShell = presContext->GetPresShell();
-  if (metrics.mScrollId == FrameMetrics::ROOT_SCROLL_ID) {
+  if (aScrollFrame == presShell->GetRootScrollFrame()) {
     metrics.mResolution = ParentLayerToLayerScale(presShell->GetXResolution(),
                                                   presShell->GetYResolution());
   } else {
-    // Only the root scrollable frame for a given presShell should pick up
-    // the presShell's resolution. All the other subframes are 1.0.
     metrics.mResolution = ParentLayerToLayerScale(1.0f);
   }
 
+  // For the cumulateive resolution, multiply the resolutions of all the
+  // presShells back up to the root
   metrics.mCumulativeResolution = LayoutDeviceToLayerScale(1.0f);
   nsIPresShell* curPresShell = presShell;
   while (curPresShell != nullptr) {
     ParentLayerToLayerScale presShellResolution(curPresShell->GetXResolution(),
                                                 curPresShell->GetYResolution());
     metrics.mCumulativeResolution.scale *= presShellResolution.scale;
     nsPresContext* parentContext = curPresShell->GetPresContext()->GetParentPresContext();
     curPresShell = parentContext ? parentContext->GetPresShell() : nullptr;
   }
-#ifdef MOZ_WIDGET_ANDROID
-  if (presContext->IsRootContentDocument() && aScrollFrame == presShell->GetRootScrollFrame()) {
-    // On Android we set the resolution on a different presshell (bug 732971) so we
-    // need some special handling here to make things work properly. Once bug 732971 is
-    // fixed we should remove this ifdef block, and adjust any other pieces that need
-    // adjusting to make this work properly.
-    metrics.mResolution.scale = metrics.mCumulativeResolution.scale;
-  }
-#endif
 
   metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(
     (float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel);
 
   // Initially, AsyncPanZoomController should render the content to the screen
   // at the painted resolution.
   const LayerToScreenScale layerToScreenScale(1.0f);
   metrics.mZoom = metrics.mCumulativeResolution * metrics.mDevPixelsPerCSSPixel
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -13,16 +13,21 @@
  * identified per MPL Section 3.3
  *
  * Date         Modified by     Description of modification
  * 05/03/2000   IBM Corp.       Observer events for reflow states
  */
 
 /* a presentation of a document, part 2 */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+#include "prlog.h"
+
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/Util.h"
 #include <algorithm>
@@ -39,17 +44,16 @@
 #include "nsCSSStyleSheet.h"
 #include "nsAnimationManager.h"
 #include "nsINameSpaceManager.h"  // for Pref-related rule management (bugs 22963,20760,31816)
 #include "nsFrame.h"
 #include "FrameLayerBuilder.h"
 #include "nsViewManager.h"
 #include "nsView.h"
 #include "nsCRTGlue.h"
-#include "prlog.h"
 #include "prprf.h"
 #include "prinrval.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsContainerFrame.h"
 #include "nsDOMEvent.h"
 #include "nsISelection.h"
 #include "mozilla/Selection.h"
@@ -676,18 +680,20 @@ PresShell::PresShell()
 {
   mSelection = nullptr;
 #ifdef MOZ_REFLOW_PERF
   mReflowCountMgr = new ReflowCountMgr();
   mReflowCountMgr->SetPresContext(mPresContext);
   mReflowCountMgr->SetPresShell(this);
 #endif
 #ifdef PR_LOGGING
-  if (! gLog)
+  mLoadBegin = TimeStamp::Now();
+  if (!gLog) {
     gLog = PR_NewLogModule("PresShell");
+  }
 #endif
   mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
   mIsThemeSupportDisabled = false;
   mIsActive = true;
   // FIXME/bug 735029: find a better solution to this problem
 #ifdef MOZ_ANDROID_OMTC
   // The java pan/zoom code uses this to mean approximately "request a
   // reset of pan/zoom state" which doesn't necessarily correspond
@@ -2386,26 +2392,55 @@ PresShell::RestoreRootScrollPosition()
     scrollableFrame->ScrollToRestoredPosition();
   }
 }
 
 void
 PresShell::BeginLoad(nsIDocument *aDocument)
 {  
   mDocumentLoading = true;
+
+#ifdef PR_LOGGING
+  if (gLog && PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
+    mLoadBegin = TimeStamp::Now();
+    nsIURI* uri = mDocument->GetDocumentURI();
+    nsAutoCString spec;
+    if (uri) {
+      uri->GetSpec(spec);
+    }
+    PR_LOG(gLog, PR_LOG_DEBUG,
+           ("(presshell) %p begin load [%s]\n",
+            this, spec.get()));
+  }
+#endif
 }
 
 void
 PresShell::EndLoad(nsIDocument *aDocument)
 {
   NS_PRECONDITION(aDocument == mDocument, "Wrong document");
   
   RestoreRootScrollPosition();
   
   mDocumentLoading = false;
+
+#ifdef PR_LOGGING
+  // log load
+  if (gLog && PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
+    TimeDuration loadTime = TimeStamp::Now() - mLoadBegin;
+    nsIURI* uri = mDocument->GetDocumentURI();
+    nsAutoCString spec;
+    if (uri) {
+      uri->GetSpec(spec);
+    }
+    PR_LOG(gLog, PR_LOG_DEBUG,
+           ("(presshell) %p end load time-ms: %9.2f [%s]\n",
+            this, loadTime.ToMilliseconds(), spec.get()));
+  }
+#endif
 }
 
 #ifdef DEBUG
 void
 PresShell::VerifyHasDirtyRootAncestor(nsIFrame* aFrame)
 {
   // XXXbz due to bug 372769, can't actually assert anything here...
   return;
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -751,16 +751,18 @@ protected:
   // the resume reflow event off a timer to avoid event starvation because
   // posted messages are processed before other messages when the modal
   // moving/sizing loop is running, see bug 491700 for details.
   nsCOMPtr<nsITimer>        mReflowContinueTimer;
 
   // The `performance.now()` value when we last started to process reflows.
   DOMHighResTimeStamp       mLastReflowStart;
 
+  mozilla::TimeStamp        mLoadBegin;  // used to time loads
+
   // Information needed to properly handle scrolling content into view if the
   // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is
   // non-null between the initial scroll attempt and the first time we finish
   // processing all our dirty roots.  mContentToScrollTo has a content property
   // storing the details for the scroll operation, see ScrollIntoViewData above.
   nsCOMPtr<nsIContent>      mContentToScrollTo;
 
   nscoord                   mLastAnchorScrollPositionY;
--- a/media/mtransport/rlogringbuffer.cpp
+++ b/media/mtransport/rlogringbuffer.cpp
@@ -10,16 +10,17 @@
 #include <cstdarg>
 
 #include "rlogringbuffer.h"
 
 #include <deque>
 #include <string>
 #include "mozilla/Assertions.h"
 #include "mozilla/Move.h" // Pinch hitting for <utility> and std::move
+#include "mozilla/Mutex.h"
 #include "mozilla/NullPtr.h"
 #include <vector>
 
 extern "C" {
 #include <csi_platform.h>
 #include "r_log.h"
 }
 
@@ -38,28 +39,31 @@ static int ringbuffer_vlog(int facility,
   return 0;
 }
 
 namespace mozilla {
 
 RLogRingBuffer* RLogRingBuffer::instance;
 
 RLogRingBuffer::RLogRingBuffer()
-  : log_limit_(4096) {
+  : log_limit_(4096),
+    mutex_("RLogRingBuffer::mutex_") {
 }
 
 RLogRingBuffer::~RLogRingBuffer() {
 }
 
 void RLogRingBuffer::SetLogLimit(uint32_t new_limit) {
+  OffTheBooksMutexAutoLock lock(mutex_);
   log_limit_ = new_limit;
   RemoveOld();
 }
 
 void RLogRingBuffer::Log(std::string&& log) {
+  OffTheBooksMutexAutoLock lock(mutex_);
   log_messages_.push_front(Move(log));
   RemoveOld();
 }
 
 inline void RLogRingBuffer::RemoveOld() {
   if (log_messages_.size() > log_limit_) {
     log_messages_.resize(log_limit_);
   }
@@ -101,16 +105,17 @@ inline bool AnySubstringMatches(const st
     }
   }
   return false;
 }
 
 void RLogRingBuffer::FilterAny(const std::vector<std::string>& substrings,
                                uint32_t limit,
                                std::deque<std::string>* matching_logs) {
+  OffTheBooksMutexAutoLock lock(mutex_);
   if (limit == 0) {
     // At a max, all of the log messages.
     limit = log_limit_;
   }
 
   for (auto log = log_messages_.begin();
        log != log_messages_.end() && matching_logs->size() < limit;
        ++log) {
--- a/media/mtransport/rlogringbuffer.h
+++ b/media/mtransport/rlogringbuffer.h
@@ -54,16 +54,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #define rlogringbuffer_h__
 
 #include <stdint.h>
 
 #include <deque>
 #include <string>
 #include <vector>
 
+#include "mozilla/Mutex.h"
+
 #include "m_cpp_utils.h"
 
 namespace mozilla {
 
 class RLogRingBuffer {
   public:
     /*
        NB: These are not threadsafe, nor are they safe to call during static
@@ -105,16 +107,17 @@ class RLogRingBuffer {
     /*
      * Might be worthwhile making this a circular buffer, but I think it is
      * preferable to take up as little space as possible if no logging is
      * happening/the ringbuffer is not being used.
     */
     std::deque<std::string> log_messages_;
     /* Max size of log buffer (should we use time-depth instead/also?) */
     uint32_t log_limit_;
+    OffTheBooksMutex mutex_;
 
     DISALLOW_COPY_ASSIGN(RLogRingBuffer);
 }; // class RLogRingBuffer
 
 } // namespace mozilla
 
 #endif // rlogringbuffer_h__
 
--- a/mfbt/PodOperations.h
+++ b/mfbt/PodOperations.h
@@ -129,16 +129,31 @@ PodCopy(volatile T* dst, const volatile 
 template <class T, size_t N>
 static void
 PodArrayCopy(T (&dst)[N], const T (&src)[N])
 {
   PodCopy(dst, src, N);
 }
 
 /**
+ * Copy the memory for |nelem| T elements from |src| to |dst|.  If the two
+ * memory ranges overlap, then the effect is as if the |nelem| elements are
+ * first copied from |src| to a temporary array, and then from the temporary
+ * array to |dst|.
+ */
+template<typename T>
+MOZ_ALWAYS_INLINE static void
+PodMove(T* dst, const T* src, size_t nelem)
+{
+  MOZ_ASSERT(nelem <= SIZE_MAX / sizeof(T),
+             "trying to move an impossible number of elements");
+  memmove(dst, src, nelem * sizeof(T));
+}
+
+/**
  * Determine whether the |len| elements at |one| are memory-identical to the
  * |len| elements at |two|.
  */
 template<typename T>
 MOZ_ALWAYS_INLINE static bool
 PodEqual(const T* one, const T* two, size_t len)
 {
   if (len < 128) {
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -829,19 +829,27 @@ public abstract class TreeBuilder<T> imp
                         if (firstCommentLocation != null) {
                             warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.",
                                     firstCommentLocation);
                         }
                         if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) {
                             if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) {
                                 warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
                             }
+                        } else if ("-//W3C//DTD XHTML 1.0 Strict//EN".equals(publicIdentifier)) {
+                            if (!"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd".equals(systemIdentifier)) {
+                                warn("The doctype did not contain the system identifier prescribed by the XHTML 1.0 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\u201D.");
+                            }
+                        } else if ("//W3C//DTD XHTML 1.1//EN".equals(publicIdentifier)) {
+                            if (!"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd".equals(systemIdentifier)) {
+                                warn("The doctype did not contain the system identifier prescribed by the XHTML 1.1 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\u201D.");
+                            }
                         } else if (!((systemIdentifier == null || Portability.literalEqualsString(
                                 "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
-                            err("Legacy doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+                            err("Unexpected doctype. Expected, e.g., \u201C<!DOCTYPE html>\u201D.");
                         }
                         documentModeInternal(DocumentMode.STANDARDS_MODE,
                                 publicIdentifier, systemIdentifier, html4);
                     }
                     break;
                 case NO_DOCTYPE_ERRORS:
                     if (isQuirky(name, publicIdentifier, systemIdentifier,
                             forceQuirks)) {
@@ -2896,26 +2904,25 @@ public abstract class TreeBuilder<T> imp
                             break starttagloop;
                         case FRAMESET:
                             appendToCurrentNodeAndPushElement(
                                     elementName,
                                     attributes);
                             mode = IN_FRAMESET;
                             attributes = null; // CPP
                             break starttagloop;
-                        case BASE:
+                        case TEMPLATE:
                             errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
-                            appendVoidElementToCurrentMayFoster(
-                                    elementName,
-                                    attributes);
-                            selfClosing = false;
-                            pop(); // head
+                            StackNode<T> headOnStack = stack[currentPtr];
+                            startTagTemplateInHead(elementName, attributes);
+                            removeFromStack(headOnStack);
                             attributes = null; // CPP
                             break starttagloop;
+                        case BASE:
                         case LINK_OR_BASEFONT_OR_BGSOUND:
                             errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
                             appendVoidElementToCurrentMayFoster(
                                     elementName,
                                     attributes);
                             selfClosing = false;
                             pop(); // head
@@ -3986,16 +3993,19 @@ public abstract class TreeBuilder<T> imp
                             mode = IN_HEAD;
                             continue;
                         default:
                             errStrayEndTag(name);
                             break endtagloop;
                     }
                 case AFTER_HEAD:
                     switch (group) {
+                        case TEMPLATE:
+                            endTagTemplateInHead();
+                            break endtagloop;
                         case HTML:
                         case BODY:
                         case BR:
                             appendToCurrentNodeAndPushBodyElement();
                             mode = FRAMESET_OK;
                             continue;
                         default:
                             errStrayEndTag(name);
@@ -4312,18 +4322,21 @@ public abstract class TreeBuilder<T> imp
         @Local String name;
         @NsUri String ns;
         for (int i = currentPtr; i >= 0; i--) {
             node = stack[i];
             name = node.name;
             ns = node.ns;
             if (i == 0) {
                 if (!(contextNamespace == "http://www.w3.org/1999/xhtml" && (contextName == "td" || contextName == "th"))) {
-                    name = contextName;
-                    ns = contextNamespace;
+                    if (fragment) {
+                        // Make sure we are parsing a fragment otherwise the context element doesn't make sense.
+                        name = contextName;
+                        ns = contextNamespace;
+                    }
                 } else {
                     mode = framesetOk ? FRAMESET_OK : IN_BODY; // XXX from Hixie's email
                     return;
                 }
             }
             if ("select" == name) {
                 int ancestorIndex = i;
                 while (ancestorIndex > 0) {
@@ -4348,32 +4361,30 @@ public abstract class TreeBuilder<T> imp
                 return;
             } else if ("tbody" == name || "thead" == name || "tfoot" == name) {
                 mode = IN_TABLE_BODY;
                 return;
             } else if ("caption" == name) {
                 mode = IN_CAPTION;
                 return;
             } else if ("colgroup" == name) {
-                // TODO: Fragment case. Add error reporting.
                 mode = IN_COLUMN_GROUP;
                 return;
             } else if ("table" == name) {
                 mode = IN_TABLE;
                 return;
             } else if ("http://www.w3.org/1999/xhtml" != ns) {
                 mode = framesetOk ? FRAMESET_OK : IN_BODY;
                 return;
             } else if ("template" == name) {
                 assert templateModePtr >= 0;
                 mode = templateModeStack[templateModePtr];
                 return;
             }  else if ("head" == name) {
                 if (name == contextName) {
-                    // TODO: Fragment case. Add error reporting.
                     mode = framesetOk ? FRAMESET_OK : IN_BODY; // really
                 } else {
                     mode = IN_HEAD;
                 }
                 return;
             } else if ("body" == name) {
                 mode = framesetOk ? FRAMESET_OK : IN_BODY;
                 return;
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -1761,25 +1761,26 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
             NS_HTML5_BREAK(starttagloop);
           }
           case NS_HTML5TREE_BUILDER_FRAMESET: {
             appendToCurrentNodeAndPushElement(elementName, attributes);
             mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
             attributes = nullptr;
             NS_HTML5_BREAK(starttagloop);
           }
-          case NS_HTML5TREE_BUILDER_BASE: {
+          case NS_HTML5TREE_BUILDER_TEMPLATE: {
             errFooBetweenHeadAndBody(name);
             pushHeadPointerOntoStack();
-            appendVoidElementToCurrentMayFoster(elementName, attributes);
-            selfClosing = false;
-            pop();
+            nsHtml5StackNode* headOnStack = stack[currentPtr];
+            startTagTemplateInHead(elementName, attributes);
+            removeFromStack(headOnStack);
             attributes = nullptr;
             NS_HTML5_BREAK(starttagloop);
           }
+          case NS_HTML5TREE_BUILDER_BASE:
           case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
             errFooBetweenHeadAndBody(name);
             pushHeadPointerOntoStack();
             appendVoidElementToCurrentMayFoster(elementName, attributes);
             selfClosing = false;
             pop();
             attributes = nullptr;
             NS_HTML5_BREAK(starttagloop);
@@ -2920,16 +2921,20 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
           default: {
             errStrayEndTag(name);
             NS_HTML5_BREAK(endtagloop);
           }
         }
       }
       case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
         switch(group) {
+          case NS_HTML5TREE_BUILDER_TEMPLATE: {
+            endTagTemplateInHead();
+            NS_HTML5_BREAK(endtagloop);
+          }
           case NS_HTML5TREE_BUILDER_HTML:
           case NS_HTML5TREE_BUILDER_BODY:
           case NS_HTML5TREE_BUILDER_BR: {
             appendToCurrentNodeAndPushBodyElement();
             mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
             continue;
           }
           default: {
@@ -3249,18 +3254,20 @@ nsHtml5TreeBuilder::resetTheInsertionMod
   nsIAtom* name;
   int32_t ns;
   for (int32_t i = currentPtr; i >= 0; i--) {
     node = stack[i];
     name = node->name;
     ns = node->ns;
     if (!i) {
       if (!(contextNamespace == kNameSpaceID_XHTML && (contextName == nsHtml5Atoms::td || contextName == nsHtml5Atoms::th))) {
-        name = contextName;
-        ns = contextNamespace;
+        if (fragment) {
+          name = contextName;
+          ns = contextNamespace;
+        }
       } else {
         mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
         return;
       }
     }
     if (nsHtml5Atoms::select == name) {
       int32_t ancestorIndex = i;
       while (ancestorIndex > 0) {
--- a/toolkit/components/ctypes/tests/Makefile.in
+++ b/toolkit/components/ctypes/tests/Makefile.in
@@ -6,43 +6,42 @@ SHORT_LIBNAME = jscttest
 FORCE_SHARED_LIB = 1
 
 LOCAL_INCLUDES = \
     -I$(topsrcdir)/js/src/ctypes \
     $(NULL)
 
 EXTRA_DSO_LDOPTS += $(MOZALLOC_LIB)
 
-# should be MOCHITEST_CHROME_FILES, see bug 770938
-MOCHITEST_CHROME_TESTS = \
-  xpcshellTestHarnessAdaptor.js \
-  ctypes_worker.js \
-  test_ctypes.xul \
-  $(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
 xpctestdir = $(testxpcobjdir)/$(relativesrcdir)/unit
 
 chrometestdir = \
   $(DEPTH)/_tests/testing/mochitest/chrome/toolkit/components/$(relativesrcdir)
 
-# preprocess and install our unit test into the appropriate directory,
-# and install the test library as well. the xpcshell test rules will
-# install the .js.in from the tests srcdir, so remove it when we're done.
-libs:: unit/test_jsctypes.js.in
-	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
-	  $^ > $(xpctestdir)/test_jsctypes.js
-	$(INSTALL) $(SHARED_LIBRARY) $(xpctestdir)
-	$(INSTALL) $(SHARED_LIBRARY) $(DEPTH)/_tests/testing/mochitest/chrome/libraries
-	$(INSTALL) $(xpctestdir)/test_jsctypes.js $(chrometestdir)
-	$(INSTALL) $(xpctestdir)/$(SHARED_LIBRARY) $(chrometestdir)
-	$(RM) $(xpctestdir)/test_jsctypes.js.in
+# should be MOCHITEST_CHROME_FILES, see bug 770938
+MOCHITEST_CHROME_TESTS_FILES = \
+  xpcshellTestHarnessAdaptor.js \
+  ctypes_worker.js \
+  test_ctypes.xul \
+  $(NULL)
+
+MOCHITEST_CHROME_TESTS_DEST = $(chrometestdir)
+INSTALL_TARGETS += MOCHITEST_CHROME_TESTS
+
+TEST_JS_CTYPES = unit/test_jsctypes.js.in
+TEST_JS_CTYPES_PATH = $(xpctestdir)
+PP_TARGETS += TEST_JS_CTYPES
 
-libs:: $(MOCHITEST_CHROME_TESTS)
-	$(INSTALL) $(foreach f,$^,"$f") $(chrometestdir)
+TEST_JS_CTYPES_2_FILES = $(xpctestdir)/test_jsctypes.js
+TEST_JS_CTYPES_2_DEST = $(chrometestdir)
+INSTALL_TARGETS += TEST_JS_CTYPES_2
+
+LIB_1_FILES = $(SHARED_LIBRARY)
+LIB_1_DEST = $(xpctestdir)
+INSTALL_TARGETS += LIB_1
 
-GARBAGE += \
-    $(xpctestdir)/test_jsctypes.js \
-    $(xpctestdir)/$(SHARED_LIBRARY) \
-    $(chrometestdir)/test_jsctypes.js \
-    $(chrometestdir)/$(SHARED_LIBRARY) \
-    $(NULL)
+LIB_2_FILES = $(SHARED_LIBRARY)
+LIB_2_DEST = $(DEPTH)/_tests/testing/mochitest/chrome/libraries
+INSTALL_TARGETS += LIB_2
+
+LIB_3_FILES = $(SHARED_LIBRARY)
+LIB_3_DEST = $(chrometestdir)
+INSTALL_TARGETS += LIB_3
--- a/toolkit/components/protobuf/README.txt
+++ b/toolkit/components/protobuf/README.txt
@@ -4,8 +4,13 @@ Protocol Buffers (protobuf) source is av
 svn checkout http://protobuf.googlecode.com/svn/trunk/ protobuf-read-only
 
 This code is covered under the BSD license (see COPYING.txt). Documentation is
 available at http://code.google.com/p/protobuf.
 
 This import includes only files in protobuf-lite, a lighter-weight library that
 does not support reflection or descriptors. Manual changes include removing all
 tests, testdata, config.h, and all files not used in protobuf-lite.
+
+Applied Patches
+===============
+r512.patch:
+  Support VS2013 (from revision r512)
--- a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.cc
+++ b/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -31,16 +31,18 @@
 // Author: kenton@google.com (Kenton Varda)
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stl_util-inl.h>
 
+#include <algorithm>
+
 namespace google {
 namespace protobuf {
 namespace io {
 
 namespace {
 
 // Default block size for Copying{In,Out}putStreamAdaptor.
 static const int kDefaultBlockSize = 8192;
new file mode 100644
--- /dev/null
+++ b/toolkit/components/protobuf/r512.patch
@@ -0,0 +1,13 @@
+Index: src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+===================================================================
+--- src/google/protobuf/io/zero_copy_stream_impl_lite.cc	(revision 511)
++++ src/google/protobuf/io/zero_copy_stream_impl_lite.cc	(revision 512)
+@@ -36,6 +36,8 @@
+ #include <google/protobuf/stubs/common.h>
+ #include <google/protobuf/stubs/stl_util.h>
+ 
++#include <algorithm>
++
+ namespace google {
+ namespace protobuf {
+ namespace io {
new file mode 100644
--- /dev/null
+++ b/toolkit/components/protobuf/update.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+patch -p1 < r512.patch
--- a/toolkit/crashreporter/test/Makefile.in
+++ b/toolkit/crashreporter/test/Makefile.in
@@ -11,26 +11,27 @@ VPATH += \
   $(topsrcdir)/build/ \
   $(NULL)
 
 LOCAL_INCLUDES += \
   -I$(srcdir)/../google-breakpad/src/ \
   $(NULL)
 EXTRA_DSO_LDOPTS += $(LIBS_DIR) $(MOZ_COMPONENT_LIBS) $(XPCOM_GLUE_LDOPTS)
 
-MOCHITEST_BROWSER_FILES = \
+MOCHITEST_CRASHREPORTER_FILES = \
   browser/head.js \
   browser/crashreport.sjs \
   browser/browser_aboutCrashes.js \
   browser/browser_bug471404.js \
   browser/browser_aboutCrashesResubmit.js \
   $(NULL)
-
-include $(topsrcdir)/config/rules.mk
+MOCHITEST_CRASHREPORTER_DEST = $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)/browser
+INSTALL_TARGETS += MOCHITEST_CRASHREPORTER
 
 DEFINES += -DSHARED_LIBRARY=$(SHARED_LIBRARY) -DNOMINMAX
 
-libs::  $(MOCHITEST_BROWSER_FILES)
-	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)/browser
+UNIT_FILES = $(SHARED_LIBRARY) $(EXTRA_JS_MODULES)
+UNIT_DEST = $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/
+INSTALL_TARGETS += UNIT
 
-libs:: $(SHARED_LIBRARY) $(EXTRA_JS_MODULES)
-	$(INSTALL) $^ $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/
-	$(INSTALL) $^ $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit_ipc/
+UNIT_IPC_FILES = $(UNIT_FILES)
+UNIT_IPC_DEST = $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit_ipc/
+INSTALL_TARGETS += UNIT_IPC
--- a/widget/windows/nsUXThemeData.cpp
+++ b/widget/windows/nsUXThemeData.cpp
@@ -302,17 +302,17 @@ nsUXThemeData::UpdateNativeThemeInfo()
     sThemeId = LookAndFeel::eWindowsTheme_Classic;
     return;
   }
 
   LPCWSTR themeName = wcsrchr(themeFileName, L'\\');
   themeName = themeName ? themeName + 1 : themeFileName;
 
   WindowsTheme theme = WINTHEME_UNRECOGNIZED;
-  for (int i = 0; i < ArrayLength(knownThemes); ++i) {
+  for (size_t i = 0; i < ArrayLength(knownThemes); ++i) {
     if (!lstrcmpiW(themeName, knownThemes[i].name)) {
       theme = (WindowsTheme)knownThemes[i].type;
       break;
     }
   }
 
   if (theme == WINTHEME_UNRECOGNIZED)
     return;
@@ -337,17 +337,17 @@ nsUXThemeData::UpdateNativeThemeInfo()
       default:
         NS_WARNING("unhandled theme type.");
         return;
     }
   }
 
   // calculate the luna color scheme
   WindowsThemeColor color = WINTHEMECOLOR_UNRECOGNIZED;
-  for (int i = 0; i < ArrayLength(knownColors); ++i) {
+  for (size_t i = 0; i < ArrayLength(knownColors); ++i) {
     if (!lstrcmpiW(themeColor, knownColors[i].name)) {
       color = (WindowsThemeColor)knownColors[i].type;
       break;
     }
   }
 
   switch(color) {
     case WINTHEMECOLOR_NORMAL:
--- a/xpcom/tests/bug656331_component/Makefile.in
+++ b/xpcom/tests/bug656331_component/Makefile.in
@@ -2,34 +2,32 @@
 # 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/.
 
 # Blatantly copied from xpcom/tests/component.
 
 FORCE_SHARED_LIB = 1
 
-MANIFEST_FILE = bug656331.manifest
+unittestlocation = xpcom/tests/unit
+
+MANIFEST = bug656331.manifest
+MANIFEST_PATH = $(testxpcobjdir)/$(unittestlocation)
+PP_TARGETS += MANIFEST
 
 EXTRA_DSO_LDOPTS = \
   $(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
   $(XPCOM_FROZEN_LDOPTS) \
   $(NSPR_LIBS) \
   $(NULL)
 
 # Need to link with CoreFoundation on Mac
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += \
   $(TK_LIBS) \
   $(NULL)
 endif
 
-include $(topsrcdir)/config/rules.mk
-
 DEFINES += -DLIBRARY_FILENAME="$(SHARED_LIBRARY)"
 
-unittestlocation = xpcom/tests/unit
-
-libs:: $(SHARED_LIBRARY)
-	$(INSTALL) $^ $(testxpcobjdir)/$(unittestlocation)
-
-libs:: $(MANIFEST_FILE)
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(unittestlocation)/$(<F)
+LIB_FILES = $(SHARED_LIBRARY)
+LIB_DEST = $(testxpcobjdir)/$(unittestlocation)
+INSTALL_TARGETS += LIB
--- a/xpcom/tests/component/Makefile.in
+++ b/xpcom/tests/component/Makefile.in
@@ -1,33 +1,31 @@
 #
 # 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/.
 
 FORCE_SHARED_LIB = 1
 
-MANIFEST_FILE = testcomponent.manifest
+unittestlocation = xpcom/tests/unit
+
+MANIFEST = testcomponent.manifest
+MANIFEST_PATH = $(testxpcobjdir)/$(unittestlocation)
+PP_TARGETS += MANIFEST
 
 EXTRA_DSO_LDOPTS = \
 		$(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
 		$(XPCOM_FROZEN_LDOPTS) \
 		$(NSPR_LIBS) \
 		$(NULL)
 
 # Need to link with CoreFoundation on Mac
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += \
 		$(TK_LIBS) \
 		$(NULL)
 endif
 
-include $(topsrcdir)/config/rules.mk
-
 DEFINES += -DLIBRARY_FILENAME="$(SHARED_LIBRARY)"
 
-unittestlocation = xpcom/tests/unit
-
-libs:: $(SHARED_LIBRARY)
-	$(INSTALL) $^ $(testxpcobjdir)/$(unittestlocation)
-
-libs:: $(MANIFEST_FILE)
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(unittestlocation)/$(<F)
+LIB_FILES = $(SHARED_LIBRARY)
+LIB_DEST = $(testxpcobjdir)/$(unittestlocation)
+INSTALL_TARGETS += LIB
--- a/xpcom/tests/component_no_aslr/Makefile.in
+++ b/xpcom/tests/component_no_aslr/Makefile.in
@@ -1,35 +1,35 @@
 #
 # 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/.
 
 FORCE_SHARED_LIB = 1
 
-MANIFEST_FILE = testcompnoaslr.manifest
+unittestlocation = xpcom/tests/unit
+
+MANIFEST = testcompnoaslr.manifest
+MANIFEST_PATH = $(testxpcobjdir)/$(unittestlocation)
+PP_TARGETS += MANIFEST
 
 EXTRA_DSO_LDOPTS = \
 		$(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
 		$(XPCOM_FROZEN_LDOPTS) \
 		$(NSPR_LIBS) \
 		$(NULL)
 
 # Need to link with CoreFoundation on Mac
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += \
 		$(TK_LIBS) \
 		$(NULL)
 endif
 
+LIB_FILES = $(SHARED_LIBRARY)
+LIB_DEST = $(testxpcobjdir)/$(unittestlocation)
+INSTALL_TARGETS += LIB
+
 include $(topsrcdir)/config/rules.mk
 
 LDFLAGS := $(filter-out -DYNAMICBASE,$(LDFLAGS)) -DYNAMICBASE:NO
 
 DEFINES += -DLIBRARY_FILENAME="$(SHARED_LIBRARY)"
-
-unittestlocation = xpcom/tests/unit
-
-libs:: $(SHARED_LIBRARY)
-	$(INSTALL) $^ $(testxpcobjdir)/$(unittestlocation)
-
-libs:: $(MANIFEST_FILE)
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(unittestlocation)/$(<F)