Merge mozilla-central to autoland
authorDorel Luca <dluca@mozilla.com>
Sun, 28 Apr 2019 12:45:12 +0300
changeset 530516 8b6c7d4f67eb690753179d5e6ba1635615425ae1
parent 530515 d091a005f031656890dfead0643ce875f997038e (current diff)
parent 530513 3eb7623b5e63b37823d5e9c562d56e586604c823 (diff)
child 530517 873e74ad120b1d74a34328a7316736c67d0474e1
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone68.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/devtools/client/debugger/test/mochitest/browser_dbg-worker-scopes.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-worker-scopes.js
@@ -1,13 +1,21 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
+// This error shows up sometimes when running the test, and while this is a
+// strange problem that shouldn't be happening it doesn't prevent the test from
+// completing successfully.
+const { PromiseTestUtils } = ChromeUtils.import(
+  "resource://testing-common/PromiseTestUtils.jsm"
+);
+PromiseTestUtils.whitelistRejectionsGlobally(/Current state is running/);
+
 function findNode(dbg, text) {
   for (let index = 0;; index++) {
     var elem = findElement(dbg, "scopeNode", index);
     if (elem && elem.innerText == text) {
       return elem;
     }
   }
 }
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -280,17 +280,17 @@ class gfxFontCacheExpirationTracker
   Lock& GetMutex() override {
     mozilla::AssertIsMainThreadOrServoFontMetricsLocked();
     return mLock;
   }
 
  public:
   enum { FONT_TIMEOUT_SECONDS = 10 };
 
-  gfxFontCacheExpirationTracker(nsIEventTarget* aEventTarget)
+  explicit gfxFontCacheExpirationTracker(nsIEventTarget* aEventTarget)
       : ExpirationTrackerImpl<gfxFont, 3, Lock, AutoLock>(
             FONT_TIMEOUT_SECONDS * 1000, "gfxFontCache", aEventTarget) {}
 };
 
 class gfxFontCache final : private gfxFontCacheExpirationTracker {
  public:
   enum { SHAPED_WORD_TIMEOUT_SECONDS = 60 };
 
--- a/js/src/builtin/Stream.cpp
+++ b/js/src/builtin/Stream.cpp
@@ -3462,30 +3462,54 @@ bool ReadableByteStreamController::const
                                                Value* vp) {
   // Step 1: Throw a TypeError exception.
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             JSMSG_BOGUS_CONSTRUCTOR,
                             "ReadableByteStreamController");
   return false;
 }
 
+// Disconnect the source from a controller without calling finalize() on it,
+// unless this class is reset(). This ensures that finalize() will not be called
+// on the source if setting up the controller fails.
+class MOZ_RAII AutoClearUnderlyingSource {
+  Rooted<ReadableStreamController*> controller_;
+
+ public:
+  AutoClearUnderlyingSource(JSContext* cx, ReadableStreamController* controller)
+      : controller_(cx, controller) {}
+
+  ~AutoClearUnderlyingSource() {
+    if (controller_) {
+      ReadableStreamController::clearUnderlyingSource(
+          controller_, /* finalizeSource */ false);
+    }
+  }
+
+  void reset() {
+    controller_ = nullptr;
+  }
+};
+
 /**
  * Version of SetUpReadableByteStreamController that's specialized for handling
  * external, embedding-provided, underlying sources.
  */
 static MOZ_MUST_USE bool SetUpExternalReadableByteStreamController(
     JSContext* cx, Handle<ReadableStream*> stream,
     JS::ReadableStreamUnderlyingSource* source) {
   // Done elsewhere in the standard: Create the controller object.
   Rooted<ReadableByteStreamController*> controller(
       cx, NewBuiltinClassInstance<ReadableByteStreamController>(cx));
   if (!controller) {
     return false;
   }
 
+  AutoClearUnderlyingSource autoClear(cx, controller);
+
   // Step 1: Assert: stream.[[readableStreamController]] is undefined.
   MOZ_ASSERT(!stream->hasController());
 
   // Step 2: If autoAllocateChunkSize is not undefined, [...]
   // (It's treated as undefined.)
 
   // Step 3: Set controller.[[controlledReadableByteStream]] to stream.
   controller->setStream(stream);
@@ -3551,16 +3575,17 @@ static MOZ_MUST_USE bool SetUpExternalRe
   if (!onStartRejected) {
     return false;
   }
   if (!JS::AddPromiseReactions(cx, startPromise, onStartFulfilled,
                                onStartRejected)) {
     return false;
   }
 
+  autoClear.reset();
   return true;
 }
 
 static const JSPropertySpec ReadableByteStreamController_properties[] = {
     JS_PS_END};
 
 static const JSFunctionSpec ReadableByteStreamController_methods[] = {
     JS_FS_END};
--- a/js/src/builtin/Stream.h
+++ b/js/src/builtin/Stream.h
@@ -312,19 +312,22 @@ class ReadableStreamController : public 
     return static_cast<JS::ReadableStreamUnderlyingSource*>(
         underlyingSource().toPrivate());
   }
   void setExternalSource(JS::ReadableStreamUnderlyingSource* underlyingSource) {
     setUnderlyingSource(JS::PrivateValue(underlyingSource));
     addFlags(Flag_ExternalSource);
   }
   static void clearUnderlyingSource(
-      JS::Handle<ReadableStreamController*> controller) {
+      JS::Handle<ReadableStreamController*> controller,
+      bool finalizeSource = true) {
     if (controller->hasExternalSource()) {
-      controller->externalSource()->finalize();
+      if (finalizeSource) {
+        controller->externalSource()->finalize();
+      }
       controller->setFlags(controller->flags() & ~Flag_ExternalSource);
     }
     controller->setUnderlyingSource(JS::UndefinedHandleValue);
   }
   double strategyHWM() const {
     return getFixedSlot(Slot_StrategyHWM).toNumber();
   }
   void setStrategyHWM(double highWaterMark) {
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -2781,17 +2781,22 @@ XDRResult ScriptSource::xdrData(XDRState
     if (mode == XDR_ENCODE) {
       uncompressedLength = ss->data.as<Uncompressed<Unit>>().length();
     }
     MOZ_TRY(xdr->codeUint32(&uncompressedLength));
 
     return ss->xdrUncompressedSource(xdr, sizeof(Unit), uncompressedLength);
   };
 
-  auto CodeBinASTData = [xdr, ss]() -> XDRResult {
+  auto CodeBinASTData = [xdr
+#if defined(JS_BUILD_BINAST)
+                         ,
+                         ss
+#endif
+  ]() -> XDRResult {
 #if !defined(JS_BUILD_BINAST)
     return xdr->fail(JS::TranscodeResult_Throw);
 #else
     // XDR the length of the BinAST data.
     uint32_t binASTLength;
     if (mode == XDR_ENCODE) {
       binASTLength = ss->data.as<BinAST>().string.length();
     }