Backed out changeset 73c4111cab17 (bug 1083361) for bustage
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 20 Nov 2014 09:51:03 +0100
changeset 216616 c13daeb9246954765810a6e6698aa155611da5e6
parent 216615 73c4111cab17d7351f26d691a04266b71cecf445
child 216617 faaa05e4e03d04eb9b9c868e984c9f1bcdd02991
push idunknown
push userunknown
push dateunknown
bugs1083361
milestone36.0a1
backs out73c4111cab17d7351f26d691a04266b71cecf445
Backed out changeset 73c4111cab17 (bug 1083361) for bustage
dom/promise/Promise.cpp
dom/promise/Promise.h
dom/promise/PromiseDebugging.cpp
dom/promise/PromiseDebugging.h
dom/promise/moz.build
dom/promise/tests/browser.ini
dom/promise/tests/browser_monitorUncaught.js
dom/webidl/PromiseDebugging.webidl
layout/build/nsLayoutStatics.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/base/CycleCollectedJSRuntime.h
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -9,43 +9,35 @@
 #include "jsfriendapi.h"
 #include "js/Debug.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/dom/PromiseBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/MediaStreamError.h"
-#include "mozilla/Atomics.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/Preferences.h"
 #include "PromiseCallback.h"
-#include "PromiseDebugging.h"
 #include "PromiseNativeHandler.h"
 #include "PromiseWorkerProxy.h"
 #include "nsContentUtils.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "nsJSPrincipals.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsJSEnvironment.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "xpcpublic.h"
 #include "nsGlobalWindow.h"
 
 namespace mozilla {
 namespace dom {
 
-namespace {
-// Generator used by Promise::GetID.
-Atomic<uintptr_t> gIDGenerator(0);
-}
-
-
 using namespace workers;
 
 NS_IMPL_ISUPPORTS0(PromiseNativeHandler)
 
 // This class processes the promise's callbacks with promise's result.
 class PromiseCallbackTask MOZ_FINAL : public nsRunnable
 {
 public:
@@ -248,21 +240,17 @@ private:
   NS_DECL_OWNINGTHREAD;
 };
 
 // Promise
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Promise)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Promise)
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   tmp->MaybeReportRejectedOnce();
-#else
-  tmp->mResult = JS::UndefinedValue();
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolveCallbacks)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRejectCallbacks)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Promise)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
@@ -289,37 +277,29 @@ NS_INTERFACE_MAP_END
 
 Promise::Promise(nsIGlobalObject* aGlobal)
   : mGlobal(aGlobal)
   , mResult(JS::UndefinedValue())
   , mAllocationStack(nullptr)
   , mRejectionStack(nullptr)
   , mFullfillmentStack(nullptr)
   , mState(Pending)
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   , mHadRejectCallback(false)
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
-  , mTaskPending(false)
   , mResolvePending(false)
-  , mIsLastInChain(true)
-  , mWasNotifiedAsUncaught(false)
-  , mID(0)
 {
   MOZ_ASSERT(mGlobal);
 
   mozilla::HoldJSObjects(this);
 
   mCreationTimestamp = TimeStamp::Now();
 }
 
 Promise::~Promise()
 {
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   MaybeReportRejectedOnce();
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
   mozilla::DropJSObjects(this);
 }
 
 JSObject*
 Promise::WrapObject(JSContext* aCx)
 {
   return PromiseBinding::Wrap(aCx, this);
 }
@@ -950,36 +930,27 @@ Promise::AppendNativeHandler(PromiseNati
 
   AppendCallbacks(resolveCb, rejectCb);
 }
 
 void
 Promise::AppendCallbacks(PromiseCallback* aResolveCallback,
                          PromiseCallback* aRejectCallback)
 {
-  MOZ_ASSERT(aResolveCallback);
-  MOZ_ASSERT(aRejectCallback);
-
-  if (mIsLastInChain && mState == PromiseState::Rejected) {
-    // This rejection is now consumed.
-    PromiseDebugging::AddConsumedRejection(*this);
-    // Note that we may not have had the opportunity to call
-    // RunResolveTask() yet, so we may never have called
-    // `PromiseDebugging:AddUncaughtRejection`.
+  if (aResolveCallback) {
+    mResolveCallbacks.AppendElement(aResolveCallback);
   }
-  mIsLastInChain = false;
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
-  // Now that there is a callback, we don't need to report anymore.
-  mHadRejectCallback = true;
-  RemoveFeature();
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
+  if (aRejectCallback) {
+    mHadRejectCallback = true;
+    mRejectCallbacks.AppendElement(aRejectCallback);
 
-  mResolveCallbacks.AppendElement(aResolveCallback);
-  mRejectCallbacks.AppendElement(aRejectCallback);
+    // Now that there is a callback, we don't need to report anymore.
+    RemoveFeature();
+  }
 
   // If promise's state is fulfilled, queue a task to process our fulfill
   // callbacks with promise's result. If promise's state is rejected, queue a
   // task to process our reject callbacks with promise's result.
   if (mState != Pending) {
     EnqueueCallbackTasks();
   }
 }
@@ -1022,17 +993,16 @@ Promise::DispatchToMicroTask(nsIRunnable
 
   CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
   nsTArray<nsRefPtr<nsIRunnable>>& microtaskQueue =
     runtime->GetPromiseMicroTaskQueue();
 
   microtaskQueue.AppendElement(aRunnable);
 }
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
 void
 Promise::MaybeReportRejected()
 {
   if (mState != Rejected || mHadRejectCallback || mResult.isUndefined()) {
     return;
   }
 
   AutoJSAPI jsapi;
@@ -1067,17 +1037,16 @@ Promise::MaybeReportRejected()
   // Now post an event to do the real reporting async
   // Since Promises preserve their wrapper, it is essential to nsRefPtr<> the
   // AsyncErrorReporter, otherwise if the call to DispatchToMainThread fails, it
   // will leak. See Bug 958684.
   nsRefPtr<AsyncErrorReporter> r =
     new AsyncErrorReporter(CycleCollectedJSRuntime::Get()->Runtime(), xpcReport);
   NS_DispatchToMainThread(r);
 }
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
 
 void
 Promise::MaybeResolveInternal(JSContext* aCx,
                               JS::Handle<JS::Value> aValue)
 {
   if (mResolvePending) {
     return;
   }
@@ -1157,26 +1126,16 @@ Promise::Settle(JS::Handle<JS::Value> aV
   AutoJSAPI jsapi;
   jsapi.Init();
   JSContext* cx = jsapi.cx();
   JS::RootedObject wrapper(cx, GetWrapper());
   MOZ_ASSERT(wrapper); // We preserved it
   JSAutoCompartment ac(cx, wrapper);
   JS::dbg::onPromiseSettled(cx, wrapper);
 
-  if (aState == PromiseState::Rejected &&
-      mIsLastInChain) {
-    // The Promise has just been rejected, and it is last in chain.
-    // We need to inform PromiseDebugging.
-    // If the Promise is eventually not the last in chain anymore,
-    // we will need to inform PromiseDebugging again.
-    PromiseDebugging::AddUncaughtRejection(*this);
-  }
-
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   // If the Promise was rejected, and there is no reject handler already setup,
   // watch for thread shutdown.
   if (aState == PromiseState::Rejected &&
       !mHadRejectCallback &&
       !NS_IsMainThread()) {
     WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(worker);
     worker->AssertIsOnWorkerThread();
@@ -1185,17 +1144,16 @@ Promise::Settle(JS::Handle<JS::Value> aV
     if (NS_WARN_IF(!worker->AddFeature(worker->GetJSContext(), mFeature))) {
       // To avoid a false RemoveFeature().
       mFeature = nullptr;
       // Worker is shutting down, report rejection immediately since it is
       // unlikely that reject callbacks will be added after this point.
       MaybeReportRejectedOnce();
     }
   }
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
 
   EnqueueCallbackTasks();
 }
 
 void
 Promise::MaybeSettle(JS::Handle<JS::Value> aValue,
                      PromiseState aState)
 {
@@ -1220,17 +1178,16 @@ Promise::EnqueueCallbackTasks()
 
   for (uint32_t i = 0; i < callbacks.Length(); ++i) {
     nsRefPtr<PromiseCallbackTask> task =
       new PromiseCallbackTask(this, callbacks[i], mResult);
     DispatchToMicroTask(task);
   }
 }
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
 void
 Promise::RemoveFeature()
 {
   if (mFeature) {
     WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(worker);
     worker->RemoveFeature(worker->GetJSContext(), mFeature);
     mFeature = nullptr;
@@ -1240,17 +1197,16 @@ Promise::RemoveFeature()
 bool
 PromiseReportRejectFeature::Notify(JSContext* aCx, workers::Status aStatus)
 {
   MOZ_ASSERT(aStatus > workers::Running);
   mPromise->MaybeReportRejectedOnce();
   // After this point, `this` has been deleted by RemoveFeature!
   return true;
 }
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
 
 bool
 Promise::CaptureStack(JSContext* aCx, JS::Heap<JSObject*>& aTarget)
 {
   JS::Rooted<JSObject*> stack(aCx);
   if (!JS::CaptureCurrentStack(aCx, &stack)) {
     return false;
   }
@@ -1483,18 +1439,10 @@ template<>
 void Promise::MaybeRejectBrokenly(const nsRefPtr<DOMError>& aArg) {
   MaybeSomething(aArg, &Promise::MaybeReject);
 }
 template<>
 void Promise::MaybeRejectBrokenly(const nsAString& aArg) {
   MaybeSomething(aArg, &Promise::MaybeReject);
 }
 
-uint64_t
-Promise::GetID() {
-  if (mID != 0) {
-    return mID;
-  }
-  return mID = ++gIDGenerator;
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/promise/Promise.h
+++ b/dom/promise/Promise.h
@@ -17,65 +17,54 @@
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/WeakPtr.h"
 #include "nsWrapperCache.h"
 #include "nsAutoPtr.h"
 #include "js/TypeDecls.h"
 
 #include "mozilla/dom/workers/bindings/WorkerFeature.h"
 
-// Bug 1083361 introduces a new mechanism for tracking uncaught
-// rejections. This #define serves to track down the parts of code
-// that need to be removed once clients have been put together
-// to take advantage of the new mechanism. New code should not
-// depend on code #ifdefed to this #define.
-#define DOM_PROMISE_DEPRECATED_REPORTING 1
-
 class nsIGlobalObject;
 
 namespace mozilla {
 namespace dom {
 
 class AnyCallback;
 class DOMError;
 class MediaStreamError;
 class PromiseCallback;
 class PromiseInit;
 class PromiseNativeHandler;
 class PromiseDebugging;
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
 class Promise;
 class PromiseReportRejectFeature : public workers::WorkerFeature
 {
   // The Promise that owns this feature.
   Promise* mPromise;
 
 public:
   explicit PromiseReportRejectFeature(Promise* aPromise)
     : mPromise(aPromise)
   {
     MOZ_ASSERT(mPromise);
   }
 
   virtual bool
   Notify(JSContext* aCx, workers::Status aStatus) MOZ_OVERRIDE;
 };
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
 
 class Promise : public nsISupports,
                 public nsWrapperCache,
                 public SupportsWeakPtr<Promise>
 {
   friend class NativePromiseCallback;
   friend class PromiseResolverTask;
   friend class PromiseTask;
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   friend class PromiseReportRejectFeature;
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
   friend class PromiseWorkerProxy;
   friend class PromiseWorkerProxyRunnable;
   friend class RejectPromiseCallback;
   friend class ResolvePromiseCallback;
   friend class ThenableResolverTask;
   friend class WrapperPromiseCallback;
 
 public:
@@ -177,19 +166,16 @@ public:
       const Sequence<JS::Value>& aIterable, ErrorResult& aRv);
 
   static already_AddRefed<Promise>
   Race(const GlobalObject& aGlobal,
        const Sequence<JS::Value>& aIterable, ErrorResult& aRv);
 
   void AppendNativeHandler(PromiseNativeHandler* aRunnable);
 
-  // Return a unique-to-the-process identifier for this Promise.
-  uint64_t GetID();
-
 protected:
   // Do NOT call this unless you're Promise::Create.  I wish we could enforce
   // that from inside this class too, somehow.
   explicit Promise(nsIGlobalObject* aGlobal);
 
   virtual ~Promise();
 
   // Queue an async microtask to current main or worker thread.
@@ -207,31 +193,16 @@ protected:
 
   bool IsPending()
   {
     return mResolvePending;
   }
 
   void GetDependentPromises(nsTArray<nsRefPtr<Promise>>& aPromises);
 
-  bool IsLastInChain() const
-  {
-    return mIsLastInChain;
-  }
-
-  void SetNotifiedAsUncaught()
-  {
-    mWasNotifiedAsUncaught = true;
-  }
-
-  bool WasNotifiedAsUncaught() const
-  {
-    return mWasNotifiedAsUncaught;
-  }
-
 private:
   friend class PromiseDebugging;
 
   enum PromiseState {
     Pending,
     Resolved,
     Rejected
   };
@@ -255,28 +226,26 @@ private:
   void EnqueueCallbackTasks();
 
   void Settle(JS::Handle<JS::Value> aValue, Promise::PromiseState aState);
   void MaybeSettle(JS::Handle<JS::Value> aValue, Promise::PromiseState aState);
 
   void AppendCallbacks(PromiseCallback* aResolveCallback,
                        PromiseCallback* aRejectCallback);
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   // If we have been rejected and our mResult is a JS exception,
   // report it to the error console.
   // Use MaybeReportRejectedOnce() for actual calls.
   void MaybeReportRejected();
 
   void MaybeReportRejectedOnce() {
     MaybeReportRejected();
     RemoveFeature();
     mResult = JS::UndefinedValue();
   }
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
 
   void MaybeResolveInternal(JSContext* aCx,
                             JS::Handle<JS::Value> aValue);
   void MaybeRejectInternal(JSContext* aCx,
                            JS::Handle<JS::Value> aValue);
 
   void ResolveInternal(JSContext* aCx,
                        JS::Handle<JS::Value> aValue);
@@ -315,19 +284,17 @@ private:
   CreateFunction(JSContext* aCx, JSObject* aParent, Promise* aPromise,
                 int32_t aTask);
 
   static JSObject*
   CreateThenableFunction(JSContext* aCx, Promise* aPromise, uint32_t aTask);
 
   void HandleException(JSContext* aCx);
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
   void RemoveFeature();
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
 
   // Capture the current stack and store it in aTarget.  If false is
   // returned, an exception is presumably pending on aCx.
   bool CaptureStack(JSContext* aCx, JS::Heap<JSObject*>& aTarget);
 
   nsRefPtr<nsIGlobalObject> mGlobal;
 
   nsTArray<nsRefPtr<PromiseCallback> > mResolveCallbacks;
@@ -343,46 +310,29 @@ private:
   // have a rejection stack.
   JS::Heap<JSObject*> mRejectionStack;
   // mFullfillmentStack is only set when the promise is fulfilled directly from
   // script, by calling Promise.resolve() or the fulfillment callback we pass to
   // the PromiseInit function.  Promises that are fulfilled internally do not
   // have a fulfillment stack.
   JS::Heap<JSObject*> mFullfillmentStack;
   PromiseState mState;
+  bool mHadRejectCallback;
 
-#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
-  bool mHadRejectCallback;
+  bool mResolvePending;
 
   // If a rejected promise on a worker has no reject callbacks attached, it
   // needs to know when the worker is shutting down, to report the error on the
   // console before the worker's context is deleted. This feature is used for
   // that purpose.
   nsAutoPtr<PromiseReportRejectFeature> mFeature;
-#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
-
-  bool mTaskPending;
-  bool mResolvePending;
-
-  // `true` if this Promise is the last in the chain, or `false` if
-  // another Promise has been created from this one by a call to
-  // `then`, `all`, `race`, etc.
-  bool mIsLastInChain;
-
-  // `true` if PromiseDebugging has already notified at least one observer that
-  // this promise was left uncaught, `false` otherwise.
-  bool mWasNotifiedAsUncaught;
 
   // The time when this promise was created.
   TimeStamp mCreationTimestamp;
 
   // The time when this promise transitioned out of the pending state.
   TimeStamp mSettlementTimestamp;
-
-  // Once `GetID()` has been called, a unique-to-the-process identifier for this
-  // promise. Until then, `0`.
-  uint64_t mID;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Promise_h
--- a/dom/promise/PromiseDebugging.cpp
+++ b/dom/promise/PromiseDebugging.cpp
@@ -1,73 +1,26 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=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 "js/Value.h"
-#include "nsThreadUtils.h"
+#include "mozilla/dom/PromiseDebugging.h"
 
-#include "mozilla/CycleCollectedJSRuntime.h"
-#include "mozilla/ThreadLocal.h"
+#include "js/Value.h"
+
 #include "mozilla/TimeStamp.h"
-
 #include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/Promise.h"
-#include "mozilla/dom/PromiseDebugging.h"
 #include "mozilla/dom/PromiseDebuggingBinding.h"
 
 namespace mozilla {
 namespace dom {
 
-namespace {
-
-class FlushRejections: public nsCancelableRunnable
-{
-public:
-  static void Init() {
-    if (!sDispatched.init()) {
-      MOZ_CRASH("Could not initialize FlushRejections::sDispatched");
-    }
-    sDispatched.set(false);
-  }
-  static void DispatchNeeded() {
-    if (sDispatched.get()) {
-      // An instance of `FlushRejections` has already been dispatched
-      // and not run yet. No need to dispatch another one.
-      return;
-    }
-    sDispatched.set(true);
-    NS_DispatchToCurrentThread(new FlushRejections());
-  }
-  nsresult Run()
-  {
-    sDispatched.set(false);
-
-    // Call the callbacks if necessary.
-    // Note that these callbacks may in turn cause Promise to turn
-    // uncaught or consumed. Since `sDispatched` is `false`,
-    // `FlushRejections` will be called once again, on an ulterior
-    // tick.
-    PromiseDebugging::FlushUncaughtRejections();
-    return NS_OK;
-  }
-private:
-  // `true` if an instance of `FlushRejections` is currently dispatched
-  // and has not been executed yet.
-  static ThreadLocal<bool> sDispatched;
-};
-
-/* static */ ThreadLocal<bool>
-FlushRejections::sDispatched;
-
-} // namespace
-
 /* static */ void
 PromiseDebugging::GetState(GlobalObject&, Promise& aPromise,
                            PromiseDebuggingStateHolder& aState)
 {
   switch (aPromise.mState) {
   case Promise::Pending:
     aState.mState = PromiseDebuggingState::Pending;
     break;
@@ -79,40 +32,16 @@ PromiseDebugging::GetState(GlobalObject&
   case Promise::Rejected:
     aState.mState = PromiseDebuggingState::Rejected;
     JS::ExposeValueToActiveJS(aPromise.mResult);
     aState.mReason = aPromise.mResult;
     break;
   }
 }
 
-/*static */ nsString
-PromiseDebugging::sIDPrefix;
-
-/* static */ void
-PromiseDebugging::Init()
-{
-  FlushRejections::Init();
-
-  // Generate a prefix for identifiers: "PromiseDebugging.$processid."
-  sIDPrefix = NS_LITERAL_STRING("PromiseDebugging.");
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    sIDPrefix.AppendInt(ContentChild::GetSingleton()->GetID());
-    sIDPrefix.Append('.');
-  } else {
-    sIDPrefix.AppendLiteral("0.");
-  }
-}
-
-/* static */ void
-PromiseDebugging::Shutdown()
-{
-  sIDPrefix.SetIsVoid(true);
-}
-
 /* static */ void
 PromiseDebugging::GetAllocationStack(GlobalObject&, Promise& aPromise,
                                      JS::MutableHandle<JSObject*> aStack)
 {
   aStack.set(aPromise.mAllocationStack);
 }
 
 /* static */ void
@@ -149,112 +78,10 @@ PromiseDebugging::GetTimeToSettle(Global
   if (aPromise.mState == Promise::Pending) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return 0;
   }
   return (aPromise.mSettlementTimestamp -
           aPromise.mCreationTimestamp).ToMilliseconds();
 }
 
-/* static */ void
-PromiseDebugging::AddUncaughtRejectionObserver(GlobalObject&,
-                                               UncaughtRejectionObserver& aObserver)
-{
-  CycleCollectedJSRuntime* storage = CycleCollectedJSRuntime::Get();
-  nsTArray<nsRefPtr<UncaughtRejectionObserver>>& observers = storage->mUncaughtRejectionObservers;
-  observers.AppendElement(&aObserver);
-}
-
-/* static */ void
-PromiseDebugging::RemoveUncaughtRejectionObserver(GlobalObject&,
-                                                  UncaughtRejectionObserver& aObserver)
-{
-  CycleCollectedJSRuntime* storage = CycleCollectedJSRuntime::Get();
-  nsTArray<nsRefPtr<UncaughtRejectionObserver>>& observers = storage->mUncaughtRejectionObservers;
-  for (size_t i = 0; i < observers.Length(); ++i) {
-    if (*observers[i] == aObserver) {
-      observers.RemoveElementAt(i);
-      return;
-    }
-  }
-}
-
-/* static */ void
-PromiseDebugging::AddUncaughtRejection(Promise& aPromise)
-{
-  CycleCollectedJSRuntime::Get()->mUncaughtRejections.AppendElement(&aPromise);
-  FlushRejections::DispatchNeeded();
-}
-
-/* void */ void
-PromiseDebugging::AddConsumedRejection(Promise& aPromise)
-{
-  CycleCollectedJSRuntime::Get()->mConsumedRejections.AppendElement(&aPromise);
-  FlushRejections::DispatchNeeded();
-}
-
-/* static */ void
-PromiseDebugging::GetPromiseID(GlobalObject&,
-                               Promise& aPromise,
-                               nsString& aID)
-{
-  uint64_t promiseID = aPromise.GetID();
-  aID = sIDPrefix;
-  aID.AppendInt(promiseID);
-}
-
-/* static */ void
-PromiseDebugging::FlushUncaughtRejections()
-{
-  CycleCollectedJSRuntime* storage = CycleCollectedJSRuntime::Get();
-
-  // The Promise that have been left uncaught (rejected and last in
-  // their chain) since the last call to this function.
-  nsTArray<nsRefPtr<Promise>> uncaught;
-  storage->mUncaughtRejections.SwapElements(uncaught);
-
-  // The Promise that have been left uncaught at some point, but that
-  // have eventually had their `then` method called.
-  nsTArray<nsRefPtr<Promise>> consumed;
-  storage->mConsumedRejections.SwapElements(consumed);
-
-  nsTArray<nsRefPtr<UncaughtRejectionObserver>>& observers = storage->mUncaughtRejectionObservers;
-
-  // Notify observers of uncaught Promise.
-
-  for (size_t i = 0; i < uncaught.Length(); ++i) {
-    nsRefPtr<Promise> promise = uncaught[i];
-    if (!promise->IsLastInChain()) {
-      // This promise is not the last in the chain anymore,
-      // so the error has been caught at some point.
-      continue;
-    }
-
-    // For the moment, the Promise is still at the end of the
-    // chain. Let's inform observers, so that they may decide whether
-    // to report it.
-    for (size_t j = 0; j < observers.Length(); ++j) {
-      ErrorResult rv;
-      observers[j]->OnLeftUncaught(*promise, rv);
-      // Ignore errors
-    }
-
-    promise->SetNotifiedAsUncaught();
-  }
-
-  // Notify observers of consumed Promise.
-
-  for (size_t i = 0; i < consumed.Length(); ++i) {
-    nsRefPtr<Promise> promise = consumed[i];
-    if (!promise->WasNotifiedAsUncaught()) {
-      continue;
-    }
-
-    MOZ_ASSERT(!promise->IsLastInChain());
-    for (size_t j = 0; j < observers.Length(); ++j) {
-      ErrorResult rv;
-      observers[j]->OnConsumed(*promise, rv); // Ignore errors
-    }
-  }
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/promise/PromiseDebugging.h
+++ b/dom/promise/PromiseDebugging.h
@@ -15,62 +15,32 @@ namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
 class Promise;
 struct PromiseDebuggingStateHolder;
 class GlobalObject;
-class UncaughtRejectionObserver;
 
 class PromiseDebugging
 {
 public:
-  static void Init();
-  static void Shutdown();
-
   static void GetState(GlobalObject&, Promise& aPromise,
                        PromiseDebuggingStateHolder& aState);
 
   static void GetAllocationStack(GlobalObject&, Promise& aPromise,
                                  JS::MutableHandle<JSObject*> aStack);
   static void GetRejectionStack(GlobalObject&, Promise& aPromise,
                                 JS::MutableHandle<JSObject*> aStack);
   static void GetFullfillmentStack(GlobalObject&, Promise& aPromise,
                                    JS::MutableHandle<JSObject*> aStack);
   static void GetDependentPromises(GlobalObject&, Promise& aPromise,
                                    nsTArray<nsRefPtr<Promise>>& aPromises);
   static double GetPromiseLifetime(GlobalObject&, Promise& aPromise);
   static double GetTimeToSettle(GlobalObject&, Promise& aPromise,
                                 ErrorResult& aRv);
-
-  static void GetPromiseID(GlobalObject&, Promise&, nsString&);
-
-  // Mechanism for watching uncaught instances of Promise.
-  static void AddUncaughtRejectionObserver(GlobalObject&,
-                                           UncaughtRejectionObserver& aObserver);
-  static void RemoveUncaughtRejectionObserver(GlobalObject&,
-                                              UncaughtRejectionObserver& aObserver);
-
-  // Mark a Promise as having been left uncaught at script completion.
-  static void AddUncaughtRejection(Promise&);
-  // Mark a Promise previously added with `AddUncaughtRejection` as
-  // eventually consumed.
-  static void AddConsumedRejection(Promise&);
-  // Propagate the informations from AddUncaughtRejection
-  // and AddConsumedRejection to observers.
-  static void FlushUncaughtRejections();
-private:
-  // Identity of the process.
-  // This property is:
-  // - set during initialization of the layout module,
-  // prior to any Worker using it;
-  // - read by both the main thread and the Workers;
-  // - unset during shutdown of the layout module,
-  // after any Worker has been shutdown.
-  static nsString sIDPrefix;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PromiseDebugging_h
--- a/dom/promise/moz.build
+++ b/dom/promise/moz.build
@@ -19,20 +19,16 @@ UNIFIED_SOURCES += [
     'PromiseCallback.cpp',
     'PromiseDebugging.cpp'
 ]
 
 FAIL_ON_WARNINGS = True
 
 LOCAL_INCLUDES += [
     '../base',
-    '../ipc',
     '../workers',
 ]
 
-include('/ipc/chromium/chromium-config.mozbuild')
-
 FINAL_LIBRARY = 'xul'
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
 MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
-BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
deleted file mode 100644
--- a/dom/promise/tests/browser.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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/.
-
-[DEFAULT]
-
-[browser_monitorUncaught.js]
\ No newline at end of file
deleted file mode 100644
--- a/dom/promise/tests/browser_monitorUncaught.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Timer.jsm", this);
-
-add_task(function* test_globals() {
-  Assert.equal(Promise.defer || undefined, undefined, "We are testing DOM Promise.");
-  Assert.notEqual(PromiseDebugging, undefined, "PromiseDebugging is available.");
-});
-
-add_task(function* test_promiseID() {
-  let p1 = new Promise(resolve => {});
-  let p2 = new Promise(resolve => {});
-  let p3 = p2.then(null, null);
-  let promise = [p1, p2, p3];
-
-  let identifiers = promise.map(PromiseDebugging.getPromiseID);
-  info("Identifiers: " + JSON.stringify(identifiers));
-  let idSet = new Set(identifiers);
-  Assert.equal(idSet.size, identifiers.length,
-    "PromiseDebugging.getPromiseID returns a distinct id per promise");
-
-  let identifiers2 = promise.map(PromiseDebugging.getPromiseID);
-  Assert.equal(JSON.stringify(identifiers),
-               JSON.stringify(identifiers2),
-               "Successive calls to PromiseDebugging.getPromiseID return the same id for the same promise");
-});
-
-add_task(function* test_observe_uncaught() {
-  // The names of Promise instances
-  let names = new Map();
-
-  // The results for UncaughtPromiseObserver callbacks.
-  let CallbackResults = function(name) {
-    this.name = name;
-    this.expected = new Set();
-    this.observed = new Set();
-    this.blocker = new Promise(resolve => this.resolve = resolve);
-  };
-  CallbackResults.prototype = {
-    observe: function(promise) {
-      info(this.name + " observing Promise " + names.get(promise));
-      Assert.equal(PromiseDebugging.getState(promise).state, "rejected",
-                   this.name + " observed a rejected Promise");
-      if (!this.expected.has(promise)) {
-        Assert.ok(false,
-            this.name + " observed a Promise that it expected to observe, " +
-            names.get(promise) +
-            " (" + PromiseDebugging.getPromiseID(promise) +
-            ", " + PromiseDebugging.getAllocationStack(promise) + ")");
-
-      }
-      Assert.ok(this.expected.delete(promise),
-                this.name + " observed a Promise that it expected to observe, " +
-                names.get(promise)  + " (" + PromiseDebugging.getPromiseID(promise) + ")");
-      Assert.ok(!this.observed.has(promise),
-                this.name + " observed a Promise that it has not observed yet");
-      this.observed.add(promise);
-      if (this.expected.size == 0) {
-        this.resolve();
-      } else {
-        info(this.name + " is still waiting for " + this.expected.size + " observations:");
-        info(JSON.stringify([names.get(x) for (x of this.expected.values())]));
-      }
-    },
-  };
-
-  let onLeftUncaught = new CallbackResults("onLeftUncaught");
-  let onConsumed = new CallbackResults("onConsumed");
-
-  let observer = {
-    onLeftUncaught: function(promise, data) {
-      onLeftUncaught.observe(promise);
-    },
-    onConsumed: function(promise) {
-      onConsumed.observe(promise);
-    },
-  };
-
-  let resolveLater = function(delay = 20) {
-    return new Promise((resolve, reject) => setTimeout(resolve, delay));
-  };
-  let rejectLater = function(delay = 20) {
-    return new Promise((resolve, reject) => setTimeout(reject, delay));
-  };
-  let makeSamples = function*() {
-    yield {
-      promise: Promise.resolve(0),
-      name: "Promise.resolve",
-    };
-    yield {
-      promise: Promise.resolve(resolve => resolve(0)),
-      name: "Resolution callback",
-    };
-    yield {
-      promise: Promise.resolve(0).then(null, null),
-      name: "`then(null, null)`"
-    };
-    yield {
-      promise: Promise.reject(0).then(null, () => {}),
-      name: "Reject and catch immediately",
-    };
-    yield {
-      promise: resolveLater(),
-      name: "Resolve later",
-    };
-    yield {
-      promise: Promise.reject("Simple rejection"),
-      leftUncaught: true,
-      consumed: false,
-      name: "Promise.reject",
-    };
-
-    // Reject a promise now, consume it later.
-    let p = Promise.reject("Reject now, consume later");
-    setTimeout(() => p.then(null, () => {
-      info("Consumed promise");
-    }), 200);
-    yield {
-      promise: p,
-      leftUncaught: true,
-      consumed: true,
-      name: "Reject now, consume later",
-    };
-
-    yield {
-      promise: Promise.all([
-        Promise.resolve("Promise.all"),
-        rejectLater()
-      ]),
-      leftUncaught: true,
-      name: "Rejecting through Promise.all"
-    };
-    yield {
-      promise: Promise.race([
-        resolveLater(500),
-        Promise.reject(),
-      ]),
-      leftUncaught: true, // The rejection wins the race.
-      name: "Rejecting through Promise.race",
-    };
-    yield {
-      promise: Promise.race([
-        Promise.resolve(),
-        rejectLater(500)
-      ]),
-      leftUncaught: false, // The resolution wins the race.
-      name: "Resolving through Promise.race",
-    };
-
-    let boom = new Error("`throw` in the constructor");
-    yield {
-      promise: new Promise(() => { throw boom; }),
-      leftUncaught: true,
-      name: "Throwing in the constructor",
-    };
-
-    let rejection = Promise.reject("`reject` during resolution");
-    yield {
-      promise: rejection,
-      leftUncaught: false,
-      consumed: false, // `rejection` is consumed immediately (see below)
-      name: "Promise.reject, again",
-    };
-
-    yield {
-      promise: new Promise(resolve => resolve(rejection)),
-      leftUncaught: true,
-      consumed: false,
-      name: "Resolving with a rejected promise",
-    };
-
-    yield {
-      promise: Promise.resolve(0).then(() => rejection),
-      leftUncaught: true,
-      consumed: false,
-      name: "Returning a rejected promise from success handler",
-    };
-
-    yield {
-      promise: Promise.resolve(0).then(() => { throw new Error(); }),
-      leftUncaught: true,
-      consumed: false,
-      name: "Throwing during the call to the success callback",
-    };
-  };
-  let samples = [];
-  for (let s of makeSamples()) {
-    samples.push(s);
-    info("Promise '" + s.name + "' has id " + PromiseDebugging.getPromiseID(s.promise));
-  }
-
-  PromiseDebugging.addUncaughtRejectionObserver(observer);
-
-  for (let s of samples) {
-    names.set(s.promise, s.name);
-    if (s.leftUncaught || false) {
-      onLeftUncaught.expected.add(s.promise);
-    }
-    if (s.consumed || false) {
-      onConsumed.expected.add(s.promise);
-    }
-  }
-
-  info("Test setup, waiting for callbacks.");
-  yield onLeftUncaught.blocker;
-
-  info("All calls to onLeftUncaught are complete.");
-  if (onConsumed.expected.size != 0) {
-    info("onConsumed is still waiting for the following Promise:");
-    info(JSON.stringify([names.get(x) for (x of onConsumed.expected.values())]));
-    yield onConsumed.blocker;
-  }
-
-  info("All calls to onConsumed are complete.");
-  PromiseDebugging.removeUncaughtRejectionObserver(observer);
-});
-
-
-add_task(function* test_uninstall_observer() {
-  let Observer = function() {
-    this.blocker = new Promise(resolve => this.resolve = resolve);
-    this.active = true;
-  };
-  Observer.prototype = {
-    set active(x) {
-      this._active = x;
-      if (x) {
-        PromiseDebugging.addUncaughtRejectionObserver(this);
-      } else {
-        PromiseDebugging.removeUncaughtRejectionObserver(this);
-      }
-    },
-    onLeftUncaught: function() {
-      Assert.ok(this._active, "This observer is active.");
-      this.resolve();
-    },
-    onConsumed: function() {
-      Assert.ok(false, "We should not consume any Promise.");
-    },
-  };
-
-  info("Adding an observer.");
-  let deactivate = new Observer();
-  Promise.reject("I am an uncaught rejection.");
-  yield deactivate.blocker;
-  Assert.ok(true, "The observer has observed an uncaught Promise.");
-  deactivate.active = false;
-  info("Removing the observer, it should not observe any further uncaught Promise.");
-
-  info("Rejecting a Promise and waiting a little to give a chance to observers.");
-  let wait = new Observer();
-  Promise.reject("I am another uncaught rejection.");
-  yield wait.blocker;
-  yield new Promise(resolve => setTimeout(resolve, 100));
-  // Normally, `deactivate` should not be notified of the uncaught rejection.
-  wait.active = false;
-
-});
--- a/dom/webidl/PromiseDebugging.webidl
+++ b/dom/webidl/PromiseDebugging.webidl
@@ -9,52 +9,16 @@
 
 dictionary PromiseDebuggingStateHolder {
   PromiseDebuggingState state = "pending";
   any value;
   any reason;
 };
 enum PromiseDebuggingState { "pending", "fulfilled", "rejected" };
 
-/**
- * An observer for Promise that _may_ be leaking uncaught rejections.
- *
- * It is generally a programming error to leave a Promise rejected and
- * not consume its rejection. The information exposed by this
- * interface is designed to allow clients to track down such Promise,
- * i.e. Promise that are currently
- * - in `rejected` state;
- * - last of their chain.
- *
- * Note, however, that a promise in such a state at the end of a tick
- * may eventually be consumed in some ulterior tick. Implementers of
- * this interface are responsible for presenting the information
- * in a meaningful manner.
- */
-callback interface UncaughtRejectionObserver {
-  /**
-   * A Promise has been left in `rejected` state and is the
-   * last in its chain.
-   *
-   * @param p A currently uncaught Promise. If `p` is is eventually
-   * caught, i.e. if its `then` callback is called, `onConsumed` will
-   * be called.
-   */
-  void onLeftUncaught(Promise<any> p);
-
-  /**
-   * A Promise previously left uncaught is not the last in its
-   * chain anymore.
-   *
-   * @param p A Promise that was previously left in uncaught state is
-   * now caught, i.e. it is not the last in its chain anymore.
-   */
-  void onConsumed(Promise<any> p);
-};
-
 [ChromeOnly, Exposed=(Window,System)]
 interface PromiseDebugging {
   static PromiseDebuggingStateHolder getState(Promise<any> p);
 
   /**
    * Return the stack to the promise's allocation point.  This can
    * return null if the promise was not created from script.
    */
@@ -70,22 +34,16 @@ interface PromiseDebugging {
   /**
    * Return the stack to the promise's fulfillment point, if the
    * fulfillment happened from script.  This can return null if the
    * promise has not been fulfilled or was not fulfilled from script.
    */
   static object? getFullfillmentStack(Promise<any> p);
 
   /**
-   * Return an identifier for a promise. This identifier is guaranteed
-   * to be unique to this instance of Firefox.
-   */
-  static DOMString getPromiseID(Promise<any> p);
-
-  /**
    * Get the promises directly depending on a given promise.  These are:
    *
    * 1) Return values of then() calls on the promise
    * 2) Return values of Promise.all() if the given promise was passed in as one
    *    of the arguments.
    * 3) Return values of Promise.race() if the given promise was passed in as
    *    one of the arguments.
    *
@@ -105,18 +63,9 @@ interface PromiseDebugging {
 
   /*
    * Get the number of milliseconds elapsed between the promise being created
    * and being settled.  Throws NS_ERROR_UNEXPECTED if the promise has not
    * settled.
    */
   [Throws]
   static DOMHighResTimeStamp getTimeToSettle(Promise<any> p);
-
-  /**
-   * Watching uncaught rejections on the current thread.
-   *
-   * Adding an observer twice will cause it to be notified twice
-   * of events.
-   */
-  static void addUncaughtRejectionObserver(UncaughtRejectionObserver o);
-  static void removeUncaughtRejectionObserver(UncaughtRejectionObserver o);
 };
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -62,17 +62,16 @@
 #include "CacheObserver.h"
 #include "DisplayItemClip.h"
 #include "ActiveLayerTracker.h"
 #include "CounterStyleManager.h"
 #include "FrameLayerBuilder.h"
 
 #include "AudioChannelService.h"
 #include "mozilla/dom/DataStoreService.h"
-#include "mozilla/dom/PromiseDebugging.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #include "nsXULContentUtils.h"
 #include "nsXULPrototypeCache.h"
 #include "nsXULTooltipListener.h"
 
 #include "inDOMView.h"
@@ -296,18 +295,16 @@ nsLayoutStatics::Initialize()
   CacheObserver::Init();
 
   CounterStyleManager::InitializeBuiltinCounterStyles();
 
   CameraPreferences::Initialize();
 
   IMEStateManager::Init();
 
-  PromiseDebugging::Init();
-
   return NS_OK;
 }
 
 void
 nsLayoutStatics::Shutdown()
 {
   // Don't need to shutdown nsWindowMemoryReporter, that will be done by the
   // memory reporter manager.
@@ -429,11 +426,9 @@ nsLayoutStatics::Shutdown()
 
   DisplayItemClip::Shutdown();
 
   nsDocument::XPCOMShutdown();
 
   CacheObserver::Shutdown();
 
   CameraPreferences::Shutdown();
-
-  PromiseDebugging::Shutdown();
 }
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -1294,9 +1294,8 @@ CycleCollectedJSRuntime::OnOutOfMemory()
 
 void
 CycleCollectedJSRuntime::OnLargeAllocationFailure()
 {
   AnnotateAndSetOutOfMemory(&mLargeAllocationFailureState, OOMState::Reporting);
   CustomLargeAllocationFailureCallback();
   AnnotateAndSetOutOfMemory(&mLargeAllocationFailureState, OOMState::Reported);
 }
-
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -11,20 +11,16 @@
 #include "jsapi.h"
 
 #include "nsCycleCollector.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 
-#include "mozilla/dom/PromiseDebugging.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/PromiseDebuggingBinding.h"
-
 class nsCycleCollectionNoteRootCallback;
 class nsIException;
 class nsIRunnable;
 
 namespace js {
 struct Class;
 }
 
@@ -290,22 +286,16 @@ public:
     MOZ_ASSERT(mJSRuntime);
     return mJSRuntime;
   }
 
   // Get the current thread's CycleCollectedJSRuntime.  Returns null if there
   // isn't one.
   static CycleCollectedJSRuntime* Get();
 
-  // Storage for watching rejected promises waiting for some client to
-  // consume their rejection.
-  nsTArray<nsRefPtr<dom::Promise>> mUncaughtRejections;
-  nsTArray<nsRefPtr<dom::Promise>> mConsumedRejections;
-  nsTArray<nsRefPtr<dom::UncaughtRejectionObserver>> mUncaughtRejectionObservers;
-
 private:
   JSGCThingParticipant mGCThingCycleCollectorGlobal;
 
   JSZoneParticipant mJSZoneCycleCollectorGlobal;
 
   JSRuntime* mJSRuntime;
 
   nsDataHashtable<nsPtrHashKey<void>, nsScriptObjectTracer*> mJSHolders;