Merge mozilla-central to autoland. a=merge CLOSED TREE
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Thu, 21 Jun 2018 12:53:49 +0300
changeset 477458 776ba1aa0feee265e8b7ee7a570bac7114433a9a
parent 477457 46ea394f0c30fdfef5cc24baa78a667e9e0c1dc0 (current diff)
parent 477448 e834d23a292972ab4250a8be00e6740c43e41db2 (diff)
child 477459 4e4be76218d898d7d068e1420e52713e9ff8f86f
push id9385
push userdluca@mozilla.com
push dateFri, 22 Jun 2018 15:47:18 +0000
treeherdermozilla-beta@82a9a1027e2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.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=merge CLOSED TREE
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -971,16 +971,25 @@ MaybeWrapValue(JSContext* cx, JS::Mutabl
 {
   if (rval.isGCThing()) {
     if (rval.isString()) {
       return MaybeWrapStringValue(cx, rval);
     }
     if (rval.isObject()) {
       return MaybeWrapObjectValue(cx, rval);
     }
+#ifdef ENABLE_BIGINT
+    // This could be optimized by checking the zone first, similar to
+    // the way strings are handled. At present, this is used primarily
+    // for structured cloning, so avoiding the overhead of JS_WrapValue
+    // calls is less important than for other types.
+    if (rval.isBigInt()) {
+      return JS_WrapValue(cx, rval);
+    }
+#endif
     MOZ_ASSERT(rval.isSymbol());
     JS_MarkCrossZoneId(cx, SYMBOL_TO_JSID(rval.toSymbol()));
   }
   return true;
 }
 
 namespace binding_detail {
 enum GetOrCreateReflectorWrapBehavior {
--- a/dom/webauthn/WebAuthnManager.cpp
+++ b/dom/webauthn/WebAuthnManager.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 "hasht.h"
 #include "nsHTMLDocument.h"
+#include "nsIURIMutator.h"
 #include "nsThreadUtils.h"
 #include "WebAuthnCoseIdentifiers.h"
 #include "mozilla/dom/AuthenticatorAttestationResponse.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PWebAuthnTransaction.h"
 #include "mozilla/dom/WebAuthnManager.h"
 #include "mozilla/dom/WebAuthnTransactionChild.h"
 #include "mozilla/dom/WebAuthnUtil.h"
@@ -119,21 +120,37 @@ RelaxSameOrigin(nsPIDOMWindowInner* aPar
   if (NS_FAILED(uri->GetAsciiHost(originHost))) {
     return NS_ERROR_FAILURE;
   }
   nsCOMPtr<nsIDocument> document = aParent->GetDoc();
   if (!document || !document->IsHTMLDocument()) {
     return NS_ERROR_FAILURE;
   }
   nsHTMLDocument* html = document->AsHTMLDocument();
-  if (!html->IsRegistrableDomainSuffixOfOrEqualTo(aInputRpId, originHost)) {
+  // See if the given RP ID is a valid domain string.
+  // (We use the document's URI here as a template so we don't have to come up
+  // with our own scheme, etc. If we can successfully set the host as the given
+  // RP ID, then it should be a valid domain string.)
+  nsCOMPtr<nsIURI> inputRpIdURI;
+  nsresult rv = NS_MutateURI(uri)
+         .SetHost(NS_ConvertUTF16toUTF8(aInputRpId))
+         .Finalize(inputRpIdURI);
+  if (NS_FAILED(rv)) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+  nsAutoCString inputRpId;
+  if (NS_FAILED(inputRpIdURI->GetAsciiHost(inputRpId))) {
+    return NS_ERROR_FAILURE;
+  }
+  if (!html->IsRegistrableDomainSuffixOfOrEqualTo(
+      NS_ConvertUTF8toUTF16(inputRpId), originHost)) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
-  aRelaxedRpId.Assign(NS_ConvertUTF16toUTF8(aInputRpId));
+  aRelaxedRpId.Assign(inputRpId);
   return NS_OK;
 }
 
 /***********************************************************************
  * WebAuthnManager Implementation
  **********************************************************************/
 
 void
--- a/dom/webauthn/tests/test_webauthn_make_credential.html
+++ b/dom/webauthn/tests/test_webauthn_make_credential.html
@@ -244,16 +244,38 @@
             rp: rp, user: user, challenge: gCredentialChallenge,
             pubKeyCredParams: [param, param, param]
           };
           return credm.create({publicKey: makeCredentialOptions})
                       .then(arrivingHereIsGood)
                       .catch(arrivingHereIsBad);
         },
 
+        // Test with an RP ID that is not a valid domain string
+        function() {
+          let rp = { id: document.domain + ":somejunk", name: "none", icon: "none" };
+          let makeCredentialOptions = {
+            rp: rp, user: user, challenge: gCredentialChallenge, pubKeyCredParams: [param]
+          };
+          return credm.create({publicKey: makeCredentialOptions})
+                      .then(arrivingHereIsBad)
+                      .catch(arrivingHereIsGood);
+        },
+
+        // Test with another RP ID that is not a valid domain string
+        function() {
+          let rp = { id: document.domain + ":8888", name: "none", icon: "none" };
+          let makeCredentialOptions = {
+            rp: rp, user: user, challenge: gCredentialChallenge, pubKeyCredParams: [param]
+          };
+          return credm.create({publicKey: makeCredentialOptions})
+                      .then(arrivingHereIsBad)
+                      .catch(arrivingHereIsGood);
+        },
+
         // Test with missing rp
         function() {
           let makeCredentialOptions = {
             user: user, challenge: gCredentialChallenge, pubKeyCredParams: [param]
           };
           return credm.create({publicKey: makeCredentialOptions})
                       .then(arrivingHereIsBad)
                       .catch(expectTypeError);
--- a/dom/webauthn/tests/test_webauthn_sameorigin.html
+++ b/dom/webauthn/tests/test_webauthn_sameorigin.html
@@ -256,17 +256,39 @@
           let publicKeyCredentialRequestOptions = {
             challenge: chall,
             rpId: window.origin,
             allowCredentials: [gTrackedCredential["basic"]]
           };
           return credm.get({publicKey: publicKeyCredentialRequestOptions})
                       .then(arrivingHereIsBad)
                       .catch(expectSecurityError);
-        }
+        },
+        function () {
+          // Test with an rpId that is not a valid domain string
+          let publicKeyCredentialRequestOptions = {
+            challenge: chall,
+            rpId: document.domain + ":somejunk",
+            allowCredentials: [gTrackedCredential["basic"]]
+          };
+          return credm.get({publicKey: publicKeyCredentialRequestOptions})
+                      .then(arrivingHereIsBad)
+                      .catch(arrivingHereIsGood);
+        },
+        function () {
+          // Test with another rpId that is not a valid domain string
+          let publicKeyCredentialRequestOptions = {
+            challenge: chall,
+            rpId: document.domain + ":8888",
+            allowCredentials: [gTrackedCredential["basic"]]
+          };
+          return credm.get({publicKey: publicKeyCredentialRequestOptions})
+                      .then(arrivingHereIsBad)
+                      .catch(arrivingHereIsGood);
+        },
       ];
       var i = 0;
       var runNextTest = () => {
         if (i == testFuncs.length) {
           SimpleTest.finish();
           return;
         }
         console.log(i, testFuncs[i], testFuncs.length);
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -2038,25 +2038,16 @@ APZCTreeManager::SetTargetAPZC(uint64_t 
   for (size_t i = 1; i < aTargets.Length(); i++) {
     RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aTargets[i]);
     target = GetMultitouchTarget(target, apzc);
   }
   mInputQueue->SetConfirmedTargetApzc(aInputBlockId, target);
 }
 
 void
-APZCTreeManager::SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aTarget)
-{
-  APZThreadUtils::AssertOnControllerThread();
-
-  RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aTarget);
-  mInputQueue->SetConfirmedTargetApzc(aInputBlockId, apzc);
-}
-
-void
 APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
                                        const Maybe<ZoomConstraints>& aConstraints)
 {
   if (!GetUpdater()->IsUpdaterThread()) {
     // This can happen if we're in the UI process and got a call directly from
     // nsBaseWidget or from a content process over PAPZCTreeManager. In that case
     // we get this call on the compositor thread, which may be different from
     // the updater thread. It can also happen in the GPU process if that is
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -316,22 +316,16 @@ public:
    *       in the drag block may be handled as no-ops until the drag metrics
    *       arrive.
    */
   void SetTargetAPZC(
       uint64_t aInputBlockId,
       const nsTArray<ScrollableLayerGuid>& aTargets) override;
 
   /**
-   * Helper function for SetTargetAPZC when used with single-target events,
-   * such as mouse wheel events.
-   */
-  void SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aTarget);
-
-  /**
    * Updates any zoom constraints contained in the <meta name="viewport"> tag.
    * If the |aConstraints| is Nothing() then previously-provided constraints for
    * the given |aGuid| are cleared.
    */
   void UpdateZoomConstraints(
       const ScrollableLayerGuid& aGuid,
       const Maybe<ZoomConstraints>& aConstraints) override;
 
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_nested_transforms_bug1459696.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>APZ hit-testing with nested inactive transforms (bug 1459696)</title>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  <meta name="viewport" content="width=device-width"/>
+  <style>
+    .pane {
+        position: fixed;
+        top: 0;
+        bottom: 0;
+    }
+    .left {
+        left: 0;
+        right: 66vw;
+        overflow: auto;
+    }
+    .content {
+        width: 100%;
+        height: 200%;
+        background-image: linear-gradient(blue, green);
+    }
+    .right {
+        left: 34vw;
+        right: 0;
+    }
+    .list {
+        overflow: hidden;
+        transform: translate3d(0, 0, 0);
+        height: 100%;
+    }
+    .track {
+        height: 100%;
+        width: 2000px;
+        transform: translate3d(-856px, 0px, 0px);
+    }
+    .slide {
+        float: left;
+        height: 100%;
+        width: 856px;
+        background-image: linear-gradient(red, yellow);
+    }
+    </style>
+</head>
+<body>
+  <div class="left pane" id="left-pane">
+      <div class="content"></div>
+  </div>
+  <div class="right pane">
+      <div class="list">
+          <div class="track">
+              <div class="slide"></div>
+              <div class="slide"></div>
+          </div>
+      </div>
+  </div>
+</body>
+<script type="application/javascript">
+
+function* test(testDriver) {
+  var utils = getHitTestConfig().utils;
+
+  var leftPane = document.getElementById("left-pane");
+
+  checkHitResult(
+    hitTest(centerOf(leftPane)),
+    APZHitResultFlags.VISIBLE,
+    utils.getViewId(leftPane),
+    "left pane was successfully hit");
+
+  subtestDone();
+}
+
+waitUntilApzStable().then(runContinuation(test));
+
+</script>
+</html>
--- a/gfx/layers/apz/test/mochitest/test_group_hittest.html
+++ b/gfx/layers/apz/test/mochitest/test_group_hittest.html
@@ -28,17 +28,18 @@ var prefs = [
 
 var subtests = [
   {'file': 'helper_hittest_basic.html', 'prefs': prefs},
   {'file': 'helper_hittest_fixed_in_scrolled_transform.html', 'prefs': prefs},
   {'file': 'helper_hittest_float_bug1434846.html', 'prefs': prefs},
   {'file': 'helper_hittest_float_bug1443518.html', 'prefs': prefs},
   {'file': 'helper_hittest_checkerboard.html', 'prefs': prefs},
   {'file': 'helper_hittest_backface_hidden.html', 'prefs': prefs},
-  {'file': 'helper_hittest_touchaction.html', 'prefs': prefs}
+  {'file': 'helper_hittest_touchaction.html', 'prefs': prefs},
+  {'file': 'helper_hittest_nested_transforms_bug1459696.html', 'prefs': prefs}
 ];
 
 if (isApzEnabled()) {
   SimpleTest.waitForExplicitFinish();
   window.onload = function() {
     runSubtestsSeriallyInFreshWindows(subtests)
     .then(SimpleTest.finish, SimpleTest.finish);
   };
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1057,17 +1057,17 @@ gfxPlatform::InitLayersIPC()
   }
   sLayersIPCIsUp = true;
 
   if (XRE_IsContentProcess()) {
     if (gfxVars::UseOMTP()) {
       layers::PaintThread::Start();
     }
   } else if (XRE_IsParentProcess()) {
-    if (gfxVars::UseWebRender()) {
+    if (!gfxConfig::IsEnabled(Feature::GPU_PROCESS) && gfxVars::UseWebRender()) {
       wr::RenderThread::Start();
     }
 
     layers::CompositorThreadHolder::Start();
     gfx::VRListenerThreadHolder::Start();
   }
 }
 
--- a/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
+++ b/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
@@ -159,17 +159,17 @@ RenderDXGITextureHostOGL::Lock(uint8_t a
   }
 
   if (!EnsureLockable()) {
     return InvalidToWrExternalImage();
   }
 
   if (!mLocked) {
     if (mKeyedMutex) {
-      HRESULT hr = mKeyedMutex->AcquireSync(0, 100);
+      HRESULT hr = mKeyedMutex->AcquireSync(0, 10000);
       if (hr != S_OK) {
         gfxCriticalError() << "RenderDXGITextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
         return InvalidToWrExternalImage();
       }
     }
     mLocked = true;
   }
 
@@ -352,17 +352,17 @@ RenderDXGIYCbCrTextureHostOGL::Lock(uint
 
   if (!EnsureLockable()) {
     return InvalidToWrExternalImage();
   }
 
   if (!mLocked) {
     if (mKeyedMutexs[0]) {
       for (const auto& mutex : mKeyedMutexs) {
-        HRESULT hr = mutex->AcquireSync(0, 100);
+        HRESULT hr = mutex->AcquireSync(0, 10000);
         if (hr != S_OK) {
           gfxCriticalError() << "RenderDXGIYCbCrTextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
           return InvalidToWrExternalImage();
         }
       }
     }
     mLocked = true;
   }
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -465,16 +465,19 @@ class BufferGrayRootsTracer final : publ
 {
     // Set to false if we OOM while buffering gray roots.
     bool bufferingGrayRootsFailed;
 
     void onObjectEdge(JSObject** objp) override { bufferRoot(*objp); }
     void onStringEdge(JSString** stringp) override { bufferRoot(*stringp); }
     void onScriptEdge(JSScript** scriptp) override { bufferRoot(*scriptp); }
     void onSymbolEdge(JS::Symbol** symbolp) override { bufferRoot(*symbolp); }
+#ifdef ENABLE_BIGINT
+    void onBigIntEdge(JS::BigInt** bip) override { bufferRoot(*bip); }
+#endif
 
     void onChild(const JS::GCCellPtr& thing) override {
         MOZ_CRASH("Unexpected gray root kind");
     }
 
     template <typename T> inline void bufferRoot(T* thing);
 
   public:
@@ -525,17 +528,17 @@ js::gc::GCRuntime::bufferGrayRoots()
 
 template <typename T>
 inline void
 BufferGrayRootsTracer::bufferRoot(T* thing)
 {
     MOZ_ASSERT(JS::RuntimeHeapIsBusy());
     MOZ_ASSERT(thing);
     // Check if |thing| is corrupt by calling a method that touches the heap.
-    MOZ_ASSERT(thing->getTraceKind() <= JS::TraceKind::Null);
+    MOZ_ASSERT(thing->getTraceKind() != JS::TraceKind(0xff));
 
     TenuredCell* tenured = &thing->asTenured();
 
     // This is run from a helper thread while the mutator is paused so we have
     // to use *FromAnyThread methods here.
     Zone* zone = tenured->zoneFromAnyThread();
     if (zone->isCollectingFromAnyThread()) {
         // See the comment on SetMaybeAliveFlag to see why we only do this for
--- a/js/src/vm/BigIntType.cpp
+++ b/js/src/vm/BigIntType.cpp
@@ -97,16 +97,39 @@ BigInt::createFromBoolean(JSContext* cx,
 {
     BigInt* x = Allocate<BigInt>(cx);
     if (!x)
         return nullptr;
     mpz_init_set_ui(x->num_, b);
     return x;
 }
 
+BigInt*
+BigInt::createFromBytes(JSContext* cx, int sign, void* bytes, size_t nbytes)
+{
+    BigInt* x = Allocate<BigInt>(cx);
+    if (!x)
+        return nullptr;
+    // Initialize num_ to zero before calling mpz_import.
+    mpz_init(x->num_);
+
+    if (nbytes == 0)
+        return x;
+
+    mpz_import(x->num_, nbytes,
+               -1, // order: least significant word first
+               1, // size: one byte per "word"
+               0, // endianness: native
+               0, // nail bits: none; use full words
+               bytes);
+    if (sign < 0)
+        mpz_neg(x->num_, x->num_);
+    return x;
+}
+
 // BigInt proposal section 5.1.1
 static bool
 IsInteger(double d)
 {
     // Step 1 is an assertion checked by the caller.
     // Step 2.
     if (!mozilla::IsFinite(d))
         return false;
@@ -289,16 +312,41 @@ js::StringToBigInt(JSContext* cx, Handle
         }
     }
 
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_BIGINT_INVALID_SYNTAX);
     return nullptr;
 }
 
+size_t
+BigInt::byteLength(BigInt* x)
+{
+    if (mpz_sgn(x->num_) == 0)
+        return 0;
+    return JS_HOWMANY(mpz_sizeinbase(x->num_, 2), 8);
+}
+
+void
+BigInt::writeBytes(BigInt* x, RangedPtr<uint8_t> buffer)
+{
+#ifdef DEBUG
+    // Check that the buffer being filled is large enough to hold the
+    // integer we're writing. The result of the RangedPtr addition is
+    // restricted to the buffer's range.
+    size_t reprSize = byteLength(x);
+    MOZ_ASSERT(buffer + reprSize, "out of bounds access to buffer");
+#endif
+
+    size_t count;
+    // cf. mpz_import parameters in createFromBytes, above.
+    mpz_export(buffer.get(), &count, -1, 1, 0, 0, x->num_);
+    MOZ_ASSERT(count == reprSize);
+}
+
 void
 BigInt::finalize(js::FreeOp* fop)
 {
     mpz_clear(num_);
 }
 
 JSAtom*
 js::BigIntToAtom(JSContext* cx, BigInt* bi)
@@ -310,16 +358,22 @@ js::BigIntToAtom(JSContext* cx, BigInt* 
 }
 
 bool
 BigInt::toBoolean()
 {
     return mpz_sgn(num_) != 0;
 }
 
+int8_t
+BigInt::sign()
+{
+    return mpz_sgn(num_);
+}
+
 js::HashNumber
 BigInt::hash()
 {
     const mp_limb_t* limbs = mpz_limbs_read(num_);
     size_t limbCount = mpz_size(num_);
     uint32_t hash = mozilla::HashBytes(limbs, limbCount * sizeof(mp_limb_t));
     hash = mozilla::AddToHash(hash, mpz_sgn(num_));
     return hash;
--- a/js/src/vm/BigIntType.h
+++ b/js/src/vm/BigIntType.h
@@ -3,16 +3,17 @@
  * 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 vm_BigIntType_h
 #define vm_BigIntType_h
 
 #include "mozilla/Range.h"
+#include "mozilla/RangedPtr.h"
 
 #include <gmp.h>
 
 #include "gc/Barrier.h"
 #include "gc/GC.h"
 #include "gc/Heap.h"
 #include "js/AllocPolicy.h"
 #include "js/GCHashTable.h"
@@ -48,34 +49,46 @@ class BigInt final : public js::gc::Tenu
   public:
     // Allocate and initialize a BigInt value
     static BigInt* create(JSContext* cx);
 
     static BigInt* createFromDouble(JSContext* cx, double d);
 
     static BigInt* createFromBoolean(JSContext* cx, bool b);
 
+    // Read a BigInt value from a little-endian byte array.
+    static BigInt* createFromBytes(JSContext* cx, int sign, void* bytes, size_t nbytes);
+
     static const JS::TraceKind TraceKind = JS::TraceKind::BigInt;
 
     void traceChildren(JSTracer* trc);
 
     void finalize(js::FreeOp* fop);
 
     js::HashNumber hash();
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
     bool toBoolean();
+    int8_t sign();
 
     static void init();
 
     static BigInt* copy(JSContext* cx, Handle<BigInt*> x);
 
     static double numberValue(BigInt* x);
     static JSLinearString* toString(JSContext* cx, BigInt* x, uint8_t radix);
+
+    // Return the length in bytes of the representation used by
+    // writeBytes.
+    static size_t byteLength(BigInt* x);
+
+    // Write a little-endian representation of a BigInt's absolute value
+    // to a byte array.
+    static void writeBytes(BigInt* x, mozilla::RangedPtr<uint8_t> buffer);
 };
 
 static_assert(sizeof(BigInt) >= js::gc::MinCellSize,
               "sizeof(BigInt) must be greater than the minimum allocation size");
 
 } // namespace JS
 
 namespace js {
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -26,44 +26,49 @@
  *     in the spec's StructuredDeserialize.
  */
 
 #include "js/StructuredClone.h"
 
 #include "mozilla/CheckedInt.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/FloatingPoint.h"
+#include "mozilla/RangedPtr.h"
 
 #include <algorithm>
 #include <utility>
 
 #include "jsapi.h"
 #include "jsdate.h"
 
 #include "builtin/DataViewObject.h"
 #include "builtin/MapObject.h"
 #include "js/Date.h"
 #include "js/GCHashTable.h"
 #include "js/Wrapper.h"
+#ifdef ENABLE_BIGINT
+#include "vm/BigIntType.h"
+#endif
 #include "vm/JSContext.h"
 #include "vm/RegExpObject.h"
 #include "vm/SavedFrame.h"
 #include "vm/SharedArrayObject.h"
 #include "vm/TypedArrayObject.h"
 #include "vm/WrapperObject.h"
 #include "wasm/WasmJS.h"
 
 #include "vm/JSContext-inl.h"
 #include "vm/JSObject-inl.h"
 
 using namespace js;
 
 using mozilla::BitwiseCast;
 using mozilla::NativeEndian;
 using mozilla::NumbersAreIdentical;
+using mozilla::RangedPtr;
 using JS::CanonicalizeNaN;
 
 // When you make updates here, make sure you consider whether you need to bump the
 // value of JS_STRUCTURED_CLONE_VERSION in js/public/StructuredClone.h.  You will
 // likely need to increment the version if anything at all changes in the serialization
 // format.
 //
 // Note that SCTAG_END_OF_KEYS is written into the serialized form and should have
@@ -102,16 +107,19 @@ enum StructuredDataType : uint32_t {
     SCTAG_JSPRINCIPALS,
     SCTAG_NULL_JSPRINCIPALS,
     SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_SYSTEM,
     SCTAG_RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_NOT_SYSTEM,
 
     SCTAG_SHARED_ARRAY_BUFFER_OBJECT,
     SCTAG_SHARED_WASM_MEMORY_OBJECT,
 
+    SCTAG_BIGINT,
+    SCTAG_BIGINT_OBJECT,
+
     SCTAG_TYPED_ARRAY_V1_MIN = 0xFFFF0100,
     SCTAG_TYPED_ARRAY_V1_INT8 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int8,
     SCTAG_TYPED_ARRAY_V1_UINT8 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint8,
     SCTAG_TYPED_ARRAY_V1_INT16 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int16,
     SCTAG_TYPED_ARRAY_V1_UINT16 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint16,
     SCTAG_TYPED_ARRAY_V1_INT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Int32,
     SCTAG_TYPED_ARRAY_V1_UINT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Uint32,
     SCTAG_TYPED_ARRAY_V1_FLOAT32 = SCTAG_TYPED_ARRAY_V1_MIN + Scalar::Float32,
@@ -408,16 +416,20 @@ struct JSStructuredCloneReader {
 
     bool readHeader();
     bool readTransferMap();
 
     template <typename CharT>
     JSString* readStringImpl(uint32_t nchars);
     JSString* readString(uint32_t data);
 
+#ifdef ENABLE_BIGINT
+    BigInt* readBigInt(uint32_t data);
+#endif
+
     bool checkDouble(double d);
     MOZ_MUST_USE bool readTypedArray(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp,
                                      bool v1Read = false);
     MOZ_MUST_USE bool readDataView(uint32_t byteLength, MutableHandleValue vp);
     MOZ_MUST_USE bool readArrayBuffer(uint32_t nbytes, MutableHandleValue vp);
     MOZ_MUST_USE bool readSharedArrayBuffer(MutableHandleValue vp);
     MOZ_MUST_USE bool readSharedWasmMemory(uint32_t nbytes, MutableHandleValue vp);
     MOZ_MUST_USE bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp);
@@ -510,16 +522,20 @@ struct JSStructuredCloneWriter {
     bool writeSharedWasmMemory(HandleObject obj);
     bool startObject(HandleObject obj, bool* backref);
     bool startWrite(HandleValue v);
     bool traverseObject(HandleObject obj);
     bool traverseMap(HandleObject obj);
     bool traverseSet(HandleObject obj);
     bool traverseSavedFrame(HandleObject obj);
 
+#ifdef ENABLE_BIGINT
+    bool writeBigInt(uint32_t tag, BigInt* bi);
+#endif
+
     bool reportDataCloneError(uint32_t errorId);
 
     bool parseTransferable();
     bool transferOwnership();
 
     inline void checkStack();
 
     SCOutput out;
@@ -1155,16 +1171,38 @@ JSStructuredCloneWriter::writeString(uin
         return false;
 
     JS::AutoCheckCannotGC nogc;
     return linear->hasLatin1Chars()
            ? out.writeChars(linear->latin1Chars(nogc), length)
            : out.writeChars(linear->twoByteChars(nogc), length);
 }
 
+#ifdef ENABLE_BIGINT
+bool
+JSStructuredCloneWriter::writeBigInt(uint32_t tag, BigInt* bi)
+{
+    bool signBit = bi->sign() < 1;
+    size_t length = BigInt::byteLength(bi);
+    // The length must fit in 31 bits to leave room for a sign bit.
+    if (length > size_t(INT32_MAX))
+        return false;
+    uint32_t lengthAndSign = length | (static_cast<uint32_t>(signBit) << 31);
+
+    js::UniquePtr<uint8_t> buf(static_cast<uint8_t*>(js_malloc(length)));
+    if (!buf)
+        return false;
+
+    BigInt::writeBytes(bi, RangedPtr<uint8_t>(buf.get(), length));
+    if (!out.writePair(tag, lengthAndSign))
+        return false;
+    return out.writeBytes(buf.get(), length);
+}
+#endif
+
 inline void
 JSStructuredCloneWriter::checkStack()
 {
 #ifdef DEBUG
     // To avoid making serialization O(n^2), limit stack-checking at 10.
     const size_t MAX = 10;
 
     size_t limit = Min(counts.length(), MAX);
@@ -1529,17 +1567,23 @@ JSStructuredCloneWriter::startWrite(Hand
     } else if (v.isDouble()) {
         return out.writeDouble(v.toDouble());
     } else if (v.isBoolean()) {
         return out.writePair(SCTAG_BOOLEAN, v.toBoolean());
     } else if (v.isNull()) {
         return out.writePair(SCTAG_NULL, 0);
     } else if (v.isUndefined()) {
         return out.writePair(SCTAG_UNDEFINED, 0);
-    } else if (v.isObject()) {
+    }
+#ifdef ENABLE_BIGINT
+    else if (v.isBigInt()) {
+        return writeBigInt(SCTAG_BIGINT, v.toBigInt());
+    }
+#endif
+    else if (v.isObject()) {
         RootedObject obj(context(), &v.toObject());
 
         bool backref;
         if (!startObject(obj, &backref))
             return false;
         if (backref)
             return true;
 
@@ -1586,17 +1630,26 @@ JSStructuredCloneWriter::startWrite(Hand
             RootedValue unboxed(context());
             if (!Unbox(context(), obj, &unboxed))
                 return false;
             return writeString(SCTAG_STRING_OBJECT, unboxed.toString());
         } else if (cls == ESClass::Map) {
             return traverseMap(obj);
         } else if (cls == ESClass::Set) {
             return traverseSet(obj);
-        } else if (SavedFrame::isSavedFrameOrWrapperAndNotProto(*obj)) {
+        }
+#ifdef ENABLE_BIGINT
+        else if (cls == ESClass::BigInt) {
+            RootedValue unboxed(context());
+            if (!Unbox(context(), obj, &unboxed))
+                return false;
+            return writeBigInt(SCTAG_BIGINT_OBJECT, unboxed.toBigInt());
+        }
+#endif
+        else if (SavedFrame::isSavedFrameOrWrapperAndNotProto(*obj)) {
             return traverseSavedFrame(obj);
         }
 
         if (out.buf.callbacks_ && out.buf.callbacks_->write)
             return out.buf.callbacks_->write(context(), this, obj, out.buf.closure_);
         // else fall through
     }
 
@@ -1899,16 +1952,35 @@ JSStructuredCloneReader::readStringImpl(
 JSString*
 JSStructuredCloneReader::readString(uint32_t data)
 {
     uint32_t nchars = data & JS_BITMASK(31);
     bool latin1 = data & (1 << 31);
     return latin1 ? readStringImpl<Latin1Char>(nchars) : readStringImpl<char16_t>(nchars);
 }
 
+#ifdef ENABLE_BIGINT
+BigInt*
+JSStructuredCloneReader::readBigInt(uint32_t data)
+{
+    size_t nbytes = data & JS_BITMASK(31);
+    bool isNegative = data & (1 << 31);
+
+    if (nbytes == 0)
+        return BigInt::create(context());
+
+    UniquePtr<uint8_t> buf(static_cast<uint8_t*>(js_malloc(nbytes)));
+    if (!buf)
+        return nullptr;
+    if (!in.readBytes(buf.get(), nbytes))
+        return nullptr;
+    return BigInt::createFromBytes(context(), isNegative ? -1 : 1, buf.get(), nbytes);
+}
+#endif
+
 static uint32_t
 TagToV1ArrayType(uint32_t tag)
 {
     MOZ_ASSERT(tag >= SCTAG_TYPED_ARRAY_V1_MIN && tag <= SCTAG_TYPED_ARRAY_V1_MAX);
     return tag - SCTAG_TYPED_ARRAY_V1_MIN;
 }
 
 bool
@@ -2219,16 +2291,34 @@ JSStructuredCloneReader::startRead(Mutab
         if (!in.readDouble(&d) || !checkDouble(d))
             return false;
         vp.setDouble(d);
         if (!PrimitiveToObject(context(), vp))
             return false;
         break;
       }
 
+      case SCTAG_BIGINT:
+      case SCTAG_BIGINT_OBJECT: {
+#ifdef ENABLE_BIGINT
+        RootedBigInt bi(context(), readBigInt(data));
+        if (!bi)
+            return false;
+        vp.setBigInt(bi);
+        if (tag == SCTAG_BIGINT_OBJECT && !PrimitiveToObject(context(), vp))
+            return false;
+        break;
+#else
+        JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
+                                  JSMSG_SC_BAD_SERIALIZED_DATA,
+                                  "BigInt unsupported");
+        return false;
+#endif
+      }
+
       case SCTAG_DATE_OBJECT: {
         double d;
         if (!in.readDouble(&d) || !checkDouble(d))
             return false;
         JS::ClippedTime t = JS::TimeClip(d);
         if (!NumbersAreIdentical(d, t.toDouble())) {
             JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
                                       JSMSG_SC_BAD_SERIALIZED_DATA,
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2520,33 +2520,33 @@ nsLayoutUtils::PostTranslate(Matrix4x4& 
     gfxOrigin.y = NS_round(gfxOrigin.y);
   }
   aTransform.PostTranslate(gfxOrigin);
 }
 
 // We want to this return true for the scroll frame, but not the
 // scrolled frame (which has the same content).
 bool
-nsLayoutUtils::FrameHasDisplayPort(nsIFrame* aFrame, nsIFrame* aScrolledFrame)
+nsLayoutUtils::FrameHasDisplayPort(nsIFrame* aFrame, const nsIFrame* aScrolledFrame)
 {
   if (!aFrame->GetContent() || !HasDisplayPort(aFrame->GetContent())) {
     return false;
   }
   nsIScrollableFrame* sf = do_QueryFrame(aFrame);
   if (sf) {
     if (aScrolledFrame && aScrolledFrame != sf->GetScrolledFrame()) {
       return false;
     }
     return true;
   }
   return false;
 }
 
 Matrix4x4Flagged
-nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame,
+nsLayoutUtils::GetTransformToAncestor(const nsIFrame *aFrame,
                                       const nsIFrame *aAncestor,
                                       uint32_t aFlags,
                                       nsIFrame** aOutAncestor)
 {
   nsIFrame* parent;
   Matrix4x4Flagged ctm;
   if (aFrame == aAncestor) {
     return ctm;
@@ -2859,17 +2859,17 @@ TransformGfxPointFromAncestor(nsIFrame *
   if (!point.HasPositiveWCoord()) {
     return false;
   }
   *aOut = point.As2DPoint();
   return true;
 }
 
 static Rect
-TransformGfxRectToAncestor(nsIFrame *aFrame,
+TransformGfxRectToAncestor(const nsIFrame *aFrame,
                            const Rect &aRect,
                            const nsIFrame *aAncestor,
                            bool* aPreservesAxisAlignedRectangles = nullptr,
                            Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
                            bool aStopAtStackingContextAndDisplayPort = false,
                            nsIFrame** aOutAncestor = nullptr)
 {
   Matrix4x4Flagged ctm;
@@ -2899,17 +2899,17 @@ TransformGfxRectToAncestor(nsIFrame *aFr
   Rect maxBounds = Rect(float(nscoord_MIN) / factor * 0.5,
                         float(nscoord_MIN) / factor * 0.5,
                         float(nscoord_MAX) / factor,
                         float(nscoord_MAX) / factor);
   return ctm.TransformAndClipBounds(aRect, maxBounds);
 }
 
 static SVGTextFrame*
-GetContainingSVGTextFrame(nsIFrame* aFrame)
+GetContainingSVGTextFrame(const nsIFrame* aFrame)
 {
   if (!nsSVGUtils::IsInSVGTextSubtree(aFrame)) {
     return nullptr;
   }
 
   return static_cast<SVGTextFrame*>(nsLayoutUtils::GetClosestFrameOfType(
     aFrame->GetParent(), LayoutFrameType::SVGText));
 }
@@ -2936,17 +2936,17 @@ nsLayoutUtils::TransformAncestorPointToF
         }
     }
 
     return nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
                    NSFloatPixelsToAppUnits(float(result.y), factor));
 }
 
 nsRect
-nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
+nsLayoutUtils::TransformFrameRectToAncestor(const nsIFrame* aFrame,
                                             const nsRect& aRect,
                                             const nsIFrame* aAncestor,
                                             bool* aPreservesAxisAlignedRectangles /* = nullptr */,
                                             Maybe<Matrix4x4Flagged>* aMatrixCache /* = nullptr */,
                                             bool aStopAtStackingContextAndDisplayPort /* = false */,
                                             nsIFrame** aOutAncestor /* = nullptr */)
 {
   SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
@@ -7274,32 +7274,32 @@ nsLayoutUtils::GetFrameTransparency(nsIF
   const nsStyleBackground* bg = bgSC->StyleBackground();
   if (NS_GET_A(bg->BackgroundColor(bgSC)) < 255 ||
       // bottom layer's clip is used for the color
       bg->BottomLayer().mClip != StyleGeometryBox::BorderBox)
     return eTransparencyTransparent;
   return eTransparencyOpaque;
 }
 
-static bool IsPopupFrame(nsIFrame* aFrame)
+static bool IsPopupFrame(const nsIFrame* aFrame)
 {
   // aFrame is a popup it's the list control frame dropdown for a combobox.
   LayoutFrameType frameType = aFrame->Type();
   if (!nsLayoutUtils::IsContentSelectEnabled() &&
       frameType == LayoutFrameType::ListControl) {
-    nsListControlFrame* lcf = static_cast<nsListControlFrame*>(aFrame);
+    const nsListControlFrame* lcf = static_cast<const nsListControlFrame*>(aFrame);
     return lcf->IsInDropDownMode();
   }
 
   // ... or if it's a XUL menupopup frame.
   return frameType == LayoutFrameType::MenuPopup;
 }
 
 /* static */ bool
-nsLayoutUtils::IsPopup(nsIFrame* aFrame)
+nsLayoutUtils::IsPopup(const nsIFrame* aFrame)
 {
   // Optimization: the frame can't possibly be a popup if it has no view.
   if (!aFrame->HasView()) {
     NS_ASSERTION(!IsPopupFrame(aFrame), "popup frame must have a view");
     return false;
   }
   return IsPopupFrame(aFrame);
 }
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -218,17 +218,17 @@ public:
   static bool HasDisplayPort(nsIContent* aContent);
 
   /**
    * Check whether the given frame has a displayport. It returns false
    * for scrolled frames and true for the corresponding scroll frame.
    * Optionally pass the child, and it only returns true if the child is the
    * scrolled frame for the displayport.
    */
-  static bool FrameHasDisplayPort(nsIFrame* aFrame, nsIFrame* aScrolledFrame = nullptr);
+  static bool FrameHasDisplayPort(nsIFrame* aFrame, const nsIFrame* aScrolledFrame = nullptr);
 
   /**
    * Check if the given element has a margins based displayport but is missing a
    * displayport base rect that it needs to properly compute a displayport rect.
    */
   static bool IsMissingDisplayPortBaseRect(nsIContent* aContent);
 
   /**
@@ -849,31 +849,31 @@ public:
    *   every call to this function.
    * non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is
    *   filled with the transform matrix that was computed. This can then be passed
    *   in to subsequent calls with the same source and destination frames to avoid
    *   recomputing the matrix.
    * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be used
    *   as the transform matrix and applied to the rect.
    */
-  static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame,
+  static nsRect TransformFrameRectToAncestor(const nsIFrame* aFrame,
                                              const nsRect& aRect,
                                              const nsIFrame* aAncestor,
                                              bool* aPreservesAxisAlignedRectangles = nullptr,
                                              mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
                                              bool aStopAtStackingContextAndDisplayPort = false,
                                              nsIFrame** aOutAncestor = nullptr);
 
 
   /**
    * Gets the transform for aFrame relative to aAncestor. Pass null for
    * aAncestor to go up to the root frame. aInCSSUnits set to true will
    * return CSS units, set to false (the default) will return App units.
    */
-  static Matrix4x4Flagged GetTransformToAncestor(nsIFrame *aFrame,
+  static Matrix4x4Flagged GetTransformToAncestor(const nsIFrame *aFrame,
                                           const nsIFrame *aAncestor,
                                           uint32_t aFlags = 0,
                                           nsIFrame** aOutAncestor = nullptr);
 
   /**
    * Gets the scale factors of the transform for aFrame relative to the root
    * frame if this transform is 2D, or the identity scale factors otherwise.
    */
@@ -2024,17 +2024,17 @@ public:
    */
   static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame,
                                                  nsIFrame* aCSSRootFrame);
 
   /**
    * A frame is a popup if it has its own floating window. Menus, panels
    * and combobox dropdowns are popups.
    */
-  static bool IsPopup(nsIFrame* aFrame);
+  static bool IsPopup(const nsIFrame* aFrame);
 
   /**
    * Find the nearest "display root". This is the nearest enclosing
    * popup frame or the root prescontext's root frame.
    */
   static nsIFrame* GetDisplayRootFrame(nsIFrame* aFrame);
 
   /**
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6804,17 +6804,17 @@ nsIFrame::GetNearestWidget(nsPoint& aOff
     GetClosestView(&offsetToView)->GetNearestWidget(&offsetToWidget);
   aOffset = offsetToView + offsetToWidget;
   return widget;
 }
 
 Matrix4x4Flagged
 nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
                              nsIFrame** aOutAncestor,
-                             uint32_t aFlags)
+                             uint32_t aFlags) const
 {
   MOZ_ASSERT(aOutAncestor, "Need a place to put the ancestor!");
 
   /* If we're transformed, we want to hand back the combination
    * transform/translate matrix that will apply our current transform, then
    * shift us to our parent.
    */
   if (IsTransformed()) {
@@ -6887,17 +6887,17 @@ nsIFrame::GetTransformMatrix(const nsIFr
    * we have to check to see if we have a parent.  If not, we'll set the
    * outparam to null (indicating that there's nothing left) and will hand back
    * the identity matrix.
    */
   if (!*aOutAncestor)
     return Matrix4x4();
 
   /* Keep iterating while the frame can't possibly be transformed. */
-  nsIFrame* current = this;
+  const nsIFrame* current = this;
   while (!(*aOutAncestor)->IsTransformed() &&
          !nsLayoutUtils::IsPopup(*aOutAncestor) &&
          *aOutAncestor != aStopAtAncestor &&
          (!(aFlags & STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT) ||
           (!(*aOutAncestor)->IsStackingContext() && !nsLayoutUtils::FrameHasDisplayPort(*aOutAncestor, current)))) {
     /* If no parent, stop iterating.  Otherwise, update the ancestor. */
     nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(*aOutAncestor);
     if (!parent)
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2827,17 +2827,17 @@ public:
    *   into points in aOutAncestor's coordinate space.
    */
   enum {
     IN_CSS_UNITS = 1 << 0,
     STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT = 1 << 1
   };
   Matrix4x4Flagged GetTransformMatrix(const nsIFrame* aStopAtAncestor,
                                       nsIFrame **aOutAncestor,
-                                      uint32_t aFlags = 0);
+                                      uint32_t aFlags = 0) const;
 
   /**
    * Bit-flags to pass to IsFrameOfType()
    */
   enum {
     eMathML =                           1 << 0,
     eSVG =                              1 << 1,
     eSVGForeignObject =                 1 << 2,
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -4440,18 +4440,19 @@ ContainerState::ProcessDisplayItems(nsDi
         ScaleToOutsidePixels(item->GetBuildingRect(), false));
     }
 
     if (maxLayers != -1 && layerCount >= maxLayers) {
       forceInactive = true;
     }
 
     // Assign the item to a layer
+    bool treatInactiveItemAsActive = (layerState == LAYER_INACTIVE && !mManager->IsWidgetLayerManager());
     if (layerState == LAYER_ACTIVE_FORCE ||
-        (layerState == LAYER_INACTIVE && !mManager->IsWidgetLayerManager()) ||
+        treatInactiveItemAsActive ||
         (!forceInactive &&
          (layerState == LAYER_ACTIVE_EMPTY ||
           layerState == LAYER_ACTIVE))) {
 
       layerCount++;
 
       // Currently we do not support flattening effects within nested inactive
       // layer trees.
@@ -4590,17 +4591,58 @@ ContainerState::ProcessDisplayItems(nsDi
       }
 
       // Just use its layer.
       // Set layerContentsVisibleRect.width/height to -1 to indicate we
       // currently don't know. If BuildContainerLayerFor gets called by
       // item->BuildLayer, this will be set to a proper rect.
       nsIntRect layerContentsVisibleRect(0, 0, -1, -1);
       params.mLayerContentsVisibleRect = &layerContentsVisibleRect;
+
+      // If this display item wants to build inactive layers but we are treating
+      // it as active because we are already inside an inactive layer tree,
+      // we need to make sure that the display item's clip is reflected in
+      // FrameLayerBuilder::mInactiveLayerClip (which is normally set in
+      // AddPaintedDisplayItem() when entering an inactive layer tree).
+      // We intersect the display item's clip into any existing inactive layer
+      // clip.
+      const DisplayItemClip* originalInactiveClip = nullptr;
+      DisplayItemClip combinedInactiveClip;
+      bool combineNestedClip = treatInactiveItemAsActive && mLayerBuilder->GetContainingPaintedLayerData();
+      if (combineNestedClip) {
+        originalInactiveClip = mLayerBuilder->GetInactiveLayerClip();
+        if (originalInactiveClip) {
+          combinedInactiveClip = *originalInactiveClip;
+        }
+        DisplayItemClip nestedClip = item->GetClip();
+        if (nestedClip.HasClip()) {
+          nsRect nestedClipRect = nestedClip.NonRoundedIntersection();
+
+          // Transform the nested clip to be relative to the same reference
+          // frame as the existing mInactiveLayerClip, so that we can intersect
+          // them below.
+          nestedClipRect = nsLayoutUtils::TransformFrameRectToAncestor(
+              item->ReferenceFrame(),
+              nestedClipRect,
+              mLayerBuilder->GetContainingPaintedLayerData()->mReferenceFrame);
+
+          nestedClip.SetTo(nestedClipRect);
+          combinedInactiveClip.IntersectWith(nestedClip);
+          mLayerBuilder->SetInactiveLayerClip(&combinedInactiveClip);
+        }
+      }
+
       RefPtr<Layer> ownLayer = item->BuildLayer(mBuilder, mManager, params);
+
+      // If above we combined a nested clip into mInactiveLayerClip, restore
+      // the original inactive layer clip here.
+      if (combineNestedClip) {
+        mLayerBuilder->SetInactiveLayerClip(originalInactiveClip);
+      }
+
       if (!ownLayer) {
         continue;
       }
 
       NS_ASSERTION(!ownLayer->AsPaintedLayer(),
                    "Should never have created a dedicated Painted layer!");
 
       if (item->BackfaceIsHidden()) {
--- a/layout/painting/FrameLayerBuilder.h
+++ b/layout/painting/FrameLayerBuilder.h
@@ -698,16 +698,27 @@ public:
     return mContainingPaintedLayer;
   }
 
   const DisplayItemClip* GetInactiveLayerClip() const
   {
     return mInactiveLayerClip;
   }
 
+  /*
+   * If we're building layers for an item with an inactive layer tree,
+   * this function saves the item's clip, which will later be applied
+   * to the event regions. The clip should be relative to
+   * mContainingPaintedLayer->mReferenceFrame.
+   */
+  void SetInactiveLayerClip(const DisplayItemClip* aClip)
+  {
+    mInactiveLayerClip = aClip;
+  }
+
   bool IsBuildingRetainedLayers()
   {
     return !mIsInactiveLayerManager && mRetainingManager;
   }
 
   /**
    * Attempt to build the most compressed layer tree possible, even if it means
    * throwing away existing retained buffers.
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -1555,17 +1555,17 @@ TextNodeCorrespondenceRecorder::Traverse
  */
 class TextFrameIterator
 {
 public:
   /**
    * Constructs a TextFrameIterator for the specified SVGTextFrame
    * with an optional frame subtree to restrict iterated text frames to.
    */
-  explicit TextFrameIterator(SVGTextFrame* aRoot, nsIFrame* aSubtree = nullptr)
+  explicit TextFrameIterator(SVGTextFrame* aRoot, const nsIFrame* aSubtree = nullptr)
     : mRootFrame(aRoot),
       mSubtree(aSubtree),
       mCurrentFrame(aRoot),
       mCurrentPosition(),
       mSubtreePosition(mSubtree ? eBeforeSubtree : eWithinSubtree)
   {
     Init();
   }
@@ -1694,17 +1694,17 @@ private:
   /**
    * The root frame we are iterating through.
    */
   SVGTextFrame* mRootFrame;
 
   /**
    * The frame for the subtree we are also interested in tracking.
    */
-  nsIFrame* mSubtree;
+  const nsIFrame* mSubtree;
 
   /**
    * The current value of the iterator.
    */
   nsIFrame* mCurrentFrame;
 
   /**
    * The position, in app units, of the current frame relative to mRootFrame.
@@ -1868,17 +1868,17 @@ public:
    *   through.
    * @param aFilter Indicates whether to iterate rendered runs for non-visible
    *   nsTextFrames.
    * @param aSubtree An optional frame subtree to restrict iterated rendered
    *   runs to.
    */
   explicit TextRenderedRunIterator(SVGTextFrame* aSVGTextFrame,
                                    RenderedRunFilter aFilter = eAllFrames,
-                                   nsIFrame* aSubtree = nullptr)
+                                   const nsIFrame* aSubtree = nullptr)
     : mFrameIterator(FrameIfAnonymousChildReflowed(aSVGTextFrame), aSubtree),
       mFilter(aFilter),
       mTextElementCharIndex(0),
       mFrameStartTextElementCharIndex(0),
       mFontSizeScaleFactor(aSVGTextFrame->mFontSizeScaleFactor),
       mCurrent(First())
   {
   }
@@ -5740,17 +5740,17 @@ SVGTextFrame::TransformFramePointToTextC
  * For each rendered run beneath aChildFrame, translate aRect from
  * aChildFrame to the run's text frame, transform it then into
  * the run's frame user space, intersect it with the run's
  * frame user space rect, then transform it up to user space.
  * The result is the union of all of these.
  */
 gfxRect
 SVGTextFrame::TransformFrameRectFromTextChild(const nsRect& aRect,
-                                              nsIFrame* aChildFrame)
+                                              const nsIFrame* aChildFrame)
 {
   NS_ASSERTION(aChildFrame &&
                nsLayoutUtils::GetClosestFrameOfType
                  (aChildFrame->GetParent(), LayoutFrameType::SVGText) == this,
                "aChildFrame must be a descendant of this frame");
 
   UpdateGlyphPositioning();
 
--- a/layout/svg/SVGTextFrame.h
+++ b/layout/svg/SVGTextFrame.h
@@ -348,17 +348,17 @@ public:
 
   /**
    * Takes an app unit rectangle in the coordinate space of a given descendant
    * frame of this frame, and returns a rectangle in the <text> element's user
    * space that covers all parts of rendered runs that intersect with the
    * rectangle.
    */
   gfxRect TransformFrameRectFromTextChild(const nsRect& aRect,
-                                          nsIFrame* aChildFrame);
+                                          const nsIFrame* aChildFrame);
 
   // Return our ::-moz-svg-text anonymous box.
   void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
 
 private:
   /**
    * Mutation observer used to watch for text positioning attribute changes
    * on descendent text content elements (like <tspan>s).
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -1131,16 +1131,17 @@ PRTime nsZipItem::LastModTime()
   return GetModTime(Date(), Time());
 }
 
 nsZipCursor::nsZipCursor(nsZipItem *item, nsZipArchive *aZip, uint8_t* aBuf,
                          uint32_t aBufSize, bool doCRC)
   : mItem(item)
   , mBuf(aBuf)
   , mBufSize(aBufSize)
+  , mZs()
 #ifdef MOZ_JAR_BROTLI
   , mBrotliState(nullptr)
 #endif
   , mCRC(0)
   , mDoCRC(doCRC)
 {
   if (mItem->Compression() == DEFLATED) {
 #ifdef DEBUG
--- a/modules/libjar/zipwriter/nsDeflateConverter.h
+++ b/modules/libjar/zipwriter/nsDeflateConverter.h
@@ -21,22 +21,28 @@ class nsDeflateConverter final : public 
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSISTREAMCONVERTER
 
     nsDeflateConverter()
+        : mWrapMode(WRAP_NONE)
+        , mOffset(0)
+        , mZstream()
     {
         // 6 is Z_DEFAULT_COMPRESSION but we need the actual value
         mLevel = 6;
     }
 
     explicit nsDeflateConverter(int32_t level)
+        : mWrapMode(WRAP_NONE)
+        , mOffset(0)
+        , mZstream()
     {
         mLevel = level;
     }
 
 private:
 
     ~nsDeflateConverter()
     {
--- a/netwerk/sctp/src/netinet/sctp_auth.c
+++ b/netwerk/sctp/src/netinet/sctp_auth.c
@@ -29,17 +29,17 @@
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 324971 2017-10-25 09:12:22Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 334532 2018-06-02 16:28:10Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
 #include <netinet/sctp.h>
 #include <netinet/sctp_header.h>
 #include <netinet/sctp_pcb.h>
 #include <netinet/sctp_var.h>
 #include <netinet/sctp_sysctl.h>
@@ -1525,16 +1525,18 @@ sctp_auth_get_cookie_params(struct sctp_
 		keylen += sizeof(*chunks) + num_chunks;
 	}
 	new_key = sctp_alloc_key(keylen);
 	if (new_key != NULL) {
 	    /* copy in the RANDOM */
 	    if (p_random != NULL) {
 		keylen = sizeof(*p_random) + random_len;
 		memcpy(new_key->key, p_random, keylen);
+	    } else {
+		keylen = 0;
 	    }
 	    /* append in the AUTH chunks */
 	    if (chunks != NULL) {
 		memcpy(new_key->key + keylen, chunks,
 		       sizeof(*chunks) + num_chunks);
 		keylen += sizeof(*chunks) + num_chunks;
 	    }
 	    /* append in the HMACs */
--- a/netwerk/sctp/src/netinet/sctp_pcb.c
+++ b/netwerk/sctp/src/netinet/sctp_pcb.c
@@ -29,17 +29,17 @@
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 325370 2017-11-03 20:46:12Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 334532 2018-06-02 16:28:10Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
 #ifdef __FreeBSD__
 #include <sys/proc.h>
 #endif
 #include <netinet/sctp_var.h>
 #include <netinet/sctp_sysctl.h>
@@ -7742,16 +7742,18 @@ sctp_load_addresses_from_init(struct sct
 		keylen += sizeof(*chunks) + num_chunks;
 	}
 	new_key = sctp_alloc_key(keylen);
 	if (new_key != NULL) {
 		/* copy in the RANDOM */
 		if (p_random != NULL) {
 			keylen = sizeof(*p_random) + random_len;
 			memcpy(new_key->key, p_random, keylen);
+		} else {
+			keylen = 0;
 		}
 		/* append in the AUTH chunks */
 		if (chunks != NULL) {
 			memcpy(new_key->key + keylen, chunks,
 			       sizeof(*chunks) + num_chunks);
 			keylen += sizeof(*chunks) + num_chunks;
 		}
 		/* append in the HMACs */
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -1730,16 +1730,17 @@ class StaticAnalysis(MachCommandBase):
         # Function return codes
         self.TOOLS_SUCCESS = 0
         self.TOOLS_FAILED_DOWNLOAD = 1
         self.TOOLS_UNSUPORTED_PLATFORM = 2
         self.TOOLS_CHECKER_NO_TEST_FILE = 3
         self.TOOLS_CHECKER_RETURNED_NO_ISSUES = 4
         self.TOOLS_CHECKER_RESULT_FILE_NOT_FOUND = 5
         self.TOOLS_CHECKER_DIFF_FAILED = 6
+        self.TOOLS_CHECKER_NOT_FOUND = 7
 
         # Configure the tree or download clang-tidy package, depending on the option that we choose
         if intree_tool:
             _, config, _ = self._get_config_environment()
             clang_tools_path = self.topsrcdir
             self._clang_tidy_path = mozpath.join(
                 clang_tools_path, "clang", "bin",
                 "clang-tidy" + config.substs.get('BIN_SUFFIX', ''))
@@ -1779,16 +1780,23 @@ class StaticAnalysis(MachCommandBase):
         import multiprocessing
 
         max_workers = multiprocessing.cpu_count()
 
         self.log(logging.INFO, 'static-analysis', {},
                  "RUNNING: clang-tidy autotest for platform {0} with {1} workers.".format(
                      platform, max_workers))
 
+        # List all available checkers
+        cmd = [self._clang_tidy_path, '-list-checks', '-checks=*']
+        clang_output = subprocess.check_output(
+            cmd, stderr=subprocess.STDOUT).decode('utf-8')
+        available_checks = clang_output.split('\n')[1:]
+        self._clang_tidy_checks = [c.strip() for c in available_checks if c]
+
         with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
             futures = []
             for item in config['clang_checkers']:
                 # Do not test mozilla specific checks nor the default '-*'
                 if not (item['publish'] and ('restricted-platforms' in item
                                              and platform not in item['restricted-platforms']
                                              or 'restricted-platforms' not in item)
                         and item['name'] not in ['mozilla-*', '-*'] and
@@ -1869,17 +1877,22 @@ class StaticAnalysis(MachCommandBase):
     def _verify_checker(self, item):
         check = item['name']
         test_file_path = mozpath.join(self._clang_tidy_base_path, "test", check)
         test_file_path_cpp = test_file_path + '.cpp'
         test_file_path_json = test_file_path + '.json'
 
         self.log(logging.INFO, 'static-analysis', {},"RUNNING: clang-tidy checker {}.".format(check))
 
-        # Verify is test file exists for checker
+        # Verify if this checker actually exists
+        if not check in self._clang_tidy_checks:
+            self.log(logging.ERROR, 'static-analysis', {}, "ERROR: clang-tidy checker {} doesn't exist in this clang-tidy version.".format(check))
+            return self.TOOLS_CHECKER_NOT_FOUND
+
+        # Verify if the test file exists for this checker
         if not os.path.exists(test_file_path_cpp):
             self.log(logging.ERROR, 'static-analysis', {}, "ERROR: clang-tidy checker {} doesn't have a test file.".format(check))
             return self.TOOLS_CHECKER_NO_TEST_FILE
 
         cmd = [self._clang_tidy_path, '-checks=-*, ' + check, test_file_path_cpp]
 
         clang_output = subprocess.check_output(
             cmd, stderr=subprocess.STDOUT).decode('utf-8')
--- a/toolkit/library/rust/gkrust-features.mozbuild
+++ b/toolkit/library/rust/gkrust-features.mozbuild
@@ -27,13 +27,13 @@ if CONFIG['MOZ_MEMORY']:
     gkrust_features += ['moz_memory']
 
 # See details in toolkit/library/rust/shared/lib.rs
 # A string test is not the best thing, but it works well enough here.
 if CONFIG['RUSTC_VERSION'] < "1.27":
     gkrust_features += ['oom_with_global_alloc']
 elif CONFIG['RUSTC_VERSION'] >= "1.28" and CONFIG['RUSTC_VERSION'] < "1.29":
     gkrust_features += ['oom_with_hook']
-elif not CONFIG['MOZ_AUTOMATION']:
-    # We don't want builds on automation to unwillingly stop annotating OOM
+elif CONFIG['MOZ_AUTOMATION']:
+    # We don't want builds on automation to unwittingly stop annotating OOM
     # crash reports from rust.
     error('Builds on automation must use a version of rust that supports OOM '
           'hooking')
--- a/tools/clang-tidy/config.yaml
+++ b/tools/clang-tidy/config.yaml
@@ -6,42 +6,43 @@ target: obj-x86_64-pc-linux-gnu
 platforms:
   - macosx64
   - linux64
   - win64
   - win32
 clang_checkers:
   - name: -*
     publish: !!bool no
-  - name: misc-forward-declaration-namespace
-    # Name with clang tidy 6.0. We are currently using 5.0
-    # - name: bugprone-forward-declaration-namespace
-    publish: !!bool yes
   - name: clang-analyzer-deadcode.DeadStores
     publish: !!bool yes
   - name: clang-analyzer-security.FloatLoopCounter
     publish: !!bool yes
-  - name: clang-analyzer-security.insecureAPI.UncheckedReturn
-    publish: !!bool yes
   - name: clang-analyzer-security.insecureAPI.getpw
     publish: !!bool yes
+  # We don't add clang-analyzer-security.insecureAPI.gets here; it's deprecated.
   - name: clang-analyzer-security.insecureAPI.mkstemp
     publish: !!bool yes
   - name: clang-analyzer-security.insecureAPI.mktemp
     publish: !!bool yes
   - name: clang-analyzer-security.insecureAPI.rand
     publish: !!bool no
   - name: clang-analyzer-security.insecureAPI.strcpy
     publish: !!bool no
+  - name: clang-analyzer-security.insecureAPI.UncheckedReturn
+    publish: !!bool yes
   - name: clang-analyzer-security.insecureAPI.vfork
     publish: !!bool yes
   - name: misc-argument-comment
     publish: !!bool yes
   - name: misc-assert-side-effect
     publish: !!bool yes
+  - name: misc-forward-declaration-namespace
+    # Name with clang tidy 6.0. We are currently using 5.0
+    # - name: bugprone-forward-declaration-namespace
+    publish: !!bool yes
   - name: misc-suspicious-missing-comma
     publish: !!bool yes
   - name: misc-suspicious-semicolon
     publish: !!bool yes
   - name: misc-unused-using-decls
     publish: !!bool yes
   - name: modernize-avoid-bind
     publish: !!bool yes
@@ -51,29 +52,39 @@ clang_checkers:
   - name: modernize-loop-convert
     publish: !!bool yes
   - name: modernize-raw-string-literal
     publish: !!bool yes
   - name: modernize-redundant-void-arg
     publish: !!bool no
   - name: modernize-shrink-to-fit
     publish: !!bool yes
+  - name: modernize-use-auto
+    # Controversial, see bug 1371052.
+    publish: !!bool no
+  - name: modernize-use-bool-literals
+    publish: !!bool yes
   - name: modernize-use-equals-default
     publish: !!bool yes
   - name: modernize-use-equals-delete
     publish: !!bool yes
   - name: modernize-use-nullptr
     publish: !!bool yes
   - name: modernize-use-override
     # Too noisy because of the way how we implement NS_IMETHOD. See Bug 1420366.
     publish: !!bool no
   - name: mozilla-*
     publish: !!bool yes
+  - name: performance-faster-string-find
+    publish: !!bool yes
   - name: performance-for-range-copy
     publish: !!bool yes
+  # Only available from clang tidy 6.0. We are currently using 5.0
+  # - name: performance-implicit-conversion-in-loop
+  #   publish: !!bool yes
   - name: performance-inefficient-string-concatenation
     publish: !!bool yes
   - name: performance-inefficient-vector-operation
     publish: !!bool yes
   - name: performance-type-promotion-in-math-fn
     publish: !!bool yes
   - name: performance-unnecessary-copy-initialization
     publish: !!bool yes
@@ -90,19 +101,14 @@ clang_checkers:
   - name: readability-redundant-smartptr-get
     publish: !!bool no
   - name: readability-redundant-string-cstr
     publish: !!bool yes
   - name: readability-redundant-string-init
     publish: !!bool yes
   - name: readability-uniqueptr-delete-release
     publish: !!bool yes
-  - name: modernize-use-auto
-    # Controversial, see bug 1371052.
-    publish: !!bool no
-  - name: modernize-use-bool-literals
-    publish: !!bool yes
 # Only available from clang tidy 6.0. We are currently using 5.0
 # - name: readability-static-accessed-through-instance
 #   publish: !!bool yes
 
 # Third party files from mozilla-central
 third_party: tools/rewriting/ThirdPartyPaths.txt
--- a/tools/clang-tidy/test/performance-faster-string-find.cpp
+++ b/tools/clang-tidy/test/performance-faster-string-find.cpp
@@ -1,6 +1,6 @@
-#include <string>
+#include "structures.h"
 
 void foo() {
   std::string str;
   str.find("A");
 }
\ No newline at end of file
--- a/tools/clang-tidy/test/structures.h
+++ b/tools/clang-tidy/test/structures.h
@@ -1,9 +1,9 @@
-// Proxy file in order to define generic data types, to void binding with system headers
+// Proxy file in order to define generic data types, to avoid binding with system headers
 
 namespace std {
 
 typedef unsigned long size_t;
 
 template <class T>
 class vector {
  public:
@@ -36,16 +36,17 @@ template <typename T>
 class basic_string {
 public:
   typedef basic_string<T> _Type;
   basic_string() {}
    basic_string(const T *p);
   ~basic_string() {}
   size_t size() const;
   bool empty() const;
+  size_t find (const char* s, size_t pos = 0) const;
   const T *c_str() const;
   _Type& assign(const T *s);
   basic_string<T> *operator+=(const basic_string<T> &) {}
   friend basic_string<T> operator+(const basic_string<T> &, const basic_string<T> &) {}
 };
 typedef basic_string<char> string;
 typedef basic_string<wchar_t> wstring;
 
--- a/widget/windows/WinCompositorWindowThread.cpp
+++ b/widget/windows/WinCompositorWindowThread.cpp
@@ -32,17 +32,17 @@ WinCompositorWindowThread::Get()
 }
 
 /* static */ void
 WinCompositorWindowThread::Start()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!sWinCompositorWindowThread);
 
-  base::Thread* thread = new base::Thread("Renderer");
+  base::Thread* thread = new base::Thread("WinCompositor");
 
   base::Thread::Options options;
   // HWND requests ui thread.
   options.message_loop_type = MessageLoop::TYPE_UI;
 
   if (!thread->StartWithOptions(options)) {
     delete thread;
     return;