Merge mozilla-central to autoland
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 20 Jan 2017 15:44:30 +0100
changeset 375302 ed9c070f9bb47121a7adb11b306667283c45ad65
parent 375301 49e6eba10d32047af1d645228419f820e96e3cde (current diff)
parent 375289 3cedab21a7e65e6a1c4c2294ecfb5502575a46e3 (diff)
child 375303 ec7143bb25f0a4fab2b783a833da6b763ffb3e10
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone53.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
--- a/browser/themes/shared/downloads/downloads.inc.css
+++ b/browser/themes/shared/downloads/downloads.inc.css
@@ -254,31 +254,26 @@ richlistitem[type="download"]:last-child
   fill: currentColor;
 }
 
 .downloadButton > .button-box > .button-text {
   margin: 0 !important;
   padding: 0;
 }
 
-@itemFinished@[exists]:hover > .downloadMainArea,
-@item@:not([verdict]):hover > .downloadButtonArea {
-  background-color: var(--arrowpanel-dimmed);
-}
-
 @itemFinished@[exists] .downloadMainArea:hover,
 @item@:not([verdict]) > .downloadButtonArea:hover,
 @item@[verdict]:hover {
-  background-color: var(--arrowpanel-dimmed-further);
+  background-color: var(--arrowpanel-dimmed);
 }
 
 @itemFinished@[exists] > .downloadMainArea:hover:active,
 @item@:not([verdict]) > .downloadButtonArea:hover:active,
 @item@[verdict]:hover:active {
-  background-color: var(--arrowpanel-dimmed-even-further);
+  background-color: var(--arrowpanel-dimmed-further);
 }
 
 @item@[showingsubview] {
   background-color: Highlight;
   color: HighlightText;
   transition: background-color var(--panelui-subview-transition-duration),
               color var(--panelui-subview-transition-duration);
 }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9091,19 +9091,25 @@ nsDocShell::CreateContentViewer(const ns
 
     nsIDocument* doc = viewer->GetDocument();
     if (doc) {
       doc->SetFailedChannel(failedChannel);
     }
 
     // Make sure we have a URI to set currentURI.
     nsCOMPtr<nsIURI> failedURI;
+    nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     if (failedChannel) {
       NS_GetFinalChannelURI(failedChannel, getter_AddRefs(failedURI));
     }
+     else {
+       // if there is no failed channel we have to explicitly provide
+       // a triggeringPrincipal for the history entry.
+       triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
+    }
 
     if (!failedURI) {
       failedURI = mFailedURI;
     }
     if (!failedURI) {
       // We need a URI object to store a session history entry, so make up a URI
       NS_NewURI(getter_AddRefs(failedURI), "about:blank");
     }
@@ -9113,17 +9119,18 @@ nsDocShell::CreateContentViewer(const ns
     MOZ_ASSERT(failedURI, "We don't have a URI for history APIs.");
 
     mFailedChannel = nullptr;
     mFailedURI = nullptr;
 
     // Create an shistory entry for the old load.
     if (failedURI) {
       bool errorOnLocationChangeNeeded = OnNewURI(
-        failedURI, failedChannel, nullptr, nullptr, mLoadType, false, false, false);
+        failedURI, failedChannel, triggeringPrincipal,
+        nullptr, mLoadType, false, false, false);
 
       if (errorOnLocationChangeNeeded) {
         FireOnLocationChange(this, failedChannel, failedURI,
                              LOCATION_CHANGE_ERROR_PAGE);
       }
     }
 
     // Be sure to have a correct mLSHE, it may have been cleared by
@@ -11991,17 +11998,19 @@ nsDocShell::AddState(JS::Handle<JS::Valu
     GetCurScrollPos(ScrollOrientation_Y, &cy);
     mOSHE->SetScrollPosition(cx, cy);
 
     bool scrollRestorationIsManual = false;
     mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
 
     // Since we're not changing which page we have loaded, pass
     // true for aCloneChildren.
-    rv = AddToSessionHistory(newURI, nullptr, nullptr, nullptr, true,
+    rv = AddToSessionHistory(newURI, nullptr,
+                             document->NodePrincipal(), // triggeringPrincipal
+                             nullptr, true,
                              getter_AddRefs(newSHEntry));
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE);
 
     // Session history entries created by pushState inherit scroll restoration
     // mode from the current entry.
     newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3462,17 +3462,17 @@ nsDOMWindowUtils::AddSheet(nsIPreloadedS
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   StyleSheet* sheet = nullptr;
   auto preloadedSheet = static_cast<PreloadedStyleSheet*>(aSheet);
   nsresult rv = preloadedSheet->GetSheet(doc->GetStyleBackendType(), &sheet);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
 
-  if (sheet->GetOwningDocument()) {
+  if (sheet->GetAssociatedDocument()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
   return doc->AddAdditionalStyleSheet(type, sheet);
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1480,17 +1480,17 @@ nsDocument::~nsDocument()
     mChildren.ChildAt(indx)->UnbindFromTree();
     mChildren.RemoveChildAt(indx);
   }
   mFirstChild = nullptr;
   mCachedRootElement = nullptr;
 
   // Let the stylesheets know we're going away
   for (StyleSheet* sheet : mStyleSheets) {
-    sheet->SetOwningDocument(nullptr);
+    sheet->ClearAssociatedDocument();
   }
   if (mAttrStyleSheet) {
     mAttrStyleSheet->SetOwningDocument(nullptr);
   }
   // We don't own the mOnDemandBuiltInUASheets, so we don't need to reset them.
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
@@ -2121,17 +2121,17 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
   }
 }
 
 void
 nsDocument::RemoveDocStyleSheetsFromStyleSets()
 {
   // The stylesheets should forget us
   for (StyleSheet* sheet : Reversed(mStyleSheets)) {
-    sheet->SetOwningDocument(nullptr);
+    sheet->ClearAssociatedDocument();
 
     if (sheet->IsApplicable()) {
       nsCOMPtr<nsIPresShell> shell = GetShell();
       if (shell) {
         shell->StyleSet()->RemoveDocStyleSheet(sheet);
       }
     }
     // XXX Tell observers?
@@ -2140,17 +2140,17 @@ nsDocument::RemoveDocStyleSheetsFromStyl
 
 void
 nsDocument::RemoveStyleSheetsFromStyleSets(
     const nsTArray<RefPtr<StyleSheet>>& aSheets,
     SheetType aType)
 {
   // The stylesheets should forget us
   for (StyleSheet* sheet : Reversed(aSheets)) {
-    sheet->SetOwningDocument(nullptr);
+    sheet->ClearAssociatedDocument();
 
     if (sheet->IsApplicable()) {
       nsCOMPtr<nsIPresShell> shell = GetShell();
       if (shell) {
         shell->StyleSet()->RemoveStyleSheet(aType, sheet);
       }
     }
     // XXX Tell observers?
@@ -4077,17 +4077,17 @@ nsDocument::NotifyStyleSheetRemoved(Styl
   }
 }
 
 void
 nsDocument::AddStyleSheet(StyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   mStyleSheets.AppendElement(aSheet);
-  aSheet->SetOwningDocument(this);
+  aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
 
   if (aSheet->IsApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
@@ -4114,17 +4114,17 @@ nsDocument::RemoveStyleSheet(StyleSheet*
   if (!mIsGoingAway) {
     if (aSheet->IsApplicable()) {
       RemoveStyleSheetFromStyleSets(aSheet);
     }
 
     NotifyStyleSheetRemoved(aSheet, true);
   }
 
-  aSheet->SetOwningDocument(nullptr);
+  aSheet->ClearAssociatedDocument();
 }
 
 void
 nsDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
                               nsTArray<RefPtr<StyleSheet>>& aNewSheets)
 {
   BeginUpdate(UPDATE_STYLE);
 
@@ -4142,17 +4142,17 @@ nsDocument::UpdateStyleSheets(nsTArray<R
     NS_ASSERTION(oldSheet, "None of the old sheets should be null");
     int32_t oldIndex = mStyleSheets.IndexOf(oldSheet);
     RemoveStyleSheet(oldSheet);  // This does the right notifications
 
     // Now put the new one in its place.  If it's null, just ignore it.
     StyleSheet* newSheet = aNewSheets[i];
     if (newSheet) {
       mStyleSheets.InsertElementAt(oldIndex, newSheet);
-      newSheet->SetOwningDocument(this);
+      newSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
       if (newSheet->IsApplicable()) {
         AddStyleSheetToStyleSets(newSheet);
       }
 
       NotifyStyleSheetAdded(newSheet, true);
     }
   }
 
@@ -4161,17 +4161,17 @@ nsDocument::UpdateStyleSheets(nsTArray<R
 
 void
 nsDocument::InsertStyleSheetAt(StyleSheet* aSheet, int32_t aIndex)
 {
   NS_PRECONDITION(aSheet, "null ptr");
 
   mStyleSheets.InsertElementAt(aIndex, aSheet);
 
-  aSheet->SetOwningDocument(this);
+  aSheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
 
   if (aSheet->IsApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
@@ -4289,17 +4289,17 @@ nsDocument::LoadAdditionalStyleSheet(add
     default:
       MOZ_CRASH("impossible value for aType");
   }
 
   RefPtr<StyleSheet> sheet;
   nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, &sheet);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  sheet->SetOwningDocument(this);
+  sheet->SetAssociatedDocument(this, StyleSheet::OwnedByDocument);
   MOZ_ASSERT(sheet->IsApplicable());
 
   return AddAdditionalStyleSheet(aType, sheet);
 }
 
 nsresult
 nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, StyleSheet* aSheet)
 {
@@ -4347,17 +4347,17 @@ nsDocument::RemoveAdditionalStyleSheet(a
       }
     }
 
     // Passing false, so documet.styleSheets.length will not be affected by
     // these additional sheets.
     NotifyStyleSheetRemoved(sheetRef, false);
     EndUpdate(UPDATE_STYLE);
 
-    sheetRef->SetOwningDocument(nullptr);
+    sheetRef->ClearAssociatedDocument();
   }
 }
 
 StyleSheet*
 nsDocument::GetFirstAdditionalAuthorSheet()
 {
   return mAdditionalSheets[eAuthorSheet].SafeElementAt(0);
 }
@@ -12017,17 +12017,17 @@ nsIDocument::DocAddSizeOfIncludingThis(n
 
 static size_t
 SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<StyleSheet>>& aSheets,
                                    MallocSizeOf aMallocSizeOf)
 {
   size_t n = 0;
   n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
   for (StyleSheet* sheet : aSheets) {
-    if (!sheet->GetOwningDocument()) {
+    if (!sheet->GetAssociatedDocument()) {
       // Avoid over-reporting shared sheets.
       continue;
     }
     n += sheet->SizeOfIncludingThis(aMallocSizeOf);
   }
   return n;
 }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8925,17 +8925,17 @@ nsGlobalWindow::EnterModalState()
     nsIPresShell::SetCapturingContent(nullptr, 0);
   }
 
   if (topWin->mModalStateDepth == 0) {
     NS_ASSERTION(!topWin->mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
 
     topWin->mSuspendedDoc = topDoc;
     if (topDoc) {
-      topDoc->SuppressEventHandling(nsIDocument::eEvents);
+      topDoc->SuppressEventHandling(nsIDocument::eAnimationsOnly);
     }
 
     nsGlobalWindow* inner = topWin->GetCurrentInnerWindowInternal();
     if (inner) {
       topWin->GetCurrentInnerWindowInternal()->Suspend();
     }
   }
   topWin->mModalStateDepth++;
@@ -8962,17 +8962,17 @@ nsGlobalWindow::LeaveModalState()
 
   if (topWin->mModalStateDepth == 0) {
     if (inner) {
       inner->Resume();
     }
 
     if (topWin->mSuspendedDoc) {
       nsCOMPtr<nsIDocument> currentDoc = topWin->GetExtantDoc();
-      topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
+      topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eAnimationsOnly,
                                                                   currentDoc == topWin->mSuspendedDoc);
       topWin->mSuspendedDoc = nullptr;
     }
   }
 
   // Remember the time of the last dialog quit.
   if (inner) {
     inner->mLastDialogQuitTime = TimeStamp::Now();
--- a/dom/tests/browser/browser.ini
+++ b/dom/tests/browser/browser.ini
@@ -22,19 +22,16 @@ skip-if = !e10s
 [browser_beforeunload_between_chrome_content.js]
 skip-if = !e10s
 [browser_bug396843.js]
 [browser_bug1004814.js]
 [browser_bug1008941_dismissGeolocationHanger.js]
 [browser_bug1238427.js]
 [browser_bug1316330.js]
 skip-if = !e10s
-[browser_cancel_keydown_keypress_event.js]
-support-files =
-  prevent_return_key.html
 [browser_ConsoleAPI_originAttributes.js]
 [browser_ConsoleAPITests.js]
 skip-if = e10s
 [browser_ConsoleStorageAPITests.js]
 [browser_ConsoleStoragePBTest_perwindowpb.js]
 [browser_focus_steal_from_chrome.js]
 [browser_focus_steal_from_chrome_during_mousedown.js]
 [browser_frame_elements.js]
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -42,16 +42,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 // See createInterfaceMap() below for a complete list of properties.
 
 // IMPORTANT: Do not change this list without review from
 //            a JavaScript Engine peer!
 var ecmaGlobals =
   [
     "Array",
     "ArrayBuffer",
+    "Atomics",
     "Boolean",
     "DataView",
     "Date",
     "Error",
     "EvalError",
     "Float32Array",
     "Float64Array",
     "Function",
@@ -73,19 +74,18 @@ var ecmaGlobals =
     "Object",
     "Promise",
     "Proxy",
     "RangeError",
     "ReferenceError",
     "Reflect",
     "RegExp",
     "Set",
-    {name: "SharedArrayBuffer", release: false},
+    "SharedArrayBuffer",
     {name: "SIMD", nightly: true},
-    {name: "Atomics", release: false},
     "StopIteration",
     "String",
     "Symbol",
     "SyntaxError",
     {name: "TypedObject", nightly: true},
     "TypeError",
     "Uint16Array",
     "Uint32Array",
--- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
+++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
@@ -20,16 +20,17 @@
 // See createInterfaceMap() below for a complete list of properties.
 
 // IMPORTANT: Do not change this list without review from
 //            a JavaScript Engine peer!
 var ecmaGlobals =
   [
     "Array",
     "ArrayBuffer",
+    "Atomics",
     "Boolean",
     "DataView",
     "Date",
     "Error",
     "EvalError",
     "Float32Array",
     "Float64Array",
     "Function",
@@ -48,19 +49,18 @@ var ecmaGlobals =
     "Object",
     "Promise",
     "Proxy",
     "RangeError",
     "ReferenceError",
     "Reflect",
     "RegExp",
     "Set",
-    {name: "SharedArrayBuffer", release: false},
+    "SharedArrayBuffer",
     {name: "SIMD", nightly: true},
-    {name: "Atomics", release: false},
     "StopIteration",
     "String",
     "Symbol",
     "SyntaxError",
     {name: "TypedObject", nightly: true},
     "TypeError",
     "Uint16Array",
     "Uint32Array",
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -20,16 +20,17 @@
 // See createInterfaceMap() below for a complete list of properties.
 
 // IMPORTANT: Do not change this list without review from
 //            a JavaScript Engine peer!
 var ecmaGlobals =
   [
     "Array",
     "ArrayBuffer",
+    "Atomics",
     "Boolean",
     "DataView",
     "Date",
     "Error",
     "EvalError",
     "Float32Array",
     "Float64Array",
     "Function",
@@ -48,19 +49,18 @@ var ecmaGlobals =
     "Object",
     "Promise",
     "Proxy",
     "RangeError",
     "ReferenceError",
     "Reflect",
     "RegExp",
     "Set",
-    {name: "SharedArrayBuffer", release: false},
+    "SharedArrayBuffer",
     {name: "SIMD", nightly: true},
-    {name: "Atomics", release: false},
     "StopIteration",
     "String",
     "Symbol",
     "SyntaxError",
     {name: "TypedObject", nightly: true},
     "TypeError",
     "Uint16Array",
     "Uint32Array",
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -2947,17 +2947,17 @@ NS_IMETHODIMP
 HTMLEditor::EnableStyleSheet(const nsAString& aURL,
                              bool aEnable)
 {
   RefPtr<StyleSheet> sheet = GetStyleSheetForURL(aURL);
   NS_ENSURE_TRUE(sheet, NS_OK); // Don't fail if sheet not found
 
   // Ensure the style sheet is owned by our document.
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
-  sheet->SetOwningDocument(doc);
+  sheet->SetAssociatedDocument(doc, StyleSheet::NotOwnedByDocument);
 
   if (sheet->IsServo()) {
     // XXXheycam ServoStyleSheets don't support being enabled/disabled yet.
     NS_ERROR("stylo: ServoStyleSheets can't be disabled yet");
     return NS_ERROR_FAILURE;
   }
   return sheet->AsGecko()->SetDisabled(!aEnable);
 }
@@ -2969,17 +2969,17 @@ HTMLEditor::EnableExistingStyleSheet(con
 
   // Enable sheet if already loaded.
   if (!sheet) {
     return false;
   }
 
   // Ensure the style sheet is owned by our document.
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
-  sheet->SetOwningDocument(doc);
+  sheet->SetAssociatedDocument(doc, StyleSheet::NotOwnedByDocument);
 
   if (sheet->IsServo()) {
     // XXXheycam ServoStyleSheets don't support being enabled/disabled yet.
     NS_ERROR("stylo: ServoStyleSheets can't be disabled yet");
     return true;
   }
   sheet->AsGecko()->SetDisabled(false);
   return true;
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -505,16 +505,62 @@ public:
 
     return result;
   }
 
   Color mColor;
   IntRect mBounds;
 };
 
+struct BorderLayerProperties : public LayerPropertiesBase
+{
+  explicit BorderLayerProperties(BorderLayer *aLayer)
+    : LayerPropertiesBase(aLayer)
+    , mColors(aLayer->GetColors())
+    , mRect(aLayer->GetRect())
+    , mCorners(aLayer->GetCorners())
+    , mWidths(aLayer->GetWidths())
+  { }
+
+protected:
+  BorderLayerProperties(const BorderLayerProperties& a) = delete;
+  BorderLayerProperties& operator=(const BorderLayerProperties& a) = delete;
+
+public:
+  nsIntRegion ComputeChangeInternal(const char* aPrefix,
+                                    NotifySubDocInvalidationFunc aCallback,
+                                    bool& aGeometryChanged) override
+  {
+    BorderLayer* border = static_cast<BorderLayer*>(mLayer.get());
+
+    if (!border->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
+      aGeometryChanged = true;
+      IntRect result = NewTransformedBounds();
+      result = result.Union(OldTransformedBounds());
+      return result;
+    }
+
+    if (!PodEqual(&mColors[0], &border->GetColors()[0], 4) ||
+        !PodEqual(&mWidths[0], &border->GetWidths()[0], 4) ||
+        !PodEqual(&mCorners[0], &border->GetCorners()[0], 4) ||
+        !mRect.IsEqualEdges(border->GetRect())) {
+      aGeometryChanged = true;
+      LTI_DUMP(NewTransformedBounds(), "bounds");
+      return NewTransformedBounds();
+    }
+
+    return nsIntRegion();
+  }
+
+  BorderColors mColors;
+  LayerRect mRect;
+  BorderCorners mCorners;
+  BorderWidths mWidths;
+};
+
 static ImageHost* GetImageHost(Layer* aLayer)
 {
   HostLayer* compositor = aLayer->AsHostLayer();
   if (compositor) {
     return static_cast<ImageHost*>(compositor->GetCompositableHost());
   }
   return nullptr;
 }
@@ -639,21 +685,22 @@ CloneLayerTreePropertiesInternal(Layer* 
     case Layer::TYPE_REF:
       return MakeUnique<ContainerLayerProperties>(aRoot->AsContainerLayer());
     case Layer::TYPE_COLOR:
       return MakeUnique<ColorLayerProperties>(static_cast<ColorLayer*>(aRoot));
     case Layer::TYPE_IMAGE:
       return MakeUnique<ImageLayerProperties>(static_cast<ImageLayer*>(aRoot), aIsMask);
     case Layer::TYPE_CANVAS:
       return MakeUnique<CanvasLayerProperties>(static_cast<CanvasLayer*>(aRoot));
+  case Layer::TYPE_BORDER:
+      return MakeUnique<BorderLayerProperties>(static_cast<BorderLayer*>(aRoot));
     case Layer::TYPE_READBACK:
     case Layer::TYPE_SHADOW:
     case Layer::TYPE_PAINTED:
     case Layer::TYPE_TEXT:
-    case Layer::TYPE_BORDER:
       return MakeUnique<LayerPropertiesBase>(aRoot);
   }
 
   MOZ_ASSERT_UNREACHABLE("Unexpected root layer type");
   return MakeUnique<LayerPropertiesBase>(aRoot);
 }
 
 /* static */ UniquePtr<LayerProperties>
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -2505,16 +2505,21 @@ public:
 
   virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
   {
     gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
     mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
     ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
   }
 
+  const BorderColors& GetColors() { return mColors; }
+  const LayerRect& GetRect() { return mRect; }
+  const BorderCorners& GetCorners() { return mCorners; }
+  const BorderWidths& GetWidths() { return mWidths; }
+
 protected:
   BorderLayer(LayerManager* aManager, void* aImplData)
     : Layer(aManager, aImplData)
   {}
 
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
 
   virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -364,16 +364,23 @@ CompositorBridgeChild::RecvCompositorUpd
     MOZ_ASSERT(aLayersId == 0);
   } else if (aLayersId != 0) {
     // Update gfxPlatform if this is the first time we're seeing this compositor
     // update (we will get an update for each connected tab).
     static uint64_t sLastSeqNo = 0;
     if (sLastSeqNo != aSeqNo) {
       gfxPlatform::GetPlatform()->CompositorUpdated();
       sLastSeqNo = aSeqNo;
+
+      // If we still get device reset here, something must wrong when creating
+      // d3d11 devices.
+      if (gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
+        gfxCriticalError() << "Unexpected reset device processing when \
+                               updating compositor.";
+      }
     }
 
     if (dom::TabChild* child = dom::TabChild::GetFrom(aLayersId)) {
       child->CompositorUpdated(aNewIdentifier);
     }
     if (!mCanSend) {
       return IPC_OK();
     }
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1511,16 +1511,24 @@ gfxWindowsPlatform::InitializeD3D11()
   DeviceManagerDx* dm = DeviceManagerDx::Get();
   if (XRE_IsParentProcess()) {
     if (!dm->CreateCompositorDevices()) {
       return;
     }
   }
 
   dm->CreateContentDevices();
+
+  // Content process failed to create the d3d11 device while parent process
+  // succeed.
+  if (XRE_IsContentProcess() &&
+      !gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
+    gfxCriticalError() << "[D3D11] Failed to create the D3D11 device in content \
+                           process.";
+  }
 }
 
 void
 gfxWindowsPlatform::InitializeD2DConfig()
 {
   FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D);
 
   if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
--- a/intl/locale/tests/unit/xpcshell.ini
+++ b/intl/locale/tests/unit/xpcshell.ini
@@ -11,11 +11,13 @@ skip-if = toolkit != "windows" && toolki
 [test_bug374040.js]
 skip-if = toolkit == "windows" || toolkit == "cocoa"
 
 [test_collation_mac_icu.js]
 skip-if = toolkit != "cocoa"
 
 [test_bug1086527.js]
 [test_intl_on_workers.js]
+skip-if = toolkit == "android" # bug 1309447
+
 [test_pluralForm.js]
 [test_pluralForm_english.js]
 [test_pluralForm_makeGetter.js]
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -800,16 +800,108 @@ BaselineCacheIRCompiler::emitStoreUnboxe
                               /* failure = */ nullptr);
 
     if (UnboxedTypeNeedsPostBarrier(fieldType))
         BaselineEmitPostWriteBarrierSlot(masm, obj, val, scratch, LiveGeneralRegisterSet(), cx_);
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
+{
+    ObjOperandId objId = reader.objOperandId();
+    Address offsetAddr = stubAddress(reader.stubOffset());
+    TypedThingLayout layout = reader.typedThingLayout();
+    ReferenceTypeDescr::Type type = reader.referenceTypeDescrType();
+
+    // Allocate the fixed registers first. These need to be fixed for
+    // callTypeUpdateIC.
+    AutoStubFrame stubFrame(*this);
+    AutoScratchRegister scratch1(allocator, masm, R1.scratchReg());
+    ValueOperand val = allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
+
+    Register obj = allocator.useRegister(masm, objId);
+
+    // We don't need a type update IC if the property is always a string.
+    if (type != ReferenceTypeDescr::TYPE_STRING) {
+        LiveGeneralRegisterSet saveRegs;
+        saveRegs.add(obj);
+        saveRegs.add(val);
+        if (!callTypeUpdateIC(stubFrame, obj, val, scratch1, saveRegs))
+            return false;
+    }
+
+    // Compute the address being written to.
+    LoadTypedThingData(masm, layout, obj, scratch1);
+    masm.addPtr(offsetAddr, scratch1);
+    Address dest(scratch1, 0);
+
+    // To avoid running out of registers on x86, use ICStubReg as second
+    // scratch. It won't be used after this.
+    Register scratch2 = ICStubReg;
+
+    switch (type) {
+      case ReferenceTypeDescr::TYPE_ANY:
+        EmitPreBarrier(masm, dest, MIRType::Value);
+        masm.storeValue(val, dest);
+        break;
+
+      case ReferenceTypeDescr::TYPE_OBJECT: {
+        EmitPreBarrier(masm, dest, MIRType::Object);
+        Label isNull, done;
+        masm.branchTestObject(Assembler::NotEqual, val, &isNull);
+        masm.unboxObject(val, scratch2);
+        masm.storePtr(scratch2, dest);
+        masm.jump(&done);
+        masm.bind(&isNull);
+        masm.storePtr(ImmWord(0), dest);
+        masm.bind(&done);
+        break;
+      }
+
+      case ReferenceTypeDescr::TYPE_STRING:
+        EmitPreBarrier(masm, dest, MIRType::String);
+        masm.unboxString(val, scratch2);
+        masm.storePtr(scratch2, dest);
+        break;
+    }
+
+    if (type != ReferenceTypeDescr::TYPE_STRING)
+        BaselineEmitPostWriteBarrierSlot(masm, obj, val, scratch1, LiveGeneralRegisterSet(), cx_);
+
+    return true;
+}
+
+bool
+BaselineCacheIRCompiler::emitStoreTypedObjectScalarProperty()
+{
+    Register obj = allocator.useRegister(masm, reader.objOperandId());
+    Address offsetAddr = stubAddress(reader.stubOffset());
+    TypedThingLayout layout = reader.typedThingLayout();
+    Scalar::Type type = reader.scalarType();
+    ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
+    AutoScratchRegister scratch1(allocator, masm);
+    AutoScratchRegister scratch2(allocator, masm);
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    // Compute the address being written to.
+    LoadTypedThingData(masm, layout, obj, scratch1);
+    masm.addPtr(offsetAddr, scratch1);
+    Address dest(scratch1, 0);
+
+    BaselineStoreToTypedArray(cx_, masm, type, val, dest, scratch2,
+                              failure->label(), failure->label());
+
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitTypeMonitorResult()
 {
     allocator.discardStack(masm);
     EmitEnterTypeMonitorIC(masm);
     return true;
 }
 
 bool
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -279,16 +279,43 @@ DoTypeUpdateFallback(JSContext* cx, Base
     RootedScript script(cx, frame->script());
     RootedObject obj(cx, &objval.toObject());
     RootedId id(cx);
 
     switch (stub->kind()) {
       case ICStub::CacheIR_Updated:
         id = stub->toCacheIR_Updated()->updateStubId();
         MOZ_ASSERT(id != JSID_EMPTY);
+
+        // If we're storing null/undefined to a typed object property, check if
+        // we want to include it in this property's type information.
+        if (MOZ_UNLIKELY(obj->is<TypedObject>()) && value.isNullOrUndefined()) {
+            StructTypeDescr* structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
+            size_t fieldIndex;
+            MOZ_ALWAYS_TRUE(structDescr->fieldIndex(id, &fieldIndex));
+
+            TypeDescr* fieldDescr = &structDescr->fieldDescr(fieldIndex);
+            ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
+            if (type == ReferenceTypeDescr::TYPE_ANY) {
+                // Ignore undefined values, which are included implicitly in type
+                // information for this property.
+                if (value.isUndefined())
+                    break;
+            } else {
+                MOZ_ASSERT(type == ReferenceTypeDescr::TYPE_OBJECT);
+
+                // Ignore null values being written here. Null is included
+                // implicitly in type information for this property. Note that
+                // non-object, non-null values are not possible here, these
+                // should have been filtered out by the IR emitter.
+                if (value.isNull())
+                    break;
+            }
+        }
+
         AddTypePropertyId(cx, obj, id, value);
         break;
       case ICStub::SetElem_DenseOrUnboxedArray:
       case ICStub::SetElem_DenseOrUnboxedArrayAdd: {
         id = JSID_VOID;
         AddTypePropertyId(cx, obj, id, value);
         break;
       }
@@ -297,35 +324,16 @@ DoTypeUpdateFallback(JSContext* cx, Base
         jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(script);
         if (*pc == JSOP_SETALIASEDVAR || *pc == JSOP_INITALIASEDLEXICAL)
             id = NameToId(EnvironmentCoordinateName(cx->caches.envCoordinateNameCache, script, pc));
         else
             id = NameToId(script->getName(pc));
         AddTypePropertyId(cx, obj, id, value);
         break;
       }
-      case ICStub::SetProp_TypedObject: {
-        MOZ_ASSERT(obj->is<TypedObject>());
-        jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(script);
-        id = NameToId(script->getName(pc));
-        if (stub->toSetProp_TypedObject()->isObjectReference()) {
-            // Ignore all values being written except plain objects. Null
-            // is included implicitly in type information for this property,
-            // and non-object non-null values will cause the stub to fail to
-            // match shortly and we will end up doing the assignment in the VM.
-            if (value.isObject())
-                AddTypePropertyId(cx, obj, id, value);
-        } else {
-            // Ignore undefined values, which are included implicitly in type
-            // information for this property.
-            if (!value.isUndefined())
-                AddTypePropertyId(cx, obj, id, value);
-        }
-        break;
-      }
       default:
         MOZ_CRASH("Invalid stub");
     }
 
     return stub->addUpdateStubForValue(cx, script /* = outerScript */, obj, id, value);
 }
 
 typedef bool (*DoTypeUpdateFallbackFn)(JSContext*, BaselineFrame*, ICUpdatedStub*, HandleValue,
@@ -1851,23 +1859,21 @@ ICSetElemDenseOrUnboxedArrayAddCompiler:
     EmitStubGuardFailure(masm);
     return true;
 }
 
 //
 // SetElem_TypedArray
 //
 
-// Write an arbitrary value to a typed array or typed object address at dest.
-// If the value could not be converted to the appropriate format, jump to
-// failure or failureModifiedScratch.
-template <typename T>
-static void
-StoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, Address value, T dest,
-                  Register scratch, Label* failure, Label* failureModifiedScratch)
+template <typename S, typename T>
+void
+BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, const S& value,
+                          const T& dest, Register scratch, Label* failure,
+                          Label* failureModifiedScratch)
 {
     Label done;
 
     if (type == Scalar::Float32 || type == Scalar::Float64) {
         masm.ensureDouble(value, FloatReg0, failure);
         if (type == Scalar::Float32) {
             masm.convertDoubleToFloat32(FloatReg0, ScratchFloat32Reg);
             masm.storeToTypedFloatArray(type, ScratchFloat32Reg, dest);
@@ -1917,16 +1923,26 @@ StoreToTypedArray(JSContext* cx, MacroAs
         } else {
             masm.jump(failure);
         }
     }
 
     masm.bind(&done);
 }
 
+template void
+BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type,
+                          const ValueOperand& value, const Address& dest, Register scratch,
+                          Label* failure, Label* failureModifiedScratch);
+
+template void
+BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type,
+                          const Address& value, const BaseIndex& dest, Register scratch,
+                          Label* failure, Label* failureModifiedScratch);
+
 bool
 ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm)
 {
     MOZ_ASSERT(engine_ == Engine::Baseline);
 
     Label failure;
 
     if (layout_ != Layout_TypedArray)
@@ -1979,18 +1995,18 @@ ICSetElem_TypedArray::Compiler::generate
     // R0 or R1, as long as it's restored before jumping to the next stub.
     regs = availableGeneralRegs(0);
     regs.takeUnchecked(obj);
     regs.takeUnchecked(key);
     regs.take(scratchReg);
     Register secondScratch = regs.takeAny();
 
     Label failureModifiedSecondScratch;
-    StoreToTypedArray(cx, masm, type_, value, dest,
-                      secondScratch, &failure, &failureModifiedSecondScratch);
+    BaselineStoreToTypedArray(cx, masm, type_, value, dest,
+                              secondScratch, &failure, &failureModifiedSecondScratch);
     EmitReturnFromIC(masm);
 
     if (failureModifiedSecondScratch.used()) {
         // Writing to secondScratch may have clobbered R0 or R1, restore them
         // first.
         masm.bind(&failureModifiedSecondScratch);
         masm.tagValue(JSVAL_TYPE_OBJECT, obj, R0);
         masm.tagValue(JSVAL_TYPE_INT32, key, R1);
@@ -2744,58 +2760,16 @@ TryAttachSetAccessorPropStub(JSContext* 
         *attached = true;
         return true;
     }
 
     return true;
 }
 
 static bool
-TryAttachTypedObjectSetPropStub(JSContext* cx, HandleScript script,
-                                ICSetProp_Fallback* stub, HandleId id,
-                                HandleObject obj, HandleValue rhs, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!cx->runtime()->jitSupportsFloatingPoint)
-        return true;
-
-    if (!obj->is<TypedObject>())
-        return true;
-
-    if (!obj->as<TypedObject>().typeDescr().is<StructTypeDescr>())
-        return true;
-    Rooted<StructTypeDescr*> structDescr(cx);
-    structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
-
-    size_t fieldIndex;
-    if (!structDescr->fieldIndex(id, &fieldIndex))
-        return true;
-
-    Rooted<TypeDescr*> fieldDescr(cx, &structDescr->fieldDescr(fieldIndex));
-    if (!fieldDescr->is<SimpleTypeDescr>())
-        return true;
-
-    uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex);
-
-    ICSetProp_TypedObject::Compiler compiler(cx, obj->maybeShape(), obj->group(), fieldOffset,
-                                             &fieldDescr->as<SimpleTypeDescr>());
-    ICUpdatedStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-    if (!newStub)
-        return false;
-    if (compiler.needsUpdateStubs() && !newStub->addUpdateStubForValue(cx, script, obj, id, rhs))
-        return false;
-
-    stub->addNewStub(newStub);
-
-    *attached = true;
-    return true;
-}
-
-static bool
 DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_, Value* stack,
                   HandleValue lhs, HandleValue rhs)
 {
     // This fallback stub may trigger debug mode toggling.
     DebugModeOSRVolatileStub<ICSetProp_Fallback*> stub(frame, stub_);
 
     RootedScript script(cx, frame->script());
     jsbytecode* pc = stub->icEntry()->pc(script);
@@ -2927,25 +2901,16 @@ DoSetPropFallback(JSContext* cx, Baselin
         !TryAttachSetValuePropStub(cx, script, pc, stub, obj, oldShape, oldGroup,
                                    name, id, rhs, &attached))
     {
         return false;
     }
     if (attached)
         return true;
 
-    if (!attached &&
-        lhs.isObject() &&
-        !TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached))
-    {
-        return false;
-    }
-    if (attached)
-        return true;
-
     MOZ_ASSERT(!attached);
     if (!isTemporarilyUnoptimizable)
         stub->noteUnoptimizableAccess();
 
     return true;
 }
 
 typedef bool (*DoSetPropFallbackFn)(JSContext*, BaselineFrame*, ICSetProp_Fallback*, Value*,
@@ -3193,138 +3158,16 @@ ICSetPropNativeAddCompiler::generateStub
     EmitUnstowICValues(masm, 2);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
 bool
-ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    CheckForTypedObjectWithDetachedStorage(cx, masm, &failure);
-
-    // Guard input is an object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
-    Register scratch = regs.takeAny();
-
-    // Unbox and shape guard.
-    Register object = masm.extractObject(R0, ExtractTemp0);
-    masm.loadPtr(Address(ICStubReg, ICSetProp_TypedObject::offsetOfShape()), scratch);
-    masm.branchTestObjShape(Assembler::NotEqual, object, scratch, &failure);
-
-    // Guard that the object group matches.
-    masm.loadPtr(Address(ICStubReg, ICSetProp_TypedObject::offsetOfGroup()), scratch);
-    masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
-                   &failure);
-
-    if (needsUpdateStubs()) {
-        // Stow both R0 and R1 (object and value).
-        EmitStowICValues(masm, 2);
-
-        // Move RHS into R0 for TypeUpdate check.
-        masm.moveValue(R1, R0);
-
-        // Call the type update stub.
-        if (!callTypeUpdateIC(masm, sizeof(Value)))
-            return false;
-
-        // Unstow R0 and R1 (object and key)
-        EmitUnstowICValues(masm, 2);
-
-        // We may have clobbered object in the TypeUpdate IC. Rederive it.
-        masm.unboxObject(R0, object);
-
-        // Trigger post barriers here on the values being written. Descriptors
-        // which can write objects also need update stubs.
-        LiveGeneralRegisterSet saveRegs;
-        saveRegs.add(R0);
-        saveRegs.add(R1);
-        saveRegs.addUnchecked(object);
-        saveRegs.add(ICStubReg);
-        BaselineEmitPostWriteBarrierSlot(masm, object, R1, scratch, saveRegs, cx);
-    }
-
-    // Save the rhs on the stack so we can get a second scratch register.
-    Label failurePopRHS;
-    masm.pushValue(R1);
-    regs = availableGeneralRegs(1);
-    regs.takeUnchecked(object);
-    regs.take(scratch);
-    Register secondScratch = regs.takeAny();
-
-    // Get the object's data pointer.
-    LoadTypedThingData(masm, layout_, object, scratch);
-
-    // Compute the address being written to.
-    masm.load32(Address(ICStubReg, ICSetProp_TypedObject::offsetOfFieldOffset()), secondScratch);
-    masm.addPtr(secondScratch, scratch);
-
-    Address dest(scratch, 0);
-    Address value(masm.getStackPointer(), 0);
-
-    if (fieldDescr_->is<ScalarTypeDescr>()) {
-        Scalar::Type type = fieldDescr_->as<ScalarTypeDescr>().type();
-        StoreToTypedArray(cx, masm, type, value, dest,
-                          secondScratch, &failurePopRHS, &failurePopRHS);
-        masm.popValue(R1);
-    } else {
-        ReferenceTypeDescr::Type type = fieldDescr_->as<ReferenceTypeDescr>().type();
-
-        masm.popValue(R1);
-
-        switch (type) {
-          case ReferenceTypeDescr::TYPE_ANY:
-            EmitPreBarrier(masm, dest, MIRType::Value);
-            masm.storeValue(R1, dest);
-            break;
-
-          case ReferenceTypeDescr::TYPE_OBJECT: {
-            EmitPreBarrier(masm, dest, MIRType::Object);
-            Label notObject;
-            masm.branchTestObject(Assembler::NotEqual, R1, &notObject);
-            Register rhsObject = masm.extractObject(R1, ExtractTemp0);
-            masm.storePtr(rhsObject, dest);
-            EmitReturnFromIC(masm);
-            masm.bind(&notObject);
-            masm.branchTestNull(Assembler::NotEqual, R1, &failure);
-            masm.storePtr(ImmWord(0), dest);
-            break;
-          }
-
-          case ReferenceTypeDescr::TYPE_STRING: {
-            EmitPreBarrier(masm, dest, MIRType::String);
-            masm.branchTestString(Assembler::NotEqual, R1, &failure);
-            Register rhsString = masm.extractString(R1, ExtractTemp0);
-            masm.storePtr(rhsString, dest);
-            break;
-          }
-
-          default:
-            MOZ_CRASH();
-        }
-    }
-
-    EmitReturnFromIC(masm);
-
-    masm.bind(&failurePopRHS);
-    masm.popValue(R1);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
 ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler& masm)
 {
     MOZ_ASSERT(engine_ == Engine::Baseline);
 
     Label failure;
     Label failureUnstow;
     Label failureLeaveStubFrame;
 
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -1230,104 +1230,16 @@ class ICSetPropNativeAddCompiler : publi
 
         return newStub<ICSetProp_NativeAddImpl<ProtoChainDepth>>(
             space, getStubCode(), oldGroup_, shapes, newShape, newGroup, offset_);
     }
 
     ICUpdatedStub* getStub(ICStubSpace* space);
 };
 
-class ICSetProp_TypedObject : public ICUpdatedStub
-{
-    friend class ICStubSpace;
-
-    GCPtrShape shape_;
-    GCPtrObjectGroup group_;
-    uint32_t fieldOffset_;
-    bool isObjectReference_;
-
-    ICSetProp_TypedObject(JitCode* stubCode, Shape* shape, ObjectGroup* group,
-                          uint32_t fieldOffset, bool isObjectReference)
-      : ICUpdatedStub(ICStub::SetProp_TypedObject, stubCode),
-        shape_(shape),
-        group_(group),
-        fieldOffset_(fieldOffset),
-        isObjectReference_(isObjectReference)
-    {
-        (void) fieldOffset_; // Silence clang warning
-    }
-
-  public:
-    GCPtrShape& shape() {
-        return shape_;
-    }
-    GCPtrObjectGroup& group() {
-        return group_;
-    }
-    bool isObjectReference() {
-        return isObjectReference_;
-    }
-
-    static size_t offsetOfShape() {
-        return offsetof(ICSetProp_TypedObject, shape_);
-    }
-    static size_t offsetOfGroup() {
-        return offsetof(ICSetProp_TypedObject, group_);
-    }
-    static size_t offsetOfFieldOffset() {
-        return offsetof(ICSetProp_TypedObject, fieldOffset_);
-    }
-
-    class Compiler : public ICStubCompiler {
-      protected:
-        RootedShape shape_;
-        RootedObjectGroup group_;
-        uint32_t fieldOffset_;
-        TypedThingLayout layout_;
-        Rooted<SimpleTypeDescr*> fieldDescr_;
-
-        MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
-
-        virtual int32_t getKey() const {
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(SimpleTypeDescrKey(fieldDescr_)) << 17) |
-                  (static_cast<int32_t>(layout_) << 25);
-        }
-
-      public:
-        Compiler(JSContext* cx, Shape* shape, ObjectGroup* group, uint32_t fieldOffset,
-                 SimpleTypeDescr* fieldDescr)
-          : ICStubCompiler(cx, ICStub::SetProp_TypedObject, Engine::Baseline),
-            shape_(cx, shape),
-            group_(cx, group),
-            fieldOffset_(fieldOffset),
-            layout_(GetTypedThingLayout(shape->getObjectClass())),
-            fieldDescr_(cx, fieldDescr)
-        {}
-
-        ICUpdatedStub* getStub(ICStubSpace* space) {
-            bool isObjectReference =
-                fieldDescr_->is<ReferenceTypeDescr>() &&
-                fieldDescr_->as<ReferenceTypeDescr>().type() == ReferenceTypeDescr::TYPE_OBJECT;
-            ICUpdatedStub* stub = newStub<ICSetProp_TypedObject>(space, getStubCode(), shape_,
-                                                                 group_, fieldOffset_,
-                                                                 isObjectReference);
-            if (!stub || !stub->initUpdatingChain(cx, space))
-                return nullptr;
-            return stub;
-        }
-
-        bool needsUpdateStubs() {
-            return fieldDescr_->is<ReferenceTypeDescr>() &&
-                   fieldDescr_->as<ReferenceTypeDescr>().type() != ReferenceTypeDescr::TYPE_STRING;
-        }
-    };
-};
-
 // Base stub for calling a setters on a native or unboxed object.
 class ICSetPropCallSetter : public ICStub
 {
     friend class ICStubSpace;
 
   protected:
     // Shape/group of receiver object. Used for both own and proto setters.
     HeapReceiverGuard receiverGuard_;
@@ -2529,12 +2441,21 @@ IsCacheableDOMProxy(JSObject* obj)
     return handler->family() == GetDOMProxyHandlerFamily();
 }
 
 struct IonOsrTempData;
 
 void EmitUnboxedPreBarrierForBaseline(MacroAssembler &masm, const BaseIndex& address,
                                       JSValueType type);
 
+// Write an arbitrary value to a typed array or typed object address at dest.
+// If the value could not be converted to the appropriate format, jump to
+// failure or failureModifiedScratch.
+template <typename S, typename T>
+void
+BaselineStoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, const S& value,
+                          const T& dest, Register scratch, Label* failure,
+                          Label* failureModifiedScratch);
+
 } // namespace jit
 } // namespace js
 
 #endif /* jit_BaselineIC_h */
--- a/js/src/jit/BaselineICList.h
+++ b/js/src/jit/BaselineICList.h
@@ -65,17 +65,16 @@ namespace jit {
                                                  \
     _(BindName_Fallback)                         \
                                                  \
     _(GetIntrinsic_Fallback)                     \
     _(GetIntrinsic_Constant)                     \
                                                  \
     _(SetProp_Fallback)                          \
     _(SetProp_NativeAdd)                         \
-    _(SetProp_TypedObject)                       \
     _(SetProp_CallScripted)                      \
     _(SetProp_CallNative)                        \
                                                  \
     _(TableSwitch)                               \
                                                  \
     _(IteratorNew_Fallback)                      \
     _(IteratorMore_Fallback)                     \
     _(IteratorMore_Native)                       \
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1562,16 +1562,18 @@ SetPropIRGenerator::tryAttachStub()
         ObjOperandId objId = writer.guardIsObject(lhsValId);
         if (nameOrSymbol) {
             if (tryAttachNativeSetSlot(obj, objId, id, rhsValId))
                 return true;
             if (tryAttachUnboxedExpandoSetSlot(obj, objId, id, rhsValId))
                 return true;
             if (tryAttachUnboxedProperty(obj, objId, id, rhsValId))
                 return true;
+            if (tryAttachTypedObjectProperty(obj, objId, id, rhsValId))
+                return true;
         }
         return false;
     }
 
     return false;
 }
 
 static void
@@ -1694,8 +1696,66 @@ SetPropIRGenerator::tryAttachUnboxedProp
                                 UnboxedPlainObject::offsetOfData() + property->offset,
                                 rhsId);
     writer.returnFromIC();
 
     setUpdateStubInfo(id);
     preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
     return true;
 }
+
+bool
+SetPropIRGenerator::tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId objId, HandleId id,
+                                                 ValOperandId rhsId)
+{
+    if (!obj->is<TypedObject>() || !cx_->runtime()->jitSupportsFloatingPoint)
+        return false;
+
+    if (cx_->compartment()->detachedTypedObjects)
+        return false;
+
+    if (!obj->as<TypedObject>().typeDescr().is<StructTypeDescr>())
+        return false;
+
+    StructTypeDescr* structDescr = &obj->as<TypedObject>().typeDescr().as<StructTypeDescr>();
+    size_t fieldIndex;
+    if (!structDescr->fieldIndex(id, &fieldIndex))
+        return false;
+
+    TypeDescr* fieldDescr = &structDescr->fieldDescr(fieldIndex);
+    if (!fieldDescr->is<SimpleTypeDescr>())
+        return false;
+
+    uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex);
+    TypedThingLayout layout = GetTypedThingLayout(obj->getClass());
+
+    writer.guardNoDetachedTypedObjects();
+    writer.guardShape(objId, obj->as<TypedObject>().shape());
+    writer.guardGroup(objId, obj->group());
+
+    setUpdateStubInfo(id);
+
+    // Scalar types can always be stored without a type update stub.
+    if (fieldDescr->is<ScalarTypeDescr>()) {
+        Scalar::Type type = fieldDescr->as<ScalarTypeDescr>().type();
+        writer.storeTypedObjectScalarProperty(objId, fieldOffset, layout, type, rhsId);
+        writer.returnFromIC();
+        return true;
+    }
+
+    // For reference types, guard on the RHS type first, so that
+    // StoreTypedObjectReferenceProperty is infallible.
+    ReferenceTypeDescr::Type type = fieldDescr->as<ReferenceTypeDescr>().type();
+    switch (type) {
+      case ReferenceTypeDescr::TYPE_ANY:
+        break;
+      case ReferenceTypeDescr::TYPE_OBJECT:
+        writer.guardIsObjectOrNull(rhsId);
+        break;
+      case ReferenceTypeDescr::TYPE_STRING:
+        writer.guardType(rhsId, JSVAL_TYPE_STRING);
+        break;
+    }
+
+    writer.storeTypedObjectReferenceProperty(objId, fieldOffset, layout, type, rhsId);
+    writer.returnFromIC();
+    return true;
+}
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -167,16 +167,18 @@ enum class CacheKind : uint8_t
     /* See CacheIR.cpp 'DOM proxies' comment. */ \
     _(LoadDOMExpandoValue)                \
     _(LoadDOMExpandoValueGuardGeneration) \
     _(LoadDOMExpandoValueIgnoreGeneration)\
     _(GuardDOMExpandoMissingOrGuardShape) \
                                           \
     _(StoreFixedSlot)                     \
     _(StoreDynamicSlot)                   \
+    _(StoreTypedObjectReferenceProperty)  \
+    _(StoreTypedObjectScalarProperty)     \
     _(StoreUnboxedProperty)               \
                                           \
     /* The *Result ops load a value into the cache's result register. */ \
     _(LoadFixedSlotResult)                \
     _(LoadDynamicSlotResult)              \
     _(LoadUnboxedPropertyResult)          \
     _(LoadTypedObjectResult)              \
     _(LoadDenseElementResult)             \
@@ -562,16 +564,35 @@ class MOZ_RAII CacheIRWriter : public JS
         addStubField(offset, StubField::Type::RawWord);
         writeOperandId(rhs);
     }
     void storeDynamicSlot(ObjOperandId obj, size_t offset, ValOperandId rhs) {
         writeOpWithOperandId(CacheOp::StoreDynamicSlot, obj);
         addStubField(offset, StubField::Type::RawWord);
         writeOperandId(rhs);
     }
+    void storeTypedObjectReferenceProperty(ObjOperandId obj, uint32_t offset,
+                                           TypedThingLayout layout, ReferenceTypeDescr::Type type,
+                                           ValOperandId rhs)
+    {
+        writeOpWithOperandId(CacheOp::StoreTypedObjectReferenceProperty, obj);
+        addStubField(offset, StubField::Type::RawWord);
+        buffer_.writeByte(uint32_t(layout));
+        buffer_.writeByte(uint32_t(type));
+        writeOperandId(rhs);
+    }
+    void storeTypedObjectScalarProperty(ObjOperandId obj, uint32_t offset, TypedThingLayout layout,
+                                        Scalar::Type type, ValOperandId rhs)
+    {
+        writeOpWithOperandId(CacheOp::StoreTypedObjectScalarProperty, obj);
+        addStubField(offset, StubField::Type::RawWord);
+        buffer_.writeByte(uint32_t(layout));
+        buffer_.writeByte(uint32_t(type));
+        writeOperandId(rhs);
+    }
     void storeUnboxedProperty(ObjOperandId obj, JSValueType type, size_t offset,
                               ValOperandId rhs)
     {
         writeOpWithOperandId(CacheOp::StoreUnboxedProperty, obj);
         buffer_.writeByte(uint32_t(type));
         addStubField(offset, StubField::Type::RawWord);
         writeOperandId(rhs);
     }
@@ -708,16 +729,20 @@ class MOZ_RAII CacheIRReader
     uint32_t stubOffset() { return buffer_.readByte() * sizeof(uintptr_t); }
     GuardClassKind guardClassKind() { return GuardClassKind(buffer_.readByte()); }
     JSValueType valueType() { return JSValueType(buffer_.readByte()); }
     TypedThingLayout typedThingLayout() { return TypedThingLayout(buffer_.readByte()); }
     Scalar::Type scalarType() { return Scalar::Type(buffer_.readByte()); }
     uint32_t typeDescrKey() { return buffer_.readByte(); }
     JSWhyMagic whyMagic() { return JSWhyMagic(buffer_.readByte()); }
 
+    ReferenceTypeDescr::Type referenceTypeDescrType() {
+        return ReferenceTypeDescr::Type(buffer_.readByte());
+    }
+
     bool matchOp(CacheOp op) {
         const uint8_t* pos = buffer_.currentPosition();
         if (readOp() == op)
             return true;
         buffer_.seek(pos, 0);
         return false;
     }
     bool matchOp(CacheOp op, OperandId id) {
@@ -875,16 +900,18 @@ class MOZ_RAII SetPropIRGenerator : publ
     }
 
     bool tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId, HandleId id,
                                  ValOperandId rhsId);
     bool tryAttachUnboxedExpandoSetSlot(HandleObject obj, ObjOperandId objId, HandleId id,
                                         ValOperandId rhsId);
     bool tryAttachUnboxedProperty(HandleObject obj, ObjOperandId objId, HandleId id,
                                   ValOperandId rhsId);
+    bool tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId objId, HandleId id,
+                                      ValOperandId rhsId);
 
   public:
     SetPropIRGenerator(JSContext* cx, jsbytecode* pc, CacheKind cacheKind,
                        bool* isTemporarilyUnoptimizable, HandleValue lhsVal, HandleValue idVal,
                        HandleValue rhsVal);
 
     bool tryAttachStub();
 
--- a/js/src/jit/FlowAliasAnalysis.cpp
+++ b/js/src/jit/FlowAliasAnalysis.cpp
@@ -810,17 +810,17 @@ FlowAliasAnalysis::saveLoadDependency(MD
 }
 
 bool
 FlowAliasAnalysis::saveStoreDependency(MDefinition* ins, BlockStoreInfo& prevStores)
 {
     // To form a store dependency chain, we store the previous last dependencies
     // in the current store.
 
-    StoreDependency* dependency = new(alloc()) StoreDependency(alloc());
+    StoreDependency* dependency = new(alloc().fallible()) StoreDependency(alloc());
     if (!dependency)
         return false;
     if (!dependency->init(prevStores))
         return false;
 
     ins->setStoreDependency(dependency);
     return true;
 }
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -851,16 +851,28 @@ IonCacheIRCompiler::emitStoreDynamicSlot
 
 bool
 IonCacheIRCompiler::emitStoreUnboxedProperty()
 {
     MOZ_CRASH("Baseline-specific op");
 }
 
 bool
+IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty()
+{
+    MOZ_CRASH("Baseline-specific op");
+}
+
+bool
+IonCacheIRCompiler::emitStoreTypedObjectScalarProperty()
+{
+    MOZ_CRASH("Baseline-specific op");
+}
+
+bool
 IonCacheIRCompiler::emitLoadTypedObjectResult()
 {
     AutoOutputRegister output(*this);
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     AutoScratchRegister scratch1(allocator, masm);
     AutoScratchRegister scratch2(allocator, masm);
 
     TypedThingLayout layout = reader.typedThingLayout();
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -367,22 +367,16 @@ ICStub::trace(JSTracer* trc)
           case 1: propStub->toImpl<1>()->traceShapes(trc); break;
           case 2: propStub->toImpl<2>()->traceShapes(trc); break;
           case 3: propStub->toImpl<3>()->traceShapes(trc); break;
           case 4: propStub->toImpl<4>()->traceShapes(trc); break;
           default: MOZ_CRASH("Invalid proto stub.");
         }
         break;
       }
-      case ICStub::SetProp_TypedObject: {
-        ICSetProp_TypedObject* propStub = toSetProp_TypedObject();
-        TraceEdge(trc, &propStub->shape(), "baseline-setprop-typedobject-stub-shape");
-        TraceEdge(trc, &propStub->group(), "baseline-setprop-typedobject-stub-group");
-        break;
-      }
       case ICStub::SetProp_CallScripted: {
         ICSetProp_CallScripted* callStub = toSetProp_CallScripted();
         callStub->receiverGuard().trace(trc);
         TraceEdge(trc, &callStub->holder(), "baseline-setpropcallscripted-stub-holder");
         TraceEdge(trc, &callStub->holderShape(), "baseline-setpropcallscripted-stub-holdershape");
         TraceEdge(trc, &callStub->setter(), "baseline-setpropcallscripted-stub-setter");
         break;
       }
--- a/js/src/jit/SharedIC.h
+++ b/js/src/jit/SharedIC.h
@@ -2378,17 +2378,17 @@ class ICGetProp_Generic : public ICMonit
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
         }
     };
 };
 
-static uint32_t
+static inline uint32_t
 SimpleTypeDescrKey(SimpleTypeDescr* descr)
 {
     if (descr->is<ScalarTypeDescr>())
         return uint32_t(descr->as<ScalarTypeDescr>().type()) << 1;
     return (uint32_t(descr->as<ReferenceTypeDescr>().type()) << 1) | 1;
 }
 
 inline bool
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -141,21 +141,18 @@ static const size_t gMaxStackSize = 128 
 #endif
 
 /*
  * Limit the timeout to 30 minutes to prevent an overflow on platfoms
  * that represent the time internally in microseconds using 32-bit int.
  */
 static const TimeDuration MAX_TIMEOUT_INTERVAL = TimeDuration::FromSeconds(1800.0);
 
-#ifdef RELEASE_OR_BETA
-# define SHARED_MEMORY_DEFAULT 0
-#else
-# define SHARED_MEMORY_DEFAULT 1
-#endif
+// SharedArrayBuffer and Atomics are enabled by default (tracking Firefox).
+#define SHARED_MEMORY_DEFAULT 1
 
 using JobQueue = GCVector<JSObject*, 0, SystemAllocPolicy>;
 
 struct ShellAsyncTasks
 {
     explicit ShellAsyncTasks(JSContext* cx)
       : outstanding(0),
         finished(cx)
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -251,22 +251,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   gConstructorProperties['Promise'] =
     constructorProps(["resolve", "reject", "all", "race", Symbol.species]);
 
   gPrototypeProperties['ArrayBuffer'] =
     ["constructor", "byteLength", "slice", Symbol.toStringTag];
   gConstructorProperties['ArrayBuffer'] =
     constructorProps(["isView", Symbol.species]);
 
-  if (!isReleaseOrBeta) {
-    gPrototypeProperties['SharedArrayBuffer'] = ["constructor", "slice", "byteLength", Symbol.toStringTag];
-    gConstructorProperties['SharedArrayBuffer'] = constructorProps([Symbol.species]);
-  } else {
-    is(typeof SharedArrayBuffer, "undefined", "Enable tests!");
-  }
+  gPrototypeProperties['SharedArrayBuffer'] = ["constructor", "slice", "byteLength", Symbol.toStringTag];
+  gConstructorProperties['SharedArrayBuffer'] = constructorProps([Symbol.species]);
 
   gPrototypeProperties['Map'] =
     ["constructor", "size", Symbol.toStringTag, "get", "has", "set", "delete",
      "keys", "values", "clear", "forEach", "entries", Symbol.iterator];
   gConstructorProperties['Map'] =
     constructorProps([Symbol.species]);
 
   gPrototypeProperties['Set'] =
@@ -907,21 +903,17 @@ for (var prop of props) {
     is(Cu.getGlobalForObject(pr.wrappedJSObject.catch), iwin, "Underlying global is correct");
 
     isnot(pr.then, Cu.unwaiveXrays(pr.wrappedJSObject.then), "Different function identities");
     is(Cu.getGlobalForObject(pr.then), window, "Xray global is correct");
     is(Cu.getGlobalForObject(pr.wrappedJSObject.then), iwin, "Underlying global is correct");
   }
 
   function testArrayBuffer() {
-    let constructors = ['ArrayBuffer'];
-
-    if (!isReleaseOrBeta) {
-      constructors.push('SharedArrayBuffer');
-    }
+    let constructors = ['ArrayBuffer', 'SharedArrayBuffer'];
 
     for (const c of constructors) {
       testXray(c, new iwin[c](0), new iwin[c](12));
 
       var t = new iwin[c](12);
       is(t.byteLength, 12, `${c} byteLength is correct`);
 
       is(t.slice(4).byteLength, 8, `${c} byteLength is correct after slicing`);
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -8056,19 +8056,16 @@ PresShell::HandleEventInternal(WidgetEve
           mIsLastChromeOnlyEscapeKeyConsumed = false;
         } else {
           if (aEvent->mFlags.mOnlyChromeDispatch &&
               aEvent->mFlags.mDefaultPreventedByChrome) {
             mIsLastChromeOnlyEscapeKeyConsumed = true;
           }
         }
       }
-      if (aEvent->mMessage == eKeyDown) {
-        mIsLastKeyDownCanceled = aEvent->mFlags.mDefaultPrevented;
-      }
       break;
     }
     case eMouseUp:
       // reset the capturing content now that the mouse button is up
       SetCapturingContent(nullptr, 0);
       break;
     case eMouseMove:
       nsIPresShell::AllowMouseCapture(false);
@@ -8848,19 +8845,16 @@ PresShell::FireOrClearDelayedEvents(bool
   }
 
   if (mDocument) {
     nsCOMPtr<nsIDocument> doc = mDocument;
     while (!mIsDestroying && mDelayedEvents.Length() &&
            !doc->EventHandlingSuppressed()) {
       nsAutoPtr<DelayedEvent> ev(mDelayedEvents[0].forget());
       mDelayedEvents.RemoveElementAt(0);
-      if (ev->IsKeyPressEvent() && mIsLastKeyDownCanceled) {
-        continue;
-      }
       ev->Dispatch();
     }
     if (!doc->EventHandlingSuppressed()) {
       mDelayedEvents.Clear();
     }
   }
 }
 
@@ -9658,22 +9652,16 @@ PresShell::DelayedKeyEvent::DelayedKeyEv
                             aEvent->mMessage,
                             aEvent->mWidget);
   keyEvent->AssignKeyEventData(*aEvent, false);
   keyEvent->mFlags.mIsSynthesizedForTests = aEvent->mFlags.mIsSynthesizedForTests;
   keyEvent->mFlags.mIsSuppressedOrDelayed = true;
   mEvent = keyEvent;
 }
 
-bool
-PresShell::DelayedKeyEvent::IsKeyPressEvent()
-{
-  return mEvent->mMessage == eKeyPress;
-}
-
 // Start of DEBUG only code
 
 #ifdef DEBUG
 
 static void
 LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg)
 {
   nsAutoString n1, n2;
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -595,17 +595,16 @@ protected:
     return rv;
   }
 
   class DelayedEvent
   {
   public:
     virtual ~DelayedEvent() { }
     virtual void Dispatch() { }
-    virtual bool IsKeyPressEvent() { return false; }
   };
 
   class DelayedInputEvent : public DelayedEvent
   {
   public:
     virtual void Dispatch() override;
 
   protected:
@@ -620,17 +619,16 @@ protected:
   public:
     explicit DelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent);
   };
 
   class DelayedKeyEvent : public DelayedInputEvent
   {
   public:
     explicit DelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent);
-    virtual bool IsKeyPressEvent() override;
   };
 
   // Check if aEvent is a mouse event and record the mouse location for later
   // synth mouse moves.
   void RecordMouseLocation(mozilla::WidgetGUIEvent* aEvent);
   class nsSynthMouseMoveEvent final : public nsARefreshObserver {
   public:
     nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
@@ -900,16 +898,14 @@ protected:
   bool                      mScaleToResolution : 1;
 
   // Whether the last chrome-only escape key event is consumed.
   bool                      mIsLastChromeOnlyEscapeKeyConsumed : 1;
 
   // Whether the widget has received a paint message yet.
   bool                      mHasReceivedPaintMessage : 1;
 
-  bool                      mIsLastKeyDownCanceled : 1;
-
   static bool               sDisableNonTestMouseEvents;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_PresShell_h
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -146,25 +146,27 @@ static bool SetStyleSheetReference(css::
 }
 
 struct ChildSheetListBuilder {
   RefPtr<CSSStyleSheet>* sheetSlot;
   CSSStyleSheet* parent;
 
   void SetParentLinks(CSSStyleSheet* aSheet) {
     aSheet->mParent = parent;
-    aSheet->SetOwningDocument(parent->mDocument);
+    aSheet->SetAssociatedDocument(parent->mDocument,
+                                  parent->mDocumentAssociationMode);
   }
 
   static void ReparentChildList(CSSStyleSheet* aPrimarySheet,
                                 CSSStyleSheet* aFirstChild)
   {
     for (CSSStyleSheet *child = aFirstChild; child; child = child->mNext) {
       child->mParent = aPrimarySheet;
-      child->SetOwningDocument(aPrimarySheet->mDocument);
+      child->SetAssociatedDocument(aPrimarySheet->mDocument,
+                                   aPrimarySheet->mDocumentAssociationMode);
     }
   }
 };
   
 bool
 CSSStyleSheet::RebuildChildList(css::Rule* aRule, void* aBuilder)
 {
   int32_t type = aRule->GetType();
@@ -607,26 +609,32 @@ CSSStyleSheet::EnabledStateChangedIntern
 
 CSSStyleSheet*
 CSSStyleSheet::GetParentSheet() const
 {
   return mParent;
 }
 
 void
-CSSStyleSheet::SetOwningDocument(nsIDocument* aDocument)
-{ // not ref counted
+CSSStyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
+                                     DocumentAssociationMode aAssociationMode)
+{
+  MOZ_ASSERT_IF(!aDocument, aAssociationMode == NotOwnedByDocument);
+
+  // not ref counted
   mDocument = aDocument;
+  mDocumentAssociationMode = aAssociationMode;
+
   // Now set the same document on all our child sheets....
   // XXXbz this is a little bogus; see the XXX comment where we
   // declare mFirstChild.
   for (CSSStyleSheet* child = mInner->mFirstChild;
        child; child = child->mNext) {
     if (child->mParent == this) {
-      child->SetOwningDocument(aDocument);
+      child->SetAssociatedDocument(aDocument, aAssociationMode);
     }
   }
 }
 
 uint64_t
 CSSStyleSheet::FindOwningWindowInnerID() const
 {
   uint64_t windowID = 0;
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -112,17 +112,18 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSStyleSheet, StyleSheet)
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_SHEET_IMPL_CID)
 
   bool HasRules() const;
 
   // style sheet owner info
   CSSStyleSheet* GetParentSheet() const;  // may be null
-  void SetOwningDocument(nsIDocument* aDocument);
+  void SetAssociatedDocument(nsIDocument* aDocument,
+                             DocumentAssociationMode aAssociationMode);
 
   // Find the ID of the owner inner window.
   uint64_t FindOwningWindowInnerID() const;
 #ifdef DEBUG
   void List(FILE* out = stdout, int32_t aIndent = 0) const;
 #endif
 
   void AppendStyleSheet(CSSStyleSheet* aSheet);
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -2213,23 +2213,23 @@ Loader::LoadChildSheet(StyleSheet* aPare
     LOG_WARN(("  Not enabled"));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   LOG_URI("  Child uri: '%s'", aURL);
 
   nsCOMPtr<nsINode> owningNode;
 
-  // check for an owning document: if none, don't bother walking up the parent
-  // sheets
+  // check for an associated document: if none, don't bother walking up the
+  // parent sheets
   //
   // FIXME(emilio): Figure out whether this walk up is necessary (try seems
   // green without it), and fix the parenting of stylesheets in the servo case
   // if that's the case.
-  if (aParentSheet->GetOwningDocument() && aParentSheet->IsGecko()) {
+  if (aParentSheet->GetAssociatedDocument() && aParentSheet->IsGecko()) {
     StyleSheet* topSheet = aParentSheet;
     while (StyleSheet* parent = topSheet->GetParentSheet()) {
       topSheet = parent;
     }
     owningNode = topSheet->GetOwnerNode();
   }
 
   nsISupports* context = owningNode;
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -65,25 +65,25 @@ ServoStyleRuleDeclaration::GetCSSDeclara
   return mDecls;
 }
 
 nsresult
 ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
 {
   ServoStyleRule* rule = Rule();
   if (RefPtr<ServoStyleSheet> sheet = rule->GetStyleSheet()->AsServo()) {
-    nsCOMPtr<nsIDocument> owningDoc = sheet->GetOwningDocument();
-    mozAutoDocUpdate updateBatch(owningDoc, UPDATE_STYLE, true);
+    nsCOMPtr<nsIDocument> doc = sheet->GetAssociatedDocument();
+    mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
     if (aDecl != mDecls) {
       RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo();
       Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw());
       mDecls = decls.forget();
     }
-    if (owningDoc) {
-      owningDoc->StyleRuleChanged(sheet, rule);
+    if (doc) {
+      doc->StyleRuleChanged(sheet, rule);
     }
   }
   return NS_OK;
 }
 
 nsIDocument*
 ServoStyleRuleDeclaration::DocToUpdate()
 {
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -50,29 +50,33 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 bool
 ServoStyleSheet::HasRules() const
 {
   return mSheet && Servo_StyleSheet_HasRules(mSheet);
 }
 
 void
-ServoStyleSheet::SetOwningDocument(nsIDocument* aDocument)
+ServoStyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
+                                       DocumentAssociationMode aAssociationMode)
 {
+  MOZ_ASSERT_IF(!aDocument, aAssociationMode == NotOwnedByDocument);
+
   // XXXheycam: Traverse to child ServoStyleSheets to set this, like
-  // CSSStyleSheet::SetOwningDocument does.
+  // CSSStyleSheet::SetAssociatedDocument does.
 
   mDocument = aDocument;
+  mDocumentAssociationMode = aAssociationMode;
 }
 
 ServoStyleSheet*
 ServoStyleSheet::GetParentSheet() const
 {
   // XXXheycam: When we implement support for child sheets, we'll have
-  // to fix SetOwningDocument to propagate the owning document down
+  // to fix SetAssociatedDocument to propagate the associated document down
   // to the children.
   MOZ_CRASH("stylo: not implemented");
 }
 
 void
 ServoStyleSheet::AppendStyleSheet(ServoStyleSheet* aSheet)
 {
   aSheet->mDocument = mDocument;
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -33,17 +33,18 @@ public:
                   net::ReferrerPolicy aReferrerPolicy,
                   const dom::SRIMetadata& aIntegrity);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoStyleSheet, StyleSheet)
 
   bool HasRules() const;
 
-  void SetOwningDocument(nsIDocument* aDocument);
+  void SetAssociatedDocument(nsIDocument* aDocument,
+                             DocumentAssociationMode aAssociationMode);
 
   ServoStyleSheet* GetParentSheet() const;
   void AppendStyleSheet(ServoStyleSheet* aSheet);
 
   MOZ_MUST_USE nsresult ParseSheet(css::Loader* aLoader,
                                    const nsAString& aInput,
                                    nsIURI* aSheetURI,
                                    nsIURI* aBaseURI,
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -1201,32 +1201,32 @@ DOMCSSDeclarationImpl::GetParentRule(nsI
 }
 
 nsresult
 DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
 {
   NS_PRECONDITION(mRule,
          "can only be called when |GetCSSDeclaration| returned a declaration");
 
-  nsCOMPtr<nsIDocument> owningDoc;
+  nsCOMPtr<nsIDocument> doc;
   RefPtr<CSSStyleSheet> sheet = mRule->GetStyleSheet();
   if (sheet) {
-    owningDoc = sheet->GetOwningDocument();
+    doc = sheet->GetAssociatedDocument();
   }
 
-  mozAutoDocUpdate updateBatch(owningDoc, UPDATE_STYLE, true);
+  mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
 
   mRule->SetDeclaration(aDecl->AsGecko());
 
   if (sheet) {
     sheet->DidDirty();
   }
 
-  if (owningDoc) {
-    owningDoc->StyleRuleChanged(sheet, mRule);
+  if (doc) {
+    doc->StyleRuleChanged(sheet, mRule);
   }
   return NS_OK;
 }
 
 nsIDocument*
 DOMCSSDeclarationImpl::DocToUpdate()
 {
   return nullptr;
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -19,28 +19,32 @@
 namespace mozilla {
 
 StyleSheet::StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMode)
   : mDocument(nullptr)
   , mOwningNode(nullptr)
   , mParsingMode(aParsingMode)
   , mType(aType)
   , mDisabled(false)
+  , mDocumentAssociationMode(NotOwnedByDocument)
 {
 }
 
 StyleSheet::StyleSheet(const StyleSheet& aCopy,
                        nsIDocument* aDocumentToUse,
                        nsINode* aOwningNodeToUse)
   : mTitle(aCopy.mTitle)
   , mDocument(aDocumentToUse)
   , mOwningNode(aOwningNodeToUse)
   , mParsingMode(aCopy.mParsingMode)
   , mType(aCopy.mType)
   , mDisabled(aCopy.mDisabled)
+    // We only use this constructor during cloning.  It's the cloner's
+    // responsibility to notify us if we end up being owned by a document.
+  , mDocumentAssociationMode(NotOwnedByDocument)
 {
   if (aCopy.mMedia) {
     // XXX This is wrong; we should be keeping @import rules and
     // sheets in sync!
     mMedia = aCopy.mMedia->Clone();
   }
 }
 
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -101,18 +101,32 @@ public:
    * should never be inserted into a style set.  A sheet may not be
    * applicable for a variety of reasons including being disabled and
    * being incomplete.
    */
   inline bool IsApplicable() const;
   inline bool HasRules() const;
 
   // style sheet owner info
-  nsIDocument* GetOwningDocument() const { return mDocument; }
-  inline void SetOwningDocument(nsIDocument* aDocument);
+  enum DocumentAssociationMode {
+    // OwnedByDocument means mDocument owns us (possibly via a chain of other
+    // stylesheets).
+    OwnedByDocument,
+    // NotOwnedByDocument means we're owned by something that might have a
+    // different lifetime than mDocument.
+    NotOwnedByDocument
+  };
+  nsIDocument* GetAssociatedDocument() const { return mDocument; }
+  bool IsOwnedByDocument() const {
+    return mDocumentAssociationMode == OwnedByDocument;
+  }
+  // aDocument must not be null.
+  inline void SetAssociatedDocument(nsIDocument* aDocument,
+                                    DocumentAssociationMode aMode);
+  inline void ClearAssociatedDocument();
   nsINode* GetOwnerNode() const { return mOwningNode; }
   inline StyleSheet* GetParentSheet() const;
 
   inline void AppendStyleSheet(StyleSheet* aSheet);
 
   // Principal() never returns a null pointer.
   inline nsIPrincipal* Principal() const;
   /**
@@ -220,13 +234,18 @@ protected:
 
   // mParsingMode controls access to nonstandard style constructs that
   // are not safe for use on the public Web but necessary in UA sheets
   // and/or useful in user sheets.
   css::SheetParsingMode mParsingMode;
 
   const StyleBackendType mType;
   bool                  mDisabled;
+
+  // mDocumentAssociationMode determines whether mDocument directly owns us (in
+  // the sense that if it's known-live then we're known-live).  Always
+  // NotOwnedByDocument when mDocument is null.
+  DocumentAssociationMode mDocumentAssociationMode;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_StyleSheet_h
--- a/layout/style/StyleSheetInlines.h
+++ b/layout/style/StyleSheetInlines.h
@@ -78,19 +78,27 @@ StyleSheet::IsApplicable() const
 
 bool
 StyleSheet::HasRules() const
 {
   MOZ_STYLO_FORWARD(HasRules, ())
 }
 
 void
-StyleSheet::SetOwningDocument(nsIDocument* aDocument)
+StyleSheet::SetAssociatedDocument(nsIDocument* aDocument,
+                                  DocumentAssociationMode aAssociationMode)
 {
-  MOZ_STYLO_FORWARD(SetOwningDocument, (aDocument))
+  MOZ_ASSERT(aDocument);
+  MOZ_STYLO_FORWARD(SetAssociatedDocument, (aDocument, aAssociationMode))
+}
+
+void
+StyleSheet::ClearAssociatedDocument()
+{
+  MOZ_STYLO_FORWARD(SetAssociatedDocument, (nullptr, NotOwnedByDocument));
 }
 
 StyleSheet*
 StyleSheet::GetParentSheet() const
 {
   MOZ_STYLO_FORWARD(GetParentSheet, ())
 }
 
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -262,17 +262,17 @@ nsDOMCSSDeclaration::GetCSSParsingEnviro
                                                      CSSParsingEnvironment& aCSSParseEnv)
 {
   StyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nullptr;
   if (!sheet) {
     aCSSParseEnv.mPrincipal = nullptr;
     return;
   }
 
-  nsIDocument* document = sheet->GetOwningDocument();
+  nsIDocument* document = sheet->GetAssociatedDocument();
   aCSSParseEnv.mSheetURI = sheet->GetSheetURI();
   aCSSParseEnv.mBaseURI = sheet->GetBaseURI();
   aCSSParseEnv.mPrincipal = sheet->Principal();
   aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nullptr;
 }
 
 nsresult
 nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID,
--- a/layout/style/nsMediaList.cpp
+++ b/layout/style/nsMediaList.cpp
@@ -578,17 +578,17 @@ nsMediaList::GetMediaText(nsAString& aMe
   GetText(aMediaText);
   return NS_OK;
 }
 
 // "sheet" should be a StyleSheet and "doc" should be an
 // nsCOMPtr<nsIDocument>
 #define BEGIN_MEDIA_CHANGE(sheet, doc)                         \
   if (sheet) {                                                 \
-    doc = sheet->GetOwningDocument();                          \
+    doc = sheet->GetAssociatedDocument();                      \
   }                                                            \
   mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);       \
   if (sheet) {                                                 \
     sheet->WillDirty();                                        \
   }
 
 #define END_MEDIA_CHANGE(sheet, doc)                           \
   if (sheet) {                                                 \
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -441,22 +441,22 @@ WebrtcVideoConduit::CreateRecvStream()
   if (!mRecvStream) {
     mDecoders.clear();
     return kMediaConduitUnknownError;
   }
 
   return kMediaConduitNoError;
 }
 
-static bool CompatibleH264Config(const webrtc::VideoCodecH264 &aEncoderSpecificH264,
-                                 const VideoCodecConfig* aCodecConfig)
+static bool CompatibleH264Config(const webrtc::VideoCodecH264& aEncoderSpecificH264,
+                                 const VideoCodecConfig& aCodecConfig)
 {
-  if (aEncoderSpecificH264.profile_byte != aCodecConfig->mProfile ||
-      aEncoderSpecificH264.constraints != aCodecConfig->mConstraints ||
-      aEncoderSpecificH264.packetizationMode != aCodecConfig->mPacketizationMode) {
+  if (aEncoderSpecificH264.profile_byte != aCodecConfig.mProfile ||
+      aEncoderSpecificH264.constraints != aCodecConfig.mConstraints ||
+      aEncoderSpecificH264.packetizationMode != aCodecConfig.mPacketizationMode) {
     return false;
   }
   return true;
 }
 
 /**
  * Note: Setting the send-codec on the Video Engine will restart the encoder,
  * sets up new SSRC and reset RTP_RTCP module with the new codec setting.
@@ -476,37 +476,16 @@ WebrtcVideoConduit::ConfigureSendMediaCo
 
   MediaConduitErrorCode condError = kMediaConduitNoError;
 
   // validate basic params
   if ((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError) {
     return condError;
   }
 
-  // StopTransmitting may be moot if mSendStream is null, but the code seems to
-  // allow for it.
-  // Recreating on PayloadType change may be overkill, but is safe.
-  if (!mSendStream ||
-      mSendStreamConfig.encoder_settings.payload_type != codecConfig->mType ||
-      mSendStreamConfig.encoder_settings.payload_name != codecConfig->mName ||
-      (codecConfig->mName == "H264" &&
-       !CompatibleH264Config(mEncoderSpecificH264, codecConfig))) {
-    condError = StopTransmitting();
-    if (condError != kMediaConduitNoError) {
-      return condError;
-    }
-    DeleteSendStream(); // safe if mSendStream is null
-  } // we are already using this codec - mSendStream tells us we're reconfiguring
-
-  mSendStreamConfig.encoder_settings.payload_name = codecConfig->mName;
-  mSendStreamConfig.encoder_settings.payload_type = codecConfig->mType;
-  mSendStreamConfig.rtp.rtcp_mode = webrtc::RtcpMode::kCompound;
-  mSendStreamConfig.rtp.max_packet_size = kVideoMtu;
-  mSendStreamConfig.overuse_callback = mLoadManager.get();
-
   size_t streamCount = std::min(codecConfig->mSimulcastEncodings.size(),
                                 (size_t)webrtc::kMaxSimulcastStreams);
   CSFLogDebug(logTag, "%s for VideoConduit:%p stream count:%d", __FUNCTION__,
               this, static_cast<int>(streamCount));
 
   mSendingFramerate = 0;
   mEncoderConfig.ClearStreams();
 
@@ -637,16 +616,45 @@ WebrtcVideoConduit::ConfigureSendMediaCo
   }
 
   mEncoderConfig.SetContentType(mCodecMode == webrtc::kRealtimeVideo ?
     webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo :
     webrtc::VideoEncoderConfig::ContentType::kScreen);
   // for the GMP H.264 encoder/decoder!!
   mEncoderConfig.SetMinTransmitBitrateBps(0);
 
+  // If only encoder stream attibutes have been changed, there is no need to stop,
+  // create a new webrtc::VideoSendStream, and restart.
+  // Recreating on PayloadType change may be overkill, but is safe.
+  if (mSendStream) {
+    if (!RequiresNewSendStream(*codecConfig)) {
+      if (!mSendStream->ReconfigureVideoEncoder(mEncoderConfig.GenerateConfig())) {
+        CSFLogError(logTag, "%s: ReconfigureVideoEncoder failed", __FUNCTION__);
+        // Don't return here; let it try to destroy the encoder and rebuild it
+        // on StartTransmitting()
+      } else {
+        return kMediaConduitNoError;
+      }
+    }
+
+    condError = StopTransmitting();
+    if (condError != kMediaConduitNoError) {
+      return condError;
+    }
+
+    // This will cause a new encoder to be created by StartTransmitting()
+    DeleteSendStream();
+  }
+
+  mSendStreamConfig.encoder_settings.payload_name = codecConfig->mName;
+  mSendStreamConfig.encoder_settings.payload_type = codecConfig->mType;
+  mSendStreamConfig.rtp.rtcp_mode = webrtc::RtcpMode::kCompound;
+  mSendStreamConfig.rtp.max_packet_size = kVideoMtu;
+  mSendStreamConfig.overuse_callback = mLoadManager.get();
+
   // See Bug 1297058, enabling FEC when basic NACK is to be enabled in H.264 is problematic
   if (codecConfig->RtcpFbFECIsSet() &&
       !(codecConfig->mName == "H264" && codecConfig->RtcpFbNackIsSet(""))) {
     mSendStreamConfig.rtp.fec.ulpfec_payload_type = kUlpFecPayloadType;
     mSendStreamConfig.rtp.fec.red_payload_type = kRedPayloadType;
     mSendStreamConfig.rtp.fec.red_rtx_payload_type = kNullPayloadType;
   }
 
@@ -654,28 +662,16 @@ WebrtcVideoConduit::ConfigureSendMediaCo
     codecConfig->RtcpFbNackIsSet("") ? 1000 : 0;
 
   {
     MutexAutoLock lock(mCodecMutex);
     // Copy the applied config for future reference.
     mCurSendCodecConfig = new VideoCodecConfig(*codecConfig);
   }
 
-  // Is this a reconfigure of a running codec?
-  if (mSendStream &&
-      !mSendStream->ReconfigureVideoEncoder(mEncoderConfig.GenerateConfig())) {
-    CSFLogError(logTag, "%s: ReconfigureVideoEncoder failed", __FUNCTION__);
-    // This will cause a new encoder to be created by StartTransmitting()
-    condError = StopTransmitting();
-    if (condError != kMediaConduitNoError) {
-      return condError;
-    }
-    DeleteSendStream();
-  }
-
   return condError;
 }
 
 bool
 WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
 {
   mRecvStreamConfig.rtp.remote_ssrc = ssrc;
   unsigned int current_ssrc;
@@ -1999,16 +1995,28 @@ WebrtcVideoConduit::CodecPluginID()
     return mSendCodecPlugin->PluginID();
   } else if (mRecvCodecPlugin) {
     return mRecvCodecPlugin->PluginID();
   }
 
   return 0;
 }
 
+bool
+WebrtcVideoConduit::RequiresNewSendStream(const VideoCodecConfig& newConfig) const
+{
+  return !mCurSendCodecConfig
+    || mCurSendCodecConfig->mName != newConfig.mName
+    || mCurSendCodecConfig->mType != newConfig.mType
+    || mCurSendCodecConfig->RtcpFbNackIsSet("") != newConfig.RtcpFbNackIsSet("")
+    || mCurSendCodecConfig->RtcpFbFECIsSet() != newConfig.RtcpFbFECIsSet()
+    || (newConfig.mName == "H264" &&
+        !CompatibleH264Config(mEncoderSpecificH264, newConfig));
+}
+
 void
 WebrtcVideoConduit::VideoEncoderConfigBuilder::SetEncoderSpecificSettings(
   void* aSettingsObj)
 {
   mConfig.encoder_specific_settings = aSettingsObj;
 };
 
 void
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -432,24 +432,26 @@ private:
   void DeleteRecvStream();
 
   webrtc::VideoDecoder* CreateDecoder(webrtc::VideoDecoder::DecoderType aType);
   webrtc::VideoEncoder* CreateEncoder(webrtc::VideoEncoder::EncoderType aType,
                                       bool enable_simulcast);
 
   MediaConduitErrorCode DeliverPacket(const void *data, int len);
 
+  bool RequiresNewSendStream(const VideoCodecConfig& newConfig) const;
+
   mozilla::ReentrantMonitor mTransportMonitor;
   RefPtr<TransportInterface> mTransmitterTransport;
   RefPtr<TransportInterface> mReceiverTransport;
   RefPtr<mozilla::VideoRenderer> mRenderer;
 
   // Engine state we are concerned with.
-  mozilla::Atomic<bool> mEngineTransmitting; //If true ==> Transmit Sub-system is up and running
-  mozilla::Atomic<bool> mEngineReceiving;    // if true ==> Receive Sus-sysmtem up and running
+  mozilla::Atomic<bool> mEngineTransmitting; // If true ==> Transmit Subsystem is up and running
+  mozilla::Atomic<bool> mEngineReceiving;    // if true ==> Receive Subsystem up and running
 
   int mCapId;   // Capturer for this conduit
   //Local database of currently applied receive codecs
   nsTArray<UniquePtr<VideoCodecConfig>> mRecvCodecList;
 
   Mutex mCodecMutex; // protects mCurrSendCodecConfig, mVideoSend/RecvStreamStats
   nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig;
   bool mInReconfig;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1291,22 +1291,17 @@ pref("javascript.options.mem.gc_dynamic_
 pref("javascript.options.mem.gc_dynamic_mark_slice", true);
 pref("javascript.options.mem.gc_refresh_frame_slices_enabled", true);
 pref("javascript.options.mem.gc_allocation_threshold_mb", 30);
 pref("javascript.options.mem.gc_min_empty_chunk_count", 1);
 pref("javascript.options.mem.gc_max_empty_chunk_count", 30);
 
 pref("javascript.options.showInConsole", false);
 
-#ifdef RELEASE_OR_BETA
-// Disabled in Beta and Release for now, see bug 1225406
-pref("javascript.options.shared_memory", false);
-#else
 pref("javascript.options.shared_memory", true);
-#endif
 
 pref("javascript.options.throw_on_debuggee_would_run", false);
 pref("javascript.options.dump_stack_on_debuggee_would_run", false);
 
 // advanced prefs
 pref("advanced.mailftp",                    false);
 pref("image.animation_mode",                "normal");
 
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -6716,16 +6716,17 @@ nsHttpChannel::OnStopRequest(nsIRequest 
 
         // If we are using the transaction to serve content, we also save the
         // time since async open in the cache entry so we can compare telemetry
         // between cache and net response.
         // Do not store the time of conditional requests because even if we
         // fetch the data from the server, the time includes loading of the old
         // cache entry which would skew the network load time.
         if (request == mTransactionPump && mCacheEntry && !mDidReval &&
+            !mCustomConditionalRequest &&
             !mAsyncOpenTime.IsNull() && !mOnStartRequestTimestamp.IsNull()) {
             nsAutoCString onStartTime;
             onStartTime.AppendInt( (uint64_t) (mOnStartRequestTimestamp - mAsyncOpenTime).ToMilliseconds());
             mCacheEntry->SetMetaDataElement("net-response-time-onstart", onStartTime.get());
 
             nsAutoCString responseTime;
             responseTime.AppendInt( (uint64_t) (TimeStamp::Now() - mAsyncOpenTime).ToMilliseconds());
             mCacheEntry->SetMetaDataElement("net-response-time-onstop", responseTime.get());
--- a/toolkit/components/passwordmgr/test/subtst_master_pass.html
+++ b/toolkit/components/passwordmgr/test/subtst_master_pass.html
@@ -1,7 +1,12 @@
 <h2>MP subtest</h2>
 This form triggers a MP and gets filled in.<br>
 <form>
 Username: <input type="text"     id="userfield" name="u"><br>
-Password: <input type="password" id="passfield" name="p"
-                 oninput="parent.postMessage('filled', '*');"><br>
+Password: <input type="password" id="passfield" name="p"><br>
+<script>
+    // Only notify when we fill in the password field.
+    document.getElementById("passfield").addEventListener("input", function() {
+        parent.postMessage("filled", "*");
+    });
+</script>
 </form>