Merge mozilla-central to autoland
authorDorel Luca <dluca@mozilla.com>
Sat, 09 Mar 2019 11:50:28 +0200
changeset 524242 5890446de11611db6831139179aa79a270577483
parent 524241 c7009174ac7e2163efbffdc9c5ecfc1acea6054e (current diff)
parent 524239 b486ad6d8c06d517316092a046a0a7c74baefc21 (diff)
child 524243 0d1df88e93f656a5eff4e1105902b2f3015cccdb
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone67.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 autoland
dom/ipc/PRemoteFrame.ipdl
dom/ipc/RemoteFrameChild.cpp
dom/ipc/RemoteFrameChild.h
dom/ipc/RemoteFrameParent.cpp
dom/ipc/RemoteFrameParent.h
third_party/rust/gleam/COPYING
third_party/rust/gleam/LICENSE-APACHE
third_party/rust/gleam/LICENSE-MIT
third_party/rust/gleam/README.md
third_party/rust/gleam/build.rs
third_party/rust/gleam/rustfmt.toml
third_party/rust/gleam/src/gl.rs
third_party/rust/gleam/src/gl_fns.rs
third_party/rust/gleam/src/gles_fns.rs
third_party/rust/gleam/src/lib.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1158,17 +1158,17 @@ source = "registry+https://github.com/ru
 dependencies = [
  "khronos_api 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gleam"
-version = "0.6.11"
+version = "0.6.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glob"
 version = "0.2.11"
@@ -3102,17 +3102,17 @@ dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "plane-split 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3153,17 +3153,17 @@ dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring 0.1.0",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender 0.60.0",
 ]
 
@@ -3407,17 +3407,17 @@ dependencies = [
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62"
 "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
 "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
 "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
 "checksum gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ffaf173cf76c73a73e080366bf556b4776ece104b06961766ff11449f38604"
-"checksum gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b93018064928ec67c429c9c9416affd93660419dbf84767fff6b8a99fbe9c277"
+"checksum gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f1519ca611d230e1deadbedfb79044b921ac4a961ab8823fef10e37271e2c38e"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum goblin 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5911d7df7b8f65ab676c5327b50acea29d3c6a1a4ad05e444cf5dce321b26db2"
 "checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
 "checksum http 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dca621d0fa606a5ff2850b6e337b57ad6137ee4d67e940449643ff45af6874c6"
 "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum hyper 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c087746de95e20e4dabe86606c3a019964a8fde2d5f386152939063c116c5971"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -65,17 +65,17 @@
 #include "mozilla/dom/HTMLTemplateElement.h"
 #include "mozilla/dom/HTMLTextAreaElement.h"
 #include "mozilla/dom/IDTracker.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/NodeBinding.h"
 #include "mozilla/dom/Promise.h"
-#include "mozilla/dom/RemoteFrameChild.h"
+#include "mozilla/dom/BrowserBridgeChild.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/Text.h"
 #include "mozilla/dom/TouchEvent.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/XULCommandEvent.h"
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/EventDispatcher.h"
@@ -6194,17 +6194,17 @@ bool nsContentUtils::IsSubDocumentTabbab
   Document* doc = aContent->GetComposedDoc();
   if (!doc) {
     return false;
   }
 
   // If the subdocument lives in another process, the frame is
   // tabbable.
   if (EventStateManager::IsRemoteTarget(aContent) ||
-      RemoteFrameChild::GetFrom(aContent)) {
+      BrowserBridgeChild::GetFrom(aContent)) {
     return true;
   }
 
   // XXXbz should this use OwnerDoc() for GetSubDocumentFor?
   // sXBL/XBL2 issue!
   Document* subDoc = doc->GetSubDocumentFor(aContent);
   if (!subDoc) {
     return false;
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -46,17 +46,17 @@
 #include "nsRange.h"
 
 #include "mozilla/AccessibleCaretEventHub.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLSlotElement.h"
-#include "mozilla/dom/RemoteFrameChild.h"
+#include "mozilla/dom/BrowserBridgeChild.h"
 #include "mozilla/dom/Text.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
@@ -1849,18 +1849,18 @@ void nsFocusManager::Focus(nsPIDOMWindow
         // if the object being focused is a remote browser, activate remote
         // content
         if (TabParent* remote = TabParent::GetFrom(aElement)) {
           remote->Activate();
           LOGFOCUS(("Remote browser activated"));
         }
 
         // Same as above but for out-of-process iframes
-        if (RemoteFrameChild* rfc = RemoteFrameChild::GetFrom(aElement)) {
-          rfc->Activate();
+        if (BrowserBridgeChild* bbc = BrowserBridgeChild::GetFrom(aElement)) {
+          bbc->Activate();
           LOGFOCUS(("Out-of-process iframe activated"));
         }
       }
 
       IMEStateManager::OnChangeFocus(presContext, aElement,
                                      GetFocusMoveActionCause(aFlags));
 
       // as long as this focus wasn't because a window was raised, update the
@@ -3470,19 +3470,19 @@ nsresult nsFocusManager::GetNextTabbable
           // into document navigation again by calling MoveFocus.
           TabParent* remote = TabParent::GetFrom(currentContent);
           if (remote) {
             remote->NavigateByKey(aForward, aForDocumentNavigation);
             return NS_SUCCESS_DOM_NO_OPERATION;
           }
 
           // Same as above but for out-of-process iframes
-          RemoteFrameChild* rfc = RemoteFrameChild::GetFrom(currentContent);
-          if (rfc) {
-            rfc->NavigateByKey(aForward, aForDocumentNavigation);
+          BrowserBridgeChild* bbc = BrowserBridgeChild::GetFrom(currentContent);
+          if (bbc) {
+            bbc->NavigateByKey(aForward, aForDocumentNavigation);
             return NS_SUCCESS_DOM_NO_OPERATION;
           }
 
           // Next, for document navigation, check if this a non-remote child
           // document.
           bool checkSubDocument = true;
           if (aForDocumentNavigation &&
               TryDocumentNavigation(currentContent, &checkSubDocument,
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -99,17 +99,17 @@
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/WebBrowserPersistLocalDocument.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/ParentSHistory.h"
 #include "mozilla/dom/ChildSHistory.h"
 #include "mozilla/dom/CanonicalBrowsingContext.h"
 #include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/RemoteFrameChild.h"
+#include "mozilla/dom/BrowserBridgeChild.h"
 
 #include "mozilla/dom/HTMLBodyElement.h"
 
 #include "mozilla/ContentPrincipal.h"
 
 #ifdef XP_WIN
 #  include "mozilla/plugins/PPluginWidgetParent.h"
 #  include "../plugins/ipc/PluginWidgetParent.h"
@@ -339,25 +339,25 @@ nsresult nsFrameLoader::ReallyStartLoadi
 
 nsresult nsFrameLoader::ReallyStartLoadingInternal() {
   NS_ENSURE_STATE(mURIToLoad && mOwnerContent &&
                   mOwnerContent->IsInComposedDoc());
 
   AUTO_PROFILER_LABEL("nsFrameLoader::ReallyStartLoadingInternal", OTHER);
 
   if (IsRemoteFrame()) {
-    if (!mRemoteBrowser && !mRemoteFrameChild && !TryRemoteBrowser()) {
+    if (!mRemoteBrowser && !mBrowserBridgeChild && !TryRemoteBrowser()) {
       NS_WARNING("Couldn't create child process for iframe.");
       return NS_ERROR_FAILURE;
     }
 
-    if (mRemoteFrameChild) {
+    if (mBrowserBridgeChild) {
       nsAutoCString spec;
       mURIToLoad->GetSpec(spec);
-      Unused << mRemoteFrameChild->SendLoadURL(spec);
+      Unused << mBrowserBridgeChild->SendLoadURL(spec);
     } else {
       // FIXME get error codes from child
       mRemoteBrowser->LoadURL(mURIToLoad);
     }
 
     if (!mRemoteBrowserShown) {
       // This can fail if it's too early to show the frame, we will retry later.
       Unused << ShowRemoteFrame(ScreenIntSize(0, 0));
@@ -801,17 +801,17 @@ void nsFrameLoader::MarginsChanged(uint3
 }
 
 bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
                                     nsSubDocumentFrame* aFrame) {
   AUTO_PROFILER_LABEL("nsFrameLoader::ShowRemoteFrame", OTHER);
   NS_ASSERTION(IsRemoteFrame(),
                "ShowRemote only makes sense on remote frames.");
 
-  if (!mRemoteBrowser && !mRemoteFrameChild && !TryRemoteBrowser()) {
+  if (!mRemoteBrowser && !mBrowserBridgeChild && !TryRemoteBrowser()) {
     NS_ERROR("Couldn't create child process.");
     return false;
   }
 
   // FIXME/bug 589337: Show()/Hide() is pretty expensive for
   // cross-process layers; need to figure out what behavior we really
   // want here.  For now, hack.
   if (!mRemoteBrowserShown) {
@@ -820,26 +820,26 @@ bool nsFrameLoader::ShowRemoteFrame(cons
     }
 
     // We never want to host remote frameloaders in simple popups, like menus.
     nsIWidget* widget = nsContentUtils::WidgetForContent(mOwnerContent);
     if (!widget || static_cast<nsBaseWidget*>(widget)->IsSmallPopup()) {
       return false;
     }
 
-    if (mRemoteFrameChild) {
+    if (mBrowserBridgeChild) {
       nsCOMPtr<nsISupports> container =
           mOwnerContent->OwnerDoc()->GetContainer();
       nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
       nsCOMPtr<nsIWidget> mainWidget;
       baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
       nsSizeMode sizeMode =
           mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
 
-      Unused << mRemoteFrameChild->SendShow(
+      Unused << mBrowserBridgeChild->SendShow(
           size, ParentWindowIsActive(mOwnerContent->OwnerDoc()), sizeMode);
       mRemoteBrowserShown = true;
       return true;
     }
 
     RenderFrame* rf =
         mRemoteBrowser ? mRemoteBrowser->GetRenderFrame() : nullptr;
 
@@ -858,18 +858,18 @@ bool nsFrameLoader::ShowRemoteFrame(cons
   } else {
     nsIntRect dimensions;
     NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false);
 
     // Don't show remote iframe if we are waiting for the completion of reflow.
     if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
       if (mRemoteBrowser) {
         mRemoteBrowser->UpdateDimensions(dimensions, size);
-      } else if (mRemoteFrameChild) {
-        mRemoteFrameChild->UpdateDimensions(dimensions, size);
+      } else if (mBrowserBridgeChild) {
+        mBrowserBridgeChild->UpdateDimensions(dimensions, size);
       }
     }
   }
 
   return true;
 }
 
 void nsFrameLoader::Hide() {
@@ -950,17 +950,17 @@ nsresult nsFrameLoader::SwapWithOtherRem
 
   nsIPresShell* ourShell = ourDoc->GetShell();
   nsIPresShell* otherShell = otherDoc->GetShell();
   if (!ourShell || !otherShell) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   // FIXME: Consider supporting FrameLoader swapping for remote sub frames.
-  if (mRemoteFrameChild) {
+  if (mBrowserBridgeChild) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   if (!mRemoteBrowser || !aOther->mRemoteBrowser) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   if (mRemoteBrowser->IsIsolatedMozBrowserElement() !=
@@ -1681,19 +1681,19 @@ void nsFrameLoader::DestroyDocShell() {
 
   // Ask the TabChild to fire the frame script "unload" event, destroy its
   // docshell, and finally destroy the PBrowser actor. This eventually leads to
   // nsFrameLoader::DestroyComplete being called.
   if (mRemoteBrowser) {
     mRemoteBrowser->Destroy();
   }
 
-  if (mRemoteFrameChild) {
-    Unused << mRemoteFrameChild->Send__delete__(mRemoteFrameChild);
-    mRemoteFrameChild = nullptr;
+  if (mBrowserBridgeChild) {
+    Unused << mBrowserBridgeChild->Send__delete__(mBrowserBridgeChild);
+    mBrowserBridgeChild = nullptr;
   }
 
   // Fire the "unload" event if we're in-process.
   if (mChildMessageManager) {
     mChildMessageManager->FireUnloadEvent();
   }
 
   // Destroy the docshell.
@@ -1727,19 +1727,19 @@ void nsFrameLoader::DestroyComplete() {
 
   // Call TabParent::Destroy if we haven't already (in case of a crash).
   if (mRemoteBrowser) {
     mRemoteBrowser->SetOwnerElement(nullptr);
     mRemoteBrowser->Destroy();
     mRemoteBrowser = nullptr;
   }
 
-  if (mRemoteFrameChild) {
-    Unused << mRemoteFrameChild->Send__delete__(mRemoteFrameChild);
-    mRemoteFrameChild = nullptr;
+  if (mBrowserBridgeChild) {
+    Unused << mBrowserBridgeChild->Send__delete__(mBrowserBridgeChild);
+    mBrowserBridgeChild = nullptr;
   }
 
   if (mMessageManager) {
     mMessageManager->Disconnect();
   }
 
   if (mChildMessageManager) {
     mChildMessageManager->Disconnect();
@@ -2293,30 +2293,30 @@ nsresult nsFrameLoader::GetWindowDimensi
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_GetInterface(parentOwner));
   treeOwnerAsWin->GetPosition(&aRect.x, &aRect.y);
   treeOwnerAsWin->GetSize(&aRect.width, &aRect.height);
   return NS_OK;
 }
 
 nsresult nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame* aIFrame) {
   if (IsRemoteFrame()) {
-    if (mRemoteBrowser || mRemoteFrameChild) {
+    if (mRemoteBrowser || mBrowserBridgeChild) {
       ScreenIntSize size = aIFrame->GetSubdocumentSize();
       // If we were not able to show remote frame before, we should probably
       // retry now to send correct showInfo.
       if (!mRemoteBrowserShown) {
         ShowRemoteFrame(size, aIFrame);
       }
       nsIntRect dimensions;
       NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE);
       mLazySize = size;
       if (mRemoteBrowser) {
         mRemoteBrowser->UpdateDimensions(dimensions, size);
-      } else if (mRemoteFrameChild) {
-        mRemoteFrameChild->UpdateDimensions(dimensions, size);
+      } else if (mBrowserBridgeChild) {
+        mBrowserBridgeChild->UpdateDimensions(dimensions, size);
       }
     }
     return NS_OK;
   }
   UpdateBaseWindowPositionAndSize(aIFrame);
   return NS_OK;
 }
 
@@ -2386,17 +2386,17 @@ static Tuple<ContentParent*, TabParent*>
   if (tabParent && tabParent->Manager()) {
     return MakeTuple(tabParent->Manager(), tabParent);
   }
 
   return ReturnTuple(nullptr, nullptr);
 }
 
 bool nsFrameLoader::TryRemoteBrowser() {
-  NS_ASSERTION(!mRemoteBrowser && !mRemoteFrameChild,
+  NS_ASSERTION(!mRemoteBrowser && !mBrowserBridgeChild,
                "TryRemoteBrowser called with a remote browser already?");
 
   if (!mOwnerContent) {
     return false;
   }
 
   // XXXsmaug Per spec (2014/08/21) frameloader should not work in case the
   //         element isn't in document, only in shadow dom, but that will change
@@ -2503,21 +2503,21 @@ bool nsFrameLoader::TryRemoteBrowser() {
     // nsIBrowserDOMWindow API as a backup.
     if (!nextTabParentId && window) {
       Unused << window->GetNextTabParentId(&nextTabParentId);
     }
   }
 
   nsCOMPtr<Element> ownerElement = mOwnerContent;
 
-  // If we're in a content process, create a RemoteFrameChild actor.
+  // If we're in a content process, create a BrowserBridgeChild actor.
   if (XRE_IsContentProcess()) {
-    mRemoteFrameChild = RemoteFrameChild::Create(
+    mBrowserBridgeChild = BrowserBridgeChild::Create(
         this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
-    return !!mRemoteFrameChild;
+    return !!mBrowserBridgeChild;
   }
 
   mRemoteBrowser =
       ContentParent::CreateBrowser(context, ownerElement, openerContentParent,
                                    sameTabGroupAs, nextTabParentId);
   if (!mRemoteBrowser) {
     return false;
   }
@@ -2581,27 +2581,27 @@ bool nsFrameLoader::IsRemoteFrame() {
   }
   return false;
 }
 
 mozilla::dom::PBrowserParent* nsFrameLoader::GetRemoteBrowser() const {
   return mRemoteBrowser;
 }
 
-mozilla::dom::RemoteFrameChild* nsFrameLoader::GetRemoteFrameChild() const {
-  return mRemoteFrameChild;
+mozilla::dom::BrowserBridgeChild* nsFrameLoader::GetBrowserBridgeChild() const {
+  return mBrowserBridgeChild;
 }
 
 mozilla::layers::LayersId nsFrameLoader::GetLayersId() const {
   MOZ_ASSERT(mRemoteFrame);
   if (mRemoteBrowser) {
     return mRemoteBrowser->GetRenderFrame()->GetLayersId();
   }
-  if (mRemoteFrameChild) {
-    return mRemoteFrameChild->GetLayersId();
+  if (mBrowserBridgeChild) {
+    return mBrowserBridgeChild->GetLayersId();
   }
   return mozilla::layers::LayersId{};
 }
 
 void nsFrameLoader::ActivateRemoteFrame(ErrorResult& aRv) {
   if (!mRemoteBrowser) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return;
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -54,17 +54,17 @@ class ChromeMessageSender;
 class ContentParent;
 class InProcessTabChildMessageManager;
 class MessageSender;
 class PBrowserParent;
 class ProcessMessageManager;
 class Promise;
 class TabParent;
 class MutableTabContext;
-class RemoteFrameChild;
+class BrowserBridgeChild;
 
 namespace ipc {
 class StructuredCloneData;
 }  // namespace ipc
 
 }  // namespace dom
 
 namespace layout {
@@ -278,20 +278,20 @@ class nsFrameLoader final : public nsStu
 
   /**
    * Returns the IPDL actor used if this is a top-level remote browser, or null
    * otherwise.
    */
   PBrowserParent* GetRemoteBrowser() const;
 
   /**
-   * Returns the RemoteFrameChild if this is an out-of-process iframe, or null
+   * Returns the BrowserBridgeChild if this is an out-of-process iframe, or null
    * otherwise.
    */
-  mozilla::dom::RemoteFrameChild* GetRemoteFrameChild() const;
+  mozilla::dom::BrowserBridgeChild* GetBrowserBridgeChild() const;
 
   /**
    * Returns the layers ID that this remote frame is using to render.
    *
    * This must only be called if this is a remote frame.
    */
   mozilla::layers::LayersId GetLayersId() const;
 
@@ -450,17 +450,17 @@ class nsFrameLoader final : public nsStu
 
   // An opener window which should be used when the docshell is created.
   nsCOMPtr<nsPIDOMWindowOuter> mOpener;
 
   TabParent* mRemoteBrowser;
   uint64_t mChildID;
 
   // This is used when this refers to a remote sub frame
-  RefPtr<mozilla::dom::RemoteFrameChild> mRemoteFrameChild;
+  RefPtr<mozilla::dom::BrowserBridgeChild> mBrowserBridgeChild;
 
   // Holds the last known size of the frame.
   mozilla::ScreenIntSize mLazySize;
 
   RefPtr<mozilla::dom::ParentSHistory> mParentSHistory;
 
   bool mDepthTooGreat : 1;
   bool mIsTopLevelContent : 1;
rename from dom/ipc/RemoteFrameChild.cpp
rename to dom/ipc/BrowserBridgeChild.cpp
--- a/dom/ipc/RemoteFrameChild.cpp
+++ b/dom/ipc/BrowserBridgeChild.cpp
@@ -1,55 +1,57 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/dom/RemoteFrameChild.h"
-
+#include "mozilla/dom/BrowserBridgeChild.h"
+#include "nsFrameLoader.h"
 #include "nsFrameLoaderOwner.h"
+#include "nsQueryObject.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace dom {
 
-RemoteFrameChild::RemoteFrameChild(nsFrameLoader* aFrameLoader)
+BrowserBridgeChild::BrowserBridgeChild(nsFrameLoader* aFrameLoader)
     : mLayersId{0}, mIPCOpen(true), mFrameLoader(aFrameLoader) {}
 
-RemoteFrameChild::~RemoteFrameChild() {}
+BrowserBridgeChild::~BrowserBridgeChild() {}
 
-already_AddRefed<RemoteFrameChild> RemoteFrameChild::Create(
+already_AddRefed<BrowserBridgeChild> BrowserBridgeChild::Create(
     nsFrameLoader* aFrameLoader, const TabContext& aContext,
     const nsString& aRemoteType) {
   MOZ_ASSERT(XRE_IsContentProcess());
 
   // Determine our embedder's TabChild actor.
   RefPtr<Element> owner = aFrameLoader->GetOwnerContent();
   MOZ_DIAGNOSTIC_ASSERT(owner);
 
   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(owner->GetOwnerGlobal());
   MOZ_DIAGNOSTIC_ASSERT(docShell);
 
   RefPtr<TabChild> tabChild = TabChild::GetFrom(docShell);
   MOZ_DIAGNOSTIC_ASSERT(tabChild);
 
-  RefPtr<RemoteFrameChild> remoteFrame = new RemoteFrameChild(aFrameLoader);
-  // Reference is freed in TabChild::DeallocPRemoteFrameChild.
-  tabChild->SendPRemoteFrameConstructor(
-      do_AddRef(remoteFrame).take(),
+  RefPtr<BrowserBridgeChild> browserBridge =
+      new BrowserBridgeChild(aFrameLoader);
+  // Reference is freed in TabChild::DeallocPBrowserBridgeChild.
+  tabChild->SendPBrowserBridgeConstructor(
+      do_AddRef(browserBridge).take(),
       PromiseFlatString(aContext.PresentationURL()), aRemoteType);
-  remoteFrame->mIPCOpen = true;
+  browserBridge->mIPCOpen = true;
 
-  return remoteFrame.forget();
+  return browserBridge.forget();
 }
 
-void RemoteFrameChild::UpdateDimensions(const nsIntRect& aRect,
-                                        const mozilla::ScreenIntSize& aSize) {
+void BrowserBridgeChild::UpdateDimensions(const nsIntRect& aRect,
+                                          const mozilla::ScreenIntSize& aSize) {
   MOZ_DIAGNOSTIC_ASSERT(mIPCOpen);
 
   RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
   nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(owner);
   if (!widget) {
     widget = nsContentUtils::WidgetForDocument(owner->OwnerDoc());
   }
   MOZ_DIAGNOSTIC_ASSERT(widget);
@@ -70,46 +72,46 @@ void RemoteFrameChild::UpdateDimensions(
   CSSSize unscaledSize = devicePixelSize / widgetScale;
   hal::ScreenOrientation orientation = hal::eScreenOrientation_Default;
   DimensionInfo di(unscaledRect, unscaledSize, orientation, clientOffset,
                    chromeOffset);
 
   Unused << SendUpdateDimensions(di);
 }
 
-void RemoteFrameChild::NavigateByKey(bool aForward,
-                                     bool aForDocumentNavigation) {
+void BrowserBridgeChild::NavigateByKey(bool aForward,
+                                       bool aForDocumentNavigation) {
   Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
 }
 
-void RemoteFrameChild::Activate() { Unused << SendActivate(); }
+void BrowserBridgeChild::Activate() { Unused << SendActivate(); }
 
 /*static*/
-RemoteFrameChild* RemoteFrameChild::GetFrom(nsFrameLoader* aFrameLoader) {
+BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsFrameLoader* aFrameLoader) {
   if (!aFrameLoader) {
     return nullptr;
   }
-  return aFrameLoader->GetRemoteFrameChild();
+  return aFrameLoader->GetBrowserBridgeChild();
 }
 
 /*static*/
-RemoteFrameChild* RemoteFrameChild::GetFrom(nsIContent* aContent) {
+BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsIContent* aContent) {
   RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aContent);
   if (!loaderOwner) {
     return nullptr;
   }
   RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
   return GetFrom(frameLoader);
 }
 
-IPCResult RemoteFrameChild::RecvSetLayersId(
+IPCResult BrowserBridgeChild::RecvSetLayersId(
     const mozilla::layers::LayersId& aLayersId) {
   MOZ_ASSERT(!mLayersId.IsValid() && aLayersId.IsValid());
   mLayersId = aLayersId;
   return IPC_OK();
 }
 
-void RemoteFrameChild::ActorDestroy(ActorDestroyReason aWhy) {
+void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
   mIPCOpen = false;
 }
 
 }  // namespace dom
 }  // namespace mozilla
rename from dom/ipc/RemoteFrameChild.h
rename to dom/ipc/BrowserBridgeChild.h
--- a/dom/ipc/RemoteFrameChild.h
+++ b/dom/ipc/BrowserBridgeChild.h
@@ -1,65 +1,65 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 mozilla_dom_RemoteFrameChild_h
-#define mozilla_dom_RemoteFrameChild_h
+#ifndef mozilla_dom_BrowserBridgeChild_h
+#define mozilla_dom_BrowserBridgeChild_h
 
-#include "mozilla/dom/PRemoteFrameChild.h"
+#include "mozilla/dom/PBrowserBridgeChild.h"
 #include "mozilla/dom/TabChild.h"
 
 namespace mozilla {
 namespace dom {
 
 /**
  * Child side for a remote frame.
  */
-class RemoteFrameChild : public PRemoteFrameChild {
+class BrowserBridgeChild : public PBrowserBridgeChild {
  public:
-  NS_INLINE_DECL_REFCOUNTING(RemoteFrameChild);
+  NS_INLINE_DECL_REFCOUNTING(BrowserBridgeChild);
 
   TabChild* Manager() {
     MOZ_ASSERT(mIPCOpen);
-    return static_cast<TabChild*>(PRemoteFrameChild::Manager());
+    return static_cast<TabChild*>(PBrowserBridgeChild::Manager());
   }
 
   mozilla::layers::LayersId GetLayersId() { return mLayersId; }
 
-  static already_AddRefed<RemoteFrameChild> Create(nsFrameLoader* aFrameLoader,
-                                                   const TabContext& aContext,
-                                                   const nsString& aRemoteType);
+  static already_AddRefed<BrowserBridgeChild> Create(
+      nsFrameLoader* aFrameLoader, const TabContext& aContext,
+      const nsString& aRemoteType);
 
   void UpdateDimensions(const nsIntRect& aRect,
                         const mozilla::ScreenIntSize& aSize);
 
   void NavigateByKey(bool aForward, bool aForDocumentNavigation);
 
   void Activate();
 
-  static RemoteFrameChild* GetFrom(nsFrameLoader* aFrameLoader);
+  static BrowserBridgeChild* GetFrom(nsFrameLoader* aFrameLoader);
 
-  static RemoteFrameChild* GetFrom(nsIContent* aContent);
+  static BrowserBridgeChild* GetFrom(nsIContent* aContent);
 
  protected:
-  friend class PRemoteFrameChild;
+  friend class PBrowserBridgeChild;
 
   mozilla::ipc::IPCResult RecvSetLayersId(
       const mozilla::layers::LayersId& aLayersId);
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
-  explicit RemoteFrameChild(nsFrameLoader* aFrameLoader);
-  ~RemoteFrameChild();
+  explicit BrowserBridgeChild(nsFrameLoader* aFrameLoader);
+  ~BrowserBridgeChild();
 
   mozilla::layers::LayersId mLayersId;
   bool mIPCOpen;
   RefPtr<nsFrameLoader> mFrameLoader;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
-#endif  // !defined(mozilla_dom_RemoteFrameParent_h)
+#endif  // !defined(mozilla_dom_BrowserBridgeParent_h)
rename from dom/ipc/RemoteFrameParent.cpp
rename to dom/ipc/BrowserBridgeParent.cpp
--- a/dom/ipc/RemoteFrameParent.cpp
+++ b/dom/ipc/BrowserBridgeParent.cpp
@@ -1,30 +1,31 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/dom/RemoteFrameParent.h"
+#include "mozilla/dom/BrowserBridgeParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentProcessManager.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::layout;
+using namespace mozilla::hal;
 
 namespace mozilla {
 namespace dom {
 
-RemoteFrameParent::RemoteFrameParent() : mIPCOpen(false) {}
+BrowserBridgeParent::BrowserBridgeParent() : mIPCOpen(false) {}
 
-RemoteFrameParent::~RemoteFrameParent() {}
+BrowserBridgeParent::~BrowserBridgeParent() {}
 
-nsresult RemoteFrameParent::Init(const nsString& aPresentationURL,
-                                 const nsString& aRemoteType) {
+nsresult BrowserBridgeParent::Init(const nsString& aPresentationURL,
+                                   const nsString& aRemoteType) {
   mIPCOpen = true;
 
   // FIXME: This should actually use a non-bogus TabContext, probably inherited
   // from our Manager().
   OriginAttributes attrs;
   attrs.mInIsolatedMozBrowser = false;
   attrs.mAppId = nsIScriptSecurityManager::NO_APP_ID;
   attrs.SyncAttributesWithPrivateBrowsing(false);
@@ -75,56 +76,56 @@ nsresult RemoteFrameParent::Init(const n
     return NS_ERROR_FAILURE;
   }
 
   // Send the newly created layers ID back into content.
   Unused << SendSetLayersId(rf->GetLayersId());
   return NS_OK;
 }
 
-IPCResult RemoteFrameParent::RecvShow(const ScreenIntSize& aSize,
-                                      const bool& aParentIsActive,
-                                      const nsSizeMode& aSizeMode) {
+IPCResult BrowserBridgeParent::RecvShow(const ScreenIntSize& aSize,
+                                        const bool& aParentIsActive,
+                                        const nsSizeMode& aSizeMode) {
   RenderFrame* rf = mTabParent->GetRenderFrame();
   if (!rf->AttachLayerManager()) {
     MOZ_CRASH();
   }
 
   Unused << mTabParent->SendShow(aSize, mTabParent->GetShowInfo(),
                                  aParentIsActive, aSizeMode);
   return IPC_OK();
 }
 
-IPCResult RemoteFrameParent::RecvLoadURL(const nsCString& aUrl) {
+IPCResult BrowserBridgeParent::RecvLoadURL(const nsCString& aUrl) {
   Unused << mTabParent->SendLoadURL(aUrl, mTabParent->GetShowInfo());
   return IPC_OK();
 }
 
-IPCResult RemoteFrameParent::RecvUpdateDimensions(
+IPCResult BrowserBridgeParent::RecvUpdateDimensions(
     const DimensionInfo& aDimensions) {
   Unused << mTabParent->SendUpdateDimensions(aDimensions);
   return IPC_OK();
 }
 
-IPCResult RemoteFrameParent::RecvRenderLayers(
+IPCResult BrowserBridgeParent::RecvRenderLayers(
     const bool& aEnabled, const bool& aForceRepaint,
     const layers::LayersObserverEpoch& aEpoch) {
   Unused << mTabParent->SendRenderLayers(aEnabled, aForceRepaint, aEpoch);
   return IPC_OK();
 }
 
-IPCResult RemoteFrameParent::RecvNavigateByKey(
+IPCResult BrowserBridgeParent::RecvNavigateByKey(
     const bool& aForward, const bool& aForDocumentNavigation) {
   Unused << mTabParent->SendNavigateByKey(aForward, aForDocumentNavigation);
   return IPC_OK();
 }
 
-IPCResult RemoteFrameParent::RecvActivate() {
+IPCResult BrowserBridgeParent::RecvActivate() {
   mTabParent->Activate();
   return IPC_OK();
 }
 
-void RemoteFrameParent::ActorDestroy(ActorDestroyReason aWhy) {
+void BrowserBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
   mIPCOpen = false;
 }
 
 }  // namespace dom
 }  // namespace mozilla
rename from dom/ipc/RemoteFrameParent.h
rename to dom/ipc/BrowserBridgeParent.h
--- a/dom/ipc/RemoteFrameParent.h
+++ b/dom/ipc/BrowserBridgeParent.h
@@ -1,42 +1,42 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 mozilla_dom_RemoteFrameParent_h
-#define mozilla_dom_RemoteFrameParent_h
+#ifndef mozilla_dom_BrowserBridgeParent_h
+#define mozilla_dom_BrowserBridgeParent_h
 
-#include "mozilla/dom/PRemoteFrameParent.h"
+#include "mozilla/dom/PBrowserBridgeParent.h"
 #include "mozilla/dom/TabParent.h"
 
 namespace mozilla {
 namespace dom {
 
-class RemoteFrameParent : public PRemoteFrameParent {
+class BrowserBridgeParent : public PBrowserBridgeParent {
  public:
-  NS_INLINE_DECL_REFCOUNTING(RemoteFrameParent);
+  NS_INLINE_DECL_REFCOUNTING(BrowserBridgeParent);
 
-  RemoteFrameParent();
+  BrowserBridgeParent();
 
   // Initialize this actor after performing startup.
   nsresult Init(const nsString& aPresentationURL, const nsString& aRemoteType);
 
   TabParent* GetTabParent() { return mTabParent; }
 
   // Get our manager actor.
   TabParent* Manager() {
     MOZ_ASSERT(mIPCOpen);
-    return static_cast<TabParent*>(PRemoteFrameParent::Manager());
+    return static_cast<TabParent*>(PBrowserBridgeParent::Manager());
   }
 
  protected:
-  friend class PRemoteFrameParent;
+  friend class PBrowserBridgeParent;
 
   mozilla::ipc::IPCResult RecvShow(const ScreenIntSize& aSize,
                                    const bool& aParentIsActive,
                                    const nsSizeMode& aSizeMode);
   mozilla::ipc::IPCResult RecvLoadURL(const nsCString& aUrl);
   mozilla::ipc::IPCResult RecvUpdateDimensions(
       const DimensionInfo& aDimensions);
   mozilla::ipc::IPCResult RecvRenderLayers(const bool& aEnabled,
@@ -46,18 +46,18 @@ class RemoteFrameParent : public PRemote
   mozilla::ipc::IPCResult RecvNavigateByKey(const bool& aForward,
                                             const bool& aForDocumentNavigation);
 
   mozilla::ipc::IPCResult RecvActivate();
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
-  ~RemoteFrameParent();
+  ~BrowserBridgeParent();
 
   RefPtr<TabParent> mTabParent;
   bool mIPCOpen;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
-#endif  // !defined(mozilla_dom_RemoteFrameParent_h)
+#endif  // !defined(mozilla_dom_BrowserBridgeParent_h)
--- a/dom/ipc/MemoryReportRequest.cpp
+++ b/dom/ipc/MemoryReportRequest.cpp
@@ -1,18 +1,21 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsMemoryReporterManager.h"
 #include "MemoryReportRequest.h"
+#include "mozilla/ipc/FileDescriptor.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 
+using namespace mozilla::ipc;
+
 namespace mozilla {
 namespace dom {
 
 MemoryReportRequestHost::MemoryReportRequestHost(uint32_t aGeneration)
     : mGeneration(aGeneration), mSuccess(false) {
   MOZ_COUNT_CTOR(MemoryReportRequestHost);
   mReporterManager = nsMemoryReporterManager::GetOrCreate();
   NS_WARNING_ASSERTION(mReporterManager, "GetOrCreate failed");
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -13,17 +13,17 @@ include protocol PIndexedDBPermissionReq
 include protocol PPluginWidget;
 include protocol PRemotePrintJob;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
 include protocol PFileDescriptorSet;
 include protocol PIPCBlobInputStream;
 include protocol PPaymentRequest;
 include protocol PWindowGlobal;
-include protocol PRemoteFrame;
+include protocol PBrowserBridge;
 
 include DOMTypes;
 include IPCBlob;
 include IPCStream;
 include JavaScriptTypes;
 include URIParams;
 include PPrintingTypes;
 include PTabContext;
@@ -137,17 +137,17 @@ nested(upto inside_cpow) sync protocol P
 
     manages PColorPicker;
     manages PDocAccessible;
     manages PFilePicker;
     manages PIndexedDBPermissionRequest;
     manages PPluginWidget;
     manages PPaymentRequest;
     manages PWindowGlobal;
-    manages PRemoteFrame;
+    manages PBrowserBridge;
 
 both:
     async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
                        Principal aPrincipal, ClonedMessageData aData);
 
 parent:
     /**
      * Tell the parent process a new accessible document has been created.
@@ -173,17 +173,17 @@ parent:
      * Construct a new WindowGlobal actor for a window global in the given
      * BrowsingContext and with the given principal.
      */
     async PWindowGlobal(WindowGlobalInit init);
 
     /**
      * Construct a new Remote iframe actor.
      */
-    async PRemoteFrame(nsString aPresentationURL, nsString aRemoteType);
+    async PBrowserBridge(nsString aPresentationURL, nsString aRemoteType);
 
     /**
      * Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
      * widget's shareable window on the chrome side. Only used on Windows.
      */
     async SetNativeChildOfShareableWindow(uintptr_t childWindow);
 
     /**
rename from dom/ipc/PRemoteFrame.ipdl
rename to dom/ipc/PBrowserBridge.ipdl
--- a/dom/ipc/PRemoteFrame.ipdl
+++ b/dom/ipc/PBrowserBridge.ipdl
@@ -12,19 +12,19 @@ using ScreenIntSize from "Units.h";
 using nsSizeMode from "nsIWidgetListener.h";
 using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 
 namespace mozilla {
 namespace dom {
 
 /**
- * PRemoteFrame corresponds to a remote iframe.
+ * PBrowserBridge corresponds to a remote iframe.
  */
-async protocol PRemoteFrame {
+async protocol PBrowserBridge {
   manager PBrowser;
 
 child:
   async SetLayersId(LayersId layersId);
 
 parent:
   // Destroy the remote web browser due to the nsFrameLoader going away.
   async __delete__();
--- a/dom/ipc/PermissionMessageUtils.cpp
+++ b/dom/ipc/PermissionMessageUtils.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/ipc/BackgroundUtils.h"
+#include "mozilla/ipc/PBackgroundSharedTypes.h"
 
 namespace mozilla {
 namespace ipc {
 
 void IPDLParamTraits<nsIPrincipal>::Write(IPC::Message* aMsg, IProtocol* aActor,
                                           nsIPrincipal* aParam) {
   MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -25,17 +25,17 @@
 #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
 #include "mozilla/dom/LoadURIOptionsBinding.h"
 #include "mozilla/dom/MessageManagerBinding.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/PaymentRequestChild.h"
 #include "mozilla/dom/PBrowser.h"
 #include "mozilla/dom/WindowProxyHolder.h"
-#include "mozilla/dom/RemoteFrameChild.h"
+#include "mozilla/dom/BrowserBridgeChild.h"
 #include "mozilla/gfx/CrossProcessPaint.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/layers/APZChild.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZCTreeManagerChild.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/ContentProcessController.h"
@@ -1241,16 +1241,20 @@ void TabChild::HandleDoubleTap(const CSS
     mApzcTreeManager->ZoomToRect(guid, zoomToRect, DEFAULT_BEHAVIOR);
   }
 }
 
 mozilla::ipc::IPCResult TabChild::RecvHandleTap(
     const GeckoContentController::TapType& aType,
     const LayoutDevicePoint& aPoint, const Modifiers& aModifiers,
     const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) {
+  // IPDL doesn't hold a strong reference to protocols as they're not required
+  // to be refcounted. This function can run script, which may trigger a nested
+  // event loop, which may release this, so we hold a strong reference here.
+  RefPtr<TabChild> kungFuDeathGrip(this);
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell) {
     return IPC_OK();
   }
   if (!presShell->GetPresContext()) {
     return IPC_OK();
   }
   CSSToLayoutDeviceScale scale(
@@ -1286,16 +1290,20 @@ mozilla::ipc::IPCResult TabChild::RecvHa
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult TabChild::RecvNormalPriorityHandleTap(
     const GeckoContentController::TapType& aType,
     const LayoutDevicePoint& aPoint, const Modifiers& aModifiers,
     const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) {
+  // IPDL doesn't hold a strong reference to protocols as they're not required
+  // to be refcounted. This function can run script, which may trigger a nested
+  // event loop, which may release this, so we hold a strong reference here.
+  RefPtr<TabChild> kungFuDeathGrip(this);
   return RecvHandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId);
 }
 
 bool TabChild::NotifyAPZStateChange(
     const ViewID& aViewId,
     const layers::GeckoContentController::APZStateChange& aChange,
     const int& aArg) {
   mAPZEventState->ProcessAPZStateChange(aViewId, aChange, aArg);
@@ -1373,16 +1381,20 @@ mozilla::ipc::IPCResult TabChild::RecvSt
   IMEStateManager::StopIMEStateManagement();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult TabChild::RecvMouseEvent(
     const nsString& aType, const float& aX, const float& aY,
     const int32_t& aButton, const int32_t& aClickCount,
     const int32_t& aModifiers, const bool& aIgnoreRootScrollFrame) {
+  // IPDL doesn't hold a strong reference to protocols as they're not required
+  // to be refcounted. This function can run script, which may trigger a nested
+  // event loop, which may release this, so we hold a strong reference here.
+  RefPtr<TabChild> kungFuDeathGrip(this);
   APZCCallbackHelper::DispatchMouseEvent(
       GetPresShell(), aType, CSSPoint(aX, aY), aButton, aClickCount, aModifiers,
       aIgnoreRootScrollFrame, MouseEvent_Binding::MOZ_SOURCE_UNKNOWN,
       0 /* Use the default value here. */);
   return IPC_OK();
 }
 
 void TabChild::ProcessPendingCoalescedMouseDataAndDispatchEvents() {
@@ -3178,25 +3190,26 @@ PWindowGlobalChild* TabChild::AllocPWind
 }
 
 bool TabChild::DeallocPWindowGlobalChild(PWindowGlobalChild* aActor) {
   // This reference was added in WindowGlobalChild::Create.
   static_cast<WindowGlobalChild*>(aActor)->Release();
   return true;
 }
 
-PRemoteFrameChild* TabChild::AllocPRemoteFrameChild(const nsString&,
-                                                    const nsString&) {
-  MOZ_CRASH("We should never be manually allocating PRemoteFrameChild actors");
+PBrowserBridgeChild* TabChild::AllocPBrowserBridgeChild(const nsString&,
+                                                        const nsString&) {
+  MOZ_CRASH(
+      "We should never be manually allocating PBrowserBridgeChild actors");
   return nullptr;
 }
 
-bool TabChild::DeallocPRemoteFrameChild(PRemoteFrameChild* aActor) {
-  // This reference was added in RemoteFrameChild::Create.
-  static_cast<RemoteFrameChild*>(aActor)->Release();
+bool TabChild::DeallocPBrowserBridgeChild(PBrowserBridgeChild* aActor) {
+  // This reference was added in BrowserBridgeChild::Create.
+  static_cast<BrowserBridgeChild*>(aActor)->Release();
   return true;
 }
 
 ScreenIntSize TabChild::GetInnerSize() {
   LayoutDeviceIntSize innerSize =
       RoundedToInt(mUnscaledInnerSize * mPuppetWidget->GetDefaultScale());
   return ViewAs<ScreenPixel>(
       innerSize, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -306,17 +306,17 @@ class TabChild final : public TabChildBa
       const mozilla::dom::DimensionInfo& aDimensionInfo) override;
   virtual mozilla::ipc::IPCResult RecvSizeModeChanged(
       const nsSizeMode& aSizeMode) override;
 
   mozilla::ipc::IPCResult RecvActivate();
 
   mozilla::ipc::IPCResult RecvDeactivate();
 
-  MOZ_CAN_RUN_SCRIPT
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   virtual mozilla::ipc::IPCResult RecvMouseEvent(
       const nsString& aType, const float& aX, const float& aY,
       const int32_t& aButton, const int32_t& aClickCount,
       const int32_t& aModifiers, const bool& aIgnoreRootScrollFrame) override;
 
   virtual mozilla::ipc::IPCResult RecvRealMouseMoveEvent(
       const mozilla::WidgetMouseEvent& aEvent, const ScrollableLayerGuid& aGuid,
       const uint64_t& aInputBlockId) override;
@@ -571,23 +571,23 @@ class TabChild final : public TabChildBa
   // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
   void DoFakeShow(const ShowInfo& aShowInfo);
 
   void ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
                                  uint64_t aInputBlockId,
                                  bool aPreventDefault) const;
   void SetTargetAPZC(uint64_t aInputBlockId,
                      const nsTArray<ScrollableLayerGuid>& aTargets) const;
-  MOZ_CAN_RUN_SCRIPT
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   mozilla::ipc::IPCResult RecvHandleTap(
       const layers::GeckoContentController::TapType& aType,
       const LayoutDevicePoint& aPoint, const Modifiers& aModifiers,
       const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) override;
 
-  MOZ_CAN_RUN_SCRIPT
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   mozilla::ipc::IPCResult RecvNormalPriorityHandleTap(
       const layers::GeckoContentController::TapType& aType,
       const LayoutDevicePoint& aPoint, const Modifiers& aModifiers,
       const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) override;
 
   void SetAllowedTouchBehavior(
       uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aFlags) const;
 
@@ -665,20 +665,20 @@ class TabChild final : public TabChildBa
  protected:
   virtual ~TabChild();
 
   virtual PWindowGlobalChild* AllocPWindowGlobalChild(
       const WindowGlobalInit& aInit) override;
 
   virtual bool DeallocPWindowGlobalChild(PWindowGlobalChild* aActor) override;
 
-  virtual PRemoteFrameChild* AllocPRemoteFrameChild(
+  virtual PBrowserBridgeChild* AllocPBrowserBridgeChild(
       const nsString& aName, const nsString& aRemoteType) override;
 
-  virtual bool DeallocPRemoteFrameChild(PRemoteFrameChild* aActor) override;
+  virtual bool DeallocPBrowserBridgeChild(PBrowserBridgeChild* aActor) override;
 
   virtual mozilla::ipc::IPCResult RecvDestroy() override;
 
   virtual mozilla::ipc::IPCResult RecvSetDocShellIsActive(
       const bool& aIsActive) override;
 
   virtual mozilla::ipc::IPCResult RecvRenderLayers(
       const bool& aEnabled, const bool& aForce,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -16,17 +16,17 @@
 #include "mozilla/dom/ChromeMessageSender.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "mozilla/dom/DataTransferItemList.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/PaymentRequestParent.h"
-#include "mozilla/dom/RemoteFrameParent.h"
+#include "mozilla/dom/BrowserBridgeParent.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/Hal.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "mozilla/layers/AsyncDragMetrics.h"
@@ -993,32 +993,32 @@ PWindowGlobalParent* TabParent::AllocPWi
 }
 
 bool TabParent::DeallocPWindowGlobalParent(PWindowGlobalParent* aActor) {
   // Free reference from AllocPWindowGlobalParent.
   static_cast<WindowGlobalParent*>(aActor)->Release();
   return true;
 }
 
-IPCResult TabParent::RecvPRemoteFrameConstructor(PRemoteFrameParent* aActor,
-                                                 const nsString& aName,
-                                                 const nsString& aRemoteType) {
-  static_cast<RemoteFrameParent*>(aActor)->Init(aName, aRemoteType);
+IPCResult TabParent::RecvPBrowserBridgeConstructor(
+    PBrowserBridgeParent* aActor, const nsString& aName,
+    const nsString& aRemoteType) {
+  static_cast<BrowserBridgeParent*>(aActor)->Init(aName, aRemoteType);
   return IPC_OK();
 }
 
-PRemoteFrameParent* TabParent::AllocPRemoteFrameParent(
+PBrowserBridgeParent* TabParent::AllocPBrowserBridgeParent(
     const nsString& aName, const nsString& aRemoteType) {
-  // Reference freed in DeallocPRemoteFrameParent.
-  return do_AddRef(new RemoteFrameParent()).take();
+  // Reference freed in DeallocPBrowserBridgeParent.
+  return do_AddRef(new BrowserBridgeParent()).take();
 }
 
-bool TabParent::DeallocPRemoteFrameParent(PRemoteFrameParent* aActor) {
-  // Free reference from AllocPRemoteFrameParent.
-  static_cast<RemoteFrameParent*>(aActor)->Release();
+bool TabParent::DeallocPBrowserBridgeParent(PBrowserBridgeParent* aActor) {
+  // Free reference from AllocPBrowserBridgeParent.
+  static_cast<BrowserBridgeParent*>(aActor)->Release();
   return true;
 }
 
 void TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
                                int32_t aButton, int32_t aClickCount,
                                int32_t aModifiers,
                                bool aIgnoreRootScrollFrame) {
   if (!mIsDestroyed) {
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -310,23 +310,23 @@ class TabParent final : public PBrowserP
 
   PWindowGlobalParent* AllocPWindowGlobalParent(const WindowGlobalInit& aInit);
 
   bool DeallocPWindowGlobalParent(PWindowGlobalParent* aActor);
 
   virtual mozilla::ipc::IPCResult RecvPWindowGlobalConstructor(
       PWindowGlobalParent* aActor, const WindowGlobalInit& aInit) override;
 
-  PRemoteFrameParent* AllocPRemoteFrameParent(const nsString& aPresentationURL,
-                                              const nsString& aRemoteType);
+  PBrowserBridgeParent* AllocPBrowserBridgeParent(
+      const nsString& aPresentationURL, const nsString& aRemoteType);
 
-  bool DeallocPRemoteFrameParent(PRemoteFrameParent* aActor);
+  bool DeallocPBrowserBridgeParent(PBrowserBridgeParent* aActor);
 
-  virtual mozilla::ipc::IPCResult RecvPRemoteFrameConstructor(
-      PRemoteFrameParent* aActor, const nsString& aPresentationURL,
+  virtual mozilla::ipc::IPCResult RecvPBrowserBridgeConstructor(
+      PBrowserBridgeParent* aActor, const nsString& aPresentationURL,
       const nsString& aRemoteType) override;
 
   void LoadURL(nsIURI* aURI);
 
   void InitRendering();
   void MaybeShowFrame();
 
   // XXX/cjones: it's not clear what we gain by hiding these
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -23,34 +23,34 @@ EXPORTS.mozilla.dom.ipc += [
     'SharedMap.h',
     'SharedMapChangeEvent.h',
     'SharedStringMap.h',
     'StringTable.h',
     'StructuredCloneData.h',
 ]
 
 EXPORTS.mozilla.dom += [
+    'BrowserBridgeChild.h',
+    'BrowserBridgeParent.h',
     'CoalescedInputData.h',
     'CoalescedMouseData.h',
     'CoalescedWheelData.h',
     'ContentChild.h',
     'ContentParent.h',
     'ContentProcess.h',
     'ContentProcessManager.h',
     'CPOWManagerGetter.h',
     'CSPMessageUtils.h',
     'DocShellMessageUtils.h',
     'FilePickerParent.h',
     'JSWindowActorChild.h',
     'JSWindowActorParent.h',
     'JSWindowActorService.h',
     'MemoryReportRequest.h',
     'PermissionMessageUtils.h',
-    'RemoteFrameChild.h',
-    'RemoteFrameParent.h',
     'TabChild.h',
     'TabContext.h',
     'TabMessageUtils.h',
     'TabParent.h',
     'URLClassifierChild.h',
     'URLClassifierParent.h',
     'WindowGlobalChild.h',
     'WindowGlobalParent.h',
@@ -59,16 +59,18 @@ EXPORTS.mozilla.dom += [
 EXPORTS.mozilla += [
     'PreallocatedProcessManager.h',
     'ProcessHangMonitor.h',
     'ProcessHangMonitorIPC.h',
     'ProcessPriorityManager.h',
 ]
 
 UNIFIED_SOURCES += [
+    'BrowserBridgeChild.cpp',
+    'BrowserBridgeParent.cpp',
     'CoalescedMouseData.cpp',
     'CoalescedWheelData.cpp',
     'ColorPickerParent.cpp',
     'ContentParent.cpp',
     'ContentProcess.cpp',
     'ContentProcessManager.cpp',
     'CSPMessageUtils.cpp',
     'DocShellMessageUtils.cpp',
@@ -77,18 +79,16 @@ UNIFIED_SOURCES += [
     'JSWindowActorParent.cpp',
     'JSWindowActorService.cpp',
     'MemMapSnapshot.cpp',
     'MemoryReportRequest.cpp',
     'MMPrinter.cpp',
     'PermissionMessageUtils.cpp',
     'PreallocatedProcessManager.cpp',
     'ProcessPriorityManager.cpp',
-    'RemoteFrameChild.cpp',
-    'RemoteFrameParent.cpp',
     'SharedMap.cpp',
     'SharedStringMap.cpp',
     'StructuredCloneData.cpp',
     'TabChild.cpp',
     'TabContext.cpp',
     'TabMessageUtils.cpp',
     'TabParent.cpp',
     'URLClassifierParent.cpp',
@@ -101,28 +101,28 @@ SOURCES += [
     'ContentChild.cpp',
     'ProcessHangMonitor.cpp',
 ]
 
 IPDL_SOURCES += [
     'DOMTypes.ipdlh',
     'MemoryReportTypes.ipdlh',
     'PBrowser.ipdl',
+    'PBrowserBridge.ipdl',
     'PBrowserOrId.ipdlh',
     'PColorPicker.ipdl',
     'PContent.ipdl',
     'PContentPermission.ipdlh',
     'PContentPermissionRequest.ipdl',
     'PCycleCollectWithLogs.ipdl',
     'PFilePicker.ipdl',
     'PLoginReputation.ipdl',
     'PPluginWidget.ipdl',
     'PProcessHangMonitor.ipdl',
     'PrefsTypes.ipdlh',
-    'PRemoteFrame.ipdl',
     'PTabContext.ipdlh',
     'PURLClassifier.ipdl',
     'PURLClassifierInfo.ipdlh',
     'PURLClassifierLocal.ipdl',
     'PWindowGlobal.ipdl',
     'ServiceWorkerConfiguration.ipdlh',
 ]
 
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -10,16 +10,17 @@
 #include "gfxEnv.h"
 #include "gfxPrefs.h"
 #include "gfxEnv.h"
 #include "GeckoProfiler.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "nsExceptionHandler.h"
 #include "mozilla/Range.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/layers/AnimationHelper.h"
 #include "mozilla/layers/APZSampler.h"
 #include "mozilla/layers/APZUpdater.h"
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/CompositorVsyncScheduler.h"
 #include "mozilla/layers/ImageBridgeParent.h"
@@ -59,16 +60,35 @@ void gecko_profiler_start_marker(const c
 
 void gecko_profiler_end_marker(const char* name) {
 #ifdef MOZ_GECKO_PROFILER
   profiler_tracing("WebRender", name, JS::ProfilingCategoryPair::GRAPHICS,
                    TRACING_INTERVAL_END);
 #endif
 }
 
+void gecko_profiler_add_text_marker(const char* name, const char* text_bytes, size_t text_len, uint64_t microseconds) {
+#ifdef MOZ_GECKO_PROFILER
+  if (profiler_thread_is_being_profiled()) {
+    auto now = mozilla::TimeStamp::Now();
+    auto start = now - mozilla::TimeDuration::FromMicroseconds(microseconds);
+    profiler_add_text_marker(
+        name, nsDependentCString(text_bytes, text_len), JS::ProfilingCategoryPair::GRAPHICS, start, now);
+  }
+#endif
+}
+
+bool gecko_profiler_thread_is_being_profiled() {
+#ifdef MOZ_GECKO_PROFILER
+  return profiler_thread_is_being_profiled();
+#else
+  return false;
+#endif
+}
+
 bool is_glcontext_egl(void* glcontext_ptr) {
   MOZ_ASSERT(glcontext_ptr);
 
   mozilla::gl::GLContext* glcontext =
       reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
   if (!glcontext) {
     return false;
   }
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -11,16 +11,17 @@ use std::path::PathBuf;
 use std::rc::Rc;
 use std::cell::RefCell;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::ops::Range;
 use std::os::raw::{c_void, c_char, c_float};
 #[cfg(target_os = "android")]
 use std::os::raw::{c_int};
+use std::time::Duration;
 use gleam::gl;
 
 use webrender::api::*;
 use webrender::{ReadPixelsFormat, Renderer, RendererOptions, RendererStats, ThreadListener};
 use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource};
 use webrender::DebugFlags;
 use webrender::{ApiRecordingReceiver, BinaryRecorder};
 use webrender::{AsyncPropertySampler, PipelineInfo, SceneBuilderHooks};
@@ -752,16 +753,19 @@ pub unsafe extern "C" fn wr_renderer_flu
 pub unsafe extern "C" fn wr_pipeline_info_delete(_info: WrPipelineInfo) {
     // _info will be dropped here, and the drop impl on FfiVec will free
     // the underlying vec memory
 }
 
 extern "C" {
     pub fn gecko_profiler_start_marker(name: *const c_char);
     pub fn gecko_profiler_end_marker(name: *const c_char);
+    pub fn gecko_profiler_add_text_marker(
+        name: *const c_char, text_bytes: *const c_char, text_len: usize, microseconds: u64);
+    pub fn gecko_profiler_thread_is_being_profiled() -> bool;
 }
 
 /// Simple implementation of the WR ProfilerHooks trait to allow profile
 /// markers to be seen in the Gecko profiler.
 struct GeckoProfilerHooks;
 
 impl ProfilerHooks for GeckoProfilerHooks {
     fn begin_marker(&self, label: &CStr) {
@@ -770,16 +774,29 @@ impl ProfilerHooks for GeckoProfilerHook
         }
     }
 
     fn end_marker(&self, label: &CStr) {
         unsafe {
             gecko_profiler_end_marker(label.as_ptr());
         }
     }
+
+    fn add_text_marker(&self, label: &CStr, text: &str, duration: Duration) {
+        unsafe {
+            // NB: This can be as_micros() once we require Rust 1.33.
+            let micros = duration.subsec_micros() as u64 + duration.as_secs() * 1000 * 1000;
+            let text_bytes = text.as_bytes();
+            gecko_profiler_add_text_marker(label.as_ptr(), text_bytes.as_ptr() as *const c_char, text_bytes.len(), micros);
+        }
+    }
+
+    fn thread_is_being_profiled(&self) -> bool {
+        unsafe { gecko_profiler_thread_is_being_profiled() }
+    }
 }
 
 static PROFILER_HOOKS: GeckoProfilerHooks = GeckoProfilerHooks {};
 
 #[allow(improper_ctypes)] // this is needed so that rustc doesn't complain about passing the &mut Transaction to an extern function
 extern "C" {
     // These callbacks are invoked from the scene builder thread (aka the APZ
     // updater thread)
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -28,16 +28,19 @@ void gfx_critical_error(const char* msg)
 void gecko_printf_stderr_output(const char* msg);
 void* get_proc_address_from_glcontext(void* glcontext_ptr,
                                       const char* procname);
 void gecko_profiler_register_thread(const char* threadname);
 void gecko_profiler_unregister_thread();
 
 void gecko_profiler_start_marker(const char* name);
 void gecko_profiler_end_marker(const char* name);
+void gecko_profiler_add_text_marker(
+    const char* name, const char* text_ptr, size_t text_len, uint64_t microseconds);
+bool gecko_profiler_thread_is_being_profiled();
 
 // IMPORTANT: Keep this synchronized with enumerate_interners in
 // gfx/wr/webrender_api
 #define WEBRENDER_FOR_EACH_INTERNER(macro) \
   macro(clip);                             \
   macro(prim);                             \
   macro(normal_border);                    \
   macro(image_border);                     \
--- a/gfx/wr/Cargo.lock
+++ b/gfx/wr/Cargo.lock
@@ -138,17 +138,17 @@ name = "cfg-if"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cgl"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clap"
 version = "2.31.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -365,17 +365,17 @@ dependencies = [
  "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "direct-composition"
 version = "0.1.0"
 dependencies = [
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender 0.60.0",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "dlib"
@@ -564,17 +564,17 @@ source = "registry+https://github.com/ru
 dependencies = [
  "khronos_api 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gleam"
-version = "0.6.11"
+version = "0.6.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glutin"
 version = "0.17.0"
@@ -1640,17 +1640,17 @@ dependencies = [
  "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cstr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "pathfinder_font_renderer 0.5.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
@@ -1676,17 +1676,17 @@ dependencies = [
 
 [[package]]
 name = "webrender-examples"
 version = "0.1.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender 0.60.0",
  "winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender_api"
@@ -1794,17 +1794,17 @@ dependencies = [
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "osmesa-src 0.1.1 (git+https://github.com/servo/osmesa-src)",
  "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1941,17 +1941,17 @@ dependencies = [
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
 "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
 "checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c"
 "checksum gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ffaf173cf76c73a73e080366bf556b4776ece104b06961766ff11449f38604"
 "checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
-"checksum gleam 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b93018064928ec67c429c9c9416affd93660419dbf84767fff6b8a99fbe9c277"
+"checksum gleam 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f1519ca611d230e1deadbedfb79044b921ac4a961ab8823fef10e37271e2c38e"
 "checksum glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70c5fe78efbd5a3b243a804ea1032053c584510f8822819f94cfb29b2100317"
 "checksum half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d5c5f71a723d10dfc58927cbed37c3071a50afc7f073d86fd7d3e5727db890f"
 "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d"
 "checksum inflate 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec18d981200fd14e65ee8e35fb60ed1ce55227a02407303f3a72517c6146dcc"
 "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
--- a/gfx/wr/webrender/Cargo.toml
+++ b/gfx/wr/webrender/Cargo.toml
@@ -25,17 +25,17 @@ webrender_build = { version = "0.0.1", p
 app_units = "0.7"
 base64 = { optional = true, version = "0.10" }
 bincode = "1.0"
 bitflags = "1.0"
 byteorder = "1.0"
 cfg-if = "0.1.2"
 cstr = "0.1.2"
 fxhash = "0.2.1"
-gleam = "0.6.11"
+gleam = "0.6.12"
 image = { optional = true, version = "0.21" }
 lazy_static = "1"
 log = "0.4"
 malloc_size_of_derive = "0.1"
 num-traits = "0.2"
 plane-split = "0.13.7"
 png = { optional = true, version = "0.14" }
 rayon = "1"
--- a/gfx/wr/webrender/src/device/gl.rs
+++ b/gfx/wr/webrender/src/device/gl.rs
@@ -5,16 +5,17 @@
 use super::super::shader_source::SHADERS;
 use api::{ColorF, ImageDescriptor, ImageFormat, MemoryReport};
 use api::{TextureTarget, VoidPtrToSizeFn};
 use api::units::*;
 use euclid::Transform3D;
 use gleam::gl;
 use internal_types::{FastHashMap, LayerIndex, RenderTargetInfo};
 use log::Level;
+use profiler;
 use sha2::{Digest, Sha256};
 use smallvec::SmallVec;
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::collections::hash_map::Entry;
 use std::marker::PhantomData;
 use std::mem;
@@ -23,16 +24,17 @@ use std::os::raw::c_void;
 use std::ops::Add;
 use std::path::PathBuf;
 use std::ptr;
 use std::rc::Rc;
 use std::slice;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::thread;
+use std::time::Duration;
 use webrender_build::shader::ProgramSourceDigest;
 use webrender_build::shader::{parse_shader_source, shader_source_from_file};
 
 /// Sequence number for frames, as tracked by the device layer.
 #[derive(Debug, Copy, Clone, PartialEq, Ord, Eq, PartialOrd)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct GpuFrameId(usize);
@@ -914,16 +916,21 @@ impl Drop for SharedDepthTarget {
 enum TexStorageUsage {
     Never,
     NonBGRA8,
     Always,
 }
 
 pub struct Device {
     gl: Rc<gl::Gl>,
+
+    /// If non-None, |gl| points to a profiling wrapper, and this points to the
+    /// underling Gl instance.
+    base_gl: Option<Rc<gl::Gl>>,
+
     // device state
     bound_textures: [gl::GLuint; 16],
     bound_program: gl::GLuint,
     bound_vao: gl::GLuint,
     bound_read_fbo: FBOId,
     bound_draw_fbo: FBOId,
     program_mode_id: UniformLocation,
     default_read_fbo: FBOId,
@@ -1230,16 +1237,17 @@ impl Device {
         let optimal_pbo_stride = if renderer_name.contains("Adreno") {
             NonZeroUsize::new(256).unwrap()
         } else {
             NonZeroUsize::new(4).unwrap()
         };
 
         Device {
             gl,
+            base_gl: None,
             resource_override_path,
             upload_method,
             inside_frame: false,
 
             capabilities: Capabilities {
                 supports_multisampling: false, //TODO
                 supports_copy_image_sub_data,
                 supports_blit_to_texture_array,
@@ -1358,16 +1366,32 @@ impl Device {
             Ok(id)
         }
     }
 
     pub fn begin_frame(&mut self) -> GpuFrameId {
         debug_assert!(!self.inside_frame);
         self.inside_frame = true;
 
+        // If our profiler state has changed, apply or remove the profiling
+        // wrapper from our GL context.
+        let being_profiled = profiler::thread_is_being_profiled();
+        let using_wrapper = self.base_gl.is_some();
+        if being_profiled && !using_wrapper {
+            fn note(name: &str, duration: Duration) {
+                profiler::add_text_marker(cstr!("OpenGL Calls"), name, duration);
+            }
+            let threshold = Duration::from_millis(1);
+            let wrapped = gl::ProfilingGl::wrap(self.gl.clone(), threshold, note);
+            let base = mem::replace(&mut self.gl, wrapped);
+            self.base_gl = Some(base);
+        } else if !being_profiled && using_wrapper {
+            self.gl = self.base_gl.take().unwrap();
+        }
+
         // Retrieve the currently set FBO.
         let mut default_read_fbo = [0];
         unsafe {
             self.gl.get_integer_v(gl::READ_FRAMEBUFFER_BINDING, &mut default_read_fbo);
         }
         self.default_read_fbo = FBOId(default_read_fbo[0] as gl::GLuint);
         let mut default_draw_fbo = [0];
         unsafe {
--- a/gfx/wr/webrender/src/glyph_rasterizer/mod.rs
+++ b/gfx/wr/webrender/src/glyph_rasterizer/mod.rs
@@ -480,16 +480,99 @@ pub struct RasterizedGlyph {
     pub left: f32,
     pub width: i32,
     pub height: i32,
     pub scale: f32,
     pub format: GlyphFormat,
     pub bytes: Vec<u8>,
 }
 
+impl RasterizedGlyph {
+    #[allow(dead_code)]
+    pub fn downscale_bitmap_if_required(&mut self, font: &FontInstance) {
+        // Check if the glyph is going to be downscaled in the shader. If the scaling is
+        // less than 0.5, that means bilinear filtering can't effectively filter the glyph
+        // without aliasing artifacts.
+        //
+        // Instead of fixing this by mipmapping the glyph cache texture, rather manually
+        // produce the appropriate mip level for individual glyphs where bilinear filtering
+        // will still produce acceptable results.
+        match self.format {
+            GlyphFormat::Bitmap | GlyphFormat::ColorBitmap => {},
+            _ => return,
+        }
+        let (x_scale, y_scale) = font.transform.compute_scale().unwrap_or((1.0, 1.0));
+        let upscaled = x_scale.max(y_scale) as f32;
+        let mut new_scale = self.scale;
+        if new_scale * upscaled <= 0.0 {
+            return;
+        }
+        let mut steps = 0;
+        while new_scale * upscaled <= 0.5 {
+            new_scale *= 2.0;
+            steps += 1;
+        }
+        // If no mipping is necessary, just bail.
+        if steps == 0 {
+            return;
+        }
+
+        // Calculate the actual size of the mip level.
+        let new_width = (self.width as usize + (1 << steps) - 1) >> steps;
+        let new_height = (self.height as usize + (1 << steps) - 1) >> steps;
+        let mut new_bytes: Vec<u8> = Vec::with_capacity(new_width * new_height * 4);
+
+        // Produce destination pixels by applying a box filter to the source pixels.
+        // The box filter corresponds to how graphics drivers may generate mipmaps.
+        for y in 0 .. new_height {
+            for x in 0 .. new_width {
+                // Calculate the number of source samples that contribute to the destination pixel.
+                let src_y = y << steps;
+                let src_x = x << steps;
+                let y_samples = (1 << steps).min(self.height as usize - src_y);
+                let x_samples = (1 << steps).min(self.width as usize - src_x);
+                let num_samples = (x_samples * y_samples) as u32;
+
+                let mut src_idx = (src_y * self.width as usize + src_x) * 4;
+                // Initialize the accumulator with half an increment so that when later divided
+                // by the sample count, it will effectively round the accumulator to the nearest
+                // increment.
+                let mut accum = [num_samples / 2; 4];
+                // Accumulate all the contributing source sampless.
+                for _ in 0 .. y_samples {
+                    for _ in 0 .. x_samples {
+                        accum[0] += self.bytes[src_idx + 0] as u32;
+                        accum[1] += self.bytes[src_idx + 1] as u32;
+                        accum[2] += self.bytes[src_idx + 2] as u32;
+                        accum[3] += self.bytes[src_idx + 3] as u32;
+                        src_idx += 4;
+                    }
+                    src_idx += (self.width as usize - x_samples) * 4;
+                }
+
+                // Finally, divide by the sample count to get the mean value for the new pixel.
+                new_bytes.extend_from_slice(&[
+                    (accum[0] / num_samples) as u8,
+                    (accum[1] / num_samples) as u8,
+                    (accum[2] / num_samples) as u8,
+                    (accum[3] / num_samples) as u8,
+                ]);
+            }
+        }
+
+        // Fix the bounds for the new glyph data.
+        self.top /= (1 << steps) as f32;
+        self.left /= (1 << steps) as f32;
+        self.width = new_width as i32;
+        self.height = new_height as i32;
+        self.scale = new_scale;
+        self.bytes = new_bytes;
+    }
+}
+
 pub struct FontContexts {
     // These worker are mostly accessed from their corresponding worker threads.
     // The goal is that there should be no noticeable contention on the mutexes.
     worker_contexts: Vec<Mutex<FontContext>>,
     // This worker should be accessed by threads that don't belong to the thread pool
     // (in theory that's only the render backend thread so no contention expected either).
     shared_context: Mutex<FontContext>,
     #[cfg(feature = "pathfinder")]
--- a/gfx/wr/webrender/src/glyph_rasterizer/no_pathfinder.rs
+++ b/gfx/wr/webrender/src/glyph_rasterizer/no_pathfinder.rs
@@ -102,28 +102,32 @@ impl GlyphRasterizer {
         // possible and in that task use rayon's fork join dispatch to rasterize the
         // glyphs in the thread pool.
         self.workers.spawn(move || {
             let jobs = glyphs
                 .par_iter()
                 .map(|key: &GlyphKey| {
                     profile_scope!("glyph-raster");
                     let mut context = font_contexts.lock_current_context();
-                    let job = GlyphRasterJob {
+                    let mut job = GlyphRasterJob {
                         key: key.clone(),
                         result: context.rasterize_glyph(&font, key),
                     };
 
-                    // Sanity check.
-                    if let Ok(ref glyph) = job.result {
+                    if let Ok(ref mut glyph) = job.result {
+                        // Sanity check.
                         let bpp = 4; // We always render glyphs in 32 bits RGBA format.
                         assert_eq!(
                             glyph.bytes.len(),
                             bpp * (glyph.width * glyph.height) as usize
                         );
+                        assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
+
+                        // Check if the glyph has a bitmap that needs to be downscaled.
+                        glyph.downscale_bitmap_if_required(&font);
                     }
 
                     job
                 })
                 .collect();
 
             glyph_tx.send(GlyphRasterJobs { font, jobs }).unwrap();
         });
@@ -161,17 +165,16 @@ impl GlyphRasterizer {
 
             for GlyphRasterJob { key, result } in jobs {
                 let glyph_info = match result {
                     Err(_) => GlyphCacheEntry::Blank,
                     Ok(ref glyph) if glyph.width == 0 || glyph.height == 0 => {
                         GlyphCacheEntry::Blank
                     }
                     Ok(glyph) => {
-                        assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
                         let mut texture_cache_handle = TextureCacheHandle::invalid();
                         texture_cache.request(&texture_cache_handle, gpu_cache);
                         texture_cache.update(
                             &mut texture_cache_handle,
                             ImageDescriptor {
                                 size: size2(glyph.width, glyph.height),
                                 stride: None,
                                 format: ImageFormat::BGRA8,
--- a/gfx/wr/webrender/src/profiler.rs
+++ b/gfx/wr/webrender/src/profiler.rs
@@ -6,16 +6,17 @@ use api::{ColorF, ColorU};
 use debug_render::DebugRenderer;
 use device::query::{GpuSampler, GpuTimer, NamedTag};
 use euclid::{Point2D, Rect, Size2D, vec2};
 use internal_types::FastHashMap;
 use renderer::{MAX_VERTEX_TEXTURE_WIDTH, wr_has_been_initialized};
 use std::collections::vec_deque::VecDeque;
 use std::{f32, mem};
 use std::ffi::CStr;
+use std::time::Duration;
 use time::precise_time_ns;
 
 const GRAPH_WIDTH: f32 = 1024.0;
 const GRAPH_HEIGHT: f32 = 320.0;
 const GRAPH_PADDING: f32 = 8.0;
 const GRAPH_FRAME_HEIGHT: f32 = 16.0;
 const PROFILE_PADDING: f32 = 10.0;
 
@@ -25,20 +26,32 @@ const ONE_SECOND_NS: u64 = 1000000000;
 pub trait ProfilerHooks : Send + Sync {
     /// Called at the beginning of a profile scope. The label must
     /// be a C string (null terminated).
     fn begin_marker(&self, label: &CStr);
 
     /// Called at the end of a profile scope. The label must
     /// be a C string (null terminated).
     fn end_marker(&self, label: &CStr);
+
+    /// Called with a duration to indicate a text marker that just ended. Text
+    /// markers allow different types of entries to be recorded on the same row
+    /// in the timeline, by adding labels to the entry.
+    ///
+    /// This variant is also useful when the caller only wants to record events
+    /// longer than a certain threshold, and thus they don't know in advance
+    /// whether the event will qualify.
+    fn add_text_marker(&self, label: &CStr, text: &str, duration: Duration);
+
+    /// Returns true if the current thread is being profiled.
+    fn thread_is_being_profiled(&self) -> bool;
 }
 
 /// The current global profiler callbacks, if set by embedder.
-static mut PROFILER_HOOKS: Option<&'static ProfilerHooks> = None;
+pub static mut PROFILER_HOOKS: Option<&'static ProfilerHooks> = None;
 
 /// Set the profiler callbacks, or None to disable the profiler.
 /// This function must only ever be called before any WR instances
 /// have been created, or the hooks will not be set.
 pub fn set_profiler_hooks(hooks: Option<&'static ProfilerHooks>) {
     if !wr_has_been_initialized() {
         unsafe {
             PROFILER_HOOKS = hooks;
@@ -46,16 +59,32 @@ pub fn set_profiler_hooks(hooks: Option<
     }
 }
 
 /// A simple RAII style struct to manage a profile scope.
 pub struct ProfileScope {
     name: &'static CStr,
 }
 
+/// Records a marker of the given duration that just ended.
+pub fn add_text_marker(label: &CStr, text: &str, duration: Duration) {
+    unsafe {
+        if let Some(ref hooks) = PROFILER_HOOKS {
+            hooks.add_text_marker(label, text, duration);
+        }
+    }
+}
+
+/// Returns true if the current thread is being profiled.
+pub fn thread_is_being_profiled() -> bool {
+    unsafe {
+        PROFILER_HOOKS.map_or(false, |h| h.thread_is_being_profiled())
+    }
+}
+
 impl ProfileScope {
     /// Begin a new profile scope
     pub fn new(name: &'static CStr) -> Self {
         unsafe {
             if let Some(ref hooks) = PROFILER_HOOKS {
                 hooks.begin_marker(name);
             }
         }
--- a/layout/ipc/RenderFrame.cpp
+++ b/layout/ipc/RenderFrame.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/TabParent.h"
-#include "mozilla/dom/RemoteFrameChild.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayerTransactionParent.h"
 #include "nsFrameLoader.h"
 #include "nsStyleStructInlines.h"
 #include "nsSubDocumentFrame.h"
 #include "RenderFrame.h"
 #include "mozilla/gfx/GPUProcessManager.h"
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-a306d84e4c70
+NSS_3_43_BETA1
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -1678,18 +1678,18 @@ PK11_MakeKEAPubKey(unsigned char *keyDat
 }
 
 SECStatus
 SECKEY_SetPublicValue(SECKEYPrivateKey *privKey, SECItem *publicValue)
 {
     SECStatus rv;
     SECKEYPublicKey pubKey;
     PLArenaPool *arena;
-    PK11SlotInfo *slot = privKey->pkcs11Slot;
-    CK_OBJECT_HANDLE privKeyID = privKey->pkcs11ID;
+    PK11SlotInfo *slot;
+    CK_OBJECT_HANDLE privKeyID;
 
     if (privKey == NULL || publicValue == NULL ||
         publicValue->data == NULL || publicValue->len == 0) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     pubKey.arena = NULL;
@@ -1699,16 +1699,19 @@ SECKEY_SetPublicValue(SECKEYPrivateKey *
     /* can't use PORT_InitCheapArena here becase SECKEY_DestroyPublic is used
       * to free it, and it uses PORT_FreeArena which not only frees the 
       * underlying arena, it also frees the allocated arena struct. */
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     pubKey.arena = arena;
     if (arena == NULL) {
         return SECFailure;
     }
+
+    slot = privKey->pkcs11Slot;
+    privKeyID = privKey->pkcs11ID;
     rv = SECFailure;
     switch (privKey->keyType) {
         default:
             /* error code already set to SECFailure */
             break;
         case rsaKey:
             pubKey.u.rsa.modulus = *publicValue;
             rv = PK11_ReadAttribute(slot, privKeyID, CKA_PUBLIC_EXPONENT,
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -326,17 +326,16 @@ class MarionetteParentProcess {
         } else {
           this.uninit();
         }
         break;
 
       case "profile-after-change":
         Services.obs.addObserver(this, "command-line-startup");
         Services.obs.addObserver(this, "sessionstore-windows-restored");
-        Services.obs.addObserver(this, "mail-startup-done");
         Services.obs.addObserver(this, "toplevel-window-ready");
         Services.obs.addObserver(this, "marionette-startup-requested");
 
         for (let [pref, value] of EnvironmentPrefs.from(ENV_PRESERVE_PREFS)) {
           Preferences.set(pref, value);
         }
         break;
 
@@ -381,21 +380,16 @@ class MarionetteParentProcess {
             let parserError = ev.target.querySelector("parsererror");
             log.fatal(parserError.textContent);
             this.uninit();
             Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
           }
         }, {once: true});
         break;
 
-      // Thunderbird only, instead of sessionstore-windows-restored.
-      case "mail-startup-done":
-        Services.obs.notifyObservers(this, "marionette-startup-requested");
-        break;
-
       case "sessionstore-windows-restored":
         Services.obs.removeObserver(this, topic);
         Services.obs.removeObserver(this, "toplevel-window-ready");
 
         // When Firefox starts on Windows, an additional GFX sanity test
         // window may appear off-screen.  Marionette should wait for it
         // to close.
         for (let win of Services.wm.getEnumerator(null)) {
--- a/third_party/rust/gleam/.cargo-checksum.json
+++ b/third_party/rust/gleam/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"21b5a3688fbbf5754800451efbdf5ee78c259657b70ecb7334c3ef91524ddba4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"1acb12040be43a3582d5897f11870b3ffdcd7ce0f4f32de158175bb6b33ec0b7","build.rs":"9881de207dd6a0347e66df9190ad0a095a2d7f0f32eff567f9ae7eb7de04c59b","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/gl.rs":"6bb2e2bb78982e3de6ad4f0d4ac9b9026042c727e39c10c9d2f8e886eefbc0f2","src/gl_fns.rs":"fc4c8898788c19f61b9e053475f122fb74370c1fecece978f276d6d59c487f99","src/gles_fns.rs":"7abaeed120d24414a4ed38e4fa2b81aa68de1d72e0e378e087b8a231593a3c23","src/lib.rs":"16610c19b45a3f26d56b379a3591aa2e4fc9477e7bd88f86b31c6ea32e834861"},"package":"b93018064928ec67c429c9c9416affd93660419dbf84767fff6b8a99fbe9c277"}
\ No newline at end of file
+{"files":{"COPYING":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"278158d345365c00bddd760e0684f94a3e057713bdd30492e0cf308fa2d9afcd","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"1acb12040be43a3582d5897f11870b3ffdcd7ce0f4f32de158175bb6b33ec0b7","build.rs":"9881de207dd6a0347e66df9190ad0a095a2d7f0f32eff567f9ae7eb7de04c59b","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/gl.rs":"ce511d167611653621bac2d3c31e569312ccdff7c954ed80c790972d37519425","src/gl_fns.rs":"fc4c8898788c19f61b9e053475f122fb74370c1fecece978f276d6d59c487f99","src/gles_fns.rs":"7abaeed120d24414a4ed38e4fa2b81aa68de1d72e0e378e087b8a231593a3c23","src/lib.rs":"16610c19b45a3f26d56b379a3591aa2e4fc9477e7bd88f86b31c6ea32e834861"},"package":"f1519ca611d230e1deadbedfb79044b921ac4a961ab8823fef10e37271e2c38e"}
\ No newline at end of file
old mode 100755
new mode 100644
--- a/third_party/rust/gleam/Cargo.toml
+++ b/third_party/rust/gleam/Cargo.toml
@@ -7,17 +7,17 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "gleam"
-version = "0.6.11"
+version = "0.6.12"
 authors = ["The Servo Project Developers"]
 build = "build.rs"
 description = "Generated OpenGL bindings and wrapper for Servo."
 documentation = "https://doc.servo.org/gleam/"
 license = "Apache-2.0/MIT"
 repository = "https://github.com/servo/gleam"
 [build-dependencies.gl_generator]
 version = "0.10"
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
--- a/third_party/rust/gleam/src/gl.rs
+++ b/third_party/rust/gleam/src/gl.rs
@@ -10,16 +10,17 @@
 use ffi;
 use std::ffi::{CStr, CString};
 use std::mem;
 use std::mem::size_of;
 use std::os::raw::{c_char, c_int, c_void};
 use std::ptr;
 use std::rc::Rc;
 use std::str;
+use std::time::{Duration, Instant};
 
 pub use ffi::types::*;
 pub use ffi::*;
 
 pub use ffi_gl::Gl as GlFfi;
 pub use ffi_gles::Gles2 as GlesFfi;
 
 #[derive(Debug, Eq, PartialEq)]
@@ -93,16 +94,28 @@ macro_rules! declare_gl_apis {
                 let rv = self.gl.$name($($arg,)*);
                 let error = self.gl.get_error();
                 if error != 0 {
                     (self.callback)(&*self.gl, stringify!($name), error);
                 }
                 rv
             })+
         }
+
+        impl<F: Fn(&str, Duration)> Gl for ProfilingGl<F> {
+            $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* {
+                let start = Instant::now();
+                let rv = self.gl.$name($($arg,)*);
+                let duration = Instant::now() - start;
+                if duration > self.threshold {
+                    (self.callback)(stringify!($name), duration);
+                }
+                rv
+            })+
+        }
     }
 }
 
 declare_gl_apis! {
     fn get_type(&self) -> GlType;
     fn buffer_data_untyped(&self,
                             target: GLenum,
                             size: GLsizeiptr,
@@ -579,16 +592,30 @@ pub struct ErrorReactingGl<F> {
 }
 
 impl<F: 'static + Fn(&Gl, &str, GLenum)> ErrorReactingGl<F> {
     pub fn wrap(fns: Rc<Gl>, callback: F) -> Rc<Gl> {
         Rc::new(ErrorReactingGl { gl: fns, callback }) as Rc<Gl>
     }
 }
 
+/// A wrapper around GL context that times each call and invokes the callback
+/// if the call takes longer than the threshold.
+pub struct ProfilingGl<F> {
+    gl: Rc<Gl>,
+    threshold: Duration,
+    callback: F,
+}
+
+impl<F: 'static + Fn(&str, Duration)> ProfilingGl<F> {
+    pub fn wrap(fns: Rc<Gl>, threshold: Duration, callback: F) -> Rc<Gl> {
+        Rc::new(ProfilingGl { gl: fns, threshold, callback }) as Rc<Gl>
+    }
+}
+
 #[inline]
 pub fn buffer_data<T>(gl_: &Gl, target: GLenum, data: &[T], usage: GLenum) {
     gl_.buffer_data_untyped(
         target,
         (data.len() * size_of::<T>()) as GLsizeiptr,
         data.as_ptr() as *const GLvoid,
         usage,
     )
old mode 100755
new mode 100644
old mode 100755
new mode 100644
old mode 100755
new mode 100644
--- a/toolkit/components/reader/Readability-readerable.js
+++ b/toolkit/components/reader/Readability-readerable.js
@@ -26,17 +26,17 @@
 /*
  * This code is heavily based on Arc90's readability.js (1.7.1) script
  * available at: http://code.google.com/p/arc90labs-readability
  */
 
 var REGEXPS = {
   // NOTE: These two regular expressions are duplicated in
   // Readability.js. Please keep both copies in sync.
-  unlikelyCandidates: /-ad-|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|foot|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
+  unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|foot|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
   okMaybeItsACandidate: /and|article|body|column|main|shadow/i,
 };
 
 function isNodeVisible(node) {
   // Have to null-check node.style to deal with SVG and MathML nodes.
   return (!node.style || node.style.display != "none") && !node.hasAttribute("hidden");
 }
 
--- a/toolkit/components/reader/Readability.js
+++ b/toolkit/components/reader/Readability.js
@@ -116,21 +116,21 @@ Readability.prototype = {
   // The default number of chars an article must have in order to return a result
   DEFAULT_CHAR_THRESHOLD: 500,
 
   // All of the regular expressions in use within readability.
   // Defined up here so we don't instantiate them repeatedly in loops.
   REGEXPS: {
     // NOTE: These two regular expressions are duplicated in
     // Readability-readerable.js. Please keep both copies in sync.
-    unlikelyCandidates: /-ad-|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|foot|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
+    unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|foot|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
     okMaybeItsACandidate: /and|article|body|column|main|shadow/i,
 
     positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,
-    negative: /hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i,
+    negative: /hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i,
     extraneous: /print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i,
     byline: /byline|author|dateline|writtenby|p-author/i,
     replaceFonts: /<(\/?)font[^>]*>/gi,
     normalize: /\s{2,}/g,
     videos: /\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i,
     nextLink: /(next|weiter|continue|>([^\|]|$)|»([^\|]|$))/i,
     prevLink: /(prev|earl|old|new|<|«)/i,
     whitespace: /^\s*$/,
@@ -579,20 +579,25 @@ Readability.prototype = {
     this._cleanConditionally(articleContent, "fieldset");
     this._clean(articleContent, "object");
     this._clean(articleContent, "embed");
     this._clean(articleContent, "h1");
     this._clean(articleContent, "footer");
     this._clean(articleContent, "link");
     this._clean(articleContent, "aside");
 
-    // Clean out elements have "share" in their id/class combinations from final top candidates,
+    // Clean out elements with little content that have "share" in their id/class combinations from final top candidates,
     // which means we don't remove the top candidates even they have "share".
-    this._forEachNode(articleContent.children, function(topCandidate) {
-      this._cleanMatchedNodes(topCandidate, /share/);
+
+    var shareElementThreshold = this.DEFAULT_CHAR_THRESHOLD;
+
+    this._forEachNode(articleContent.children, function (topCandidate) {
+      this._cleanMatchedNodes(topCandidate, function (node, matchString) {
+        return /share/.test(matchString) && node.textContent.length < shareElementThreshold;
+      });
     });
 
     // If there is only one h2 and its text content substantially equals article title,
     // they are probably using it as a header and not a subheader,
     // so remove it since we already extract the title separately.
     var h2 = articleContent.getElementsByTagName("h2");
     if (h2.length === 1) {
       var lengthSimilarRate = (h2[0].textContent.length - this._articleTitle.length) / this._articleTitle.length;
@@ -733,19 +738,20 @@ Readability.prototype = {
 
   _checkByline: function(node, matchString) {
     if (this._articleByline) {
       return false;
     }
 
     if (node.getAttribute !== undefined) {
       var rel = node.getAttribute("rel");
+      var itemprop = node.getAttribute("itemprop");
     }
 
-    if ((rel === "author" || this.REGEXPS.byline.test(matchString)) && this._isValidByline(node.textContent)) {
+    if ((rel === "author" || (itemprop && itemprop.indexOf("author") !== -1) || this.REGEXPS.byline.test(matchString)) && this._isValidByline(node.textContent)) {
       this._articleByline = node.textContent.trim();
       return true;
     }
 
     return false;
   },
 
   _getNodeAncestors: function(node, maxDepth) {
@@ -804,16 +810,17 @@ Readability.prototype = {
           node = this._removeAndGetNext(node);
           continue;
         }
 
         // Remove unlikely candidates
         if (stripUnlikelyCandidates) {
           if (this.REGEXPS.unlikelyCandidates.test(matchString) &&
               !this.REGEXPS.okMaybeItsACandidate.test(matchString) &&
+              !this._hasAncestorTag(node, "table") &&
               node.tagName !== "BODY" &&
               node.tagName !== "A") {
             this.log("Removing unlikely candidate - " + matchString);
             node = this._removeAndGetNext(node);
             continue;
           }
         }
 
@@ -1483,27 +1490,27 @@ Readability.prototype = {
    * @return void
    **/
   _clean: function(e, tag) {
     var isEmbed = ["object", "embed", "iframe"].indexOf(tag) !== -1;
 
     this._removeNodes(e.getElementsByTagName(tag), function(element) {
       // Allow youtube and vimeo videos through as people usually want to see those.
       if (isEmbed) {
-        var attributeValues = [].map.call(element.attributes, function(attr) {
-          return attr.value;
-        }).join("|");
+        // First, check the elements attributes to see if any of them contain youtube or vimeo
+        for (var i = 0; i < element.attributes.length; i++) {
+          if (this.REGEXPS.videos.test(element.attributes[i].value)) {
+            return false;
+          }
+        }
 
-        // First, check the elements attributes to see if any of them contain youtube or vimeo
-        if (this.REGEXPS.videos.test(attributeValues))
+        // For embed with <object> tag, check inner HTML as well.
+        if (element.tagName === "object" && this.REGEXPS.videos.test(element.innerHTML)) {
           return false;
-
-        // Then check the elements inside this element for the same.
-        if (this.REGEXPS.videos.test(element.innerHTML))
-          return false;
+        }
       }
 
       return true;
     });
   },
 
   /**
    * Check if a given node has one of its ancestor tag name matching the
@@ -1629,21 +1636,26 @@ Readability.prototype = {
     var isList = tag === "ul" || tag === "ol";
 
     // Gather counts for other typical elements embedded within.
     // Traverse backwards so we can remove nodes at the same time
     // without effecting the traversal.
     //
     // TODO: Consider taking into account original contentScore here.
     this._removeNodes(e.getElementsByTagName(tag), function(node) {
-      // First check if we're in a data table, in which case don't remove us.
+      // First check if this node IS data table, in which case don't remove it.
       var isDataTable = function(t) {
         return t._readabilityDataTable;
       };
 
+      if (tag === "table" && isDataTable(node)) {
+        return false;
+      }
+
+      // Next check if we're inside a data table, in which case don't remove it as well.
       if (this._hasAncestorTag(node, "table", -1, isDataTable)) {
         return false;
       }
 
       var weight = this._getClassWeight(node);
       var contentScore = 0;
 
       this.log("Cleaning Conditionally", node);
@@ -1657,20 +1669,35 @@ Readability.prototype = {
         // non-paragraph elements is more than paragraphs or other
         // ominous signs, remove the element.
         var p = node.getElementsByTagName("p").length;
         var img = node.getElementsByTagName("img").length;
         var li = node.getElementsByTagName("li").length - 100;
         var input = node.getElementsByTagName("input").length;
 
         var embedCount = 0;
-        var embeds = node.getElementsByTagName("embed");
-        for (var ei = 0, il = embeds.length; ei < il; ei += 1) {
-          if (!this.REGEXPS.videos.test(embeds[ei].src))
-            embedCount += 1;
+        var embeds = this._concatNodeLists(
+          node.getElementsByTagName("object"),
+          node.getElementsByTagName("embed"),
+          node.getElementsByTagName("iframe"));
+
+        for (var i = 0; i < embeds.length; i++) {
+          // If this embed has attribute that matches video regex, don't delete it.
+          for (var j = 0; j < embeds[i].attributes.length; j++) {
+            if (this.REGEXPS.videos.test(embeds[i].attributes[j].value)) {
+              return false;
+            }
+          }
+
+          // For embed with <object> tag, check inner HTML as well.
+          if (embeds[i].tagName === "object" && this.REGEXPS.videos.test(embeds[i].innerHTML)) {
+            return false;
+          }
+
+          embedCount++;
         }
 
         var linkDensity = this._getLinkDensity(node);
         var contentLength = this._getInnerText(node).length;
 
         var haveToRemove =
           (img > 1 && p / img < 0.5 && !this._hasAncestorTag(node, "figure")) ||
           (!isList && li > p) ||
@@ -1681,27 +1708,27 @@ Readability.prototype = {
           ((embedCount === 1 && contentLength < 75) || embedCount > 1);
         return haveToRemove;
       }
       return false;
     });
   },
 
   /**
-   * Clean out elements whose id/class combinations match specific string.
+   * Clean out elements that match the specified conditions
    *
    * @param Element
-   * @param RegExp match id/class combination.
+   * @param Function determines whether a node should be removed
    * @return void
    **/
-  _cleanMatchedNodes: function(e, regex) {
+  _cleanMatchedNodes: function(e, filter) {
     var endOfSearchMarkerNode = this._getNextNode(e, true);
     var next = this._getNextNode(e);
     while (next && next != endOfSearchMarkerNode) {
-      if (regex.test(next.className + " " + next.id)) {
+      if (filter(next, next.className + " " + next.id)) {
         next = this._removeAndGetNext(next);
       } else {
         next = this._getNextNode(next);
       }
     }
   },
 
   /**