backout c42ff6847631 (bug 1250572) for causing aborts during startup
authorDaniel Holbert <dholbert@cs.stanford.edu>
Wed, 24 Feb 2016 11:54:35 -0800
changeset 285454 07f601e5ce85d64f01434cacd3361c21b5e73e33
parent 285453 84ba22179d9775a7b79e78df2a9e099ba18ebaac
child 285455 93390f1d1faa6a133d5ed53629df227030304198
push id17822
push usercbook@mozilla.com
push dateThu, 25 Feb 2016 11:00:09 +0000
treeherderfx-team@1c779b0b8969 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1250572
milestone47.0a1
backs outc42ff68476314d5fc849f9a90e5195000ccf2128
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();
     }