Merge autoland to mozilla-central. a=merge
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Thu, 21 Jun 2018 12:46:57 +0300
changeset 423229 e834d23a292972ab4250a8be00e6740c43e41db2
parent 423204 a79434a2511b80f92554c15317e2d6271849ace9 (diff)
parent 423228 a0c124cdf70fae2889fa93ac3c0d08f4a0b4fe68 (current diff)
child 423230 50ea4de900701dc7c65334a8798d1f4a3b23dcb5
child 423260 776ba1aa0feee265e8b7ee7a570bac7114433a9a
child 423281 1c33a38da75d550750923358e73d7af2102b9c1d
push id104496
push usernbeleuzu@mozilla.com
push dateThu, 21 Jun 2018 09:55:56 +0000
treeherdermozilla-inbound@50ea4de90070 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
e834d23a2929 / 62.0a1 / 20180621100048 / files
nightly linux64
e834d23a2929 / 62.0a1 / 20180621100048 / files
nightly mac
e834d23a2929 / 62.0a1 / 20180621100048 / files
nightly win32
e834d23a2929 / 62.0a1 / 20180621100048 / files
nightly win64
e834d23a2929 / 62.0a1 / 20180621100048 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
--- 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;