Revert to revision 63dfac3c9c87 due to mass bustage pile-ups that landed after it on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 16 May 2014 12:29:37 -0400
changeset 202751 eb2a6f7785a2e3c61bf44a24f8ce234b9aa3d948
parent 202750 9cc5c3a465e64e9fd1803ac4d9957da56ed2bb67
child 202768 aaa0e054fa0ecb7dc5c7bfdee2f2723428c0f7df
child 202815 36bfb1d8b8fef01877faaf2741d9b1908a47708d
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone32.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
Revert to revision 63dfac3c9c87 due to mass bustage pile-ups that landed after it on a CLOSED TREE.
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/test/mochitest.ini
dom/base/test/test_open_null_features.html
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/browser-element/mochitest/mochitest.ini
embedding/components/windowwatcher/src/nsAutoWindowStateHelper.cpp
embedding/components/windowwatcher/src/nsAutoWindowStateHelper.h
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
gfx/layers/apz/public/GeckoContentController.h
gfx/layers/apz/src/GestureEventListener.cpp
gfx/layers/apz/src/GestureEventListener.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/CompositableClient.h
gfx/layers/client/ImageClient.cpp
gfx/layers/client/ImageClient.h
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/PImageBridge.ipdl
gfx/tests/gtest/TestAsyncPanZoomController.cpp
gfx/thebes/gfxPlatform.cpp
layout/reftests/webm-video/bug686957.html
layout/style/nsStyleUtil.cpp
layout/style/test/test_css_escape_api.html
layout/style/test/test_parser_diagnostics_unprintables.html
netwerk/cache2/CacheStorageService.cpp
netwerk/protocol/http/nsHttpChannel.cpp
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/frontend/data/test-manifest-inactive-ignored/mochitest.ini
python/mozbuild/mozbuild/test/frontend/data/test-manifest-inactive-ignored/moz.build
python/mozbuild/mozbuild/test/frontend/data/test-manifest-inactive-ignored/test_active.html
python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/foo.txt
python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/moz.build
python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/support-disabled-tests.ini
python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/test_blah.html
python/mozbuild/mozbuild/test/frontend/test_emitter.py
xpcom/build/nsXPComInit.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8425,17 +8425,17 @@ nsGlobalWindow::ReallyCloseWindow()
 
     CleanUp();
   }
 }
 
 void
 nsGlobalWindow::EnterModalState()
 {
-  MOZ_ASSERT(IsOuterWindow(), "Modal state is maintained on outer windows");
+  FORWARD_TO_OUTER_VOID(EnterModalState, ());
 
   // GetScriptableTop, not GetTop, so that EnterModalState works properly with
   // <iframe mozbrowser>.
   nsGlobalWindow* topWin = GetScriptableTop();
 
   if (!topWin) {
     NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
     return;
@@ -8558,17 +8558,17 @@ public:
 
 private:
   nsRefPtr<nsGlobalWindow> mWindow;
 };
 
 void
 nsGlobalWindow::LeaveModalState()
 {
-  MOZ_ASSERT(IsOuterWindow(), "Modal state is maintained on outer windows");
+  FORWARD_TO_OUTER_VOID(LeaveModalState, ());
 
   nsGlobalWindow* topWin = GetScriptableTop();
 
   if (!topWin) {
     NS_ERROR("Uh, LeaveModalState() called w/o a reachable top window?");
     return;
   }
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2039,55 +2039,51 @@ nsJSContext::BeginCycleCollectionCallbac
   if (sICCTimer) {
     sICCTimer->InitWithFuncCallback(ICCTimerFired,
                                     nullptr,
                                     kICCIntersliceDelay,
                                     nsITimer::TYPE_REPEATING_SLACK);
   }
 }
 
-static_assert(NS_GC_DELAY > kMaxICCDuration, "A max duration ICC shouldn't reduce GC delay to 0");
-
 //static
 void
 nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsJSContext::KillICCTimer();
 
   // Update timing information for the current slice before we log it, if
   // we previously called PrepareForCycleCollectionSlice(). During shutdown
   // CCs, this won't happen.
   gCCStats.FinishCycleCollectionSlice();
 
   sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed;
 
+  if (NeedsGCAfterCC()) {
+    PokeGC(JS::gcreason::CC_WAITING);
+  }
+
   TimeStamp endCCTimeStamp = TimeStamp::Now();
-  uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
-
-  if (NeedsGCAfterCC()) {
-    PokeGC(JS::gcreason::CC_WAITING,
-           NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration));
-  }
 
   PRTime endCCTime;
   if (sPostGCEventsToObserver) {
     endCCTime = PR_Now();
   }
 
   // Log information about the CC via telemetry, JSON and the console.
+  uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
   Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, gCCStats.mAnyLockedOut);
   Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE, gCCStats.mRanSyncForgetSkippable);
   Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL, ccNowDuration);
   Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_MAX_PAUSE, gCCStats.mMaxSliceTime);
 
   if (!sLastCCEndTime.IsNull()) {
-    // TimeBetween returns milliseconds, but we want to report seconds.
-    uint32_t timeBetween = TimeBetween(sLastCCEndTime, gCCStats.mBeginTime) / 1000;
+    uint32_t timeBetween = TimeBetween(sLastCCEndTime, gCCStats.mBeginTime);
     Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN, timeBetween);
   }
   sLastCCEndTime = endCCTimeStamp;
 
   Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX,
                         sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
 
   PRTime delta = GetCollectionTimeDelta();
@@ -2228,26 +2224,37 @@ static bool
 ShouldTriggerCC(uint32_t aSuspected)
 {
   return sNeedsFullCC ||
          aSuspected > NS_CC_PURPLE_LIMIT ||
          (aSuspected > NS_CC_FORCED_PURPLE_LIMIT &&
           TimeUntilNow(sLastCCEndTime) > NS_CC_FORCED);
 }
 
+static uint32_t
+TimeToNextCC()
+{
+  if (sIncrementalCC) {
+    return NS_CC_DELAY - kMaxICCDuration;
+  }
+  return NS_CC_DELAY;
+}
+
+static_assert(NS_CC_DELAY > kMaxICCDuration, "ICC shouldn't reduce CC delay to 0");
+
 static void
 CCTimerFired(nsITimer *aTimer, void *aClosure)
 {
   if (sDidShutdown) {
     return;
   }
 
   static uint32_t ccDelay = NS_CC_DELAY;
   if (sCCLockedOut) {
-    ccDelay = NS_CC_DELAY / 3;
+    ccDelay = TimeToNextCC() / 3;
 
     PRTime now = PR_Now();
     if (sCCLockedOutTime == 0) {
       // Reset sCCTimerFireCount so that we run forgetSkippable
       // often enough before CC. Because of reduced ccDelay
       // forgetSkippable will be called just a few times.
       // NS_MAX_CC_LOCKEDOUT_TIME limit guarantees that we end up calling
       // forgetSkippable and CycleCollectNow eventually.
@@ -2284,17 +2291,17 @@ CCTimerFired(nsITimer *aTimer, void *aCl
       nsJSContext::RunCycleCollectorSlice();
     }
   } else if ((sPreviousSuspectedCount + 100) <= suspected) {
       // Only do a forget skippable if there are more than a few new objects.
       FireForgetSkippable(suspected, false);
   }
 
   if (isLateTimerFire) {
-    ccDelay = NS_CC_DELAY;
+    ccDelay = TimeToNextCC();
 
     // We have either just run the CC or decided we don't want to run the CC
     // next time, so kill the timer.
     sPreviousSuspectedCount = 0;
     nsJSContext::KillCCTimer();
   }
 }
 
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -45,17 +45,16 @@ support-files =
 [test_messagemanager_targetchain.html]
 [test_messageChannel_transferable.html]
 [test_messageChannel_unshipped.html]
 [test_named_frames.html]
 [test_navigator_resolve_identity.html]
 [test_navigator_language.html]
 [test_nondomexception.html]
 [test_openDialogChromeOnly.html]
-[test_open_null_features.html]
 [test_postMessage_solidus.html]
 [test_screen_orientation.html]
 [test_settimeout_extra_arguments.html]
 [test_settimeout_inner.html]
 [test_setting_opener.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_url.html]
 [test_url_empty_port.html]
deleted file mode 100644
--- a/dom/base/test/test_open_null_features.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1009529
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 1009529</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript">
-
-  /** Test for Bug 1009529 **/
-  SimpleTest.waitForExplicitFinish();
-
-  var win1 = open("about:blank", "_blank", null);
-  var win2 = open("about:blank", "_blank", "");
-  for (var k in win1) {
-    var v;
-    try {
-      v = win1[k];
-    } catch (ex) {}
-    if (v instanceof win1.BarProp) {
-      is(v.visible, win2[k] && win2[k].visible, "Both windows should have the same value for " + k);
-    }
-  }
-
-  var closeCount = 0;
-  var closeInc = function(e) {
-    this.removeEventListener("unload", closeInc, true);
-    closeCount++;
-    if (closeCount == 2) {
-      SimpleTest.finish();
-    }
-  };
-  win1.addEventListener("unload", closeInc, true);
-  win2.addEventListener("unload", closeInc, true);
-  win1.close();
-  win2.close();
-  
-  </script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1009529">Mozilla Bug 1009529</a>
-<p id="display">
-</p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-</pre>
-</body>
-</html>
-
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2253,23 +2253,17 @@ GenericBindingGetter(JSContext* cx, unsi
       return ThrowInvalidThis(cx, args,
                               GetInvalidThisErrorForGetter(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO),
                               protoID);
     }
   }
 
   MOZ_ASSERT(info->type() == JSJitInfo::Getter);
   JSJitGetterOp getter = info->getter;
-  bool ok = getter(cx, obj, self, JSJitGetterCallArgs(args));
-#ifdef DEBUG
-  if (ok) {
-    AssertReturnTypeMatchesJitinfo(info, args.rval());
-  }
-#endif
-  return ok;
+  return getter(cx, obj, self, JSJitGetterCallArgs(args));
 }
 
 bool
 GenericBindingSetter(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
   prototypes::ID protoID = static_cast<prototypes::ID>(info->protoID);
@@ -2292,20 +2286,17 @@ GenericBindingSetter(JSContext* cx, unsi
   if (args.length() == 0) {
     return ThrowNoSetterArg(cx, protoID);
   }
   MOZ_ASSERT(info->type() == JSJitInfo::Setter);
   JSJitSetterOp setter = info->setter;
   if (!setter(cx, obj, self, JSJitSetterCallArgs(args))) {
     return false;
   }
-  args.rval().setUndefined();
-#ifdef DEBUG
-  AssertReturnTypeMatchesJitinfo(info, args.rval());
-#endif
+  args.rval().set(JSVAL_VOID);
   return true;
 }
 
 bool
 GenericBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
@@ -2323,23 +2314,17 @@ GenericBindingMethod(JSContext* cx, unsi
     if (NS_FAILED(rv)) {
       return ThrowInvalidThis(cx, args,
                               GetInvalidThisErrorForMethod(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO),
                               protoID);
     }
   }
   MOZ_ASSERT(info->type() == JSJitInfo::Method);
   JSJitMethodOp method = info->method;
-  bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
-#ifdef DEBUG
-  if (ok) {
-    AssertReturnTypeMatchesJitinfo(info, args.rval());
-  }
-#endif
-  return ok;
+  return method(cx, obj, self, JSJitMethodCallArgs(args));
 }
 
 bool
 GenericPromiseReturningBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   // Make sure to save the callee before someone maybe messes with rval().
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   JS::Rooted<JSObject*> callee(cx, &args.callee());
@@ -2367,24 +2352,19 @@ GenericPromiseReturningBindingMethod(JSC
       return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
                                        args.rval());
     }
   }
   MOZ_ASSERT(info->type() == JSJitInfo::Method);
   JSJitMethodOp method = info->method;
   bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
   if (ok) {
-#ifdef DEBUG
-    AssertReturnTypeMatchesJitinfo(info, args.rval());
-#endif
     return true;
   }
 
-  // Promise-returning methods always return objects
-  MOZ_ASSERT(info->returnType() == JSVAL_TYPE_OBJECT);
   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
                                    args.rval());
 }
 
 bool
 StaticMethodPromiseWrapper(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   // Make sure to save the callee before someone maybe messes with rval().
@@ -2444,49 +2424,10 @@ CreateGlobalOptions<nsGlobalWindow>::Tra
 /* static */
 bool
 CreateGlobalOptions<nsGlobalWindow>::PostCreateGlobal(JSContext* aCx,
                                                       JS::Handle<JSObject*> aGlobal)
 {
   return XPCWrappedNativeScope::GetNewOrUsed(aCx, aGlobal);
 }
 
-#ifdef DEBUG
-void
-AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
-                               JS::Handle<JS::Value> aValue)
-{
-  switch (aJitInfo->returnType()) {
-  case JSVAL_TYPE_UNKNOWN:
-    // Any value is good.
-    break;
-  case JSVAL_TYPE_DOUBLE:
-    // The value could actually be an int32 value as well.
-    MOZ_ASSERT(aValue.isNumber());
-    break;
-  case JSVAL_TYPE_INT32:
-    MOZ_ASSERT(aValue.isInt32());
-    break;
-  case JSVAL_TYPE_UNDEFINED:
-    MOZ_ASSERT(aValue.isUndefined());
-    break;
-  case JSVAL_TYPE_BOOLEAN:
-    MOZ_ASSERT(aValue.isBoolean());
-    break;
-  case JSVAL_TYPE_STRING:
-    MOZ_ASSERT(aValue.isString());
-    break;
-  case JSVAL_TYPE_NULL:
-    MOZ_ASSERT(aValue.isNull());
-    break;
-  case JSVAL_TYPE_OBJECT:
-    MOZ_ASSERT(aValue.isObject());
-    break;
-  default:
-    // Someone messed up their jitinfo type.
-    MOZ_ASSERT(false, "Unexpected JSValueType stored in jitinfo");
-    break;
-  }
-}
-#endif
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -2739,18 +2739,12 @@ ConvertExceptionToPromise(JSContext* cx,
 // DOM global objects live on the object or the prototype, we supply this one
 // place to switch the behaviour, so we can easily turn this off on branches.
 inline bool
 GlobalPropertiesAreOwn()
 {
   return true;
 }
 
-#ifdef DEBUG
-void
-AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo,
-                               JS::Handle<JS::Value> aValue);
-#endif
-
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_BindingUtils_h__ */
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -65,17 +65,17 @@ def wantsAddProperty(desc):
 lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
 
 
 def indent(s, indentLevel=2):
     """
     Indent C++ code.
 
     Weird secret feature: this doesn't indent lines that start with # (such as
-    #include lines or #ifdef/#endif).
+    #include lines).
     """
     if s == "":
         return s
     return re.sub(lineStartDetector, indentLevel * " ", s)
 
 
 def dedent(s):
     """
@@ -6678,23 +6678,17 @@ class CGGenericMethod(CGAbstractBindingM
                                          unwrapFailureCode=unwrapFailureCode,
                                          allowCrossOriginThis=allowCrossOriginThis)
 
     def generate_code(self):
         return CGGeneric(indent(dedent("""
             const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
             MOZ_ASSERT(info->type() == JSJitInfo::Method);
             JSJitMethodOp method = info->method;
-            bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
-            #ifdef DEBUG
-            if (ok) {
-              AssertReturnTypeMatchesJitinfo(info, args.rval());
-            }
-            #endif
-            return ok;
+            return method(cx, obj, self, JSJitMethodCallArgs(args));
             """)))
 
 
 class CGSpecializedMethod(CGAbstractStaticMethod):
     """
     A class for generating the C++ code for a specialized method that the JIT
     can call with lower overhead.
     """
@@ -6982,23 +6976,17 @@ class CGGenericGetter(CGAbstractBindingM
                                          unwrapFailureCode,
                                          allowCrossOriginThis=allowCrossOriginThis)
 
     def generate_code(self):
         return CGGeneric(indent(dedent("""
             const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
             MOZ_ASSERT(info->type() == JSJitInfo::Getter);
             JSJitGetterOp getter = info->getter;
-            bool ok = getter(cx, obj, self, JSJitGetterCallArgs(args));
-            #ifdef DEBUG
-            if (ok) {
-              AssertReturnTypeMatchesJitinfo(info, args.rval());
-            }
-            #endif
-            return ok;
+            return getter(cx, obj, self, JSJitGetterCallArgs(args));
             """)))
 
 
 class CGSpecializedGetter(CGAbstractStaticMethod):
     """
     A class for generating the code for a specialized attribute getter
     that the JIT can call with lower overhead.
     """
@@ -7123,19 +7111,16 @@ class CGGenericSetter(CGAbstractBindingM
             }
             const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
             MOZ_ASSERT(info->type() == JSJitInfo::Setter);
             JSJitSetterOp setter = info->setter;
             if (!setter(cx, obj, self, JSJitSetterCallArgs(args))) {
               return false;
             }
             args.rval().set(JSVAL_VOID);
-            #ifdef DEBUG
-            AssertReturnTypeMatchesJitinfo(info, args.rval());
-            #endif
             return true;
             """,
             name=self.descriptor.interface.identifier.name)))
 
 
 class CGSpecializedSetter(CGAbstractStaticMethod):
     """
     A class for generating the code for a specialized attribute setter
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -187,8 +187,12 @@ skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_XFrameOptionsSameOrigin.html]
 [test_browserElement_oop_NextPaint.html]
 # Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
 [test_browserElement_inproc_Reload.html]
 disabled = bug 774100
 # Disabled due to focus issues (no bug that I'm aware of)
 [test_browserElement_oop_KeyEvents.html]
 disabled =
+# Disable due to certificate issue (no bug that I'm aware of)
+[test_browserElement_inproc_ErrorSecurity.html]
+skip-if = buildapp=='b2g'
+disabled =
--- a/embedding/components/windowwatcher/src/nsAutoWindowStateHelper.cpp
+++ b/embedding/components/windowwatcher/src/nsAutoWindowStateHelper.cpp
@@ -14,58 +14,61 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /****************************************************************
  ****************** nsAutoWindowStateHelper *********************
  ****************************************************************/
 
-nsAutoWindowStateHelper::nsAutoWindowStateHelper(nsPIDOMWindow *aWindow)
+nsAutoWindowStateHelper::nsAutoWindowStateHelper(nsIDOMWindow *aWindow)
   : mWindow(aWindow),
     mDefaultEnabled(DispatchEventToChrome("DOMWillOpenModalDialog"))
 {
-  if (mWindow) {
-    mWindow->EnterModalState();
+  nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
+
+  if (window) {
+    window->EnterModalState();
   }
 }
 
 nsAutoWindowStateHelper::~nsAutoWindowStateHelper()
 {
-  if (mWindow) {
-    mWindow->LeaveModalState();
+  nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mWindow));
+
+  if (window) {
+    window->LeaveModalState();
   }
 
   if (mDefaultEnabled) {
     DispatchEventToChrome("DOMModalDialogClosed");
   }
 }
 
 bool
 nsAutoWindowStateHelper::DispatchEventToChrome(const char *aEventName)
 {
-  // XXXbz should we skip dispatching the event if the inner changed?
-  // That is, should we store both the inner and the outer?
-  if (!mWindow) {
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mWindow);
+  if (!window || (window->IsInnerWindow() && !window->IsCurrentInnerWindow())) {
     return true;
   }
 
   // The functions of nsContentUtils do not provide the required behavior,
   // so the following is inlined.
-  nsIDocument* doc = mWindow->GetExtantDoc();
+  nsIDocument* doc = window->GetExtantDoc();
   if (!doc) {
     return true;
   }
 
   ErrorResult rv;
   nsRefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("Events"), rv);
   if (rv.Failed()) {
     return false;
   }
   NS_ENSURE_TRUE(NS_SUCCEEDED(event->InitEvent(NS_ConvertASCIItoUTF16(aEventName), true, true)), false);
   event->SetTrusted(true);
   event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
 
-  nsCOMPtr<EventTarget> target = do_QueryInterface(mWindow);
+  nsCOMPtr<EventTarget> target = do_QueryInterface(window);
   bool defaultActionEnabled;
   target->DispatchEvent(event, &defaultActionEnabled);
   return defaultActionEnabled;
 }
--- a/embedding/components/windowwatcher/src/nsAutoWindowStateHelper.h
+++ b/embedding/components/windowwatcher/src/nsAutoWindowStateHelper.h
@@ -2,37 +2,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __nsAutoWindowStateHelper_h
 #define __nsAutoWindowStateHelper_h
 
 #include "nsCOMPtr.h"
-#include "nsPIDOMWindow.h"
 
 /**
  * Helper class for dealing with notifications around opening modal
  * windows.
  */
 
-class nsPIDOMWindow;
+class nsIDOMWindow;
 
 class nsAutoWindowStateHelper
 {
 public:
-  nsAutoWindowStateHelper(nsPIDOMWindow *aWindow);
+  nsAutoWindowStateHelper(nsIDOMWindow *aWindow);
   ~nsAutoWindowStateHelper();
 
   bool DefaultEnabled()
   {
     return mDefaultEnabled;
   }
 
 protected:
   bool DispatchEventToChrome(const char *aEventName);
 
-  nsCOMPtr<nsPIDOMWindow> mWindow;
+  nsIDOMWindow *mWindow;
   bool mDefaultEnabled;
 };
 
 
 #endif
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -950,21 +950,17 @@ nsWindowWatcher::OpenWindowInternal(nsID
     // Throw an exception here if no web browser chrome is available,
     // we need that to show a modal window.
     NS_ENSURE_TRUE(newChrome, NS_ERROR_NOT_AVAILABLE);
 
     // Dispatch dialog events etc, but we only want to do that if
     // we're opening a modal content window (the helper classes are
     // no-ops if given no window), for chrome dialogs we don't want to
     // do any of that (it's done elsewhere for us).
-    // Make sure we maintain the state on an outer window, because
-    // that's where it lives; inner windows assert if you try to
-    // maintain the state on them.
-    nsAutoWindowStateHelper windowStateHelper(
-      parentWindow ? parentWindow->GetOuterWindow() : nullptr);
+    nsAutoWindowStateHelper windowStateHelper(aParent);
 
     if (!windowStateHelper.DefaultEnabled()) {
       // Default to cancel not opening the modal window.
       NS_RELEASE(*_retval);
 
       return NS_OK;
     }
 
--- a/gfx/layers/apz/public/GeckoContentController.h
+++ b/gfx/layers/apz/public/GeckoContentController.h
@@ -61,19 +61,17 @@ public:
    */
   virtual void HandleLongTap(const CSSPoint& aPoint,
                              int32_t aModifiers,
                              const ScrollableLayerGuid& aGuid) = 0;
 
   /**
    * Requests handling of releasing a long tap. |aPoint| is in CSS pixels,
    * relative to the current scroll offset. HandleLongTapUp will always be
-   * preceeded by HandleLongTap. However not all calls to HandleLongTap will
-   * be followed by a HandleLongTapUp (for example, if the user drags
-   * around between the long-tap and lifting their finger).
+   * preceeded by HandleLongTap
    */
   virtual void HandleLongTapUp(const CSSPoint& aPoint,
                                int32_t aModifiers,
                                const ScrollableLayerGuid& aGuid) = 0;
 
   /**
    * Requests sending a mozbrowserasyncscroll domevent to embedder.
    * |aContentRect| is in CSS pixels, relative to the current cssPage.
--- a/gfx/layers/apz/src/GestureEventListener.cpp
+++ b/gfx/layers/apz/src/GestureEventListener.cpp
@@ -175,44 +175,32 @@ nsEventStatus GestureEventListener::Hand
     NS_WARNING("Unhandled state upon multitouch start");
     SetState(GESTURE_NONE);
     break;
   }
 
   return rv;
 }
 
-bool GestureEventListener::MoveDistanceIsLarge()
-{
-  ScreenIntPoint delta = mLastTouchInput.mTouches[0].mScreenPoint - mTouchStartPosition;
-  return (NS_hypot(delta.x, delta.y) > AsyncPanZoomController::GetTouchStartTolerance());
-}
-
 nsEventStatus GestureEventListener::HandleInputTouchMove()
 {
   nsEventStatus rv = nsEventStatus_eIgnore;
 
   switch (mState) {
   case GESTURE_NONE:
+  case GESTURE_LONG_TOUCH_DOWN:
     // Ignore this input signal as the corresponding events get handled by APZC
     break;
 
-  case GESTURE_LONG_TOUCH_DOWN:
-    if (MoveDistanceIsLarge()) {
-      // So that we don't fire a long-tap-up if the user moves around after a
-      // long-tap
-      SetState(GESTURE_NONE);
-    }
-    break;
-
   case GESTURE_FIRST_SINGLE_TOUCH_DOWN:
   case GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN:
   case GESTURE_SECOND_SINGLE_TOUCH_DOWN: {
     // If we move too much, bail out of the tap.
-    if (MoveDistanceIsLarge()) {
+    ScreenIntPoint delta = mLastTouchInput.mTouches[0].mScreenPoint - mTouchStartPosition;
+    if (NS_hypot(delta.x, delta.y) > AsyncPanZoomController::GetTouchStartTolerance()) {
       CancelLongTapTimeoutTask();
       CancelMaxTapTimeoutTask();
       SetState(GESTURE_NONE);
     }
     break;
   }
 
   case GESTURE_MULTI_TOUCH_DOWN: {
--- a/gfx/layers/apz/src/GestureEventListener.h
+++ b/gfx/layers/apz/src/GestureEventListener.h
@@ -121,18 +121,16 @@ private:
   nsEventStatus HandleInputTouchEnd();
   nsEventStatus HandleInputTouchMove();
   nsEventStatus HandleInputTouchCancel();
   void HandleInputTimeoutLongTap();
   void HandleInputTimeoutMaxTap();
 
   void TriggerSingleTapConfirmedEvent();
 
-  bool MoveDistanceIsLarge();
-
   /**
    * Do actual state transition and reset substates.
    */
   void SetState(GestureState aState);
 
   nsRefPtr<AsyncPanZoomController> mAsyncPanZoomController;
 
   /**
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -47,20 +47,19 @@ CanvasClient::CreateCanvasClient(CanvasC
     return new CanvasClientSurfaceStream(aForwarder, aFlags);
   }
   return new CanvasClient2D(aForwarder, aFlags);
 }
 
 void
 CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
-  AutoRemoveTexture autoRemove(this);
   if (mBuffer &&
       (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
-    autoRemove.mTexture = mBuffer;
+    GetForwarder()->RemoveTextureFromCompositable(this, mBuffer);
     mBuffer = nullptr;
   }
 
   bool bufferCreated = false;
   if (!mBuffer) {
     bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
     gfxContentType contentType = isOpaque
                                                 ? gfxContentType::COLOR
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -191,16 +191,10 @@ CompositableClient::AddTextureClient(Tex
   return aClient->InitIPDLActor(mForwarder);
 }
 
 void
 CompositableClient::OnTransaction()
 {
 }
 
-void
-CompositableClient::RemoveTexture(TextureClient* aTexture)
-{
-  mForwarder->RemoveTextureFromCompositable(this, aTexture);
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -140,25 +140,16 @@ public:
   virtual void OnDetach() {}
 
   /**
    * Clear any resources that are not immediately necessary. This may be called
    * in low-memory conditions.
    */
   virtual void ClearCachedResources() {}
 
-  /**
-   * Should be called when deataching a TextureClient from a Compositable, because
-   * some platforms need to do some extra book keeping when this happens (for
-   * example to properly keep track of fences on Gonk).
-   *
-   * See AutoRemoveTexture to automatically invoke this at the end of a scope.
-   */
-  virtual void RemoveTexture(TextureClient* aTexture);
-
   static CompositableClient* FromIPDLActor(PCompositableChild* aActor);
 
   /**
    * Allocate and deallocate a CompositableChild actor.
    *
    * CompositableChild is an implementation detail of CompositableClient that is not
    * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
    * are for use with the managing IPDL protocols only (so that they can
@@ -179,34 +170,12 @@ protected:
   CompositableForwarder* mForwarder;
   // Some layers may want to enforce some flags to all their textures
   // (like disallowing tiling)
   TextureFlags mTextureFlags;
 
   friend class CompositableChild;
 };
 
-/**
- * Helper to call RemoveTexture at the end of a scope.
- */
-struct AutoRemoveTexture MOZ_STACK_CLASS {
-  AutoRemoveTexture(CompositableClient* aCompositable,
-                    TextureClient* aTexture = nullptr)
-    : mTexture(aTexture)
-    , mCompositable(aCompositable)
-  {}
-
-  ~AutoRemoveTexture()
-  {
-    if (mCompositable && mTexture) {
-      mCompositable->RemoveTexture(mTexture);
-    }
-  }
-
-  RefPtr<TextureClient> mTexture;
-private:
-  CompositableClient* mCompositable;
-};
-
 } // namespace
 } // namespace
 
 #endif
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -106,24 +106,18 @@ ImageClient::CreateImageClient(Composita
   }
 
   NS_ASSERTION(result, "Failed to create ImageClient");
 
   return result.forget();
 }
 
 void
-ImageClient::RemoveTexture(TextureClient* aTexture)
-{
-  RemoveTextureWithTracker(aTexture, nullptr);
-}
-
-void
-ImageClient::RemoveTextureWithTracker(TextureClient* aTexture,
-                                      AsyncTransactionTracker* aAsyncTransactionTracker)
+ImageClient::RemoveTextureFromCompositable(TextureClient* aTexture,
+                                           AsyncTransactionTracker* aAsyncTransactionTracker)
 {
 #ifdef MOZ_WIDGET_GONK
   // AsyncTransactionTracker is supported only on ImageBridge.
   // Use AsyncTransactionTracker only when TextureClient is recyeled.
   if (GetForwarder()->IsImageBridgeChild() &&
       aTexture->HasRecycleCallback()) {
     RefPtr<AsyncTransactionTracker> request = aAsyncTransactionTracker;
     if (!request) {
@@ -172,34 +166,34 @@ ImageClientSingle::PrepareFlushAllImages
   return status;
 }
 
 void
 ImageClientSingle::FlushAllImages(bool aExceptFront,
                                   AsyncTransactionTracker* aAsyncTransactionTracker)
 {
   if (!aExceptFront && mFrontBuffer) {
-    RemoveTextureWithTracker(mFrontBuffer, aAsyncTransactionTracker);
+    RemoveTextureFromCompositable(mFrontBuffer, aAsyncTransactionTracker);
     mFrontBuffer = nullptr;
   } else if(aAsyncTransactionTracker) {
     // already flushed
     aAsyncTransactionTracker->NotifyComplete();
   }
 }
 
 void
 ImageClientBuffered::FlushAllImages(bool aExceptFront,
                                     AsyncTransactionTracker* aAsyncTransactionTracker)
 {
   if (!aExceptFront && mFrontBuffer) {
-    RemoveTexture(mFrontBuffer);
+    RemoveTextureFromCompositable(mFrontBuffer);
     mFrontBuffer = nullptr;
   }
   if (mBackBuffer) {
-    RemoveTextureWithTracker(mBackBuffer, aAsyncTransactionTracker);
+    RemoveTextureFromCompositable(mBackBuffer, aAsyncTransactionTracker);
     mBackBuffer = nullptr;
   }
 }
 
 bool
 ImageClientSingle::UpdateImage(ImageContainer* aContainer,
                                uint32_t aContentFlags)
 {
@@ -218,39 +212,39 @@ ImageClientSingle::UpdateImageInternal(I
   if (!image) {
     return false;
   }
 
   if (mLastPaintedImageSerial == image->GetSerial()) {
     return true;
   }
 
-  AutoRemoveTexture autoRemoveTexture(this);
-
   if (image->AsSharedImage() && image->AsSharedImage()->GetTextureClient(this)) {
     // fast path: no need to allocate and/or copy image data
     RefPtr<TextureClient> texture = image->AsSharedImage()->GetTextureClient(this);
 
-    autoRemoveTexture.mTexture = mFrontBuffer;
+    if (mFrontBuffer) {
+      RemoveTextureFromCompositable(mFrontBuffer);
+    }
     mFrontBuffer = texture;
     if (!AddTextureClient(texture)) {
       mFrontBuffer = nullptr;
       return false;
     }
     GetForwarder()->UpdatedTexture(this, texture, nullptr);
     GetForwarder()->UseTexture(this, texture);
   } else if (image->GetFormat() == ImageFormat::PLANAR_YCBCR) {
     PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image);
     const PlanarYCbCrData* data = ycbcr->GetData();
     if (!data) {
       return false;
     }
 
     if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
-      autoRemoveTexture.mTexture = mFrontBuffer;
+      RemoveTextureFromCompositable(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
       mFrontBuffer = CreateBufferTextureClient(gfx::SurfaceFormat::YUV, TextureFlags::DEFAULT);
       gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
       gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
@@ -284,17 +278,17 @@ ImageClientSingle::UpdateImageInternal(I
     }
 
   } else if (image->GetFormat() == ImageFormat::SHARED_TEXTURE) {
     SharedTextureImage* sharedImage = static_cast<SharedTextureImage*>(image);
     const SharedTextureImage::Data *data = sharedImage->GetData();
     gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
 
     if (mFrontBuffer) {
-      autoRemoveTexture.mTexture = mFrontBuffer;
+      RemoveTextureFromCompositable(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     RefPtr<SharedTextureClientOGL> buffer = new SharedTextureClientOGL(mTextureFlags);
     buffer->InitWith(data->mHandle, size, data->mShareType, data->mInverted);
     mFrontBuffer = buffer;
     if (!AddTextureClient(mFrontBuffer)) {
       mFrontBuffer = nullptr;
@@ -305,17 +299,17 @@ ImageClientSingle::UpdateImageInternal(I
   } else {
     RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
     MOZ_ASSERT(surface);
 
     gfx::IntSize size = image->GetSize();
 
     if (mFrontBuffer &&
         (mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
-      autoRemoveTexture.mTexture = mFrontBuffer;
+      RemoveTextureFromCompositable(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
       gfxImageFormat format
         = gfxPlatform::GetPlatform()->OptimalFormatForContent(gfx::ContentForFormat(surface->GetFormat()));
       mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
--- a/gfx/layers/client/ImageClient.h
+++ b/gfx/layers/client/ImageClient.h
@@ -70,20 +70,18 @@ public:
 
   /**
    * asynchronously remove all the textures used by the image client.
    *
    */
   virtual void FlushAllImages(bool aExceptFront,
                               AsyncTransactionTracker* aAsyncTransactionTracker) {}
 
-  virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
-
-  void RemoveTextureWithTracker(TextureClient* aTexture,
-                                AsyncTransactionTracker* aAsyncTransactionTracker = nullptr);
+  virtual void RemoveTextureFromCompositable(TextureClient* aTexture,
+                                             AsyncTransactionTracker* aAsyncTransactionTracker = nullptr);
 
 protected:
   ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
               CompositableType aType);
 
   CompositableType mType;
   int32_t mLastPaintedImageSerial;
   nsIntRect mPictureRect;
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -82,28 +82,24 @@ static int sCompositorThreadRefCount = 0
 static MessageLoop* sMainLoop = nullptr;
 // When ContentParent::StartUp() is called, we use the Thread global.
 // When StartUpWithExistingThread() is used, we have to use the two
 // duplicated globals, because there's no API to make a Thread from an
 // existing thread.
 static PlatformThreadId sCompositorThreadID = 0;
 static MessageLoop* sCompositorLoop = nullptr;
 
-// See ImageBridgeChild.cpp
-void ReleaseImageBridgeParentSingleton();
-
 static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie)
 {
   aNowReadyToDie->Release();
 }
 
 static void DeleteCompositorThread()
 {
   if (NS_IsMainThread()){
-    ReleaseImageBridgeParentSingleton();
     delete sCompositorThread;
     sCompositorThread = nullptr;
     sCompositorLoop = nullptr;
     sCompositorThreadID = 0;
   } else {
     sMainLoop->PostTask(FROM_HERE, NewRunnableFunction(&DeleteCompositorThread));
   }
 }
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -160,60 +160,39 @@ ImageBridgeChild::UpdatePictureRect(Comp
   mTxn->AddNoSwapEdit(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect));
 }
 
 // Singleton
 static StaticRefPtr<ImageBridgeChild> sImageBridgeChildSingleton;
 static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
 static Thread *sImageBridgeChildThread = nullptr;
 
-void ReleaseImageBridgeParentSingleton() {
-  sImageBridgeParentSingleton = nullptr;
-}
-
-
 // dispatched function
-static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone)
+static void StopImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone)
 {
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
 
   NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                     "Should be in ImageBridgeChild thread.");
   if (sImageBridgeChildSingleton) {
-    // Force all managed protocols to shut themselves down cleanly
-    InfallibleTArray<PCompositableChild*> compositables;
-    sImageBridgeChildSingleton->ManagedPCompositableChild(compositables);
-    for (int i = compositables.Length() - 1; i >= 0; --i) {
-      CompositableClient::FromIPDLActor(compositables[i])->Destroy();
-    }
-    InfallibleTArray<PTextureChild*> textures;
-    sImageBridgeChildSingleton->ManagedPTextureChild(textures);
-    for (int i = textures.Length() - 1; i >= 0; --i) {
-      TextureClient::AsTextureClient(textures[i])->ForceRemove();
-    }
-    sImageBridgeChildSingleton->SendWillStop();
-    sImageBridgeChildSingleton->MarkShutDown();
-    // From now on, no message can be sent through the image bridge from the
-    // client side except the final Stop message.
+    sImageBridgeChildSingleton->SendStop();
   }
   *aDone = true;
   aBarrier->NotifyAll();
 }
 
 // dispatched function
-static void ImageBridgeShutdownStep2(ReentrantMonitor *aBarrier, bool *aDone)
+static void DeleteImageBridgeSync(ReentrantMonitor *aBarrier, bool *aDone)
 {
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
 
   NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                     "Should be in ImageBridgeChild thread.");
-
-  sImageBridgeChildSingleton->SendStop();
-
   sImageBridgeChildSingleton = nullptr;
+  sImageBridgeParentSingleton = nullptr;
   *aDone = true;
   aBarrier->NotifyAll();
 }
 
 // dispatched function
 static void CreateImageClientSync(RefPtr<ImageClient>* result,
                                   ReentrantMonitor* barrier,
                                   CompositableType aType,
@@ -228,48 +207,38 @@ static void CreateImageClientSync(RefPtr
 static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * parent)
 {
   MessageLoop *parentMsgLoop = parent->GetMessageLoop();
   ipc::MessageChannel *parentChannel = parent->GetIPCChannel();
   child->Open(parentChannel, parentMsgLoop, mozilla::ipc::ChildSide);
 }
 
 ImageBridgeChild::ImageBridgeChild()
-  : mShuttingDown(false)
 {
   mTxn = new CompositableTransaction();
 }
 ImageBridgeChild::~ImageBridgeChild()
 {
   delete mTxn;
 }
 
 void
-ImageBridgeChild::MarkShutDown()
-{
-  MOZ_ASSERT(!mShuttingDown);
-  mShuttingDown = true;
-}
-
-void
 ImageBridgeChild::Connect(CompositableClient* aCompositable)
 {
   MOZ_ASSERT(aCompositable);
-  MOZ_ASSERT(!mShuttingDown);
   uint64_t id = 0;
   PCompositableChild* child =
     SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id);
   MOZ_ASSERT(child);
   aCompositable->InitIPDLActor(child, id);
 }
 
 PCompositableChild*
 ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID)
 {
-  MOZ_ASSERT(!mShuttingDown);
   return CompositableClient::CreateIPDLActor();
 }
 
 bool
 ImageBridgeChild::DeallocPCompositableChild(PCompositableChild* aActor)
 {
   return CompositableClient::DestroyIPDLActor(aActor);
 }
@@ -323,52 +292,30 @@ static void ReleaseImageClientNow(ImageC
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient)
 {
-  if (!IsCreated()) {
-    // CompositableClient::Release should normally happen in the ImageBridgeChild
-    // thread because it usually generate some IPDL messages.
-    // However, if we take this branch it means that the ImageBridgeChild
-    // has already shut down, along with the CompositableChild, which means no
-    // message will be sent and it is safe to run this code from any thread.
-    MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
-    aClient->Release();
-    return;
-  }
-
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseImageClientNow, aClient));
 }
 
 static void ReleaseTextureClientNow(TextureClient* aClient)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
 {
-  if (!IsCreated()) {
-    // TextureClient::Release should normally happen in the ImageBridgeChild
-    // thread because it usually generate some IPDL messages.
-    // However, if we take this branch it means that the ImageBridgeChild
-    // has already shut down, along with the TextureChild, which means no
-    // message will be sent and it is safe to run this code from any thread.
-    MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
-    aClient->Release();
-    return;
-  }
-
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
 static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContainer)
 {
   MOZ_ASSERT(aClient);
@@ -378,20 +325,16 @@ static void UpdateImageClientNow(ImageCl
   aClient->OnTransaction();
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 //static
 void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
                                                  ImageContainer* aContainer)
 {
-  if (!IsCreated()) {
-    return;
-  }
-
   if (InImageBridgeChildThread()) {
     UpdateImageClientNow(aClient, aContainer);
     return;
   }
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction<
       void (*)(ImageClient*, ImageContainer*),
@@ -410,17 +353,16 @@ static void FlushAllImagesSync(ImageClie
   aClient->OnTransaction();
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 //static
 void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront)
 {
   MOZ_ASSERT(aClient);
-  MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
   MOZ_ASSERT(!InImageBridgeChildThread());
   if (InImageBridgeChildThread()) {
     NS_ERROR("ImageBridgeChild::FlushAllImages() is called on ImageBridge thread.");
      return;
    }
 
   RefPtr<AsyncTransactionTracker> status = aClient->PrepareFlushAllImages();
 
@@ -429,17 +371,16 @@ void ImageBridgeChild::FlushAllImages(Im
     NewRunnableFunction(&FlushAllImagesSync, aClient, aContainer, aExceptFront, status));
 
   status->WaitComplete();
 }
 
 void
 ImageBridgeChild::BeginTransaction()
 {
-  MOZ_ASSERT(!mShuttingDown);
   MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
   mTxn->Begin();
 }
 
 class MOZ_STACK_CLASS AutoRemoveTextures
 {
 public:
   AutoRemoveTextures(ImageBridgeChild* aImageBridge)
@@ -451,17 +392,16 @@ public:
   }
 private:
   ImageBridgeChild* mImageBridge;
 };
 
 void
 ImageBridgeChild::EndTransaction()
 {
-  MOZ_ASSERT(!mShuttingDown);
   MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
 
   AutoEndTransaction _(mTxn);
   AutoRemoveTextures autoRemoveTextures(this);
 
   if (mTxn->IsEmpty()) {
     return;
   }
@@ -546,44 +486,19 @@ ImageBridgeChild::StartUpInChildProcess(
     NewRunnableFunction(ConnectImageBridgeInChildProcess,
                         aTransport, processHandle));
 
   return sImageBridgeChildSingleton;
 }
 
 void ImageBridgeChild::ShutDown()
 {
-  MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
+  NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
   if (ImageBridgeChild::IsCreated()) {
-    MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
-
-    {
-      ReentrantMonitor barrier("ImageBridge ShutdownStep1 lock");
-      ReentrantMonitorAutoEnter autoMon(barrier);
-
-      bool done = false;
-      sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
-                      NewRunnableFunction(&ImageBridgeShutdownStep1, &barrier, &done));
-      while (!done) {
-        barrier.Wait();
-      }
-    }
-
-    {
-      ReentrantMonitor barrier("ImageBridge ShutdownStep2 lock");
-      ReentrantMonitorAutoEnter autoMon(barrier);
-
-      bool done = false;
-      sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
-                      NewRunnableFunction(&ImageBridgeShutdownStep2, &barrier, &done));
-      while (!done) {
-        barrier.Wait();
-      }
-    }
-
+    ImageBridgeChild::DestroyBridge();
     delete sImageBridgeChildThread;
     sImageBridgeChildThread = nullptr;
   }
 }
 
 bool ImageBridgeChild::StartUpOnThread(Thread* aThread)
 {
   NS_ABORT_IF_FALSE(aThread, "ImageBridge needs a thread.");
@@ -597,16 +512,45 @@ bool ImageBridgeChild::StartUpOnThread(T
       CompositorParent::CompositorLoop(), nullptr);
     sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
     return true;
   } else {
     return false;
   }
 }
 
+void ImageBridgeChild::DestroyBridge()
+{
+  if (!IsCreated()) {
+    return;
+  }
+  NS_ABORT_IF_FALSE(!InImageBridgeChildThread(),
+                    "This method must not be called in this thread.");
+  // ...because we are about to dispatch synchronous messages to the
+  // ImageBridgeChild thread.
+
+  ReentrantMonitor barrier("ImageBridgeDestroyTask lock");
+  ReentrantMonitorAutoEnter autoMon(barrier);
+
+  bool done = false;
+  sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
+                  NewRunnableFunction(&StopImageBridgeSync, &barrier, &done));
+  while (!done) {
+    barrier.Wait();
+  }
+
+  done = false;
+  sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
+                  NewRunnableFunction(&DeleteImageBridgeSync, &barrier, &done));
+  while (!done) {
+    barrier.Wait();
+  }
+
+}
+
 bool InImageBridgeChildThread()
 {
   return ImageBridgeChild::IsCreated() &&
     sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
 }
 
 MessageLoop * ImageBridgeChild::GetMessageLoop() const
 {
@@ -646,45 +590,42 @@ ImageBridgeChild::CreateImageClient(Comp
     barrier.Wait();
   }
   return result.forget();
 }
 
 TemporaryRef<ImageClient>
 ImageBridgeChild::CreateImageClientNow(CompositableType aType)
 {
-  MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
   RefPtr<ImageClient> client
     = ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS);
   MOZ_ASSERT(client, "failed to create ImageClient");
   if (client) {
     client->Connect();
   }
   return client.forget();
 }
 
 bool
 ImageBridgeChild::AllocUnsafeShmem(size_t aSize,
                                    ipc::SharedMemory::SharedMemoryType aType,
                                    ipc::Shmem* aShmem)
 {
-  MOZ_ASSERT(!mShuttingDown);
   if (InImageBridgeChildThread()) {
     return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
   } else {
     return DispatchAllocShmemInternal(aSize, aType, aShmem, true); // true: unsafe
   }
 }
 
 bool
 ImageBridgeChild::AllocShmem(size_t aSize,
                              ipc::SharedMemory::SharedMemoryType aType,
                              ipc::Shmem* aShmem)
 {
-  MOZ_ASSERT(!mShuttingDown);
   if (InImageBridgeChildThread()) {
     return PImageBridgeChild::AllocShmem(aSize, aType, aShmem);
   } else {
     return DispatchAllocShmemInternal(aSize, aType, aShmem, false); // false: unsafe
   }
 }
 
 // NewRunnableFunction accepts a limited number of parameters so we need a
@@ -783,17 +724,16 @@ ImageBridgeChild::DeallocShmem(ipc::Shme
     }
   }
 }
 
 PTextureChild*
 ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
                                      const TextureFlags&)
 {
-  MOZ_ASSERT(!mShuttingDown);
   return TextureClient::CreateIPDLActor();
 }
 
 bool
 ImageBridgeChild::DeallocPTextureChild(PTextureChild* actor)
 {
   return TextureClient::DestroyIPDLActor(actor);
 }
@@ -830,25 +770,23 @@ ImageBridgeChild::RecvParentAsyncMessage
   }
   return true;
 }
 
 PTextureChild*
 ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
                                 TextureFlags aFlags)
 {
-  MOZ_ASSERT(!mShuttingDown);
   return SendPTextureConstructor(aSharedData, aFlags);
 }
 
 void
 ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable,
                                                 TextureClient* aTexture)
 {
-  MOZ_ASSERT(!mShuttingDown);
   if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
     mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
                                   nullptr, aTexture->GetIPDLActor()));
   } else {
     mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
                                         nullptr, aTexture->GetIPDLActor()));
   }
   // Hold texture until transaction complete.
@@ -878,17 +816,16 @@ static void RemoveTextureSync(TextureCli
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
   *aDone = true;
   aBarrier->NotifyAll();
 }
 
 void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
 {
   if (InImageBridgeChildThread()) {
-    MOZ_ASSERT(!mShuttingDown);
     aTexture->ForceRemove();
     return;
   }
 
   ReentrantMonitor barrier("RemoveTexture Lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
 
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -127,16 +127,25 @@ public:
   static void ShutDown();
 
   /**
    * Creates the ImageBridgeChild manager protocol.
    */
   static bool StartUpOnThread(base::Thread* aThread);
 
   /**
+   * Destroys The ImageBridge protcol.
+   *
+   * The actual destruction happens synchronously on the ImageBridgeChild thread
+   * which means that if this function is called from another thread, the current
+   * thread will be paused until the destruction is done.
+   */
+  static void DestroyBridge();
+
+  /**
    * Returns true if the singleton has been created.
    *
    * Can be called from any thread.
    */
   static bool IsCreated();
 
   /**
    * returns the singleton instance.
@@ -296,24 +305,22 @@ public:
 
   virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
                                        TextureFlags aFlags) MOZ_OVERRIDE;
 
   virtual bool IsSameProcess() const MOZ_OVERRIDE;
 
   void SendPendingAsyncMessge();
 
-  void MarkShutDown();
 protected:
   ImageBridgeChild();
   bool DispatchAllocShmemInternal(size_t aSize,
                                   SharedMemory::SharedMemoryType aType,
                                   Shmem* aShmem,
                                   bool aUnsafe);
 
   CompositableTransaction* mTxn;
-  bool mShuttingDown;
 };
 
 } // layers
 } // mozilla
 
 #endif
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -133,38 +133,31 @@ ImageBridgeParent::Create(Transport* aTr
   nsRefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport);
   bridge->mSelfRef = bridge;
   loop->PostTask(FROM_HERE,
                  NewRunnableFunction(ConnectImageBridgeInParentProcess,
                                      bridge.get(), aTransport, processHandle));
   return bridge.get();
 }
 
-bool ImageBridgeParent::RecvWillStop()
+bool ImageBridgeParent::RecvStop()
 {
   // If there is any texture still alive we have to force it to deallocate the
   // device data (GL textures, etc.) now because shortly after SenStop() returns
   // on the child side the widget will be destroyed along with it's associated
   // GL context.
   InfallibleTArray<PTextureParent*> textures;
   ManagedPTextureParent(textures);
   for (unsigned int i = 0; i < textures.Length(); ++i) {
     RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]);
     tex->DeallocateDeviceData();
   }
   return true;
 }
 
-bool ImageBridgeParent::RecvStop()
-{
-  // Nothing to do. This message just serves as synchronization between the
-  // child and parent threads during shutdown.
-  return true;
-}
-
 static  uint64_t GenImageContainerID() {
   static uint64_t sNextImageID = 1;
 
   ++sNextImageID;
   return sNextImageID;
 }
 
 PCompositableParent*
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -73,20 +73,17 @@ public:
 
   virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                               const TextureFlags& aFlags) MOZ_OVERRIDE;
   virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
 
   virtual bool
   RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages) MOZ_OVERRIDE;
 
-  // Shutdown step 1
-  virtual bool RecvWillStop() MOZ_OVERRIDE;
-  // Shutdown step 2
-  virtual bool RecvStop() MOZ_OVERRIDE;
+  bool RecvStop() MOZ_OVERRIDE;
 
   MessageLoop * GetMessageLoop();
 
 
   // ISurfaceAllocator
 
   bool AllocShmem(size_t aSize,
                   ipc::SharedMemory::SharedMemoryType aType,
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -31,26 +31,23 @@ intr protocol PImageBridge
 child:
   async ParentAsyncMessage(AsyncParentMessageData[] aMessages);
 
 parent:
 
   sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
   async UpdateNoSwap(CompositableOperation[] ops);
 
-  // First step of the destruction sequence. This puts ImageBridge
-  // in a state in which it can't send asynchronous messages
-  // so as to not race with the upcomming Stop message and destruction.
-  // In the child side, the Stop message is not sent right after WillStop,
-  // it is scheduled in the ImageBridgeChild's message queue in order to ensure
-  // that all of the messages from the parent side have been received and processed
-  // before sending Stop, and that after Stop returns, there is no message in
-  // flight on any side and we can safely destroy the channel and threads.
-  sync WillStop();
-  // Second step
+  // First step of the destruction sequence. This puts all the ImageContainerParents
+  // in a state in which they can't send asynchronous messages to their child
+  // counterpart so as to not race with the upcomming __delete__ message.
+  // In the child side, the __delete__ messages are not sent right after Stop,
+  // they are scheduled in the ImageBridgeChild's message queue in order to ensure
+  // that all the messages from the parent side have been received and processed
+  // before sending __delete__.
   sync Stop();
 
   sync PCompositable(TextureInfo aInfo) returns (uint64_t id);
   async PTexture(SurfaceDescriptor aSharedData, TextureFlags aTextureFlags);
 
   async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
 };
 
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -945,17 +945,17 @@ DoLongPressPreventDefaultTest(bool aShou
   nsRefPtr<TestAPZCTreeManager> tm = new TestAPZCTreeManager();
   nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(
     0, mcc, tm, AsyncPanZoomController::USE_GESTURE_DETECTOR);
 
   apzc->SetFrameMetrics(TestFrameMetrics());
   apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
   apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
 
-  apzc->SetTouchActionEnabled(aShouldUseTouchAction);
+  apzc->SetTouchActionEnabled(aShouldUseTouchAction);
 
   EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(0);
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0);
 
   int touchX = 10,
       touchStartY = 10,
       touchEndY = 50;
 
@@ -994,17 +994,17 @@ DoLongPressPreventDefaultTest(bool aShou
 
   time += 1000;
 
   MultiTouchInput mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, time, 0);
   mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(touchX, touchEndY), ScreenSize(0, 0), 0, 0));
   status = apzc->ReceiveInputEvent(mti);
   EXPECT_EQ(nsEventStatus_eIgnore, status);
 
-  EXPECT_CALL(*mcc, HandleLongTapUp(CSSPoint(touchX, touchEndY), 0, apzc->GetGuid())).Times(0);
+  EXPECT_CALL(*mcc, HandleLongTapUp(CSSPoint(touchX, touchEndY), 0, apzc->GetGuid())).Times(1);
   status = ApzcUp(apzc, touchX, touchEndY, time);
   EXPECT_EQ(nsEventStatus_eIgnore, status);
 
   // Flush the event queue. Once the "contextmenu" event is handled, any touch
   // events that come from the same series of start->n*move->end events should
   // be discarded, even if only the "contextmenu" event is preventDefaulted.
   apzc->ContentReceivedTouch(false);
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -495,16 +495,26 @@ gfxPlatform::Shutdown()
     // most platforms.  Windows is a "special snowflake", though, and has three
     // context providers available, so we have to shut all of them down.
     // We should only support the default GL provider on Windows; then, this
     // could go away. Unfortunately, we currently support WGL (the default) for
     // WebGL on Optimus.
     mozilla::gl::GLContextProviderEGL::Shutdown();
 #endif
 
+    // This will block this thread untill the ImageBridge protocol is completely
+    // deleted.
+    ImageBridgeChild::ShutDown();
+#ifdef MOZ_WIDGET_GONK
+    SharedBufferManagerChild::ShutDown();
+#endif
+    CompositorParent::ShutDown();
+
+    AsyncTransactionTracker::Finalize();
+
     delete gGfxPlatformPrefsLock;
 
     gfxPrefs::DestroySingleton();
     gfxFont::DestroySingletons();
 
     delete gPlatform;
     gPlatform = nullptr;
 }
--- a/layout/reftests/webm-video/bug686957.html
+++ b/layout/reftests/webm-video/bug686957.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <html class="reftest-wait">
 <body style="background:white;">
 <!-- Test that if we seek to the end of a video we get the last frame displayed -->
 <video src="frames.webm"
        preload="auto"
        id="v"
        onloadedmetadata="document.getElementById('v').currentTime=document.getElementById('v').duration"
-       onseeked="setTimeout(function(){document.documentElement.className = '';}, 15);"
+       onseeked="setTimeout(function(){document.documentElement.className = '';}, 0);"
 </video>
 </body>
 </html>
--- a/layout/style/nsStyleUtil.cpp
+++ b/layout/style/nsStyleUtil.cpp
@@ -76,51 +76,50 @@ void nsStyleUtil::AppendEscapedCSSString
 
   aReturn.Append(quoteChar);
 }
 
 /* static */ bool
 nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
 {
   // The relevant parts of the CSS grammar are:
-  //   ident    ([-]?{nmstart}|[-][-]){nmchar}*
+  //   ident    [-]?{nmstart}{nmchar}*
   //   nmstart  [_a-z]|{nonascii}|{escape}
   //   nmchar   [_a-z0-9-]|{nonascii}|{escape}
   //   nonascii [^\0-\177]
   //   escape   {unicode}|\\[^\n\r\f0-9a-f]
   //   unicode  \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-  // from http://www.w3.org/TR/CSS21/syndata.html#tokenization but
-  // modified for idents by
-  // http://dev.w3.org/csswg/cssom/#serialize-an-identifier and
-  // http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier
+  // from http://www.w3.org/TR/CSS21/syndata.html#tokenization
 
   const char16_t* in = aIdent.BeginReading();
   const char16_t* const end = aIdent.EndReading();
 
   if (in == end)
     return true;
 
   // A leading dash does not need to be escaped as long as it is not the
   // *only* character in the identifier.
-  if (*in == '-') {
-    if (in + 1 == end) {
-      aReturn.Append(char16_t('\\'));
-      aReturn.Append(char16_t('-'));
-      return true;
-    }
-
+  if (in + 1 != end && *in == '-') {
     aReturn.Append(char16_t('-'));
     ++in;
   }
 
   // Escape a digit at the start (including after a dash),
   // numerically.  If we didn't escape it numerically, it would get
   // interpreted as a numeric escape for the wrong character.
-  if (in != end && ('0' <= *in && *in <= '9')) {
-    aReturn.AppendPrintf("\\%hX ", *in);
+  // A second dash immediately after a leading dash must also be
+  // escaped, but this may be done symbolically.
+  if (in != end && (*in == '-' ||
+                    ('0' <= *in && *in <= '9'))) {
+    if (*in == '-') {
+      aReturn.Append(char16_t('\\'));
+      aReturn.Append(char16_t('-'));
+    } else {
+      aReturn.AppendPrintf("\\%hX ", *in);
+    }
     ++in;
   }
 
   for (; in != end; ++in) {
     char16_t ch = *in;
     if (ch == 0x00) {
       return false;
     }
--- a/layout/style/test/test_css_escape_api.html
+++ b/layout/style/test/test_css_escape_api.html
@@ -61,17 +61,17 @@ is(CSS.escape('-2a'), '-\\32 a', "escapi
 is(CSS.escape('-3a'), '-\\33 a', "escapingFailed Char: -3a");
 is(CSS.escape('-4a'), '-\\34 a', "escapingFailed Char: -4a");
 is(CSS.escape('-5a'), '-\\35 a', "escapingFailed Char: -5a");
 is(CSS.escape('-6a'), '-\\36 a', "escapingFailed Char: -6a");
 is(CSS.escape('-7a'), '-\\37 a', "escapingFailed Char: -7a");
 is(CSS.escape('-8a'), '-\\38 a', "escapingFailed Char: -8a");
 is(CSS.escape('-9a'), '-\\39 a', "escapingFailed Char: -9a");
 
-is(CSS.escape('--a'), '--a', 'Should not need to escape leading "--"');
+is(CSS.escape('--a'), '-\\-a', "escapingFailed Char: --a");
 
 is(CSS.escape('\x80\x2D\x5F\xA9'), '\\80 \x2D\x5F\xA9', "escapingFailed Char: \\x80\\x2D\\x5F\\xA9");
 is(CSS.escape('\xA0\xA1\xA2'), '\xA0\xA1\xA2', "escapingFailed Char: \\xA0\\xA1\\xA2");
 is(CSS.escape('a0123456789b'), 'a0123456789b', "escapingFailed Char: a0123465789");
 is(CSS.escape('abcdefghijklmnopqrstuvwxyz'), 'abcdefghijklmnopqrstuvwxyz', "escapingFailed Char: abcdefghijklmnopqrstuvwxyz");
 is(CSS.escape('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', "escapingFailed Char: ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXYZ");
 
 is(CSS.escape('\x20\x21\x78\x79'), '\\ \\!xy', "escapingFailed Char: \\x20\\x21\\x78\\x79");
--- a/layout/style/test/test_parser_diagnostics_unprintables.html
+++ b/layout/style/test/test_parser_diagnostics_unprintables.html
@@ -69,17 +69,17 @@ const substitutions = [
   { t: "\\32 ",  i: "\\32 ",  s: "2"  },
   { t: "\\33 ",  i: "\\33 ",  s: "3"  },
   { t: "\\34 ",  i: "\\34 ",  s: "4"  },
   { t: "\\35 ",  i: "\\35 ",  s: "5"  },
   { t: "\\36 ",  i: "\\36 ",  s: "6"  },
   { t: "\\37 ",  i: "\\37 ",  s: "7"  },
   { t: "\\38 ",  i: "\\38 ",  s: "8"  },
   { t: "\\39 ",  i: "\\39 ",  s: "9"  },
-  { t: "-\\-",   i: "--",     s: "--" },
+  { t: "-\\-",   i: "-\\-",   s: "--" },
   { t: "-\\30 ", i: "-\\30 ", s: "-0" },
   { t: "-\\31 ", i: "-\\31 ", s: "-1" },
   { t: "-\\32 ", i: "-\\32 ", s: "-2" },
   { t: "-\\33 ", i: "-\\33 ", s: "-3" },
   { t: "-\\34 ", i: "-\\34 ", s: "-4" },
   { t: "-\\35 ", i: "-\\35 ", s: "-5" },
   { t: "-\\36 ", i: "-\\36 ", s: "-6" },
   { t: "-\\37 ", i: "-\\37 ", s: "-7" },
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -174,24 +174,16 @@ protected:
   WalkCacheRunnable(nsICacheStorageVisitor* aVisitor,
                     bool aVisitEntries)
     : mService(CacheStorageService::Self())
     , mCallback(aVisitor)
     , mSize(0)
     , mNotifyStorage(true)
     , mVisitEntries(aVisitEntries)
   {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  virtual ~WalkCacheRunnable()
-  {
-    if (mCallback) {
-      ProxyReleaseMainThread(mCallback);
-    }
   }
 
   nsRefPtr<CacheStorageService> mService;
   nsCOMPtr<nsICacheStorageVisitor> mCallback;
 
   uint64_t mSize;
 
   bool mNotifyStorage : 1;
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -2176,17 +2176,16 @@ nsHttpChannel::ProcessPartialContent()
         if (NS_FAILED(rv)) return rv;
 
         UpdateInhibitPersistentCachingFlag();
 
         rv = UpdateExpirationTime();
         if (NS_FAILED(rv)) return rv;
 
         mCachedContentIsPartial = false;
-        mConcurentCacheAccess = 0;
 
         // notify observers interested in looking at a response that has been
         // merged with any cached headers (http-on-examine-merged-response).
         gHttpHandler->OnExamineMergedResponse(this);
     }
     else {
         // suspend the current transaction
         rv = mTransactionPump->Suspend();
@@ -5136,16 +5135,18 @@ nsHttpChannel::OnStopRequest(nsIRequest 
 
         if (mUpgradeProtocolCallback && stickyConn &&
             mResponseHead && mResponseHead->Status() == 101) {
             gHttpHandler->ConnMgr()->CompleteUpgrade(stickyConn,
                                                      mUpgradeProtocolCallback);
         }
     }
 
+    mIsPending = false;
+
     // if needed, check cache entry has all data we expect
     if (mCacheEntry && mCachePump &&
         mConcurentCacheAccess && contentComplete) {
         int64_t size, contentLength;
         nsresult rv = CheckPartial(mCacheEntry, &size, &contentLength);
         if (NS_SUCCEEDED(rv)) {
             if (size == int64_t(-1)) {
                 // mayhemer TODO - we have to restart read from cache here at the size offset
@@ -5175,17 +5176,16 @@ nsHttpChannel::OnStopRequest(nsIRequest 
                 }
                 else {
                     LOG(("  but range request setup failed rv=0x%08x, failing load", rv));
                 }
             }
         }
     }
 
-    mIsPending = false;
     mStatus = status;
 
     // perform any final cache operations before we close the cache entry.
     if (mCacheEntry && mRequestTimeInitialized) {
         bool writeAccess;
         // New implementation just returns value of the !mCacheEntryIsReadOnly flag passed in.
         // Old implementation checks on nsICache::ACCESS_WRITE flag.
         mCacheEntry->HasWriteAccess(!mCacheEntryIsReadOnly, &writeAccess);
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -476,17 +476,17 @@ class TreeMetadataEmitter(LoggingMixin):
                 relpath=mozpath.join(manifest_reldir, mozpath.basename(path)),
                 dupe_manifest='dupe-manifest' in defaults)
 
             filtered = m.tests
 
             if filter_inactive:
                 # We return tests that don't exist because we want manifests
                 # defining tests that don't exist to result in error.
-                filtered = m.active_tests(exists=False, disabled=True,
+                filtered = m.active_tests(exists=False, disabled=False,
                     **self.info)
 
                 missing = [t['name'] for t in filtered if not os.path.exists(t['path'])]
                 if missing:
                     raise SandboxValidationError('Test manifest (%s) lists '
                         'test that does not exist: %s' % (
                         path, ', '.join(missing)))
 
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-inactive-ignored/mochitest.ini
@@ -0,0 +1,3 @@
+[test_active.html]
+[test_inactive.html]
+skip-if = true
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-inactive-ignored/moz.build
@@ -0,0 +1,4 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+MOCHITEST_MANIFESTS += ['mochitest.ini']
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/foo.txt
@@ -0,0 +1,1 @@
+hello
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/moz.build
@@ -0,0 +1,4 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+MOCHITEST_MANIFESTS += ['support-disabled-tests.ini']
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/support-disabled-tests.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+support-files = foo.txt
+
+[test_blah.html]
+disabled =
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/test-manifest-support-disabled-tests/test_blah.html
@@ -0,0 +1,1 @@
+<html></html>
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -316,16 +316,27 @@ class TestEmitterBasic(unittest.TestCase
 
         objs = self.read_topsrcdir(reader)
         self.assertEqual(len(objs), 1)
         o = objs[0]
         self.assertEqual(len(o.installs), 2)
         paths = sorted([k[len(o.directory)+1:] for k in o.installs.keys()])
         self.assertEqual(paths, ["foo.txt", "just-support.ini"])
 
+    def test_test_manifest_support_files_disabled_test(self):
+        """A test manifest with just disabled tests and support-files is supported."""
+        reader = self.reader('test-manifest-support-disabled-tests')
+
+        objs = self.read_topsrcdir(reader)
+        self.assertEqual(len(objs), 1)
+        o = objs[0]
+        self.assertEqual(len(o.installs), 2)
+        paths = sorted([k[len(o.directory)+1:] for k in o.installs.keys()])
+        self.assertEqual(paths, ["foo.txt", "support-disabled-tests.ini"])
+
     def test_test_manifest_absolute_support_files(self):
         """Support files starting with '/' are placed relative to the install root"""
         reader = self.reader('test-manifest-absolute-support')
 
         objs = self.read_topsrcdir(reader)
         self.assertEqual(len(objs), 1)
         o = objs[0]
         self.assertEqual(len(o.installs), 2)
@@ -462,16 +473,33 @@ class TestEmitterBasic(unittest.TestCase
 
     def test_test_manifest_unmatched_generated(self):
         reader = self.reader('test-manifest-unmatched-generated')
 
         with self.assertRaisesRegexp(SandboxValidationError,
             'entry in generated-files not present elsewhere'):
             self.read_topsrcdir(reader),
 
+    # This test is only needed until all harnesses support filtering from
+    # manifests.
+    def test_test_manifest_inactive_ignored(self):
+        """Inactive tests should not be installed."""
+        reader = self.reader('test-manifest-inactive-ignored')
+
+        objs = [o for o in self.read_topsrcdir(reader)
+               if isinstance(o, TestManifest)]
+
+        self.assertEqual(len(objs), 1)
+
+        o = objs[0]
+
+        self.assertEqual(o.flavor, 'mochitest')
+        basenames = set(mozpath.basename(k) for k in o.installs.keys())
+        self.assertEqual(basenames, {'mochitest.ini', 'test_active.html'})
+
     def test_test_manifest_parent_support_files_dir(self):
         """support-files referencing a file in a parent directory works."""
         reader = self.reader('test-manifest-parent-support-files-dir')
 
         objs = [o for o in self.read_topsrcdir(reader)
                 if isinstance(o, TestManifest)]
 
         self.assertEqual(len(objs), 1)
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -9,22 +9,20 @@
 #include "mozilla/Atomics.h"
 #include "mozilla/Poison.h"
 #include "mozilla/XPCOM.h"
 #include "nsXULAppAPI.h"
 
 #include "nsXPCOMPrivate.h"
 #include "nsXPCOMCIDInternal.h"
 
+#include "prlink.h"
+
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/CompositorParent.h"
-#include "mozilla/layers/AsyncTransactionTracker.h"
-#include "mozilla/layers/SharedBufferManagerChild.h"
-
-#include "prlink.h"
 
 #include "nsCycleCollector.h"
 #include "nsObserverList.h"
 #include "nsObserverService.h"
 #include "nsProperties.h"
 #include "nsPersistentProperties.h"
 #include "nsScriptableInputStream.h"
 #include "nsBinaryStream.h"
@@ -786,33 +784,23 @@ ShutdownXPCOM(nsIServiceManager* servMgr
             if (NS_SUCCEEDED(rv))
             {
                 (void) observerService->
                     NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                     nullptr);
             }
         }
 
-        // This must happen after the shutdown of media and widgets, which
-        // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
-        layers::ImageBridgeChild::ShutDown();
-#ifdef MOZ_WIDGET_GONK
-        layers::SharedBufferManagerChild::ShutDown();
-#endif
-
         NS_ProcessPendingEvents(thread);
         mozilla::scache::StartupCache::DeleteSingleton();
         if (observerService)
             (void) observerService->
                 NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
                                 nullptr);
 
-        layers::CompositorParent::ShutDown();
-        layers::AsyncTransactionTracker::Finalize();
-
         gXPCOMThreadsShutDown = true;
         NS_ProcessPendingEvents(thread);
 
         // Shutdown the timer thread and all timers that might still be alive before
         // shutting down the component manager
         nsTimerImpl::Shutdown();
 
         NS_ProcessPendingEvents(thread);