backout c42ff6847631 (bug 1250572) for causing aborts during startup
authorDaniel Holbert <dholbert@cs.stanford.edu>
Wed, 24 Feb 2016 11:54:35 -0800
changeset 321776 07f601e5ce85d64f01434cacd3361c21b5e73e33
parent 321775 84ba22179d9775a7b79e78df2a9e099ba18ebaac
child 321777 93390f1d1faa6a133d5ed53629df227030304198
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1250572
milestone47.0a1
backs outc42ff68476314d5fc849f9a90e5195000ccf2128
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
backout c42ff6847631 (bug 1250572) for causing aborts during startup
dom/base/StructuredCloneHolder.cpp
dom/messagechannel/MessageChannel.cpp
dom/messagechannel/MessageChannel.h
dom/messagechannel/MessagePort.cpp
dom/messagechannel/MessagePort.h
dom/workers/RuntimeService.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/XMLHttpRequest.cpp
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -290,17 +290,16 @@ StructuredCloneHolder::Write(JSContext* 
 void
 StructuredCloneHolder::Read(nsISupports* aParent,
                             JSContext* aCx,
                             JS::MutableHandle<JS::Value> aValue,
                             ErrorResult& aRv)
 {
   MOZ_ASSERT_IF(mSupportedContext == SameProcessSameThread,
                 mCreationThread == NS_GetCurrentThread());
-  MOZ_ASSERT(aParent);
 
   mozilla::AutoRestore<nsISupports*> guard(mParent);
   mParent = aParent;
 
   if (!StructuredCloneHolderBase::Read(aCx, aValue)) {
     JS_ClearPendingException(aCx);
     aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
   }
@@ -1040,21 +1039,19 @@ StructuredCloneHolder::CustomReadTransfe
                                                  JS::MutableHandleObject aReturnObject)
 {
   MOZ_ASSERT(mSupportsTransferring);
 
   if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
     MOZ_ASSERT(aExtraData < mPortIdentifiers.Length());
     const MessagePortIdentifier& portIdentifier = mPortIdentifiers[aExtraData];
 
-    nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mParent);
-
     ErrorResult rv;
     RefPtr<MessagePort> port =
-      MessagePort::Create(global, portIdentifier, rv);
+      MessagePort::Create(mParent, portIdentifier, rv);
     if (NS_WARN_IF(rv.Failed())) {
       return false;
     }
 
     mTransferredPorts.AppendElement(port);
 
     JS::Rooted<JS::Value> value(aCx);
     if (!GetOrCreateDOMReflector(aCx, port, &value)) {
--- a/dom/messagechannel/MessageChannel.cpp
+++ b/dom/messagechannel/MessageChannel.cpp
@@ -8,80 +8,78 @@
 
 #include "mozilla/dom/MessageChannelBinding.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
-#include "nsIGlobalObject.h"
 #include "nsIPrincipal.h"
+#include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MessageChannel, mGlobal, mPort1, mPort2)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MessageChannel, mWindow, mPort1, mPort2)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MessageChannel)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MessageChannel)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageChannel)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-MessageChannel::MessageChannel(nsIGlobalObject* aGlobal)
-  : mGlobal(aGlobal)
+MessageChannel::MessageChannel(nsPIDOMWindowInner* aWindow)
+  : mWindow(aWindow)
 {
-  MOZ_ASSERT(aGlobal);
 }
 
 MessageChannel::~MessageChannel()
 {
 }
 
 JSObject*
 MessageChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return MessageChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<MessageChannel>
 MessageChannel::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
-  return Constructor(global, aRv);
+  // window can be null in workers.
+  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
+  return Constructor(window, aRv);
 }
 
 /* static */ already_AddRefed<MessageChannel>
-MessageChannel::Constructor(nsIGlobalObject* aGlobal, ErrorResult& aRv)
+MessageChannel::Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv)
 {
-  MOZ_ASSERT(aGlobal);
-
   nsID portUUID1;
   aRv = nsContentUtils::GenerateUUIDInPlace(portUUID1);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   nsID portUUID2;
   aRv = nsContentUtils::GenerateUUIDInPlace(portUUID2);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  RefPtr<MessageChannel> channel = new MessageChannel(aGlobal);
+  RefPtr<MessageChannel> channel = new MessageChannel(aWindow);
 
-  channel->mPort1 = MessagePort::Create(aGlobal, portUUID1, portUUID2, aRv);
+  channel->mPort1 = MessagePort::Create(aWindow, portUUID1, portUUID2, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  channel->mPort2 = MessagePort::Create(aGlobal, portUUID2, portUUID1, aRv);
+  channel->mPort2 = MessagePort::Create(aWindow, portUUID2, portUUID1, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   channel->mPort1->UnshippedEntangle(channel->mPort2);
   channel->mPort2->UnshippedEntangle(channel->mPort1);
 
   return channel.forget();
--- a/dom/messagechannel/MessageChannel.h
+++ b/dom/messagechannel/MessageChannel.h
@@ -9,62 +9,62 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "nsCOMPtr.h"
 
-class nsIGlobalObject;
+class nsPIDOMWindowInner;
 
 namespace mozilla {
 namespace dom {
 
 class MessagePort;
 
 class MessageChannel final : public nsISupports
                            , public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MessageChannel)
 
-  nsIGlobalObject*
+  nsPIDOMWindowInner*
   GetParentObject() const
   {
-    return mGlobal;
+    return mWindow;
   }
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   static already_AddRefed<MessageChannel>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
   static already_AddRefed<MessageChannel>
-  Constructor(nsIGlobalObject* aGlobal, ErrorResult& aRv);
+  Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv);
 
   MessagePort*
   Port1() const
   {
     return mPort1;
   }
 
   MessagePort*
   Port2() const
   {
     return mPort2;
   }
 
 private:
-  explicit MessageChannel(nsIGlobalObject* aGlobal);
+  explicit MessageChannel(nsPIDOMWindowInner* aWindow);
   ~MessageChannel();
 
-  nsCOMPtr<nsIGlobalObject> mGlobal;
+  nsCOMPtr<nsPIDOMWindowInner> mWindow;
 
   RefPtr<MessagePort> mPort1;
   RefPtr<MessagePort> mPort2;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -81,18 +81,25 @@ public:
     mData = nullptr;
     return NS_OK;
   }
 
 private:
   nsresult
   DispatchMessage() const
   {
-    nsCOMPtr<nsIGlobalObject> globalObject = mPort->GetParentObject();
-    MOZ_ASSERT(globalObject);
+    nsCOMPtr<nsIGlobalObject> globalObject;
+
+    if (NS_IsMainThread()) {
+      globalObject = do_QueryInterface(mPort->GetParentObject());
+    } else {
+      WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
+      MOZ_ASSERT(workerPrivate);
+      globalObject = workerPrivate->GlobalScope();
+    }
 
     AutoJSAPI jsapi;
     if (!globalObject || !jsapi.Init(globalObject)) {
       NS_WARNING("Failed to initialize AutoJSAPI object.");
       return NS_ERROR_FAILURE;
     }
 
     JSContext* cx = jsapi.cx();
@@ -247,55 +254,54 @@ private:
 
   const MessagePortIdentifier mIdentifier;
 };
 
 NS_IMPL_ISUPPORTS(ForceCloseHelper, nsIIPCBackgroundChildCreateCallback)
 
 } // namespace
 
-MessagePort::MessagePort(nsIGlobalObject* aGlobal)
-  : DOMEventTargetHelper(aGlobal)
-  , mInnerID(0)
+MessagePort::MessagePort(nsISupports* aSupports)
+  : mInnerID(0)
   , mMessageQueueEnabled(false)
   , mIsKeptAlive(false)
 {
-  MOZ_ASSERT(aGlobal);
-
   mIdentifier = new MessagePortIdentifier();
   mIdentifier->neutered() = true;
   mIdentifier->sequenceId() = 0;
+
+  nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(aSupports);
+  if (NS_WARN_IF(!globalObject)) {
+    return;
+  }
+  BindToOwner(globalObject);
 }
 
 MessagePort::~MessagePort()
 {
   CloseForced();
   MOZ_ASSERT(!mWorkerFeature);
 }
 
 /* static */ already_AddRefed<MessagePort>
-MessagePort::Create(nsIGlobalObject* aGlobal, const nsID& aUUID,
+MessagePort::Create(nsISupports* aSupport, const nsID& aUUID,
                     const nsID& aDestinationUUID, ErrorResult& aRv)
 {
-  MOZ_ASSERT(aGlobal);
-
-  RefPtr<MessagePort> mp = new MessagePort(aGlobal);
+  RefPtr<MessagePort> mp = new MessagePort(aSupport);
   mp->Initialize(aUUID, aDestinationUUID, 1 /* 0 is an invalid sequence ID */,
                  false /* Neutered */, eStateUnshippedEntangled, aRv);
   return mp.forget();
 }
 
 /* static */ already_AddRefed<MessagePort>
-MessagePort::Create(nsIGlobalObject* aGlobal,
+MessagePort::Create(nsISupports* aSupport,
                     const MessagePortIdentifier& aIdentifier,
                     ErrorResult& aRv)
 {
-  MOZ_ASSERT(aGlobal);
-
-  RefPtr<MessagePort> mp = new MessagePort(aGlobal);
+  RefPtr<MessagePort> mp = new MessagePort(aSupport);
   mp->Initialize(aIdentifier.uuid(), aIdentifier.destinationUuid(),
                  aIdentifier.sequenceId(), aIdentifier.neutered(),
                  eStateEntangling, aRv);
   return mp.forget();
 }
 
 void
 MessagePort::UnshippedEntangle(MessagePort* aEntangledPort)
--- a/dom/messagechannel/MessagePort.h
+++ b/dom/messagechannel/MessagePort.h
@@ -11,17 +11,17 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsIIPCBackgroundChildCreateCallback.h"
 #include "nsTArray.h"
 
 #ifdef XP_WIN
 #undef PostMessage
 #endif
 
-class nsIGlobalObject;
+class nsPIDOMWindowInner;
 
 namespace mozilla {
 namespace dom {
 
 class MessagePortChild;
 class MessagePortIdentifier;
 class MessagePortMessage;
 class PostMessageRunnable;
@@ -40,22 +40,21 @@ class MessagePort final : public DOMEven
 public:
   NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
   NS_DECL_NSIOBSERVER
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort,
                                            DOMEventTargetHelper)
 
   static already_AddRefed<MessagePort>
-  Create(nsIGlobalObject* aGlobal, const nsID& aUUID,
+  Create(nsISupports* aSupport, const nsID& aUUID,
          const nsID& aDestinationUUID, ErrorResult& aRv);
 
   static already_AddRefed<MessagePort>
-  Create(nsIGlobalObject* aGlobal,
-         const MessagePortIdentifier& aIdentifier,
+  Create(nsISupports* aSupport, const MessagePortIdentifier& aIdentifier,
          ErrorResult& aRv);
 
   // For IPC.
   static void
   ForceClose(const MessagePortIdentifier& aIdentifier);
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@@ -84,17 +83,17 @@ public:
   // These methods are useful for MessagePortChild
 
   void Entangled(nsTArray<MessagePortMessage>& aMessages);
   void MessagesReceived(nsTArray<MessagePortMessage>& aMessages);
   void StopSendingDataConfirmed();
   void Closed();
 
 private:
-  explicit MessagePort(nsIGlobalObject* aGlobal);
+  explicit MessagePort(nsISupports* nsISupports);
   ~MessagePort();
 
   enum State {
     // When a port is created by a MessageChannel it is entangled with the
     // other. They both run on the same thread, same event loop and the
     // messages are added to the queues without using PBackground actors.
     // When one of the port is shipped, the state is changed to
     // StateEntangling.
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2381,24 +2381,23 @@ RuntimeService::CreateSharedWorkerFromLo
     // If we're attaching to an existing SharedWorker private, then we
     // must update the overriden load group to account for our document's
     // load group.
     workerPrivate->UpdateOverridenLoadGroup(aLoadInfo->mLoadGroup);
   }
 
   // We don't actually care about this MessageChannel, but we use it to 'steal'
   // its 2 connected ports.
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
-  RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, rv);
+  RefPtr<MessageChannel> channel = MessageChannel::Constructor(window, rv);
   if (NS_WARN_IF(rv.Failed())) {
     return rv.StealNSResult();
   }
 
   RefPtr<SharedWorker> sharedWorker = new SharedWorker(window, workerPrivate,
-                                                       channel->Port1());
+                                                         channel->Port1());
 
   if (!workerPrivate->RegisterSharedWorker(aCx, sharedWorker,
                                            channel->Port2())) {
     NS_WARNING("Worker is unreachable, this shouldn't happen!");
     sharedWorker->Close();
     return NS_ERROR_FAILURE;
   }
 
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -667,18 +667,20 @@ public:
   {
     mEventSource = Move(aSource);
   }
 
   bool
   DispatchDOMEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
                    DOMEventTargetHelper* aTarget, bool aIsMainThread)
   {
-    nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(aTarget->GetParentObject());
-    MOZ_ASSERT(parent);
+    nsCOMPtr<nsPIDOMWindowInner> parent;
+    if (aIsMainThread) {
+      parent = do_QueryInterface(aTarget->GetParentObject());
+    }
 
     JS::Rooted<JS::Value> messageData(aCx);
     ErrorResult rv;
 
     UniquePtr<AbstractTimelineMarker> start;
     UniquePtr<AbstractTimelineMarker> end;
     RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
     bool isTimelineRecording = timelines && !timelines->IsEmpty();
@@ -6377,17 +6379,17 @@ WorkerPrivate::ConnectMessagePort(JSCont
   WorkerGlobalScope* globalScope = GlobalScope();
 
   JS::Rooted<JSObject*> jsGlobal(aCx, globalScope->GetWrapper());
   MOZ_ASSERT(jsGlobal);
 
   // This MessagePortIdentifier is used to create a new port, still connected
   // with the other one, but in the worker thread.
   ErrorResult rv;
-  RefPtr<MessagePort> port = MessagePort::Create(globalScope, aIdentifier, rv);
+  RefPtr<MessagePort> port = MessagePort::Create(nullptr, aIdentifier, rv);
   if (NS_WARN_IF(rv.Failed())) {
     return false;
   }
 
   GlobalObject globalObject(aCx, jsGlobal);
   if (globalObject.Failed()) {
     return false;
   }
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -21,17 +21,16 @@
 #include "mozilla/dom/StructuredCloneHolder.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "nsThreadUtils.h"
 #include "nsVariant.h"
 
 #include "RuntimeService.h"
-#include "WorkerScope.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "XMLHttpRequestUpload.h"
 
 using namespace mozilla;
 
 using namespace mozilla::dom;
 USING_WORKERS_NAMESPACE
@@ -1332,22 +1331,17 @@ EventRunnable::WorkerRun(JSContext* aCx,
     state->mResponseResult = mResponseResult;
 
     if (NS_SUCCEEDED(mResponseResult)) {
       if (HasData()) {
         MOZ_ASSERT(mResponse.isUndefined());
 
         ErrorResult rv;
         JS::Rooted<JS::Value> response(aCx);
-
-        GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
-        nsCOMPtr<nsIGlobalObject> global =
-          do_QueryInterface(globalObj.GetAsSupports());
-
-        Read(global, aCx, &response, rv);
+        Read(nullptr, aCx, &response, rv);
         if (NS_WARN_IF(rv.Failed())) {
           rv.SuppressException();
           return false;
         }
 
         state->mResponse = response;
       }
       else {
@@ -1514,28 +1508,18 @@ SendRunnable::MainThreadRun()
     AutoSafeJSContext cx;
     JSAutoRequest ar(cx);
 
     nsIXPConnect* xpc = nsContentUtils::XPConnect();
     MOZ_ASSERT(xpc);
 
     ErrorResult rv;
 
-    JS::Rooted<JSObject*> globalObject(cx, JS::CurrentGlobalOrNull(cx));
-    if (NS_WARN_IF(!globalObject)) {
-      return NS_ERROR_FAILURE;
-    }
-
-    nsCOMPtr<nsIGlobalObject> parent = xpc::NativeGlobal(globalObject);
-    if (NS_WARN_IF(!parent)) {
-      return NS_ERROR_FAILURE;
-    }
-
     JS::Rooted<JS::Value> body(cx);
-    Read(parent, cx, &body, rv);
+    Read(nullptr, cx, &body, rv);
     if (NS_WARN_IF(rv.Failed())) {
       return rv.StealNSResult();
     }
 
     rv = xpc->JSValToVariant(cx, body, getter_AddRefs(variant));
     if (NS_WARN_IF(rv.Failed())) {
       return rv.StealNSResult();
     }