Backout rev eedf61cab3fa (bug 643325) for test failures
authorBen Turner <bent.mozilla@gmail.com>
Tue, 01 Oct 2013 01:06:11 -0700
changeset 149473 af4605d0cc6b64214f3b344c12a376a03d43fd13
parent 149472 f550869d86bc6e7b3733fc33d49ca952f6e50af7
child 149474 fd6ed8459a47018249301b8f47fcba2b37aae165
push id1345
push userryanvm@gmail.com
push dateTue, 01 Oct 2013 20:49:22 +0000
treeherderb2g-inbound@242aa3916310 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs643325
milestone27.0a1
Backout rev eedf61cab3fa (bug 643325) for test failures
content/events/test/test_all_synthetic_events.html
dom/base/nsGlobalWindow.cpp
dom/bindings/BindingDeclarations.h
dom/bindings/Bindings.conf
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/AbstractWorker.webidl
dom/webidl/ErrorEvent.webidl
dom/webidl/SharedWorker.webidl
dom/webidl/WorkerMessagePort.webidl
dom/webidl/moz.build
dom/workers/DOMBindingInlines.h
dom/workers/Events.cpp
dom/workers/Events.h
dom/workers/FileReaderSync.cpp
dom/workers/FileReaderSync.h
dom/workers/Location.cpp
dom/workers/MessagePort.cpp
dom/workers/MessagePort.h
dom/workers/Navigator.cpp
dom/workers/RuntimeService.cpp
dom/workers/RuntimeService.h
dom/workers/ScriptLoader.cpp
dom/workers/ScriptLoader.h
dom/workers/SharedWorker.cpp
dom/workers/SharedWorker.h
dom/workers/Worker.cpp
dom/workers/Worker.h
dom/workers/WorkerMessagePort.cpp
dom/workers/WorkerMessagePort.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/WorkerScope.cpp
dom/workers/WorkerScope.h
dom/workers/Workers.h
dom/workers/moz.build
dom/workers/test/Makefile.in
dom/workers/test/mochitest.ini
dom/workers/test/multi_sharedWorker_frame.html
dom/workers/test/multi_sharedWorker_sharedWorker.js
dom/workers/test/sharedWorker_sharedWorker.js
dom/workers/test/test_multi_sharedWorker.html
dom/workers/test/test_multi_sharedWorker_lifetimes.html
dom/workers/test/test_sharedWorker.html
modules/libpref/src/init/all.js
--- a/content/events/test/test_all_synthetic_events.html
+++ b/content/events/test/test_all_synthetic_events.html
@@ -130,20 +130,16 @@ const kEventConstructors = {
                                                                          aProps.view, aProps.detail,
                                                                          aProps.screenX, aProps.screenY,
                                                                          aProps.clientX, aProps.clientY,
                                                                          aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey,
                                                                          aProps.button, aProps.relatedTarget, aProps.dataTransfer);
                                                          return e;
                                                        },
                                              },
-  ErrorEvent:                                { create: function (aName, aProps) {
-                                                         return new ErrorEvent(aName, aProps);
-                                                       },
-  },
   ElementReplaceEvent:                       { create: function (aName, aProps) {
                                                          return new ElementReplaceEvent(aName, aProps);
                                                        },
                                              },
   FocusEvent:                                { create: function (aName, aProps) {
                                                          return new FocusEvent(aName, aProps);
                                                        },
                                              },
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1428,17 +1428,22 @@ nsGlobalWindow::FreeInnerObjects()
   NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
 
   // Make sure that this is called before we null out the document and
   // other members that the window destroyed observers could
   // re-create.
   NotifyDOMWindowDestroyed(this);
 
   // Kill all of the workers for this window.
-  mozilla::dom::workers::CancelWorkersForWindow(this);
+  // We push a cx so that exceptions get reported in the right DOM Window.
+  {
+    nsIScriptContext *scx = GetContextInternal();
+    AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
+    mozilla::dom::workers::CancelWorkersForWindow(cx, this);
+  }
 
   // Close all offline storages for this window.
   quota::QuotaManager* quotaManager = quota::QuotaManager::Get();
   if (quotaManager) {
     quotaManager->AbortCloseStoragesForWindow(this);
   }
 
   ClearAllTimeouts();
@@ -11230,17 +11235,22 @@ nsGlobalWindow::SuspendTimeouts(uint32_t
     nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
     if (ac) {
       for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
         ac->RemoveWindowListener(mEnabledSensors[i], this);
     }
     DisableGamepadUpdates();
 
     // Suspend all of the workers for this window.
-    mozilla::dom::workers::SuspendWorkersForWindow(this);
+    // We push a cx so that exceptions get reported in the right DOM Window.
+    {
+      nsIScriptContext *scx = GetContextInternal();
+      AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
+      mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
+    }
 
     TimeStamp now = TimeStamp::Now();
     for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
       // Set mTimeRemaining to be the time remaining for this timer.
       if (t->mWhen > now)
         t->mTimeRemaining = t->mWhen - now;
       else
         t->mTimeRemaining = TimeDuration(0);
@@ -11319,17 +11329,20 @@ nsGlobalWindow::ResumeTimeouts(bool aTha
     EnableGamepadUpdates();
 
     // Resume all of the AudioContexts for this window
     for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
       mAudioContexts[i]->Resume();
     }
 
     // Resume all of the workers for this window.
-    mozilla::dom::workers::ResumeWorkersForWindow(this);
+    // We push a cx so that exceptions get reported in the right DOM Window.
+    nsIScriptContext *scx = GetContextInternal();
+    AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
+    mozilla::dom::workers::ResumeWorkersForWindow(scx, this);
 
     // Restore all of the timeouts, using the stored time remaining
     // (stored in timeout->mTimeRemaining).
 
     TimeStamp now = TimeStamp::Now();
 
 #ifdef DEBUG
     bool _seenDummyTimeout = false;
@@ -12111,9 +12124,10 @@ nsGlobalWindow::DisableNetworkEvent(uint
   }
 #define WINDOW_ONLY_EVENT EVENT
 #define TOUCH_EVENT EVENT
 #include "nsEventNameList.h"
 #undef TOUCH_EVENT
 #undef WINDOW_ONLY_EVENT
 #undef BEFOREUNLOAD_EVENT
 #undef ERROR_EVENT
-#undef EVENT
\ No newline at end of file
+#undef EVENT
+
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -616,9 +616,9 @@ struct ParentObject {
 
   nsISupports* const mObject;
   nsWrapperCache* const mWrapperCache;
 };
 
 } // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_dom_BindingDeclarations_h__
\ No newline at end of file
+#endif // mozilla_dom_BindingDeclarations_h__
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -78,20 +78,16 @@
 # worker descriptors for objects that will never actually appear in workers.
 
 DOMInterfaces = {
 
 'MozActivity': {
     'nativeType': 'mozilla::dom::Activity',
 },
 
-'AbstractWorker': {
-    'concrete': False
-},
-
 'AnimationEvent': {
     'nativeType': 'nsDOMAnimationEvent',
 },
 
 'ArchiveReader': {
     'nativeType': 'mozilla::dom::file::ArchiveReader',
 },
 
@@ -942,22 +938,16 @@ DOMInterfaces = {
 'Screen': {
     'nativeType': 'nsScreen',
 },
 
 'ScrollAreaEvent': {
     'nativeType': 'nsDOMScrollAreaEvent',
 },
 
-'SharedWorker': {
-    'nativeType': 'mozilla::dom::workers::SharedWorker',
-    'headerFile': 'mozilla/dom/workers/bindings/SharedWorker.h',
-    'implicitJSContext': [ 'constructor' ],
-},
-
 'SimpleGestureEvent': {
     'nativeType': 'nsDOMSimpleGestureEvent',
 },
 
 'SourceBufferList': {
     'resultNotAddRefed': [ '__indexedGetter' ],
 },
 
@@ -1443,28 +1433,16 @@ DOMInterfaces = {
     'workers': True
 }],
 
 'WorkerLocation': {
     'headerFile': 'mozilla/dom/workers/bindings/Location.h',
     'workers': True,
 },
 
-'WorkerMessagePort': [{
-    'nativeType': 'mozilla::dom::workers::MessagePort',
-    'headerFile': 'mozilla/dom/workers/bindings/MessagePort.h',
-    'implicitJSContext': [ 'postMessage' ],
-},
-{
-    'nativeType': 'mozilla::dom::workers::WorkerMessagePort',
-    'headerFile': 'mozilla/dom/workers/bindings/WorkerMessagePort.h',
-    'workers': True,
-    'nativeOwnership': 'worker',
-}],
-
 'WorkerNavigator': {
     'headerFile': 'mozilla/dom/workers/bindings/Navigator.h',
     'workers': True,
 },
 
 'XMLHttpRequest': [
 {
     'nativeType': 'nsXMLHttpRequest',
@@ -1880,9 +1858,9 @@ addExternalIface('CameraCapabilities', n
 addExternalIface('CameraAutoFocusCallback', nativeType='nsICameraAutoFocusCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraShutterCallback', nativeType='nsICameraShutterCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraClosedCallback', nativeType='nsICameraClosedCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraTakePictureCallback', nativeType='nsICameraTakePictureCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraReleaseCallback', nativeType='nsICameraReleaseCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraStartRecordingCallback', nativeType='nsICameraStartRecordingCallback', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraPreviewStateChange', nativeType='nsICameraPreviewStateChange', headerFile='nsIDOMCameraManager.h')
 addExternalIface('CameraPreviewStreamCallback', nativeType='nsICameraPreviewStreamCallback', headerFile='nsIDOMCameraManager.h')
-addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')
\ No newline at end of file
+addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -179,17 +179,16 @@ var interfaceNamesInGlobalScope =
     "DOMStringList",
     "DOMStringMap",
     "DOMTokenList",
     "DOMTransactionEvent",
     "DragEvent",
     "DynamicsCompressorNode",
     "Element",
     "ElementReplaceEvent",
-    "ErrorEvent",
     "Event",
     "EventListenerInfo",
     "EventSource",
     "EventTarget",
     "File",
     "FileHandle",
     "FileList",
     "FileReader",
deleted file mode 100644
--- a/dom/webidl/AbstractWorker.webidl
+++ /dev/null
@@ -1,10 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-[NoInterfaceObject]
-interface AbstractWorker {
-    attribute EventHandler onerror;
-};
deleted file mode 100644
--- a/dom/webidl/ErrorEvent.webidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-[Constructor(DOMString type, optional ErrorEventInit eventInitDict)]
-interface ErrorEvent : Event
-{
-  readonly attribute DOMString message;
-  readonly attribute DOMString filename;
-  readonly attribute unsigned long lineno;
-  readonly attribute unsigned long column;
-};
-
-dictionary ErrorEventInit : EventInit
-{
-  DOMString message = "";
-  DOMString filename = "";
-  unsigned long lineno = 0;
-  unsigned long column = 0;
-};
deleted file mode 100644
--- a/dom/webidl/SharedWorker.webidl
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-[PrefControlled,
- Constructor(DOMString scriptURL, optional DOMString name)]
-interface SharedWorker : EventTarget {
-    readonly attribute WorkerMessagePort port;
-};
-
-SharedWorker implements AbstractWorker;
deleted file mode 100644
--- a/dom/webidl/WorkerMessagePort.webidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-// XXX Remove me soon!
-[PrefControlled]
-interface WorkerMessagePort : EventTarget {
-    [Throws]
-    void postMessage(any message, optional sequence<any> transferable);
-
-    void start();
-
-    void close();
-
-    [SetterThrows=Workers, GetterThrows=Workers]
-    attribute EventHandler onmessage;
-};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -11,17 +11,16 @@ GENERATED_WEBIDL_FILES = [
 ]
 
 PREPROCESSED_WEBIDL_FILES = [
     'Crypto.webidl',
     'Navigator.webidl',
 ]
 
 WEBIDL_FILES = [
-    'AbstractWorker.webidl',
     'AnalyserNode.webidl',
     'AnimationEvent.webidl',
     'ArchiveReader.webidl',
     'ArchiveRequest.webidl',
     'Attr.webidl',
     'AudioBuffer.webidl',
     'AudioBufferSourceNode.webidl',
     'AudioContext.webidl',
@@ -362,17 +361,16 @@ WEBIDL_FILES = [
     'SVGUseElement.webidl',
     'SVGViewElement.webidl',
     'SVGZoomAndPan.webidl',
     'SVGZoomEvent.webidl',
     'Screen.webidl',
     'ScriptProcessorNode.webidl',
     'ScrollAreaEvent.webidl',
     'SettingsManager.webidl',
-    'SharedWorker.webidl',
     'SimpleGestureEvent.webidl',
     'SourceBuffer.webidl',
     'SourceBufferList.webidl',
     'StorageType.webidl',
     'StyleSheet.webidl',
     'Telephony.webidl',
     'TelephonyCall.webidl',
     'TelephonyCallGroup.webidl',
@@ -403,17 +401,16 @@ WEBIDL_FILES = [
     'VideoStreamTrack.webidl',
     'WaveShaperNode.webidl',
     'WebComponents.webidl',
     'WebSocket.webidl',
     'WheelEvent.webidl',
     'WifiOptions.webidl',
     'Window.webidl',
     'WorkerLocation.webidl',
-    'WorkerMessagePort.webidl',
     'WorkerNavigator.webidl',
     'XMLDocument.webidl',
     'XMLHttpRequest.webidl',
     'XMLHttpRequestEventTarget.webidl',
     'XMLHttpRequestUpload.webidl',
     'XMLSerializer.webidl',
     'XMLStylesheetProcessingInstruction.webidl',
     'XPathEvaluator.webidl',
@@ -535,23 +532,23 @@ if CONFIG['ENABLE_TESTS']:
         'TestExampleGen.webidl',
         'TestJSImplGen.webidl',
     ]
 
 GENERATED_EVENTS_WEBIDL_FILES = [
     'BlobEvent.webidl',
     'DeviceLightEvent.webidl',
     'DeviceProximityEvent.webidl',
-    'ErrorEvent.webidl',
     'MediaStreamEvent.webidl',
     'MozInterAppMessageEvent.webidl',
     'RTCDataChannelEvent.webidl',
     'RTCPeerConnectionIceEvent.webidl',
     'UserProximityEvent.webidl',
 ]
 
 if CONFIG['MOZ_GAMEPAD']:
     GENERATED_EVENTS_WEBIDL_FILES += [
         'GamepadAxisMoveEvent.webidl',
         'GamepadButtonEvent.webidl',
         'GamepadEvent.webidl',
     ]
 
+
--- a/dom/workers/DOMBindingInlines.h
+++ b/dom/workers/DOMBindingInlines.h
@@ -1,29 +1,27 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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 mozilla_dom_workers_dombindinginlines_h__
 #define mozilla_dom_workers_dombindinginlines_h__
 
-#include "jsfriendapi.h"
 #include "mozilla/dom/JSSlots.h"
-#include "mozilla/dom/URLBinding.h"
-#include "mozilla/dom/WorkerMessagePortBinding.h"
 #include "mozilla/dom/XMLHttpRequestBinding.h"
 #include "mozilla/dom/XMLHttpRequestUploadBinding.h"
+#include "mozilla/dom/URLBinding.h"
+#include "jsfriendapi.h"
 
 BEGIN_WORKERS_NAMESPACE
 
-class URL;
-class WorkerMessagePort;
 class XMLHttpRequest;
 class XMLHttpRequestUpload;
+class URL;
 
 namespace {
 
 template <class T>
 struct WrapPrototypeTraits
 { };
 
 // XXX I kinda hate this, but we decided it wasn't worth generating this in the
@@ -42,20 +40,19 @@ struct WrapPrototypeTraits
     static inline JSObject*                                                    \
     GetProtoObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal)              \
     {                                                                          \
       using namespace mozilla::dom;                                            \
       return _class##Binding_workers::GetProtoObject(aCx, aGlobal);            \
     }                                                                          \
   };
 
-SPECIALIZE_PROTO_TRAITS(URL)
-SPECIALIZE_PROTO_TRAITS(WorkerMessagePort)
 SPECIALIZE_PROTO_TRAITS(XMLHttpRequest)
 SPECIALIZE_PROTO_TRAITS(XMLHttpRequestUpload)
+SPECIALIZE_PROTO_TRAITS(URL)
 
 #undef SPECIALIZE_PROTO_TRAITS
 
 } // anonymous namespace
 
 template <class T>
 inline JSObject*
 Wrap(JSContext* aCx, JSObject* aGlobal, nsRefPtr<T>& aConcreteObject)
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -409,101 +409,57 @@ public:
   {
     const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     return JS_InitClass(aCx, aObj, aParentProto, clasp, Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
   static JSObject*
-  Create(JSContext* aCx, JS::Handle<JSObject*> aParent,
-         JSAutoStructuredCloneBuffer& aData,
-         nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects,
-         bool aMainRuntime)
+  Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JSAutoStructuredCloneBuffer& aData,
+         nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects, bool aMainRuntime)
   {
     JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "message"));
     if (!type) {
       return NULL;
     }
 
     const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, clasp, NULL, aParent));
     if (!obj) {
       return NULL;
     }
 
-    JS::Rooted<JSObject*> ports(aCx, JS_NewArrayObject(aCx, 0, nullptr));
-    if (!ports) {
-      return NULL;
-    }
-
     MessageEvent* priv = new MessageEvent(aMainRuntime);
     SetJSPrivateSafeish(obj, priv);
-
     InitMessageEventCommon(aCx, obj, priv, type, false, false, NULL, NULL, NULL,
-                           ports, true);
-
+                           true);
     priv->mBuffer.swap(aData);
     priv->mClonedObjects.SwapElements(aClonedObjects);
 
     return obj;
   }
 
-  static JSObject*
-  Create(JSContext* aCx, JS::Handle<JSObject*> aParent,
-         JS::Handle<JSString*> aType, bool aBubbles, bool aCancelable,
-         JS::Handle<JSString*> aData, JS::Handle<JSString*> aOrigin,
-         JS::Handle<JSObject*> aSource, JS::Handle<JSObject*> aMessagePort,
-         bool aIsTrusted)
-  {
-    JS::Rooted<JSObject*> obj(aCx,
-                              JS_NewObject(aCx, &sClass, nullptr, aParent));
-    if (!obj) {
-      return nullptr;
-    }
-
-    JS::Rooted<JSObject*> ports(aCx);
-    if (aMessagePort) {
-      JS::Value port = OBJECT_TO_JSVAL(aMessagePort);
-      ports = JS_NewArrayObject(aCx, 1, &port);
-    } else {
-      ports = JS_NewArrayObject(aCx, 0, nullptr);
-    }
-
-    if (!ports) {
-      return NULL;
-    }
-
-    MessageEvent* priv = new MessageEvent(false);
-    SetJSPrivateSafeish(obj, priv);
-
-    InitMessageEventCommon(aCx, obj, priv, aType, aBubbles, aCancelable, aData,
-                           aOrigin, aSource, ports, aIsTrusted);
-
-    return obj;
-  }
-
 protected:
   MessageEvent(bool aMainRuntime)
   : mMainRuntime(aMainRuntime)
   {
     MOZ_COUNT_CTOR(mozilla::dom::workers::MessageEvent);
   }
 
   virtual ~MessageEvent()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::MessageEvent);
   }
 
   enum SLOT {
     SLOT_data = Event::SLOT_COUNT,
     SLOT_origin,
     SLOT_source,
-    SLOT_ports,
 
     SLOT_COUNT,
     SLOT_FIRST = SLOT_data
   };
 
 private:
   static MessageEvent*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
@@ -518,28 +474,27 @@ private:
                          classPtr->name);
     return NULL;
   }
 
   static void
   InitMessageEventCommon(JSContext* aCx, JSObject* aObj, Event* aEvent,
                          JSString* aType, bool aBubbles, bool aCancelable,
                          JSString* aData, JSString* aOrigin, JSObject* aSource,
-                         JS::Handle<JSObject*> aMessagePorts, bool aIsTrusted)
+                         bool aIsTrusted)
   {
     jsval emptyString = JS_GetEmptyStringValue(aCx);
 
     Event::InitEventCommon(aObj, aEvent, aType, aBubbles, aCancelable,
                            aIsTrusted);
     JS_SetReservedSlot(aObj, SLOT_data,
                        aData ? STRING_TO_JSVAL(aData) : emptyString);
     JS_SetReservedSlot(aObj, SLOT_origin,
                        aOrigin ? STRING_TO_JSVAL(aOrigin) : emptyString);
     JS_SetReservedSlot(aObj, SLOT_source, OBJECT_TO_JSVAL(aSource));
-    JS_SetReservedSlot(aObj, SLOT_ports, OBJECT_TO_JSVAL(aMessagePorts));
   }
 
   static bool
   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
@@ -631,17 +586,17 @@ private:
     JS::Rooted<JSObject*> source(aCx);
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "SbbSSo", type.address(),
                              &bubbles, &cancelable, data.address(),
                              origin.address(), source.address())) {
       return false;
     }
 
     InitMessageEventCommon(aCx, obj, event, type, bubbles, cancelable,
-                           data, origin, source, JS::NullPtr(), false);
+                           data, origin, source, false);
     return true;
   }
 };
 
 #define DECL_MESSAGEEVENT_CLASS(_varname, _name) \
   const JSClass _varname = { \
     _name, \
     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT), \
@@ -656,18 +611,16 @@ DECL_MESSAGEEVENT_CLASS(MessageEvent::sM
 
 const JSPropertySpec MessageEvent::sProperties[] = {
   JS_PSGS("data", Property<SLOT_data>::Get, GetterOnlyJSNative,
           JSPROP_ENUMERATE),
   JS_PSGS("origin", Property<SLOT_origin>::Get, GetterOnlyJSNative,
           JSPROP_ENUMERATE),
   JS_PSGS("source", Property<SLOT_source>::Get, GetterOnlyJSNative,
           JSPROP_ENUMERATE),
-  JS_PSGS("ports", Property<SLOT_ports>::Get, GetterOnlyJSNative,
-          JSPROP_ENUMERATE),
   JS_PS_END
 };
 
 const JSFunctionSpec MessageEvent::sFunctions[] = {
   JS_FN("initMessageEvent", InitMessageEvent, 6, FUNCTION_FLAGS),
   JS_FS_END
 };
 
@@ -1091,35 +1044,16 @@ JSObject*
 CreateProgressEvent(JSContext* aCx, JS::Handle<JSString*> aType, bool aLengthComputable,
                     double aLoaded, double aTotal)
 {
   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
   return ProgressEvent::Create(aCx, global, aType, aLengthComputable, aLoaded,
                                aTotal);
 }
 
-JSObject*
-CreateConnectEvent(JSContext* aCx, JS::Handle<JSObject*> aMessagePort)
-{
-  JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
-
-  JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "connect"));
-  if (!type) {
-    return nullptr;
-  }
-
-  JS::Rooted<JSString*> emptyStr(aCx, JS_GetEmptyString(JS_GetRuntime(aCx)));
-  if (!emptyStr) {
-    return nullptr;
-  }
-
-  return MessageEvent::Create(aCx, global, type, false, false, emptyStr,
-                              emptyStr, JS::NullPtr(), aMessagePort, true);
-}
-
 bool
 IsSupportedEventClass(JSObject* aEvent)
 {
   return Event::IsSupportedClass(aEvent);
 }
 
 void
 SetEventTarget(JSObject* aEvent, JSObject* aTarget)
@@ -1161,9 +1095,9 @@ DispatchEventToTarget(JSContext* aCx, JS
   }
 
   *aPreventDefaultCalled = !!preventDefaultCalled;
   return true;
 }
 
 } // namespace events
 
-END_WORKERS_NAMESPACE
\ No newline at end of file
+END_WORKERS_NAMESPACE
--- a/dom/workers/Events.h
+++ b/dom/workers/Events.h
@@ -30,19 +30,16 @@ JSObject*
 CreateErrorEvent(JSContext* aCx, JS::Handle<JSString*> aMessage,
                  JS::Handle<JSString*> aFilename,
                  uint32_t aLineNumber, bool aMainRuntime);
 
 JSObject*
 CreateProgressEvent(JSContext* aCx, JS::Handle<JSString*> aType,
                     bool aLengthComputable, double aLoaded, double aTotal);
 
-JSObject*
-CreateConnectEvent(JSContext* aCx, JS::Handle<JSObject*> aMessagePort);
-
 bool
 IsSupportedEventClass(JSObject* aEvent);
 
 void
 SetEventTarget(JSObject* aEvent, JSObject* aTarget);
 
 bool
 EventWasCanceled(JSObject* aEvent);
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -1,67 +1,59 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "FileReaderSync.h"
 
-#include "jsfriendapi.h"
-#include "mozilla/Base64.h"
-#include "mozilla/dom/EncodingUtils.h"
-#include "mozilla/dom/FileReaderSyncBinding.h"
 #include "nsCExternalHandlerService.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDOMClassInfoID.h"
 #include "nsError.h"
 #include "nsIDOMFile.h"
 #include "nsICharsetDetector.h"
 #include "nsIConverterInputStream.h"
 #include "nsIInputStream.h"
 #include "nsIPlatformCharset.h"
 #include "nsISeekableStream.h"
 #include "nsISupportsImpl.h"
 #include "nsISupportsImpl.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
-
 #include "File.h"
 #include "RuntimeService.h"
+#include "DOMBindingInlines.h"
+
+#include "mozilla/Base64.h"
+#include "mozilla/dom/EncodingUtils.h"
 
 USING_WORKERS_NAMESPACE
 using namespace mozilla;
 using mozilla::dom::Optional;
 using mozilla::dom::GlobalObject;
 
 NS_IMPL_ADDREF(FileReaderSync)
 NS_IMPL_RELEASE(FileReaderSync)
-
 NS_INTERFACE_MAP_BEGIN(FileReaderSync)
   NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
 NS_INTERFACE_MAP_END
 
 // static
 already_AddRefed<FileReaderSync>
 FileReaderSync::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<FileReaderSync> frs = new FileReaderSync();
 
   return frs.forget();
 }
 
 JSObject*
-FileReaderSync::WrapObject(JSContext* aCx, JS::HandleObject aScope)
-{
-  return FileReaderSyncBinding_workers::Wrap(aCx, aScope, this);
-}
-
-JSObject*
 FileReaderSync::ReadAsArrayBuffer(JSContext* aCx,
                                   JS::Handle<JSObject*> aScopeObj,
                                   JS::Handle<JSObject*> aBlob,
                                   ErrorResult& aRv)
 {
   nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob);
   if (!blob) {
     aRv.Throw(NS_ERROR_INVALID_ARG);
--- a/dom/workers/FileReaderSync.h
+++ b/dom/workers/FileReaderSync.h
@@ -5,16 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_workers_filereadersync_h__
 #define mozilla_dom_workers_filereadersync_h__
 
 #include "Workers.h"
 
 #include "nsICharsetDetectionObserver.h"
+#include "nsString.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/FileReaderSyncBinding.h"
 
 class nsIInputStream;
 class nsIDOMBlob;
 
 namespace mozilla {
 class ErrorResult;
 
 namespace dom {
@@ -31,17 +34,20 @@ class FileReaderSync MOZ_FINAL : public 
   nsresult ConvertStream(nsIInputStream *aStream, const char *aCharset,
                          nsAString &aResult);
   nsresult GuessCharset(nsIInputStream *aStream, nsACString &aCharset);
 
 public:
   static already_AddRefed<FileReaderSync>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
-  JSObject* WrapObject(JSContext* aCx, JS::HandleObject aScope);
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+  {
+    return FileReaderSyncBinding_workers::Wrap(aCx, aScope, this);
+  }
 
   NS_DECL_ISUPPORTS
 
   JSObject* ReadAsArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aScopeObj,
                               JS::Handle<JSObject*> aBlob,
                               ErrorResult& aRv);
   void ReadAsBinaryString(JS::Handle<JSObject*> aBlob, nsAString& aResult,
                           ErrorResult& aRv);
--- a/dom/workers/Location.cpp
+++ b/dom/workers/Location.cpp
@@ -1,15 +1,18 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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 "Location.h"
 
+#include "DOMBindingInlines.h"
+
+#include "nsTraceRefcnt.h"
 #include "mozilla/dom/WorkerLocationBinding.h"
 
 BEGIN_WORKERS_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WorkerLocation)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WorkerLocation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WorkerLocation, Release)
deleted file mode 100644
--- a/dom/workers/MessagePort.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 "MessagePort.h"
-
-#include "mozilla/dom/WorkerMessagePortBinding.h"
-#include "nsDOMEvent.h"
-#include "nsEventDispatcher.h"
-
-#include "SharedWorker.h"
-
-using mozilla::dom::Optional;
-using mozilla::dom::Sequence;
-
-USING_WORKERS_NAMESPACE
-
-namespace {
-
-class DelayedEventRunnable MOZ_FINAL : public nsIRunnable
-{
-  nsRefPtr<MessagePort> mMessagePort;
-  nsCOMPtr<nsIDOMEvent> mEvent;
-
-public:
-  DelayedEventRunnable(MessagePort* aMessagePort,
-                       already_AddRefed<nsIDOMEvent> aEvent)
-  : mMessagePort(aMessagePort), mEvent(aEvent)
-  {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(aMessagePort);
-    MOZ_ASSERT(aEvent.get());
-  }
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIRUNNABLE
-};
-
-} // anonymous namespace
-
-MessagePort::MessagePort(nsPIDOMWindow* aWindow, SharedWorker* aSharedWorker,
-                         uint64_t aSerial)
-: nsDOMEventTargetHelper(aWindow), mSharedWorker(aSharedWorker),
-  mSerial(aSerial), mStarted(false)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aSharedWorker);
-}
-
-MessagePort::~MessagePort()
-{
-  AssertIsOnMainThread();
-
-  Close();
-}
-
-// static
-bool
-MessagePort::PrefEnabled()
-{
-  AssertIsOnMainThread();
-
-  // Currently tied to the SharedWorker preference.
-  return SharedWorker::PrefEnabled();
-}
-
-void
-MessagePort::PostMessage(JSContext* aCx, JS::HandleValue aMessage,
-                         const Optional<Sequence<JS::Value>>& aTransferable,
-                         ErrorResult& aRv)
-{
-  AssertIsOnMainThread();
-
-  if (IsClosed()) {
-    aRv = NS_ERROR_DOM_INVALID_STATE_ERR;
-    return;
-  }
-
-  mSharedWorker->PostMessage(aCx, aMessage, aTransferable, aRv);
-}
-
-void
-MessagePort::Start()
-{
-  AssertIsOnMainThread();
-
-  if (IsClosed()) {
-    NS_WARNING("Called start() after calling close()!");
-    return;
-  }
-
-  if (mStarted) {
-    return;
-  }
-
-  mStarted = true;
-
-  if (!mQueuedEvents.IsEmpty()) {
-    for (uint32_t index = 0; index < mQueuedEvents.Length(); index++) {
-      nsCOMPtr<nsIRunnable> runnable =
-        new DelayedEventRunnable(this, mQueuedEvents[index].forget());
-      if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
-        NS_WARNING("Failed to dispatch queued event!");
-      }
-    }
-    mQueuedEvents.Clear();
-  }
-}
-
-void
-MessagePort::QueueEvent(nsIDOMEvent* aEvent)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aEvent);
-  MOZ_ASSERT(!IsClosed());
-  MOZ_ASSERT(!mStarted);
-
-  mQueuedEvents.AppendElement(aEvent);
-}
-
-void
-MessagePort::CloseInternal()
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(!IsClosed());
-  MOZ_ASSERT_IF(mStarted, mQueuedEvents.IsEmpty());
-
-  NS_WARN_IF_FALSE(mStarted, "Called close() before start()!");
-
-  if (!mStarted) {
-    mQueuedEvents.Clear();
-  }
-
-  mSharedWorker = nullptr;
-}
-
-NS_IMPL_ADDREF_INHERITED(MessagePort, nsDOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(MessagePort, nsDOMEventTargetHelper)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MessagePort)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(MessagePort)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MessagePort,
-                                                  nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSharedWorker)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEvents)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MessagePort,
-                                                nsDOMEventTargetHelper)
-  tmp->Close();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-JSObject*
-MessagePort::WrapObject(JSContext* aCx, JS::HandleObject aScope)
-{
-  AssertIsOnMainThread();
-
-  return WorkerMessagePortBinding::Wrap(aCx, aScope, this);
-}
-
-nsresult
-MessagePort::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
-{
-  AssertIsOnMainThread();
-
-  nsIDOMEvent*& event = aVisitor.mDOMEvent;
-
-  if (event) {
-    bool preventDispatch = false;
-
-    if (IsClosed()) {
-      preventDispatch = true;
-    } else if (mSharedWorker->IsSuspended()) {
-      mSharedWorker->QueueEvent(event);
-      preventDispatch = true;
-    } else if (!mStarted) {
-      QueueEvent(event);
-      preventDispatch = true;
-    }
-
-    if (preventDispatch) {
-      aVisitor.mCanHandle = false;
-      aVisitor.mParentTarget = nullptr;
-      return NS_OK;
-    }
-  }
-
-  return nsDOMEventTargetHelper::PreHandleEvent(aVisitor);
-}
-
-NS_IMPL_ISUPPORTS1(DelayedEventRunnable, nsIRunnable)
-
-NS_IMETHODIMP
-DelayedEventRunnable::Run()
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mMessagePort);
-  MOZ_ASSERT(mEvent);
-
-  bool ignored;
-  nsresult rv = mMessagePort->DispatchEvent(mEvent, &ignored);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
deleted file mode 100644
--- a/dom/workers/MessagePort.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 mozilla_dom_workers_messageport_h_
-#define mozilla_dom_workers_messageport_h_
-
-#include "Workers.h"
-
-#include "mozilla/dom/BindingDeclarations.h"
-#include "nsDOMEventTargetHelper.h"
-
-class nsIDOMEvent;
-class nsPIDOMWindow;
-
-BEGIN_WORKERS_NAMESPACE
-
-class SharedWorker;
-
-class MessagePort MOZ_FINAL : public nsDOMEventTargetHelper
-{
-  friend class SharedWorker;
-
-  typedef mozilla::ErrorResult ErrorResult;
-
-  nsRefPtr<SharedWorker> mSharedWorker;
-  nsTArray<nsCOMPtr<nsIDOMEvent>> mQueuedEvents;
-  uint64_t mSerial;
-  bool mStarted;
-
-public:
-  static bool
-  PrefEnabled();
-
-  void
-  PostMessage(JSContext* aCx, JS::HandleValue aMessage,
-              const Optional<Sequence<JS::Value>>& aTransferable,
-              ErrorResult& aRv);
-
-  void
-  Start();
-
-  void
-  Close()
-  {
-    AssertIsOnMainThread();
-
-    if (!IsClosed()) {
-      CloseInternal();
-    }
-  }
-
-  uint64_t
-  Serial() const
-  {
-    return mSerial;
-  }
-
-  void
-  QueueEvent(nsIDOMEvent* aEvent);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort, nsDOMEventTargetHelper)
-
-  EventHandlerNonNull*
-  GetOnmessage()
-  {
-    AssertIsOnMainThread();
-
-    return GetEventHandler(nsGkAtoms::onmessage, EmptyString());
-  }
-
-  void
-  SetOnmessage(EventHandlerNonNull* aCallback)
-  {
-    AssertIsOnMainThread();
-
-    SetEventHandler(nsGkAtoms::onmessage, EmptyString(), aCallback);
-
-    Start();
-  }
-
-  bool
-  IsClosed() const
-  {
-    AssertIsOnMainThread();
-
-    return !mSharedWorker;
-  }
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::HandleObject aScope) MOZ_OVERRIDE;
-
-  virtual nsresult
-  PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
-
-private:
-  // This class can only be created by SharedWorker.
-  MessagePort(nsPIDOMWindow* aWindow, SharedWorker* aSharedWorker,
-              uint64_t aSerial);
-
-  // This class is reference-counted and will be destroyed from Release().
-  ~MessagePort();
-
-  void
-  CloseInternal();
-};
-
-END_WORKERS_NAMESPACE
-
-#endif // mozilla_dom_workers_messageport_h_
--- a/dom/workers/Navigator.cpp
+++ b/dom/workers/Navigator.cpp
@@ -1,19 +1,19 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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 "Navigator.h"
 
+#include "DOMBindingInlines.h"
+#include "RuntimeService.h"
 #include "mozilla/dom/WorkerNavigatorBinding.h"
 
-#include "RuntimeService.h"
-
 BEGIN_WORKERS_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WorkerNavigator)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WorkerNavigator, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WorkerNavigator, Release)
 
 /* static */ already_AddRefed<WorkerNavigator>
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -1,29 +1,25 @@
 /* -*- 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 "RuntimeService.h"
 
-#include "nsIChannel.h"
 #include "nsIContentSecurityPolicy.h"
-#include "nsIDocument.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIObserverService.h"
 #include "nsIPlatformCharset.h"
 #include "nsIPrincipal.h"
-#include "nsIScriptContext.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISupportsPriority.h"
 #include "nsITimer.h"
-#include "nsIURI.h"
 #include "nsPIDOMWindow.h"
 
 #include <algorithm>
 #include "GeckoProfiler.h"
 #include "js/OldDebugAPI.h"
 #include "jsfriendapi.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/dom/AtomList.h"
@@ -35,24 +31,22 @@
 #include <Navigator.h>
 #include "nsContentUtils.h"
 #include "nsCycleCollector.h"
 #include "nsDOMJSUtils.h"
 #include "nsLayoutStatics.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
-#include "nsTraceRefcnt.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMPrivate.h"
 #include "OSFileConstants.h"
 #include "xpcpublic.h"
 
 #include "Events.h"
-#include "SharedWorker.h"
 #include "Worker.h"
 #include "WorkerPrivate.h"
 
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
 
 using namespace mozilla;
@@ -1031,42 +1025,42 @@ ResolveWorkerClasses(JSContext* aCx, JS:
   }
 
   // Not resolved.
   aObjp.set(nullptr);
   return true;
 }
 
 void
-CancelWorkersForWindow(nsPIDOMWindow* aWindow)
+CancelWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow)
 {
   AssertIsOnMainThread();
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
-    runtime->CancelWorkersForWindow(aWindow);
+    runtime->CancelWorkersForWindow(aCx, aWindow);
   }
 }
 
 void
-SuspendWorkersForWindow(nsPIDOMWindow* aWindow)
+SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow)
 {
   AssertIsOnMainThread();
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
-    runtime->SuspendWorkersForWindow(aWindow);
+    runtime->SuspendWorkersForWindow(aCx, aWindow);
   }
 }
 
 void
-ResumeWorkersForWindow(nsPIDOMWindow* aWindow)
+ResumeWorkersForWindow(nsIScriptContext* aCx, nsPIDOMWindow* aWindow)
 {
   AssertIsOnMainThread();
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
-    runtime->ResumeWorkersForWindow(aWindow);
+    runtime->ResumeWorkersForWindow(aCx, aWindow);
   }
 }
 
 namespace {
 
 class WorkerTaskRunnable : public WorkerRunnable
 {
 public:
@@ -1206,75 +1200,51 @@ RuntimeService::RegisterWorker(JSContext
     AssertIsOnMainThread();
 
     if (mShuttingDown) {
       JS_ReportError(aCx, "Cannot create worker during shutdown!");
       return false;
     }
   }
 
-  bool isSharedWorker = aWorkerPrivate->IsSharedWorker();
-
-  const nsString& sharedWorkerName = aWorkerPrivate->SharedWorkerName();
-  nsCString sharedWorkerScriptSpec;
-
-  if (isSharedWorker) {
-    AssertIsOnMainThread();
-
-    nsCOMPtr<nsIURI> scriptURI = aWorkerPrivate->GetResolvedScriptURI();
-    NS_ASSERTION(scriptURI, "Null script URI!");
-
-    nsresult rv = scriptURI->GetSpec(sharedWorkerScriptSpec);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("GetSpec failed?!");
-      xpc::Throw(aCx, rv);
-      return false;
-    }
-
-    NS_ASSERTION(!sharedWorkerScriptSpec.IsEmpty(), "Empty spec!");
-  }
-
-  const nsCString& domain = aWorkerPrivate->Domain();
-
   WorkerDomainInfo* domainInfo;
   bool queued = false;
   {
+    const nsCString& domain = aWorkerPrivate->Domain();
+
     MutexAutoLock lock(mMutex);
 
     if (!mDomainMap.Get(domain, &domainInfo)) {
       NS_ASSERTION(!parent, "Shouldn't have a parent here!");
 
       domainInfo = new WorkerDomainInfo();
       domainInfo->mDomain = domain;
       mDomainMap.Put(domain, domainInfo);
     }
 
-    queued = gMaxWorkersPerDomain &&
-             domainInfo->ActiveWorkerCount() >= gMaxWorkersPerDomain &&
-             !domain.IsEmpty();
+    if (domainInfo) {
+      queued = gMaxWorkersPerDomain &&
+               domainInfo->ActiveWorkerCount() >= gMaxWorkersPerDomain &&
+               !domain.IsEmpty();
 
-    if (queued) {
-      domainInfo->mQueuedWorkers.AppendElement(aWorkerPrivate);
-    }
-    else if (parent) {
-      domainInfo->mChildWorkerCount++;
+      if (queued) {
+        domainInfo->mQueuedWorkers.AppendElement(aWorkerPrivate);
+      }
+      else if (parent) {
+        domainInfo->mChildWorkerCount++;
+      }
+      else {
+        domainInfo->mActiveWorkers.AppendElement(aWorkerPrivate);
+      }
     }
-    else {
-      domainInfo->mActiveWorkers.AppendElement(aWorkerPrivate);
-    }
-
-    if (isSharedWorker) {
-      MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(sharedWorkerScriptSpec));
+  }
 
-      SharedWorkerInfo* sharedWorkerInfo =
-        new SharedWorkerInfo(aWorkerPrivate, sharedWorkerScriptSpec,
-                             sharedWorkerName);
-      domainInfo->mSharedWorkerInfos.Put(sharedWorkerScriptSpec,
-                                         sharedWorkerInfo);
-    }
+  if (!domainInfo) {
+    JS_ReportOutOfMemory(aCx);
+    return false;
   }
 
   // From here on out we must call UnregisterWorker if something fails!
   if (parent) {
     if (!parent->AddChildWorker(aCx, aWorkerPrivate)) {
       UnregisterWorker(aCx, aWorkerPrivate);
       return false;
     }
@@ -1292,25 +1262,25 @@ RuntimeService::RegisterWorker(JSContext
 
       mNavigatorStringsLoaded = true;
     }
 
     nsPIDOMWindow* window = aWorkerPrivate->GetWindow();
 
     nsTArray<WorkerPrivate*>* windowArray;
     if (!mWindowMap.Get(window, &windowArray)) {
+      NS_ASSERTION(!parent, "Shouldn't have a parent here!");
+
       windowArray = new nsTArray<WorkerPrivate*>(1);
       mWindowMap.Put(window, windowArray);
     }
 
-    if (!windowArray->Contains(aWorkerPrivate)) {
-      windowArray->AppendElement(aWorkerPrivate);
-    } else {
-      MOZ_ASSERT(aWorkerPrivate->IsSharedWorker());
-    }
+    NS_ASSERTION(!windowArray->Contains(aWorkerPrivate),
+                 "Already know about this worker!");
+    windowArray->AppendElement(aWorkerPrivate);
   }
 
   if (!queued && !ScheduleWorker(aCx, aWorkerPrivate)) {
     return false;
   }
 
   return true;
 }
@@ -1320,20 +1290,20 @@ RuntimeService::UnregisterWorker(JSConte
 {
   aWorkerPrivate->AssertIsOnParentThread();
 
   WorkerPrivate* parent = aWorkerPrivate->GetParent();
   if (!parent) {
     AssertIsOnMainThread();
   }
 
-  const nsCString& domain = aWorkerPrivate->Domain();
-
   WorkerPrivate* queuedWorker = nullptr;
   {
+    const nsCString& domain = aWorkerPrivate->Domain();
+
     MutexAutoLock lock(mMutex);
 
     WorkerDomainInfo* domainInfo;
     if (!mDomainMap.Get(domain, &domainInfo)) {
       NS_ERROR("Don't have an entry for this domain!");
     }
 
     // Remove old worker from everywhere.
@@ -1347,27 +1317,16 @@ RuntimeService::UnregisterWorker(JSConte
       domainInfo->mChildWorkerCount--;
     }
     else {
       NS_ASSERTION(domainInfo->mActiveWorkers.Contains(aWorkerPrivate),
                    "Don't know about this worker!");
       domainInfo->mActiveWorkers.RemoveElement(aWorkerPrivate);
     }
 
-    if (aWorkerPrivate->IsSharedWorker()) {
-      MatchSharedWorkerInfo match(aWorkerPrivate);
-      domainInfo->mSharedWorkerInfos.EnumerateRead(FindSharedWorkerInfo,
-                                                   &match);
-
-      if (match.mSharedWorkerInfo) {
-        domainInfo->mSharedWorkerInfos.Remove(
-          match.mSharedWorkerInfo->mScriptSpec);
-      }
-    }
-
     // See if there's a queued worker we can schedule.
     if (domainInfo->ActiveWorkerCount() < gMaxWorkersPerDomain &&
         !domainInfo->mQueuedWorkers.IsEmpty()) {
       queuedWorker = domainInfo->mQueuedWorkers[0];
       domainInfo->mQueuedWorkers.RemoveElementAt(0);
 
       if (queuedWorker->GetParent()) {
         domainInfo->mChildWorkerCount++;
@@ -1378,49 +1337,33 @@ RuntimeService::UnregisterWorker(JSConte
     }
 
     if (!domainInfo->ActiveWorkerCount()) {
       NS_ASSERTION(domainInfo->mQueuedWorkers.IsEmpty(), "Huh?!");
       mDomainMap.Remove(domain);
     }
   }
 
-  if (aWorkerPrivate->IsSharedWorker()) {
-    AssertIsOnMainThread();
-
-    nsAutoTArray<nsRefPtr<SharedWorker>, 5> sharedWorkersToNotify;
-    aWorkerPrivate->GetAllSharedWorkers(sharedWorkersToNotify);
-
-    for (uint32_t index = 0; index < sharedWorkersToNotify.Length(); index++) {
-      MOZ_ASSERT(sharedWorkersToNotify[index]);
-      sharedWorkersToNotify[index]->NoteDeadWorker(aCx);
-    }
-  }
-
   if (parent) {
     parent->RemoveChildWorker(aCx, aWorkerPrivate);
   }
-  else if (aWorkerPrivate->IsSharedWorker()) {
-    mWindowMap.Enumerate(RemoveSharedWorkerFromWindowMap, aWorkerPrivate);
-  }
   else {
-    // May be null.
     nsPIDOMWindow* window = aWorkerPrivate->GetWindow();
 
     nsTArray<WorkerPrivate*>* windowArray;
     if (!mWindowMap.Get(window, &windowArray)) {
-      MOZ_ASSERT(false, "Don't have an entry for this window!");
+      NS_ERROR("Don't have an entry for this window!");
     }
 
-    if (!windowArray->RemoveElement(aWorkerPrivate)) {
-      MOZ_ASSERT(false, "Worker wasn't in the correct window array!");
-    }
+    NS_ASSERTION(windowArray->Contains(aWorkerPrivate),
+                 "Don't know about this worker!");
+    windowArray->RemoveElement(aWorkerPrivate);
 
     if (windowArray->IsEmpty()) {
-      MOZ_ASSERT(!queuedWorker, "queuedWorker should be in this array!");
+      NS_ASSERTION(!queuedWorker, "How can this be?!");
       mWindowMap.Remove(window);
     }
   }
 
   if (queuedWorker && !ScheduleWorker(aCx, queuedWorker)) {
     UnregisterWorker(aCx, queuedWorker);
   }
 }
@@ -1846,58 +1789,16 @@ RuntimeService::AddAllTopLevelWorkersToA
     if (!worker->GetParent()) {
       array->AppendElement(worker);
     }
   }
 
   return PL_DHASH_NEXT;
 }
 
-// static
-PLDHashOperator
-RuntimeService::RemoveSharedWorkerFromWindowMap(
-                                  nsPIDOMWindow* aKey,
-                                  nsAutoPtr<nsTArray<WorkerPrivate*> >& aData,
-                                  void* aUserArg)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aData.get());
-  MOZ_ASSERT(aUserArg);
-
-  auto workerPrivate = static_cast<WorkerPrivate*>(aUserArg);
-
-  MOZ_ASSERT(workerPrivate->IsSharedWorker());
-
-  if (aData->RemoveElement(workerPrivate)) {
-    MOZ_ASSERT(!aData->Contains(workerPrivate), "Added worker more than once!");
-
-    if (aData->IsEmpty()) {
-      return PL_DHASH_REMOVE;
-    }
-  }
-
-  return PL_DHASH_NEXT;
-}
-
-// static
-PLDHashOperator
-RuntimeService::FindSharedWorkerInfo(const nsACString& aKey,
-                                     SharedWorkerInfo* aData,
-                                     void* aUserArg)
-{
-  auto match = static_cast<MatchSharedWorkerInfo*>(aUserArg);
-
-  if (aData->mWorkerPrivate == match->mWorkerPrivate) {
-    match->mSharedWorkerInfo = aData;
-    return PL_DHASH_STOP;
-  }
-
-  return PL_DHASH_NEXT;
-}
-
 void
 RuntimeService::GetWorkersForWindow(nsPIDOMWindow* aWindow,
                                     nsTArray<WorkerPrivate*>& aWorkers)
 {
   AssertIsOnMainThread();
 
   nsTArray<WorkerPrivate*>* workers;
   if (mWindowMap.Get(aWindow, &workers)) {
@@ -1905,177 +1806,67 @@ RuntimeService::GetWorkersForWindow(nsPI
     aWorkers.AppendElements(*workers);
   }
   else {
     NS_ASSERTION(aWorkers.IsEmpty(), "Should be empty!");
   }
 }
 
 void
-RuntimeService::CancelWorkersForWindow(nsPIDOMWindow* aWindow)
+RuntimeService::CancelWorkersForWindow(JSContext* aCx,
+                                       nsPIDOMWindow* aWindow)
 {
   AssertIsOnMainThread();
 
-  nsAutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsAutoTArray<WorkerPrivate*, 100> workers;
   GetWorkersForWindow(aWindow, workers);
 
   if (!workers.IsEmpty()) {
-    nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
-    MOZ_ASSERT(sgo);
-
-    nsIScriptContext* scx = sgo->GetContext();
-
-    AutoPushJSContext cx(scx ?
-                         scx->GetNativeContext() :
-                         nsContentUtils::GetSafeJSContext());
-
     for (uint32_t index = 0; index < workers.Length(); index++) {
-      WorkerPrivate*& worker = workers[index];
-
-      if (worker->IsSharedWorker()) {
-        worker->CloseSharedWorkersForWindow(aWindow);
-      } else if (!worker->Cancel(cx)) {
-        JS_ReportPendingException(cx);
-      }
-    }
-  }
-}
-
-void
-RuntimeService::SuspendWorkersForWindow(nsPIDOMWindow* aWindow)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aWindow);
-
-  nsAutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
-  GetWorkersForWindow(aWindow, workers);
-
-  if (!workers.IsEmpty()) {
-    nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
-    MOZ_ASSERT(sgo);
-
-    nsIScriptContext* scx = sgo->GetContext();
-
-    AutoPushJSContext cx(scx ?
-                         scx->GetNativeContext() :
-                         nsContentUtils::GetSafeJSContext());
-
-    for (uint32_t index = 0; index < workers.Length(); index++) {
-      if (!workers[index]->Suspend(cx, aWindow)) {
-        JS_ReportPendingException(cx);
+      if (!workers[index]->Cancel(aCx)) {
+        NS_WARNING("Failed to cancel worker!");
       }
     }
   }
 }
 
 void
-RuntimeService::ResumeWorkersForWindow(nsPIDOMWindow* aWindow)
+RuntimeService::SuspendWorkersForWindow(JSContext* aCx,
+                                        nsPIDOMWindow* aWindow)
 {
   AssertIsOnMainThread();
-  MOZ_ASSERT(aWindow);
 
-  nsAutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsAutoTArray<WorkerPrivate*, 100> workers;
   GetWorkersForWindow(aWindow, workers);
 
   if (!workers.IsEmpty()) {
-    nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
-    MOZ_ASSERT(sgo);
-
-    nsIScriptContext* scx = sgo->GetContext();
-
-    AutoPushJSContext cx(scx ?
-                         scx->GetNativeContext() :
-                         nsContentUtils::GetSafeJSContext());
-
     for (uint32_t index = 0; index < workers.Length(); index++) {
-      if (!workers[index]->SynchronizeAndResume(cx, aWindow, scx)) {
-        JS_ReportPendingException(cx);
+      if (!workers[index]->Suspend(aCx)) {
+        NS_WARNING("Failed to cancel worker!");
       }
     }
   }
 }
 
-nsresult
-RuntimeService::CreateSharedWorker(JSContext* aCx, nsPIDOMWindow* aWindow,
-                                   const nsAString& aScriptURL,
-                                   const nsAString& aName,
-                                   SharedWorker** aSharedWorker)
+void
+RuntimeService::ResumeWorkersForWindow(nsIScriptContext* aCx,
+                                       nsPIDOMWindow* aWindow)
 {
   AssertIsOnMainThread();
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT(aWindow);
 
-  WorkerPrivate::LoadInfo loadInfo;
-  nsresult rv = WorkerPrivate::GetLoadInfo(aCx, aWindow, nullptr, aScriptURL,
-                                           false, &loadInfo);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  MOZ_ASSERT(loadInfo.mResolvedScriptURI);
+  nsAutoTArray<WorkerPrivate*, 100> workers;
+  GetWorkersForWindow(aWindow, workers);
 
-  nsCString scriptSpec;
-  rv = loadInfo.mResolvedScriptURI->GetSpec(scriptSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  WorkerPrivate* workerPrivate = nullptr;
-  {
-    MutexAutoLock lock(mMutex);
-
-    WorkerDomainInfo* domainInfo;
-    SharedWorkerInfo* sharedWorkerInfo;
-
-    if (mDomainMap.Get(loadInfo.mDomain, &domainInfo) &&
-        domainInfo->mSharedWorkerInfos.Get(scriptSpec, &sharedWorkerInfo) &&
-        sharedWorkerInfo->mName == aName) {
-      workerPrivate = sharedWorkerInfo->mWorkerPrivate;
+  if (!workers.IsEmpty()) {
+    for (uint32_t index = 0; index < workers.Length(); index++) {
+      if (!workers[index]->SynchronizeAndResume(aCx)) {
+        NS_WARNING("Failed to cancel worker!");
+      }
     }
   }
-
-  bool created = false;
-
-  if (!workerPrivate) {
-    nsRefPtr<WorkerPrivate> newWorkerPrivate =
-      WorkerPrivate::Create(aCx, JS::NullPtr(), nullptr, aScriptURL, false,
-                            true, aName, &loadInfo);
-    NS_ENSURE_TRUE(newWorkerPrivate, NS_ERROR_FAILURE);
-
-    if (!RegisterWorker(aCx, newWorkerPrivate)) {
-      NS_WARNING("Failed to register worker!");
-      return NS_ERROR_FAILURE;
-    }
-
-    created = true;
-    newWorkerPrivate.forget(&workerPrivate);
-  }
-
-  MOZ_ASSERT(workerPrivate->IsSharedWorker());
-
-  nsRefPtr<SharedWorker> sharedWorker =
-    new SharedWorker(aWindow, workerPrivate);
-
-  if (!workerPrivate->RegisterSharedWorker(aCx, sharedWorker)) {
-    NS_WARNING("Failed to dispatch to worker!");
-    return NS_ERROR_FAILURE;
-  }
-
-  // This is normally handled in RegisterWorker, but that wasn't called if the
-  // worker already existed.
-  if (!created) {
-    nsTArray<WorkerPrivate*>* windowArray;
-    if (!mWindowMap.Get(aWindow, &windowArray)) {
-      windowArray = new nsTArray<WorkerPrivate*>(1);
-      mWindowMap.Put(aWindow, windowArray);
-    }
-
-    if (!windowArray->Contains(workerPrivate)) {
-      windowArray->AppendElement(workerPrivate);
-    }
-  }
-
-  sharedWorker.forget(aSharedWorker);
-  return NS_OK;
 }
 
 void
 RuntimeService::NoteIdleThread(nsIThread* aThread)
 {
   AssertIsOnMainThread();
   NS_ASSERTION(aThread, "Null pointer!");
 
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -9,95 +9,65 @@
 
 #include "Workers.h"
 
 #include "nsIObserver.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
-#include "mozilla/dom/BindingDeclarations.h"
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsCOMPtr.h"
-#include "nsCycleCollectionParticipant.h"
 #include "nsHashKeys.h"
 #include "nsString.h"
 #include "nsTArray.h"
 
 class nsIThread;
 class nsITimer;
 class nsPIDOMWindow;
 
 BEGIN_WORKERS_NAMESPACE
 
-class SharedWorker;
 class WorkerPrivate;
 
 class RuntimeService MOZ_FINAL : public nsIObserver
 {
-  struct SharedWorkerInfo
-  {
-    WorkerPrivate* mWorkerPrivate;
-    nsCString mScriptSpec;
-    nsString mName;
-
-    SharedWorkerInfo(WorkerPrivate* aWorkerPrivate,
-                     const nsACString& aScriptSpec,
-                     const nsAString& aName)
-    : mWorkerPrivate(aWorkerPrivate), mScriptSpec(aScriptSpec), mName(aName)
-    { }
-  };
-
   struct WorkerDomainInfo
   {
     nsCString mDomain;
     nsTArray<WorkerPrivate*> mActiveWorkers;
     nsTArray<WorkerPrivate*> mQueuedWorkers;
-    nsClassHashtable<nsCStringHashKey, SharedWorkerInfo> mSharedWorkerInfos;
     uint32_t mChildWorkerCount;
 
-    WorkerDomainInfo()
-    : mActiveWorkers(1), mChildWorkerCount(0)
-    { }
+    WorkerDomainInfo() : mActiveWorkers(1), mChildWorkerCount(0) { }
 
     uint32_t
     ActiveWorkerCount() const
     {
       return mActiveWorkers.Length() + mChildWorkerCount;
     }
   };
 
   struct IdleThreadInfo
   {
     nsCOMPtr<nsIThread> mThread;
     mozilla::TimeStamp mExpirationTime;
   };
 
-  struct MatchSharedWorkerInfo
-  {
-    WorkerPrivate* mWorkerPrivate;
-    SharedWorkerInfo* mSharedWorkerInfo;
-
-    MatchSharedWorkerInfo(WorkerPrivate* aWorkerPrivate)
-    : mWorkerPrivate(aWorkerPrivate), mSharedWorkerInfo(nullptr)
-    { }
-  };
-
   mozilla::Mutex mMutex;
 
   // Protected by mMutex.
   nsClassHashtable<nsCStringHashKey, WorkerDomainInfo> mDomainMap;
 
   // Protected by mMutex.
   nsTArray<IdleThreadInfo> mIdleThreadArray;
 
   // *Not* protected by mMutex.
-  nsClassHashtable<nsPtrHashKey<nsPIDOMWindow>,
-                   nsTArray<WorkerPrivate*> > mWindowMap;
+  nsClassHashtable<nsPtrHashKey<nsPIDOMWindow>, nsTArray<WorkerPrivate*> > mWindowMap;
 
   // Only used on the main thread.
   nsCOMPtr<nsITimer> mIdleThreadTimer;
 
   nsCString mDetectorName;
   nsCString mSystemCharset;
 
   static JSSettings sDefaultJSSettings;
@@ -131,28 +101,23 @@ public:
 
   bool
   RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
 
   void
   UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
 
   void
-  CancelWorkersForWindow(nsPIDOMWindow* aWindow);
-
-  void
-  SuspendWorkersForWindow(nsPIDOMWindow* aWindow);
+  CancelWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
   void
-  ResumeWorkersForWindow(nsPIDOMWindow* aWindow);
+  SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
-  nsresult
-  CreateSharedWorker(JSContext* aCx, nsPIDOMWindow* aWindow,
-                     const nsAString& aScriptURL, const nsAString& aName,
-                     SharedWorker** aSharedWorker);
+  void
+  ResumeWorkersForWindow(nsIScriptContext* aCx, nsPIDOMWindow* aWindow);
 
   const nsACString&
   GetDetectorName() const
   {
     return mDetectorName;
   }
 
   const nsACString&
@@ -249,26 +214,16 @@ private:
   void
   Cleanup();
 
   static PLDHashOperator
   AddAllTopLevelWorkersToArray(const nsACString& aKey,
                                WorkerDomainInfo* aData,
                                void* aUserArg);
 
-  static PLDHashOperator
-  RemoveSharedWorkerFromWindowMap(nsPIDOMWindow* aKey,
-                                  nsAutoPtr<nsTArray<WorkerPrivate*> >& aData,
-                                  void* aUserArg);
-
-  static PLDHashOperator
-  FindSharedWorkerInfo(const nsACString& aKey,
-                       SharedWorkerInfo* aData,
-                       void* aUserArg);
-
   void
   GetWorkersForWindow(nsPIDOMWindow* aWindow,
                       nsTArray<WorkerPrivate*>& aWorkers);
 
   bool
   ScheduleWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
 
   static void
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -33,108 +33,40 @@
 
 #include "mozilla/dom/Exceptions.h"
 #include "Principal.h"
 #include "WorkerFeature.h"
 #include "WorkerPrivate.h"
 
 #define MAX_CONCURRENT_SCRIPTS 1000
 
-USING_WORKERS_NAMESPACE
+BEGIN_WORKERS_NAMESPACE
 
-using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
-
-namespace {
-
+namespace scriptloader {
+static
 nsresult
 ChannelFromScriptURL(nsIPrincipal* principal,
                      nsIURI* baseURI,
                      nsIDocument* parentDoc,
                      nsILoadGroup* loadGroup,
                      nsIIOService* ios,
                      nsIScriptSecurityManager* secMan,
-                     const nsAString& aScriptURL,
+                     const nsString& aScriptURL,
                      bool aIsWorkerScript,
-                     nsIChannel** aChannel)
-{
-  AssertIsOnMainThread();
-
-  nsresult rv;
-  nsCOMPtr<nsIURI> uri;
-  rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
-                                                 aScriptURL, parentDoc,
-                                                 baseURI);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_DOM_SYNTAX_ERR;
-  }
+                     nsIChannel** aChannel);
 
-  // If we're part of a document then check the content load policy.
-  if (parentDoc) {
-    int16_t shouldLoad = nsIContentPolicy::ACCEPT;
-    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, uri,
-                                   principal, parentDoc,
-                                   NS_LITERAL_CSTRING("text/javascript"),
-                                   nullptr, &shouldLoad,
-                                   nsContentUtils::GetContentPolicy(),
-                                   secMan);
-    if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
-      if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
-        return rv = NS_ERROR_CONTENT_BLOCKED;
-      }
-      return rv = NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
-    }
-  }
-
-  // If this script loader is being used to make a new worker then we need
-  // to do a same-origin check. Otherwise we need to clear the load with the
-  // security manager.
-  if (aIsWorkerScript) {
-    nsCString scheme;
-    rv = uri->GetScheme(scheme);
-    NS_ENSURE_SUCCESS(rv, rv);
+} // namespace scriptloader
 
-    // We pass true as the 3rd argument to checkMayLoad here.
-    // This allows workers in sandboxed documents to load data URLs
-    // (and other URLs that inherit their principal from their
-    // creator.)
-    rv = principal->CheckMayLoad(uri, false, true);
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
-  }
-  else {
-    rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);
-    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
-  }
+END_WORKERS_NAMESPACE
 
-  // Get Content Security Policy from parent document to pass into channel.
-  nsCOMPtr<nsIContentSecurityPolicy> csp;
-  rv = principal->GetCsp(getter_AddRefs(csp));
-  NS_ENSURE_SUCCESS(rv, rv);
+USING_WORKERS_NAMESPACE
 
-  nsCOMPtr<nsIChannelPolicy> channelPolicy;
-  if (csp) {
-    channelPolicy = do_CreateInstance(NSCHANNELPOLICY_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = channelPolicy->SetContentSecurityPolicy(csp);
-    NS_ENSURE_SUCCESS(rv, rv);
+using mozilla::dom::Throw;
 
-    rv = channelPolicy->SetLoadType(nsIContentPolicy::TYPE_SCRIPT);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  uint32_t flags = nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI;
-
-  nsCOMPtr<nsIChannel> channel;
-  rv = NS_NewChannel(getter_AddRefs(channel), uri, ios, loadGroup, nullptr,
-                     flags, channelPolicy);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  channel.forget(aChannel);
-  return rv;
-}
+namespace {
 
 class ScriptLoaderRunnable;
 
 struct ScriptLoadInfo
 {
   ScriptLoadInfo()
   : mLoadResult(NS_ERROR_NOT_INITIALIZED), mExecutionScheduled(false),
     mExecutionResult(false)
@@ -338,17 +270,17 @@ public:
     }
 
     // May be null.
     nsCOMPtr<nsIDocument> parentDoc = mWorkerPrivate->GetDocument();
 
     nsCOMPtr<nsIChannel> channel;
     if (mIsWorkerScript) {
       // May be null.
-      channel = mWorkerPrivate->ForgetWorkerChannel();
+      channel = mWorkerPrivate->GetChannel();
     }
 
     // All of these can potentially be null, but that should be ok. We'll either
     // succeed without them or fail below.
     nsCOMPtr<nsILoadGroup> loadGroup;
     if (parentDoc) {
       loadGroup = parentDoc->GetDocumentLoadGroup();
     }
@@ -358,18 +290,19 @@ public:
     nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
     NS_ASSERTION(secMan, "This should never be null!");
 
     for (uint32_t index = 0; index < mLoadInfos.Length(); index++) {
       ScriptLoadInfo& loadInfo = mLoadInfos[index];
       nsresult& rv = loadInfo.mLoadResult;
 
       if (!channel) {
-        rv = ChannelFromScriptURL(principal, baseURI, parentDoc, loadGroup, ios,
-                                  secMan, loadInfo.mURL, mIsWorkerScript,
+        rv = scriptloader::ChannelFromScriptURL(principal, baseURI, parentDoc,
+                                                loadGroup, ios, secMan,
+                                                loadInfo.mURL, mIsWorkerScript,
                                                 getter_AddRefs(channel));
         if (NS_FAILED(rv)) {
           return rv;
         }
       }
 
       // We need to know which index we're on in OnStreamComplete so we know
       // where to put the result.
@@ -543,22 +476,16 @@ public:
     }
 
     return NS_OK;
   }
 
   void
   ExecuteFinishedScripts()
   {
-    AssertIsOnMainThread();
-
-    if (mIsWorkerScript) {
-      mWorkerPrivate->WorkerScriptLoaded();
-    }
-
     uint32_t firstIndex = UINT32_MAX;
     uint32_t lastIndex = UINT32_MAX;
 
     // Find firstIndex based on whether mExecutionScheduled is unset.
     for (uint32_t index = 0; index < mLoadInfos.Length(); index++) {
       if (!mLoadInfos[index].mExecutionScheduled) {
         firstIndex = index;
         break;
@@ -612,24 +539,24 @@ public:
     return true;
   }
 };
 
 class ChannelGetterRunnable MOZ_FINAL : public nsRunnable
 {
   WorkerPrivate* mParentWorker;
   uint32_t mSyncQueueKey;
-  const nsAString& mScriptURL;
+  const nsString& mScriptURL;
   nsIChannel** mChannel;
   nsresult mResult;
 
 public:
   ChannelGetterRunnable(WorkerPrivate* aParentWorker,
                         uint32_t aSyncQueueKey,
-                        const nsAString& aScriptURL,
+                        const nsString& aScriptURL,
                         nsIChannel** aChannel)
   : mParentWorker(aParentWorker), mSyncQueueKey(aSyncQueueKey),
     mScriptURL(aScriptURL), mChannel(aChannel), mResult(NS_ERROR_FAILURE)
   {
     aParentWorker->AssertIsOnWorkerThread();
   }
 
   virtual ~ChannelGetterRunnable() { }
@@ -791,21 +718,108 @@ LoadAllScripts(JSContext* aCx, WorkerPri
 }
 
 } /* anonymous namespace */
 
 BEGIN_WORKERS_NAMESPACE
 
 namespace scriptloader {
 
+// static
+nsresult
+ChannelFromScriptURL(nsIPrincipal* principal,
+                     nsIURI* baseURI,
+                     nsIDocument* parentDoc,
+                     nsILoadGroup* loadGroup,
+                     nsIIOService* ios,
+                     nsIScriptSecurityManager* secMan,
+                     const nsString& aScriptURL,
+                     bool aIsWorkerScript,
+                     nsIChannel** aChannel)
+{
+  nsresult rv;
+  nsCOMPtr<nsIURI> uri;
+  rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
+                                                 aScriptURL, parentDoc,
+                                                 baseURI);
+  if (NS_FAILED(rv)) {
+    return NS_ERROR_DOM_SYNTAX_ERR;
+  }
+
+  // If we're part of a document then check the content load policy.
+  if (parentDoc) {
+    int16_t shouldLoad = nsIContentPolicy::ACCEPT;
+    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT, uri,
+                                   principal, parentDoc,
+                                   NS_LITERAL_CSTRING("text/javascript"),
+                                   nullptr, &shouldLoad,
+                                   nsContentUtils::GetContentPolicy(),
+                                   secMan);
+    if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
+      if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
+        return rv = NS_ERROR_CONTENT_BLOCKED;
+      }
+      return rv = NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
+    }
+  }
+
+  // If this script loader is being used to make a new worker then we need
+  // to do a same-origin check. Otherwise we need to clear the load with the
+  // security manager.
+  if (aIsWorkerScript) {
+    nsCString scheme;
+    rv = uri->GetScheme(scheme);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // We pass true as the 3rd argument to checkMayLoad here.
+    // This allows workers in sandboxed documents to load data URLs
+    // (and other URLs that inherit their principal from their
+    // creator.)
+    rv = principal->CheckMayLoad(uri, false, true);
+    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
+  }
+  else {
+    rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);
+    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
+  }
+
+  // Get Content Security Policy from parent document to pass into channel.
+  nsCOMPtr<nsIContentSecurityPolicy> csp;
+  rv = principal->GetCsp(getter_AddRefs(csp));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIChannelPolicy> channelPolicy;
+  if (csp) {
+    channelPolicy = do_CreateInstance(NSCHANNELPOLICY_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = channelPolicy->SetContentSecurityPolicy(csp);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = channelPolicy->SetLoadType(nsIContentPolicy::TYPE_SCRIPT);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  uint32_t flags = nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI;
+
+  nsCOMPtr<nsIChannel> channel;
+  rv = NS_NewChannel(getter_AddRefs(channel), uri, ios, loadGroup, nullptr,
+                     flags, channelPolicy);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  channel.forget(aChannel);
+  return rv;
+}
+
+
 nsresult
 ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
                                nsIURI* aBaseURI,
                                nsIDocument* aParentDoc,
-                               const nsAString& aScriptURL,
+                               const nsString& aScriptURL,
                                nsIChannel** aChannel)
 {
   AssertIsOnMainThread();
 
   nsCOMPtr<nsILoadGroup> loadGroup;
   if (aParentDoc) {
     loadGroup = aParentDoc->GetDocumentLoadGroup();
   }
@@ -817,17 +831,17 @@ ChannelFromScriptURLMainThread(nsIPrinci
 
   return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, loadGroup,
                               ios, secMan, aScriptURL, true, aChannel);
 }
 
 nsresult
 ChannelFromScriptURLWorkerThread(JSContext* aCx,
                                  WorkerPrivate* aParent,
-                                 const nsAString& aScriptURL,
+                                 const nsString& aScriptURL,
                                  nsIChannel** aChannel)
 {
   aParent->AssertIsOnWorkerThread();
 
   AutoSyncLoopHolder syncLoop(aParent);
 
   nsRefPtr<ChannelGetterRunnable> getter =
     new ChannelGetterRunnable(aParent, syncLoop.SyncQueueKey(),
@@ -840,17 +854,17 @@ ChannelFromScriptURLWorkerThread(JSConte
 
   if (!syncLoop.RunAndForget(aCx)) {
     return NS_ERROR_FAILURE;
   }
 
   return getter->GetResult();
 }
 
-void ReportLoadError(JSContext* aCx, const nsAString& aURL,
+void ReportLoadError(JSContext* aCx, const nsString& aURL,
                      nsresult aLoadResult, bool aIsMainThread)
 {
   NS_LossyConvertUTF16toASCII url(aURL);
 
   switch (aLoadResult) {
     case NS_BINDING_ABORTED:
       // Canceled, don't set an exception.
       break;
--- a/dom/workers/ScriptLoader.h
+++ b/dom/workers/ScriptLoader.h
@@ -17,26 +17,26 @@ class nsIChannel;
 BEGIN_WORKERS_NAMESPACE
 
 namespace scriptloader {
 
 nsresult
 ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
                                nsIURI* aBaseURI,
                                nsIDocument* aParentDoc,
-                               const nsAString& aScriptURL,
+                               const nsString& aScriptURL,
                                nsIChannel** aChannel);
 
 nsresult
 ChannelFromScriptURLWorkerThread(JSContext* aCx,
                                  WorkerPrivate* aParent,
-                                 const nsAString& aScriptURL,
+                                 const nsString& aScriptURL,
                                  nsIChannel** aChannel);
 
-void ReportLoadError(JSContext* aCx, const nsAString& aURL,
+void ReportLoadError(JSContext* aCx, const nsString& aURL,
                      nsresult aLoadResult, bool aIsMainThread);
 
 bool LoadWorkerScript(JSContext* aCx);
 
 bool Load(JSContext* aCx, unsigned aURLCount, jsval* aURLs);
 
 } // namespace scriptloader
 
deleted file mode 100644
--- a/dom/workers/SharedWorker.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 "SharedWorker.h"
-
-#include "nsPIDOMWindow.h"
-
-#include "mozilla/Preferences.h"
-#include "mozilla/dom/SharedWorkerBinding.h"
-#include "nsContentUtils.h"
-#include "nsDOMEvent.h"
-#include "nsEventDispatcher.h"
-#include "nsIClassInfoImpl.h"
-
-#include "MessagePort.h"
-#include "RuntimeService.h"
-#include "Worker.h"
-#include "WorkerPrivate.h"
-
-using mozilla::dom::Optional;
-using mozilla::dom::Sequence;
-
-USING_WORKERS_NAMESPACE
-
-namespace {
-
-const char kSharedWorkersEnabledPref[] = "dom.workers.sharedWorkers.enabled";
-
-} // anonymous namespace
-
-SharedWorker::SharedWorker(nsPIDOMWindow* aWindow,
-                           WorkerPrivate* aWorkerPrivate)
-: nsDOMEventTargetHelper(aWindow), mWorkerPrivate(aWorkerPrivate),
-  mSuspended(false)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aWorkerPrivate);
-
-  mSerial = aWorkerPrivate->NextMessagePortSerial();
-
-  mMessagePort = new MessagePort(aWindow, this, mSerial);
-}
-
-SharedWorker::~SharedWorker()
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(!mWorkerPrivate);
-}
-
-//static
-bool
-SharedWorker::PrefEnabled()
-{
-  AssertIsOnMainThread();
-
-  return mozilla::Preferences::GetBool(kSharedWorkersEnabledPref, false);
-}
-
-// static
-already_AddRefed<SharedWorker>
-SharedWorker::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
-                          const nsAString& aScriptURL,
-                          const mozilla::dom::Optional<nsAString>& aName,
-                          ErrorResult& aRv)
-{
-  AssertIsOnMainThread();
-
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
-  MOZ_ASSERT(window);
-
-  RuntimeService* rts = RuntimeService::GetOrCreateService();
-  if (!rts) {
-    aRv = NS_ERROR_NOT_AVAILABLE;
-    return nullptr;
-  }
-
-  nsString name;
-  if (aName.WasPassed()) {
-    name = aName.Value();
-  }
-
-  nsRefPtr<SharedWorker> sharedWorker;
-  nsresult rv = rts->CreateSharedWorker(aCx, window, aScriptURL, name,
-                                        getter_AddRefs(sharedWorker));
-  if (NS_FAILED(rv)) {
-    aRv = rv;
-    return nullptr;
-  }
-
-  return sharedWorker.forget();
-}
-
-already_AddRefed<MessagePort>
-SharedWorker::Port()
-{
-  AssertIsOnMainThread();
-
-  nsRefPtr<MessagePort> messagePort = mMessagePort;
-  return messagePort.forget();
-}
-
-void
-SharedWorker::Suspend()
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(!IsSuspended());
-
-  mSuspended = true;
-}
-
-void
-SharedWorker::Resume()
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(IsSuspended());
-
-  mSuspended = false;
-
-  if (!mSuspendedEvents.IsEmpty()) {
-    nsTArray<nsCOMPtr<nsIDOMEvent>> events;
-    mSuspendedEvents.SwapElements(events);
-
-    for (uint32_t index = 0; index < events.Length(); index++) {
-      nsCOMPtr<nsIDOMEvent>& event = events[index];
-      MOZ_ASSERT(event);
-
-      nsCOMPtr<nsIDOMEventTarget> target;
-      if (NS_SUCCEEDED(event->GetTarget(getter_AddRefs(target)))) {
-        bool ignored;
-        if (NS_FAILED(target->DispatchEvent(event, &ignored))) {
-          NS_WARNING("Failed to dispatch event!");
-        }
-      } else {
-        NS_WARNING("Failed to get target!");
-      }
-    }
-  }
-}
-
-void
-SharedWorker::QueueEvent(nsIDOMEvent* aEvent)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aEvent);
-  MOZ_ASSERT(IsSuspended());
-
-  mSuspendedEvents.AppendElement(aEvent);
-}
-
-void
-SharedWorker::Close()
-{
-  AssertIsOnMainThread();
-
-  if (mMessagePort) {
-    mMessagePort->Close();
-  }
-
-  if (mWorkerPrivate) {
-    AutoSafeJSContext cx;
-    NoteDeadWorker(cx);
-  }
-}
-
-void
-SharedWorker::PostMessage(JSContext* aCx, JS::HandleValue aMessage,
-                          const Optional<Sequence<JS::Value>>& aTransferable,
-                          ErrorResult& aRv)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mWorkerPrivate);
-  MOZ_ASSERT(mMessagePort);
-
-  mWorkerPrivate->PostMessageToMessagePort(aCx, mMessagePort->Serial(),
-                                           aMessage, aTransferable, aRv);
-}
-
-void
-SharedWorker::NoteDeadWorker(JSContext* aCx)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mWorkerPrivate);
-
-  mWorkerPrivate->UnregisterSharedWorker(aCx, this);
-  mWorkerPrivate = nullptr;
-}
-
-NS_IMPL_ADDREF_INHERITED(SharedWorker, nsDOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(SharedWorker, nsDOMEventTargetHelper)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SharedWorker)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(SharedWorker)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SharedWorker,
-                                                  nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagePort)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuspendedEvents)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SharedWorker,
-                                                nsDOMEventTargetHelper)
-  tmp->Close();
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessagePort)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuspendedEvents)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-JSObject*
-SharedWorker::WrapObject(JSContext* aCx, JS::HandleObject aScope)
-{
-  AssertIsOnMainThread();
-
-  return SharedWorkerBinding::Wrap(aCx, aScope, this);
-}
-
-nsresult
-SharedWorker::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
-{
-  AssertIsOnMainThread();
-
-  nsIDOMEvent*& event = aVisitor.mDOMEvent;
-
-  if (IsSuspended() && event) {
-    QueueEvent(event);
-
-    aVisitor.mCanHandle = false;
-    aVisitor.mParentTarget = nullptr;
-    return NS_OK;
-  }
-
-  return nsDOMEventTargetHelper::PreHandleEvent(aVisitor);
-}
deleted file mode 100644
--- a/dom/workers/SharedWorker.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 mozilla_dom_workers_sharedworker_h__
-#define mozilla_dom_workers_sharedworker_h__
-
-#include "Workers.h"
-
-#include "mozilla/dom/BindingDeclarations.h"
-#include "nsDOMEventTargetHelper.h"
-
-class nsIDOMEvent;
-class nsPIDOMWindow;
-
-BEGIN_WORKERS_NAMESPACE
-
-class MessagePort;
-class RuntimeService;
-class WorkerPrivate;
-
-class SharedWorker MOZ_FINAL : public nsDOMEventTargetHelper
-{
-  friend class MessagePort;
-  friend class RuntimeService;
-
-  typedef mozilla::ErrorResult ErrorResult;
-  typedef mozilla::dom::GlobalObject GlobalObject;
-
-  WorkerPrivate* mWorkerPrivate;
-  nsRefPtr<MessagePort> mMessagePort;
-  nsTArray<nsCOMPtr<nsIDOMEvent>> mSuspendedEvents;
-  uint64_t mSerial;
-  bool mSuspended;
-
-public:
-  static bool
-  PrefEnabled();
-
-  static already_AddRefed<SharedWorker>
-  Constructor(const GlobalObject& aGlobal, JSContext* aCx,
-              const nsAString& aScriptURL, const Optional<nsAString>& aName,
-              ErrorResult& aRv);
-
-  already_AddRefed<MessagePort>
-  Port();
-
-  uint64_t
-  Serial() const
-  {
-    return mSerial;
-  }
-
-  bool
-  IsSuspended() const
-  {
-    return mSuspended;
-  }
-
-  void
-  Suspend();
-
-  void
-  Resume();
-
-  void
-  QueueEvent(nsIDOMEvent* aEvent);
-
-  void
-  Close();
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SharedWorker, nsDOMEventTargetHelper)
-
-  IMPL_EVENT_HANDLER(error)
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::HandleObject aScope) MOZ_OVERRIDE;
-
-  virtual nsresult
-  PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
-
-private:
-  // This class can only be created from the RuntimeService.
-  SharedWorker(nsPIDOMWindow* aWindow, WorkerPrivate* aWorkerPrivate);
-
-  // This class is reference-counted and will be destroyed from Release().
-  ~SharedWorker();
-
-  // Only called by MessagePort.
-  void
-  PostMessage(JSContext* aCx, JS::HandleValue aMessage,
-              const Optional<Sequence<JS::Value>>& aTransferable,
-              ErrorResult& aRv);
-
-  // Only called by RuntimeService.
-  void
-  NoteDeadWorker(JSContext* aCx);
-};
-
-END_WORKERS_NAMESPACE
-
-#endif // mozilla_dom_workers_sharedworker_h__
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -3,17 +3,16 @@
  * 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 "Worker.h"
 
 #include "mozilla/dom/DOMJSClass.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/EventHandlerBinding.h"
-#include "nsJSUtils.h"
 
 #include "jsapi.h"
 #include "EventTarget.h"
 #include "RuntimeService.h"
 #include "WorkerPrivate.h"
 
 #include "WorkerInlines.h"
 
@@ -87,53 +86,79 @@ public:
     }
 
     return proto;
   }
 
   static WorkerPrivate*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName);
 
-  static JSObject*
-  Create(JSContext* aCx, WorkerPrivate* aParentObj, const nsAString& aScriptURL,
-         bool aIsChromeWorker, bool aIsSharedWorker,
-         const nsAString& aSharedWorkerName);
-
 protected:
   static bool
-  ConstructInternal(JSContext* aCx, JS::CallArgs aArgs, bool aIsChromeWorker)
+  ConstructInternal(JSContext* aCx, unsigned aArgc, jsval* aVp,
+                    bool aIsChromeWorker, const JSClass* aClass)
   {
-    if (!aArgs.length()) {
+    if (!aArgc) {
       JS_ReportError(aCx, "Constructor requires at least one argument!");
       return false;
     }
 
-    nsDependentJSString scriptURL;
-    if (!scriptURL.init(aCx, aArgs[0])) {
+    JS::Rooted<JSString*> scriptURL(aCx, JS_ValueToString(aCx, JS_ARGV(aCx, aVp)[0]));
+    if (!scriptURL) {
       return false;
     }
 
-    JS::Rooted<JS::Value> priv(aCx,
-      js::GetFunctionNativeReserved(&aArgs.callee(), CONSTRUCTOR_SLOT_PARENT));
+    jsval priv = js::GetFunctionNativeReserved(JSVAL_TO_OBJECT(JS_CALLEE(aCx, aVp)),
+                                               CONSTRUCTOR_SLOT_PARENT);
 
+    RuntimeService* runtimeService;
     WorkerPrivate* parent;
-    if (priv.isUndefined()) {
+
+    if (JSVAL_IS_VOID(priv)) {
+      runtimeService = RuntimeService::GetOrCreateService();
+      if (!runtimeService) {
+        JS_ReportError(aCx, "Failed to create runtime service!");
+        return false;
+      }
       parent = NULL;
-    } else {
-      parent = static_cast<WorkerPrivate*>(priv.get().toPrivate());
+    }
+    else {
+      runtimeService = RuntimeService::GetService();
+      parent = static_cast<WorkerPrivate*>(JSVAL_TO_PRIVATE(priv));
       parent->AssertIsOnWorkerThread();
     }
 
-    JS::Rooted<JSObject*> obj(aCx,
-      Create(aCx, parent, scriptURL, aIsChromeWorker, false, EmptyString()));
+    JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, aClass, nullptr, nullptr));
     if (!obj) {
       return false;
     }
 
-    aArgs.rval().setObject(*obj);
+    // Ensure that the DOM_OBJECT_SLOT always has a PrivateValue set, as this
+    // will be accessed in the Trace() method if WorkerPrivate::Create()
+    // triggers a GC.
+    js::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::PrivateValue(nullptr));
+
+    nsRefPtr<WorkerPrivate> worker =
+      WorkerPrivate::Create(aCx, obj, parent, scriptURL, aIsChromeWorker);
+    if (!worker) {
+      return false;
+    }
+
+    // Worker now owned by the JS object.
+    NS_ADDREF(worker.get());
+    js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(worker));
+
+    if (!runtimeService->RegisterWorker(aCx, worker)) {
+      return false;
+    }
+
+    // Worker now also owned by its thread.
+    NS_ADDREF(worker.get());
+
+    JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(obj));
     return true;
   }
 
 private:
   // No instance of this class should ever be created so these are explicitly
   // left without an implementation to prevent linking in case someone tries to
   // make one.
   Worker();
@@ -251,20 +276,19 @@ private:
   static bool
   SetOnmessage(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
     JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
     return JS::CallNonGenericMethod<IsWorker, SetOnmessageImpl>(aCx, args);
   }
 
   static bool
-  Construct(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
-    return ConstructInternal(aCx, args, false);
+    return ConstructInternal(aCx, aArgc, aVp, false, Class());
   }
 
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
     if (worker) {
@@ -460,20 +484,19 @@ private:
         return UnwrapDOMObject<WorkerPrivate>(aObj);
       }
     }
 
     return Worker::GetInstancePrivate(aCx, aObj, aFunctionName);
   }
 
   static bool
-  Construct(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
-    return ConstructInternal(aCx, args, true);
+    return ConstructInternal(aCx, aArgc, aVp, true, Class());
   }
 
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
     if (worker) {
@@ -546,73 +569,16 @@ Worker::GetInstancePrivate(JSContext* aC
     return UnwrapDOMObject<WorkerPrivate>(aObj);
   }
 
   JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
                        Class()->name, aFunctionName, classPtr->name);
   return NULL;
 }
 
-JSObject*
-Worker::Create(JSContext* aCx, WorkerPrivate* aParent,
-               const nsAString& aScriptURL, bool aIsChromeWorker,
-               bool aIsSharedWorker, const nsAString& aSharedWorkerName)
-{
-  MOZ_ASSERT_IF(aIsSharedWorker, !aSharedWorkerName.IsVoid());
-  MOZ_ASSERT_IF(!aIsSharedWorker, aSharedWorkerName.IsEmpty());
-
-  RuntimeService* runtimeService;
-  if (aParent) {
-    runtimeService = RuntimeService::GetService();
-    NS_ASSERTION(runtimeService, "Null runtime service!");
-  }
-  else {
-    runtimeService = RuntimeService::GetOrCreateService();
-    if (!runtimeService) {
-      JS_ReportError(aCx, "Failed to create runtime service!");
-      return nullptr;
-    }
-  }
-
-  const JSClass* classPtr = aIsChromeWorker ? ChromeWorker::Class() : Class();
-
-  JS::Rooted<JSObject*> obj(aCx,
-    JS_NewObject(aCx, const_cast<JSClass*>(classPtr), nullptr, nullptr));
-  if (!obj) {
-    return nullptr;
-  }
-
-  // Ensure that the DOM_OBJECT_SLOT always has a PrivateValue set, as this will
-  // be accessed in the Trace() method if WorkerPrivate::Create() triggers a GC.
-  js::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::PrivateValue(nullptr));
-
-  nsRefPtr<WorkerPrivate> worker =
-    WorkerPrivate::Create(aCx, obj, aParent, aScriptURL, aIsChromeWorker,
-                          aIsSharedWorker, aSharedWorkerName);
-  if (!worker) {
-    // It'd be better if we could avoid allocating the JSObject until after we
-    // make sure we have a WorkerPrivate, but failing that we should at least
-    // make sure that the DOM_OBJECT_SLOT always has a PrivateValue.
-    return nullptr;
-  }
-
-  // Worker now owned by the JS object.
-  NS_ADDREF(worker.get());
-  js::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::PrivateValue(worker));
-
-  if (!runtimeService->RegisterWorker(aCx, worker)) {
-    return nullptr;
-  }
-
-  // Worker now also owned by its thread.
-  NS_ADDREF(worker.get());
-
-  return obj;
-}
-
 } // anonymous namespace
 
 BEGIN_WORKERS_NAMESPACE
 
 namespace worker {
 
 JSObject*
 InitClass(JSContext* aCx, JSObject* aGlobal, JSObject* aProto,
--- a/dom/workers/Worker.h
+++ b/dom/workers/Worker.h
@@ -3,17 +3,16 @@
  * 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 mozilla_dom_workers_worker_h__
 #define mozilla_dom_workers_worker_h__
 
 #include "Workers.h"
 
-
 BEGIN_WORKERS_NAMESPACE
 
 namespace worker {
 
 JSObject*
 InitClass(JSContext* aCx, JSObject* aGlobal, JSObject* aProto,
           bool aMainRuntime);
 
@@ -27,9 +26,9 @@ InitClass(JSContext* aCx, JSObject* aGlo
 
 } // namespace chromeworker
 
 bool
 ClassIsWorker(const JSClass* aClass);
 
 END_WORKERS_NAMESPACE
 
-#endif /* mozilla_dom_workers_worker_h__ */
\ No newline at end of file
+#endif /* mozilla_dom_workers_worker_h__ */
deleted file mode 100644
--- a/dom/workers/WorkerMessagePort.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 "WorkerMessagePort.h"
-
-#include "DOMBindingInlines.h"
-#include "Events.h"
-#include "WorkerPrivate.h"
-
-using mozilla::dom::Optional;
-using mozilla::dom::Sequence;
-
-USING_WORKERS_NAMESPACE
-using namespace mozilla::dom::workers::events;
-
-namespace {
-
-bool
-DispatchMessageEvent(JSContext* aCx, JS::HandleObject aMessagePort,
-                     JSAutoStructuredCloneBuffer& aBuffer,
-                     nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects)
-{
-  MOZ_ASSERT(aMessagePort);
-
-  JSAutoStructuredCloneBuffer buffer;
-  aBuffer.swap(buffer);
-
-  nsTArray<nsCOMPtr<nsISupports>> clonedObjects;
-  aClonedObjects.SwapElements(clonedObjects);
-
-  JS::Rooted<JSObject*> event(aCx,
-    CreateMessageEvent(aCx, buffer, clonedObjects, false));
-  if (!event) {
-    return false;
-  }
-
-  bool dummy;
-  return DispatchEventToTarget(aCx, aMessagePort, event, &dummy);
-}
-
-
-class QueuedMessageEventRunnable : public WorkerRunnable
-{
-  JSAutoStructuredCloneBuffer mBuffer;
-  nsTArray<nsCOMPtr<nsISupports>> mClonedObjects;
-  nsRefPtr<WorkerMessagePort> mMessagePort;
-  JSObject* mMessagePortObject;
-
-public:
-  QueuedMessageEventRunnable(WorkerPrivate* aWorkerPrivate,
-                             JSAutoStructuredCloneBuffer& aBuffer,
-                             nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects)
-  : WorkerRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount,
-                   RunWhenClearing),
-    mMessagePortObject(nullptr)
-  {
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    mBuffer.swap(aBuffer);
-    mClonedObjects.SwapElements(aClonedObjects);
-  }
-
-  bool
-  Hold(JSContext* aCx, WorkerMessagePort* aMessagePort)
-  {
-    mWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aMessagePort);
-    MOZ_ASSERT(aMessagePort->GetJSObject());
-    MOZ_ASSERT(!mMessagePortObject);
-
-    if (!JS_AddNamedObjectRoot(aCx, &mMessagePortObject,
-                               "WorkerMessagePort::MessageEventRunnable::"
-                               "mMessagePortObject")) {
-      return false;
-    }
-
-    mMessagePortObject = aMessagePort->GetJSObject();
-    mMessagePort = aMessagePort;
-    return true;
-  }
-
-  bool
-  PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
-  {
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    return true;
-  }
-
-  void
-  PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
-               bool aDispatchResult)
-  {
-    aWorkerPrivate->AssertIsOnWorkerThread();
-  }
-
-  bool
-  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
-  {
-    JS::Rooted<JSObject*> messagePortObject(aCx, mMessagePortObject);
-    mMessagePortObject = nullptr;
-
-    JS_RemoveObjectRoot(aCx, &mMessagePortObject);
-
-    nsRefPtr<WorkerMessagePort> messagePort;
-    mMessagePort.swap(messagePort);
-
-    return DispatchMessageEvent(aCx, messagePortObject, mBuffer,
-                                mClonedObjects);
-  }
-};
-
-} // anonymous namespace
-
-void
-WorkerMessagePort::_trace(JSTracer* aTrc)
-{
-  EventTarget::_trace(aTrc);
-}
-
-void
-WorkerMessagePort::_finalize(JSFreeOp* aFop)
-{
-  EventTarget::_finalize(aFop);
-}
-
-void
-WorkerMessagePort::PostMessage(
-                             JSContext* /* aCx */, JS::HandleValue aMessage,
-                             const Optional<Sequence<JS::Value>>& aTransferable,
-                             ErrorResult& aRv)
-{
-  if (mClosed) {
-    aRv = NS_ERROR_DOM_INVALID_STATE_ERR;
-    return;
-  }
-
-  JSContext* cx = GetJSContext();
-
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
-  MOZ_ASSERT(workerPrivate);
-
-  workerPrivate->PostMessageToParentMessagePort(cx, Serial(), aMessage,
-                                                aTransferable, aRv);
-}
-
-void
-WorkerMessagePort::Start()
-{
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(GetJSContext());
-  MOZ_ASSERT(workerPrivate);
-
-  if (mClosed) {
-    NS_WARNING("Called start() after calling close()!");
-    return;
-  }
-
-  if (mStarted) {
-    return;
-  }
-
-  mStarted = true;
-
-  if (!mQueuedMessages.IsEmpty()) {
-    for (uint32_t index = 0; index < mQueuedMessages.Length(); index++) {
-      MessageInfo& info = mQueuedMessages[index];
-
-      nsRefPtr<QueuedMessageEventRunnable> runnable =
-        new QueuedMessageEventRunnable(workerPrivate, info.mBuffer,
-                                       info.mClonedObjects);
-
-      JSContext* cx = GetJSContext();
-
-      if (!runnable->Hold(cx, this) ||
-          !runnable->Dispatch(cx)) {
-        NS_WARNING("Failed to dispatch queued event!");
-        break;
-      }
-    }
-    mQueuedMessages.Clear();
-  }
-}
-
-bool
-WorkerMessagePort::MaybeDispatchEvent(
-                                JSContext* aCx,
-                                JSAutoStructuredCloneBuffer& aBuffer,
-                                nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects)
-{
-  if (mClosed) {
-    NS_WARNING("Not going to ever run this event!");
-    aBuffer.clear();
-    aClonedObjects.Clear();
-    return true;
-  }
-
-  if (!mStarted) {
-    // Queue the message for later.
-    MessageInfo* info = mQueuedMessages.AppendElement();
-    info->mBuffer.swap(aBuffer);
-    info->mClonedObjects.SwapElements(aClonedObjects);
-    return true;
-  }
-
-  // Go ahead and dispatch the event.
-  JS::Rooted<JSObject*> target(aCx, GetJSObject());
-  return DispatchMessageEvent(aCx, target, aBuffer, aClonedObjects);
-}
-
-void
-WorkerMessagePort::CloseInternal()
-{
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(GetJSContext());
-  MOZ_ASSERT(workerPrivate);
-  MOZ_ASSERT(!IsClosed());
-  MOZ_ASSERT_IF(mStarted, mQueuedMessages.IsEmpty());
-
-  mClosed = true;
-
-  workerPrivate->DisconnectMessagePort(Serial());
-
-  if (!mStarted) {
-    mQueuedMessages.Clear();
-  }
-}
deleted file mode 100644
--- a/dom/workers/WorkerMessagePort.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 mozilla_dom_workers_workermessageport_h__
-#define mozilla_dom_workers_workermessageport_h__
-
-#include "js/StructuredClone.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/workers/bindings/EventTarget.h"
-
-BEGIN_WORKERS_NAMESPACE
-
-class WorkerPrivate;
-
-class WorkerMessagePort : public EventTarget
-{
-  friend class WorkerPrivate;
-
-  typedef mozilla::ErrorResult ErrorResult;
-
-  struct MessageInfo
-  {
-    JSAutoStructuredCloneBuffer mBuffer;
-    nsTArray<nsCOMPtr<nsISupports>> mClonedObjects;
-  };
-
-  nsTArray<MessageInfo> mQueuedMessages;
-  uint64_t mSerial;
-  bool mStarted;
-  bool mClosed;
-
-public:
-  virtual void
-  _trace(JSTracer* aTrc) MOZ_OVERRIDE;
-
-  virtual void
-  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
-
-  void
-  PostMessage(JSContext* aCx, JS::HandleValue aMessage,
-              const Optional<Sequence<JS::Value>>& aTransferable,
-              ErrorResult& aRv);
-
-  void
-  Start();
-
-  void
-  Close()
-  {
-    if (!IsClosed()) {
-      CloseInternal();
-    }
-  }
-
-  already_AddRefed<EventHandlerNonNull>
-  GetOnmessage(ErrorResult& aRv)
-  {
-    return GetEventListener(NS_LITERAL_STRING("message"), aRv);
-  }
-
-  void
-  SetOnmessage(EventHandlerNonNull* aListener, ErrorResult& aRv)
-  {
-    SetEventListener(NS_LITERAL_STRING("message"), aListener, aRv);
-    if (!aRv.Failed()) {
-      Start();
-    }
-  }
-
-  uint64_t
-  Serial() const
-  {
-    return mSerial;
-  }
-
-  bool
-  MaybeDispatchEvent(JSContext* aCx, JSAutoStructuredCloneBuffer& aBuffer,
-                     nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects);
-
-  bool
-  IsClosed() const
-  {
-    return mClosed;
-  }
-
-private:
-  // Only created by WorkerPrivate.
-  WorkerMessagePort(JSContext* aCx, uint64_t aSerial)
-  : EventTarget(aCx), mSerial(aSerial), mStarted(false), mClosed(false)
-  { }
-
-  virtual ~WorkerMessagePort()
-  { }
-
-  void
-  CloseInternal();
-};
-
-END_WORKERS_NAMESPACE
-
-#endif // mozilla_dom_workers_workermessageport_h__
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -6,77 +6,68 @@
 
 #include "WorkerPrivate.h"
 
 #include "amIAddonManager.h"
 #include "nsIClassInfo.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIConsoleService.h"
 #include "nsIDOMDOMException.h"
-#include "nsIDOMEvent.h"
 #include "nsIDOMFile.h"
 #include "nsIDocument.h"
 #include "nsIDocShell.h"
 #include "nsIMemoryReporter.h"
 #include "nsIPermissionManager.h"
 #include "nsIScriptError.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsITextToSubURI.h"
 #include "nsITimer.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIXPConnect.h"
+#include "nsPrintfCString.h"
+#include "nsHostObjectProtocolHandler.h"
 
 #include <algorithm>
-#include "GeneratedEvents.h"
 #include "jsfriendapi.h"
 #include "js/OldDebugAPI.h"
 #include "js/MemoryMetrics.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/Likely.h"
 #include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/ImageDataBinding.h"
-#include "mozilla/Util.h"
 #include "nsAlgorithm.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsError.h"
-#include "nsDOMMessageEvent.h"
 #include "nsDOMJSUtils.h"
-#include "nsHostObjectProtocolHandler.h"
 #include "nsJSEnvironment.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
-#include "nsPrintfCString.h"
 #include "nsProxyRelease.h"
 #include "nsSandboxFlags.h"
 #include "nsThreadUtils.h"
 #include "xpcpublic.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
-#include "DOMBindingInlines.h"
 #include "Events.h"
 #include "mozilla/dom/Exceptions.h"
 #include "File.h"
-#include "MessagePort.h"
 #include "Principal.h"
 #include "RuntimeService.h"
 #include "ScriptLoader.h"
-#include "SharedWorker.h"
 #include "Worker.h"
 #include "WorkerFeature.h"
-#include "WorkerMessagePort.h"
 #include "WorkerScope.h"
 
 // GC will run once every thirty seconds during normal execution.
 #define NORMAL_GC_TIMER_DELAY_MS 30000
 
 // GC will run five seconds after the last event is processed.
 #define IDLE_GC_TIMER_DELAY_MS 5000
 
@@ -135,95 +126,16 @@ SwapToISupportsArray(SmartPtr<T>& aSrc,
   T* raw = nullptr;
   aSrc.swap(raw);
 
   nsISupports* rawSupports =
     static_cast<typename ISupportsBaseInfo<T>::ISupportsBase*>(raw);
   dest->swap(rawSupports);
 }
 
-struct WindowAction
-{
-  nsPIDOMWindow* mWindow;
-  JSContext* mJSContext;
-  bool mDefaultAction;
-
-  WindowAction(nsPIDOMWindow* aWindow, JSContext* aJSContext)
-  : mWindow(aWindow), mJSContext(aJSContext), mDefaultAction(true)
-  {
-    MOZ_ASSERT(aJSContext);
-  }
-
-  WindowAction(nsPIDOMWindow* aWindow)
-  : mWindow(aWindow), mJSContext(nullptr), mDefaultAction(true)
-  { }
-
-  bool
-  operator==(const WindowAction& aOther) const
-  {
-    return mWindow == aOther.mWindow;
-  }
-};
-
-void
-LogErrorToConsole(const nsAString& aMessage,
-                  const nsAString& aFilename,
-                  const nsAString& aLine,
-                  uint32_t aLineNumber,
-                  uint32_t aColumnNumber,
-                  uint32_t aFlags,
-                  uint64_t aInnerWindowId)
-{
-  AssertIsOnMainThread();
-
-  nsCOMPtr<nsIScriptError> scriptError =
-    do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
-  NS_WARN_IF_FALSE(scriptError, "Failed to create script error!");
-
-  if (scriptError) {
-    if (NS_FAILED(scriptError->InitWithWindowID(aMessage, aFilename, aLine,
-                                                aLineNumber, aColumnNumber,
-                                                aFlags, "Web Worker",
-                                                aInnerWindowId))) {
-      NS_WARNING("Failed to init script error!");
-      scriptError = nullptr;
-    }
-  }
-
-  nsCOMPtr<nsIConsoleService> consoleService =
-    do_GetService(NS_CONSOLESERVICE_CONTRACTID);
-  NS_WARN_IF_FALSE(consoleService, "Failed to get console service!");
-
-  if (consoleService) {
-    if (scriptError) {
-      if (NS_SUCCEEDED(consoleService->LogMessage(scriptError))) {
-        return;
-      }
-      NS_WARNING("LogMessage failed!");
-    } else if (NS_SUCCEEDED(consoleService->LogStringMessage(
-                                                    aMessage.BeginReading()))) {
-      return;
-    }
-    NS_WARNING("LogStringMessage failed!");
-  }
-
-  NS_ConvertUTF16toUTF8 msg(aMessage);
-  NS_ConvertUTF16toUTF8 filename(aFilename);
-
-  static const char kErrorString[] = "JS error in Web Worker: %s [%s:%u]";
-
-#ifdef ANDROID
-  __android_log_print(ANDROID_LOG_INFO, "Gecko", kErrorString, msg.get(),
-                      filename.get(), aLineNumber);
-#endif
-
-  fprintf(stderr, kErrorString, msg.get(), filename.get(), aLineNumber);
-  fflush(stderr);
-}
-
 struct WorkerStructuredCloneCallbacks
 {
   static JSObject*
   Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
        uint32_t aData, void* aClosure)
   {
     // See if object is a nsIDOMFile pointer.
     if (aTag == DOMWORKER_SCTAG_FILE) {
@@ -802,17 +714,17 @@ public:
   CompileScriptRunnable(WorkerPrivate* aWorkerPrivate)
   : WorkerRunnable(aWorkerPrivate, WorkerThread, ModifyBusyCount,
                    SkipWhenClearing)
   { }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
-    JS::Rooted<JSObject*> global(aCx, CreateGlobalScope(aCx));
+    JS::Rooted<JSObject*> global(aCx, CreateDedicatedWorkerGlobalScope(aCx));
     if (!global) {
       NS_WARNING("Failed to make global!");
       return false;
     }
 
     JSAutoCompartment ac(aCx, global);
     return scriptloader::LoadWorkerScript(aCx);
   }
@@ -862,81 +774,57 @@ public:
     aWorkerPrivate->CloseHandlerFinished();
   }
 };
 
 class MessageEventRunnable : public WorkerRunnable
 {
   JSAutoStructuredCloneBuffer mBuffer;
   nsTArray<nsCOMPtr<nsISupports> > mClonedObjects;
-  uint64_t mMessagePortSerial;
-  bool mToMessagePort;
 
 public:
   MessageEventRunnable(WorkerPrivate* aWorkerPrivate, Target aTarget,
                        JSAutoStructuredCloneBuffer& aData,
-                       nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects,
-                       bool aToMessagePort, uint64_t aMessagePortSerial)
+                       nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects)
   : WorkerRunnable(aWorkerPrivate, aTarget, aTarget == WorkerThread ?
                                                        ModifyBusyCount :
                                                        UnchangedBusyCount,
-                   SkipWhenClearing),
-    mMessagePortSerial(aMessagePortSerial), mToMessagePort(aToMessagePort)
+                   SkipWhenClearing)
   {
     mBuffer.swap(aData);
     mClonedObjects.SwapElements(aClonedObjects);
   }
 
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
-    MOZ_ASSERT_IF(mToMessagePort, aWorkerPrivate->IsSharedWorker());
-
     bool mainRuntime;
     JS::Rooted<JSObject*> target(aCx);
     if (mTarget == ParentThread) {
       // Don't fire this event if the JS object has been disconnected from the
       // private object.
       if (!aWorkerPrivate->IsAcceptingEvents()) {
         return true;
       }
 
-      if (mToMessagePort) {
-        return
-          aWorkerPrivate->DispatchMessageEventToMessagePort(aCx,
-                                                            mMessagePortSerial,
-                                                            mBuffer,
-                                                            mClonedObjects);
-      }
-
       mainRuntime = !aWorkerPrivate->GetParent();
 
       target = aWorkerPrivate->GetJSObject();
       NS_ASSERTION(target, "Must have a target!");
 
       if (aWorkerPrivate->IsSuspended()) {
         aWorkerPrivate->QueueRunnable(this);
         return true;
       }
 
       aWorkerPrivate->AssertInnerWindowIsCorrect();
     }
     else {
       NS_ASSERTION(aWorkerPrivate == GetWorkerPrivateFromContext(aCx),
                    "Badness!");
-      if (mToMessagePort) {
-        WorkerMessagePort* port =
-          aWorkerPrivate->GetMessagePort(mMessagePortSerial);
-        if (!port) {
-          // Must have been closed already.
-          return true;
-        }
-        return port->MaybeDispatchEvent(aCx, mBuffer, mClonedObjects);
-      }
-
       mainRuntime = false;
       target = JS::CurrentGlobalOrNull(aCx);
     }
 
     NS_ASSERTION(target, "This should never be null!");
 
     JS::Rooted<JSObject*> event(aCx,
       CreateMessageEvent(aCx, mBuffer, mClonedObjects, mainRuntime));
@@ -1065,61 +953,53 @@ public:
     // private object.
     if (!aWorkerPrivate->IsAcceptingEvents()) {
       return true;
     }
 
     JS::Rooted<JSObject*> target(aCx, aWorkerPrivate->GetJSObject());
 
     uint64_t innerWindowId;
-    bool fireAtScope = true;
 
     WorkerPrivate* parent = aWorkerPrivate->GetParent();
     if (parent) {
       innerWindowId = 0;
     }
     else {
       AssertIsOnMainThread();
 
       if (aWorkerPrivate->IsSuspended()) {
         aWorkerPrivate->QueueRunnable(this);
         return true;
       }
 
-      if (aWorkerPrivate->IsSharedWorker()) {
-        aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename,
-                                                      mLine, mLineNumber,
-                                                      mColumnNumber, mFlags);
-        return true;
-      }
-
       aWorkerPrivate->AssertInnerWindowIsCorrect();
 
       innerWindowId = aWorkerPrivate->GetInnerWindowId();
     }
 
-    return ReportErrorRunnable::ReportError(aCx, parent, fireAtScope, target,
-                                            mMessage, mFilename, mLine,
-                                            mLineNumber, mColumnNumber, mFlags,
+    return ReportErrorRunnable::ReportError(aCx, parent, true, target, mMessage,
+                                            mFilename, mLine, mLineNumber,
+                                            mColumnNumber, mFlags,
                                             mErrorNumber, innerWindowId);
   }
 
   void PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult)
   {
     WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
   }
 
   static bool
   ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
-              bool aFireAtScope, JSObject* aTarget, const nsString& aMessage,
+              bool aFireAtScope, JSObject* target, const nsString& aMessage,
               const nsString& aFilename, const nsString& aLine,
               uint32_t aLineNumber, uint32_t aColumnNumber, uint32_t aFlags,
               uint32_t aErrorNumber, uint64_t aInnerWindowId)
   {
-    JS::Rooted<JSObject*> target(aCx, aTarget);
+    JS::Rooted<JSObject*> aTarget(aCx, target);
     if (aWorkerPrivate) {
       aWorkerPrivate->AssertIsOnWorkerThread();
     }
     else {
       AssertIsOnMainThread();
     }
 
     JS::Rooted<JSString*> message(aCx, JS_NewUCStringCopyN(aCx, aMessage.get(),
@@ -1133,52 +1013,52 @@ public:
     if (!filename) {
       return false;
     }
 
     // We should not fire error events for warnings but instead make sure that
     // they show up in the error console.
     if (!JSREPORT_IS_WARNING(aFlags)) {
       // First fire an ErrorEvent at the worker.
-      if (target) {
+      if (aTarget) {
         JS::Rooted<JSObject*> event(aCx,
           CreateErrorEvent(aCx, message, filename, aLineNumber, !aWorkerPrivate));
         if (!event) {
           return false;
         }
 
         bool preventDefaultCalled;
-        if (!DispatchEventToTarget(aCx, target, event, &preventDefaultCalled)) {
+        if (!DispatchEventToTarget(aCx, aTarget, event, &preventDefaultCalled)) {
           return false;
         }
 
         if (preventDefaultCalled) {
           return true;
         }
       }
 
       // Now fire an event at the global object, but don't do that if the error
       // code is too much recursion and this is the same script threw the error.
-      if (aFireAtScope && (target || aErrorNumber != JSMSG_OVER_RECURSED)) {
-        target = JS::CurrentGlobalOrNull(aCx);
-        NS_ASSERTION(target, "This should never be null!");
+      if (aFireAtScope && (aTarget || aErrorNumber != JSMSG_OVER_RECURSED)) {
+        aTarget = JS::CurrentGlobalOrNull(aCx);
+        NS_ASSERTION(aTarget, "This should never be null!");
 
         bool preventDefaultCalled;
         nsIScriptGlobalObject* sgo;
 
         if (aWorkerPrivate ||
-            !(sgo = nsJSUtils::GetStaticScriptGlobal(target))) {
+            !(sgo = nsJSUtils::GetStaticScriptGlobal(aTarget))) {
           // Fire a normal ErrorEvent if we're running on a worker thread.
           JS::Rooted<JSObject*> event(aCx,
             CreateErrorEvent(aCx, message, filename, aLineNumber, false));
           if (!event) {
             return false;
           }
 
-          if (!DispatchEventToTarget(aCx, target, event,
+          if (!DispatchEventToTarget(aCx, aTarget, event,
                                      &preventDefaultCalled)) {
             return false;
           }
         }
         else {
           // Icky, we have to fire an InternalScriptErrorEvent...
           InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
           event.lineNr = aLineNumber;
@@ -1205,18 +1085,66 @@ public:
       nsRefPtr<ReportErrorRunnable> runnable =
         new ReportErrorRunnable(aWorkerPrivate, aMessage, aFilename, aLine,
                                 aLineNumber, aColumnNumber, aFlags,
                                 aErrorNumber);
       return runnable->Dispatch(aCx);
     }
 
     // Otherwise log an error to the error console.
-    LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber,
-                      aFlags, aInnerWindowId);
+    nsCOMPtr<nsIScriptError> scriptError =
+      do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
+    NS_WARN_IF_FALSE(scriptError, "Failed to create script error!");
+
+    if (scriptError) {
+      if (NS_FAILED(scriptError->InitWithWindowID(aMessage,
+                                                  aFilename,
+                                                  aLine, aLineNumber,
+                                                  aColumnNumber, aFlags,
+                                                  "Web Worker",
+                                                  aInnerWindowId))) {
+        NS_WARNING("Failed to init script error!");
+        scriptError = nullptr;
+      }
+    }
+
+    nsCOMPtr<nsIConsoleService> consoleService =
+      do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+    NS_WARN_IF_FALSE(consoleService, "Failed to get console service!");
+
+    bool logged = false;
+
+    if (consoleService) {
+      if (scriptError) {
+        if (NS_SUCCEEDED(consoleService->LogMessage(scriptError))) {
+          logged = true;
+        }
+        else {
+          NS_WARNING("Failed to log script error!");
+        }
+      }
+      else if (NS_SUCCEEDED(consoleService->LogStringMessage(aMessage.get()))) {
+        logged = true;
+      }
+      else {
+        NS_WARNING("Failed to log script error!");
+      }
+    }
+
+    if (!logged || nsContentUtils::DOMWindowDumpEnabled()) {
+      NS_ConvertUTF16toUTF8 msg(aMessage);
+      NS_ConvertUTF16toUTF8 fname(aFilename);
+#ifdef ANDROID
+      __android_log_print(ANDROID_LOG_INFO, "Gecko", "JS error in worker: %s, %s:%u",
+                          msg.get(), fname.get(), aLineNumber);
+#endif
+      fprintf(stderr, "JS error in worker: %s, %s:%u\n", msg.get(), fname.get(), aLineNumber);
+      fflush(stderr);
+    }
+
     return true;
   }
 };
 
 class TimerRunnable : public WorkerRunnable
 {
 public:
   TimerRunnable(WorkerPrivate* aWorkerPrivate)
@@ -1507,42 +1435,34 @@ public:
     return true;
   }
 };
 
 class SynchronizeAndResumeRunnable : public nsRunnable
 {
 protected:
   WorkerPrivate* mWorkerPrivate;
-  nsCOMPtr<nsPIDOMWindow> mWindow;
-  nsCOMPtr<nsIScriptContext> mScriptContext;
+  nsCOMPtr<nsIScriptContext> mCx;
 
 public:
   SynchronizeAndResumeRunnable(WorkerPrivate* aWorkerPrivate,
-                               nsPIDOMWindow* aWindow,
-                               nsIScriptContext* aScriptContext)
-  : mWorkerPrivate(aWorkerPrivate), mWindow(aWindow),
-    mScriptContext(aScriptContext)
+                               nsIScriptContext* aCx)
+  : mWorkerPrivate(aWorkerPrivate), mCx(aCx)
   {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(aWorkerPrivate);
-    MOZ_ASSERT(aWindow);
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   }
 
   NS_IMETHOD Run()
   {
-    AssertIsOnMainThread();
-
-    AutoPushJSContext cx(mScriptContext ?
-                         mScriptContext->GetNativeContext() :
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+    AutoPushJSContext cx(mCx ? mCx->GetNativeContext() :
                          nsContentUtils::GetSafeJSContext());
-
-    if (!mWorkerPrivate->Resume(cx, mWindow)) {
-      JS_ReportPendingException(cx);
-    }
+    JSAutoRequest ar(cx);
+    mWorkerPrivate->Resume(cx);
 
     return NS_OK;
   }
 };
 
 class WorkerJSRuntimeStats : public JS::RuntimeStats
 {
   const nsACString& mRtPath;
@@ -1600,50 +1520,23 @@ public:
 
     // This should never be used when reporting with workers (hence the "?!").
     extras->domPathPrefix.AssignLiteral("explicit/workers/?!/");
 
     aCompartmentStats->extra = extras;
   }
 };
 
-class MessagePortRunnable : public WorkerRunnable
-{
-  uint64_t mMessagePortSerial;
-  bool mConnect;
-
-public:
-  MessagePortRunnable(WorkerPrivate* aWorkerPrivate,
-                      uint64_t aMessagePortSerial,
-                      bool aConnect)
-  : WorkerRunnable(aWorkerPrivate, WorkerThread,
-                   aConnect ? ModifyBusyCount : UnchangedBusyCount,
-                   SkipWhenClearing),
-    mMessagePortSerial(aMessagePortSerial), mConnect(aConnect)
-  { }
-
-  bool
-  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
-  {
-    if (mConnect) {
-      return aWorkerPrivate->ConnectMessagePort(aCx, mMessagePortSerial);
-    }
-
-    aWorkerPrivate->DisconnectMessagePort(mMessagePortSerial);
-    return true;
-  }
-};
-
 } /* anonymous namespace */
 
 #ifdef DEBUG
 void
 mozilla::dom::workers::AssertIsOnMainThread()
 {
-  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 WorkerRunnable::WorkerRunnable(WorkerPrivate* aWorkerPrivate, Target aTarget,
                                BusyBehavior aBusyBehavior,
                                ClearingBehavior aClearingBehavior)
 : mWorkerPrivate(aWorkerPrivate), mTarget(aTarget),
   mBusyBehavior(aBusyBehavior), mClearingBehavior(aClearingBehavior)
 {
@@ -1990,64 +1883,69 @@ private:
     mRtPath.Insert(addonId, explicitLength);
   }
 };
 
 NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
 
 template <class Derived>
 WorkerPrivateParent<Derived>::WorkerPrivateParent(
-                                             JSContext* aCx,
-                                             JS::HandleObject aObject,
-                                             WorkerPrivate* aParent,
-                                             const nsAString& aScriptURL,
-                                             bool aIsChromeWorker,
-                                             bool aIsSharedWorker,
-                                             const nsAString& aSharedWorkerName,
-                                             LoadInfo& aLoadInfo)
-: EventTarget(aParent ? aCx : nullptr), mMutex("WorkerPrivateParent Mutex"),
+                                     JSContext* aCx,
+                                     JS::Handle<JSObject*> aObject,
+                                     WorkerPrivate* aParent,
+                                     JSContext* aParentJSContext,
+                                     const nsAString& aScriptURL,
+                                     bool aIsChromeWorker,
+                                     const nsACString& aDomain,
+                                     nsCOMPtr<nsPIDOMWindow>& aWindow,
+                                     nsCOMPtr<nsIScriptContext>& aScriptContext,
+                                     nsCOMPtr<nsIURI>& aBaseURI,
+                                     nsCOMPtr<nsIPrincipal>& aPrincipal,
+                                     nsCOMPtr<nsIChannel>& aChannel,
+                                     nsCOMPtr<nsIContentSecurityPolicy>& aCSP,
+                                     bool aEvalAllowed,
+                                     bool aReportCSPViolations)
+: EventTarget(aParent ? aCx : NULL), mMutex("WorkerPrivateParent Mutex"),
   mCondVar(mMutex, "WorkerPrivateParent CondVar"),
   mMemoryReportCondVar(mMutex, "WorkerPrivateParent Memory Report CondVar"),
-  mJSObject(aObject), mParent(aParent), mScriptURL(aScriptURL),
-  mSharedWorkerName(aSharedWorkerName), mBusyCount(0), mMessagePortSerial(0),
+  mJSObject(aObject), mParent(aParent), mParentJSContext(aParentJSContext),
+  mScriptURL(aScriptURL), mDomain(aDomain), mBusyCount(0),
   mParentStatus(Pending), mJSObjectRooted(false), mParentSuspended(false),
-  mIsChromeWorker(aIsChromeWorker), mMainThreadObjectsForgotten(false),
-  mIsSharedWorker(aIsSharedWorker)
+  mIsChromeWorker(aIsChromeWorker), mPrincipalIsSystem(false),
+  mMainThreadObjectsForgotten(false), mEvalAllowed(aEvalAllowed),
+  mReportCSPViolations(aReportCSPViolations)
 {
   MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerPrivateParent);
-  MOZ_ASSERT_IF(aIsSharedWorker, !aObject && !aSharedWorkerName.IsVoid());
-  MOZ_ASSERT_IF(!aIsSharedWorker, aObject && aSharedWorkerName.IsEmpty());
-
-  if (aLoadInfo.mWindow) {
-    NS_ASSERTION(aLoadInfo.mWindow->IsInnerWindow(),
-                 "Should have inner window here!");
+
+  if (aWindow) {
+    NS_ASSERTION(aWindow->IsInnerWindow(), "Should have inner window here!");
   }
 
-  mLoadInfo.StealFrom(aLoadInfo);
+  mWindow.swap(aWindow);
+  mScriptContext.swap(aScriptContext);
+  mBaseURI.swap(aBaseURI);
+  mPrincipal.swap(aPrincipal);
+  mChannel.swap(aChannel);
+  mCSP.swap(aCSP);
 
   if (aParent) {
     aParent->AssertIsOnWorkerThread();
 
     aParent->CopyJSSettings(mJSSettings);
 
     NS_ASSERTION(JS_GetOptions(aCx) == (aParent->IsChromeWorker() ?
                                         mJSSettings.chrome.options :
                                         mJSSettings.content.options),
                  "Options mismatch!");
   }
   else {
     AssertIsOnMainThread();
 
     RuntimeService::GetDefaultJSSettings(mJSSettings);
   }
-
-  if (!aIsSharedWorker) {
-    SetIsDOMBinding();
-    SetWrapper(aObject);
-  }
 }
 
 template <class Derived>
 WorkerPrivateParent<Derived>::~WorkerPrivateParent()
 {
   MOZ_COUNT_DTOR(mozilla::dom::workers::WorkerPrivateParent);
 }
 
@@ -2113,223 +2011,88 @@ WorkerPrivateParent<Derived>::NotifyPriv
 
   nsRefPtr<NotifyRunnable> runnable =
     new NotifyRunnable(ParentAsWorkerPrivate(), aStatus);
   return runnable->Dispatch(aCx);
 }
 
 template <class Derived>
 bool
-WorkerPrivateParent<Derived>::Suspend(JSContext* aCx, nsPIDOMWindow* aWindow)
+WorkerPrivateParent<Derived>::Suspend(JSContext* aCx)
 {
   AssertIsOnParentThread();
-  MOZ_ASSERT(aCx);
-
-  // Shared workers are only suspended if all of their owning documents are
-  // suspended.
-  if (IsSharedWorker()) {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(mSharedWorkers.Count());
-
-    struct Closure
-    {
-      nsPIDOMWindow* mWindow;
-      bool mAllSuspended;
-
-      Closure(nsPIDOMWindow* aWindow)
-      : mWindow(aWindow), mAllSuspended(true)
-      {
-        AssertIsOnMainThread();
-        // aWindow may be null here.
-      }
-
-      static PLDHashOperator
-      Suspend(const uint64_t& aKey,
-              SharedWorker* aSharedWorker,
-              void* aClosure)
-      {
-        AssertIsOnMainThread();
-        MOZ_ASSERT(aSharedWorker);
-        MOZ_ASSERT(aClosure);
-
-        auto closure = static_cast<Closure*>(aClosure);
-
-        if (closure->mWindow && aSharedWorker->GetOwner() == closure->mWindow) {
-          // Calling Suspend() may change the refcount, ensure that the worker
-          // outlives this call.
-          nsRefPtr<SharedWorker> kungFuDeathGrip = aSharedWorker;
-
-          aSharedWorker->Suspend();
-        } else {
-          MOZ_ASSERT_IF(aSharedWorker->GetOwner() && closure->mWindow,
-                        !SameCOMIdentity(aSharedWorker->GetOwner(),
-                                         closure->mWindow));
-          if (!aSharedWorker->IsSuspended()) {
-            closure->mAllSuspended = false;
-          }
-        }
-        return PL_DHASH_NEXT;
-      }
-    };
-
-    Closure closure(aWindow);
-
-    mSharedWorkers.EnumerateRead(Closure::Suspend, &closure);
-
-    if (!closure.mAllSuspended || mParentSuspended) {
-      return true;
-    }
-  }
-
-  MOZ_ASSERT(!mParentSuspended, "Suspended more than once!");
+  NS_ASSERTION(!mParentSuspended, "Suspended more than once!");
 
   mParentSuspended = true;
 
   {
     MutexAutoLock lock(mMutex);
 
     if (mParentStatus >= Terminating) {
       return true;
     }
   }
 
   nsRefPtr<SuspendRunnable> runnable =
     new SuspendRunnable(ParentAsWorkerPrivate());
-  if (!runnable->Dispatch(aCx)) {
-    return false;
-  }
-
-  return true;
+  return runnable->Dispatch(aCx);
 }
 
 template <class Derived>
-bool
-WorkerPrivateParent<Derived>::Resume(JSContext* aCx, nsPIDOMWindow* aWindow)
+void
+WorkerPrivateParent<Derived>::Resume(JSContext* aCx)
 {
   AssertIsOnParentThread();
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT_IF(!IsSharedWorker(), mParentSuspended);
-
-  // Shared workers are resumed if any of their owning documents are resumed.
-  if (IsSharedWorker()) {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(mSharedWorkers.Count());
-
-    struct Closure
-    {
-      nsPIDOMWindow* mWindow;
-      bool mAnyRunning;
-
-      Closure(nsPIDOMWindow* aWindow)
-      : mWindow(aWindow), mAnyRunning(false)
-      {
-        AssertIsOnMainThread();
-        // aWindow may be null here.
-      }
-
-      static PLDHashOperator
-      Resume(const uint64_t& aKey,
-              SharedWorker* aSharedWorker,
-              void* aClosure)
-      {
-        AssertIsOnMainThread();
-        MOZ_ASSERT(aSharedWorker);
-        MOZ_ASSERT(aClosure);
-
-        auto closure = static_cast<Closure*>(aClosure);
-
-        if (closure->mWindow && aSharedWorker->GetOwner() == closure->mWindow) {
-          // Calling Resume() may change the refcount, ensure that the worker
-          // outlives this call.
-          nsRefPtr<SharedWorker> kungFuDeathGrip = aSharedWorker;
-
-          aSharedWorker->Resume();
-          closure->mAnyRunning = true;
-        } else {
-          MOZ_ASSERT_IF(aSharedWorker->GetOwner() && closure->mWindow,
-                        !SameCOMIdentity(aSharedWorker->GetOwner(),
-                                         closure->mWindow));
-          if (!aSharedWorker->IsSuspended()) {
-            closure->mAnyRunning = true;
-          }
-        }
-        return PL_DHASH_NEXT;
-      }
-    };
-
-    Closure closure(aWindow);
-
-    mSharedWorkers.EnumerateRead(Closure::Resume, &closure);
-
-    if (!closure.mAnyRunning || !mParentSuspended) {
-      return true;
-    }
-  }
-
-  MOZ_ASSERT(mParentSuspended);
+  NS_ASSERTION(mParentSuspended, "Not yet suspended!");
 
   mParentSuspended = false;
 
   {
     MutexAutoLock lock(mMutex);
 
     if (mParentStatus >= Terminating) {
-      return true;
+      return;
     }
   }
 
   // Execute queued runnables before waking up the worker, otherwise the worker
   // could post new messages before we run those that have been queued.
   if (!mQueuedRunnables.IsEmpty()) {
     AssertIsOnMainThread();
-    MOZ_ASSERT(!IsSharedWorker());
 
     nsTArray<nsRefPtr<WorkerRunnable> > runnables;
     mQueuedRunnables.SwapElements(runnables);
 
     for (uint32_t index = 0; index < runnables.Length(); index++) {
       nsRefPtr<WorkerRunnable>& runnable = runnables[index];
       runnable->Run();
     }
   }
 
   nsRefPtr<ResumeRunnable> runnable =
     new ResumeRunnable(ParentAsWorkerPrivate());
-  if (!runnable->Dispatch(aCx)) {
-    return false;
-  }
-
-  return true;
+  runnable->Dispatch(aCx);
 }
 
 template <class Derived>
 bool
-WorkerPrivateParent<Derived>::SynchronizeAndResume(
-                                               JSContext* aCx,
-                                               nsPIDOMWindow* aWindow,
-                                               nsIScriptContext* aScriptContext)
+WorkerPrivateParent<Derived>::SynchronizeAndResume(nsIScriptContext* aCx)
 {
-  AssertIsOnMainThread();
-  MOZ_ASSERT_IF(!IsSharedWorker(), mParentSuspended);
+  AssertIsOnParentThread();
+  NS_ASSERTION(mParentSuspended, "Not yet suspended!");
 
   // NB: There may be pending unqueued messages.  If we resume here we will
   // execute those messages out of order.  Instead we post an event to the
   // end of the event queue, allowing all of the outstanding messages to be
   // queued up in order on the worker.  Then and only then we execute all of
   // the messages.
 
   nsRefPtr<SynchronizeAndResumeRunnable> runnable =
-    new SynchronizeAndResumeRunnable(ParentAsWorkerPrivate(), aWindow,
-                                     aScriptContext);
-  if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
-    JS_ReportError(aCx, "Failed to dispatch to current thread!");
-    return false;
-  }
-
-  return true;
+    new SynchronizeAndResumeRunnable(ParentAsWorkerPrivate(), aCx);
+  return NS_SUCCEEDED(NS_DispatchToCurrentThread(runnable));
 }
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::_trace(JSTracer* aTrc)
 {
   // This should only happen on the parent thread but we can't assert that
   // because it can also happen on the cycle collector thread when this is a
@@ -2457,42 +2220,34 @@ WorkerPrivateParent<Derived>::RootJSObje
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::ForgetMainThreadObjects(
                                       nsTArray<nsCOMPtr<nsISupports> >& aDoomed)
 {
   AssertIsOnParentThread();
   MOZ_ASSERT(!mMainThreadObjectsForgotten);
 
-  static const uint32_t kDoomedCount = 7;
-
-  aDoomed.SetCapacity(kDoomedCount);
-
-  SwapToISupportsArray(mLoadInfo.mWindow, aDoomed);
-  SwapToISupportsArray(mLoadInfo.mScriptContext, aDoomed);
-  SwapToISupportsArray(mLoadInfo.mBaseURI, aDoomed);
-  SwapToISupportsArray(mLoadInfo.mResolvedScriptURI, aDoomed);
-  SwapToISupportsArray(mLoadInfo.mPrincipal, aDoomed);
-  SwapToISupportsArray(mLoadInfo.mChannel, aDoomed);
-  SwapToISupportsArray(mLoadInfo.mCSP, aDoomed);
-  // Before adding anything here update kDoomedCount above!
-
-  MOZ_ASSERT(aDoomed.Length() == kDoomedCount);
+  aDoomed.SetCapacity(7);
+
+  SwapToISupportsArray(mWindow, aDoomed);
+  SwapToISupportsArray(mScriptContext, aDoomed);
+  SwapToISupportsArray(mBaseURI, aDoomed);
+  SwapToISupportsArray(mScriptURI, aDoomed);
+  SwapToISupportsArray(mPrincipal, aDoomed);
+  SwapToISupportsArray(mChannel, aDoomed);
+  SwapToISupportsArray(mCSP, aDoomed);
 
   mMainThreadObjectsForgotten = true;
 }
 
 template <class Derived>
 bool
-WorkerPrivateParent<Derived>::PostMessageInternal(
-                                            JSContext* aCx,
-                                            JS::Handle<JS::Value> aMessage,
-                                            JS::Handle<JS::Value> aTransferable,
-                                            bool aToMessagePort,
-                                            uint64_t aMessagePortSerial)
+WorkerPrivateParent<Derived>::PostMessage(JSContext* aCx,
+                                          JS::Handle<JS::Value> aMessage,
+                                          JS::Handle<JS::Value> aTransferable)
 {
   AssertIsOnParentThread();
 
   {
     MutexAutoLock lock(mMutex);
     if (mParentStatus > Running) {
       return true;
     }
@@ -2523,131 +2278,27 @@ WorkerPrivateParent<Derived>::PostMessag
   JSAutoStructuredCloneBuffer buffer;
   if (!buffer.write(aCx, aMessage, aTransferable, callbacks, &clonedObjects)) {
     return false;
   }
 
   nsRefPtr<MessageEventRunnable> runnable =
     new MessageEventRunnable(ParentAsWorkerPrivate(),
                              WorkerRunnable::WorkerThread, buffer,
-                             clonedObjects, aToMessagePort, aMessagePortSerial);
+                             clonedObjects);
   return runnable->Dispatch(aCx);
 }
 
 template <class Derived>
-void
-WorkerPrivateParent<Derived>::PostMessageToMessagePort(
-                           JSContext* aCx,
-                           uint64_t aMessagePortSerial,
-                           JS::Handle<JS::Value> aMessage,
-                           const Optional<Sequence<JS::Value > >& aTransferable,
-                           ErrorResult& aRv)
-{
-  AssertIsOnMainThread();
-
-  JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
-  if (aTransferable.WasPassed()) {
-    const Sequence<JS::Value>& realTransferable = aTransferable.Value();
-    JSObject* array =
-      JS_NewArrayObject(aCx, realTransferable.Length(),
-                        const_cast<jsval*>(realTransferable.Elements()));
-    if (!array) {
-      aRv = NS_ERROR_OUT_OF_MEMORY;
-      return;
-    }
-    transferable.setObject(*array);
-  }
-
-  if (!PostMessageInternal(aCx, aMessage, transferable, true,
-                           aMessagePortSerial)) {
-    aRv = NS_ERROR_FAILURE;
-  }
-}
-
-template <class Derived>
-bool
-WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
-                               JSContext* aCx, uint64_t aMessagePortSerial,
-                               JSAutoStructuredCloneBuffer& aBuffer,
-                               nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects)
-{
-  AssertIsOnMainThread();
-
-  JSAutoStructuredCloneBuffer buffer;
-  buffer.swap(aBuffer);
-
-  nsTArray<nsCOMPtr<nsISupports> > clonedObjects;
-  clonedObjects.SwapElements(aClonedObjects);
-
-  SharedWorker* sharedWorker;
-  if (!mSharedWorkers.Get(aMessagePortSerial, &sharedWorker)) {
-    // SharedWorker has already been unregistered?
-    return true;
-  }
-
-  nsRefPtr<MessagePort> port = sharedWorker->Port();
-  NS_ASSERTION(port, "SharedWorkers always have a port!");
-
-  if (port->IsClosed()) {
-    return true;
-  }
-
-  nsCOMPtr<nsIScriptGlobalObject> sgo;
-  port->GetParentObject(getter_AddRefs(sgo));
-  MOZ_ASSERT(sgo, "Should never happen if IsClosed() returned false!");
-  MOZ_ASSERT(sgo->GetGlobalJSObject());
-
-  nsCOMPtr<nsIScriptContext> scx = sgo->GetContext();
-  MOZ_ASSERT_IF(scx, scx->GetNativeContext());
-
-  AutoPushJSContext cx(scx ? scx->GetNativeContext() : aCx);
-  JSAutoCompartment(cx, sgo->GetGlobalJSObject());
-
-  JS::Rooted<JS::Value> data(cx);
-  if (!buffer.read(cx, data.address(), WorkerStructuredCloneCallbacks(true))) {
-    return false;
-  }
-
-  buffer.clear();
-
-  nsRefPtr<nsDOMMessageEvent> event =
-    new nsDOMMessageEvent(port, nullptr, nullptr);
-
-  nsresult rv =
-    event->InitMessageEvent(NS_LITERAL_STRING("message"), false, false, data,
-                            EmptyString(), EmptyString(), nullptr);
-  if (NS_FAILED(rv)) {
-    xpc::Throw(cx, rv);
-    return false;
-  }
-
-  event->SetTrusted(true);
-
-  nsCOMPtr<nsIDOMEvent> domEvent;
-  CallQueryInterface(event.get(), getter_AddRefs(domEvent));
-  NS_ASSERTION(domEvent, "This should never fail!");
-
-  bool ignored;
-  rv = port->DispatchEvent(domEvent, &ignored);
-  if (NS_FAILED(rv)) {
-    xpc::Throw(cx, rv);
-    return false;
-  }
-
-  return true;
-}
-
-template <class Derived>
 uint64_t
 WorkerPrivateParent<Derived>::GetInnerWindowId()
 {
   AssertIsOnMainThread();
-  NS_ASSERTION(!mLoadInfo.mWindow || mLoadInfo.mWindow->IsInnerWindow(),
-               "Outer window?");
-  return mLoadInfo.mWindow ? mLoadInfo.mWindow->WindowID() : 0;
+  NS_ASSERTION(!mWindow || mWindow->IsInnerWindow(), "Outer window?");
+  return mWindow ? mWindow->WindowID() : 0;
 }
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::UpdateJSContextOptions(JSContext* aCx,
                                                      uint32_t aContentOptions,
                                                      uint32_t aChromeOptions)
 {
@@ -2736,345 +2387,31 @@ WorkerPrivateParent<Derived>::UpdateJITH
     JS_ClearPendingException(aCx);
   }
 }
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::GarbageCollect(JSContext* aCx, bool aShrinking)
 {
-  AssertIsOnParentThread();
-
   nsRefPtr<GarbageCollectRunnable> runnable =
     new GarbageCollectRunnable(ParentAsWorkerPrivate(), aShrinking, true);
   if (!runnable->Dispatch(aCx)) {
     NS_WARNING("Failed to update worker heap size!");
     JS_ClearPendingException(aCx);
   }
 }
 
 template <class Derived>
-bool
-WorkerPrivateParent<Derived>::RegisterSharedWorker(JSContext* aCx,
-                                                   SharedWorker* aSharedWorker)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aSharedWorker);
-  MOZ_ASSERT(IsSharedWorker());
-  MOZ_ASSERT(!mSharedWorkers.Get(aSharedWorker->Serial()));
-
-  nsRefPtr<MessagePortRunnable> runnable =
-    new MessagePortRunnable(ParentAsWorkerPrivate(), aSharedWorker->Serial(),
-                            true);
-  if (!runnable->Dispatch(aCx)) {
-    return false;
-  }
-
-  mSharedWorkers.Put(aSharedWorker->Serial(), aSharedWorker);
-
-  // If there were other SharedWorker objects attached to this worker then they
-  // may all have been suspended and this worker would need to be resumed.
-  if (mSharedWorkers.Count() > 1 && !Resume(aCx, nullptr)) {
-    return false;
-  }
-
-  return true;
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::UnregisterSharedWorker(
-                                                    JSContext* aCx,
-                                                    SharedWorker* aSharedWorker)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aSharedWorker);
-  MOZ_ASSERT(IsSharedWorker());
-  MOZ_ASSERT(mSharedWorkers.Get(aSharedWorker->Serial()));
-
-  nsRefPtr<MessagePortRunnable> runnable =
-    new MessagePortRunnable(ParentAsWorkerPrivate(), aSharedWorker->Serial(),
-                            false);
-  if (!runnable->Dispatch(aCx)) {
-    JS_ReportPendingException(aCx);
-  }
-
-  mSharedWorkers.Remove(aSharedWorker->Serial());
-
-  if (mSharedWorkers.Count()) {
-    // If there are still SharedWorker objects attached to this worker then they
-    // may all be suspended and this worker would need to be suspended.
-    if (!Suspend(aCx, nullptr)) {
-      JS_ReportPendingException(aCx);
-    }
-  } else {
-    // If that was the last SharedWorker then it's time to cancel this worker.
-    if (!Cancel(aCx)) {
-      JS_ReportPendingException(aCx);
-    }
-  }
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
-                                                    JSContext* aCx,
-                                                    const nsAString& aMessage,
-                                                    const nsAString& aFilename,
-                                                    const nsAString& aLine,
-                                                    uint32_t aLineNumber,
-                                                    uint32_t aColumnNumber,
-                                                    uint32_t aFlags)
-{
-  AssertIsOnMainThread();
-
-  nsAutoTArray<nsRefPtr<SharedWorker>, 10> sharedWorkers;
-  GetAllSharedWorkers(sharedWorkers);
-
-  if (sharedWorkers.IsEmpty()) {
-    return;
-  }
-
-  nsAutoTArray<WindowAction, 10> windowActions;
-  nsresult rv;
-
-  // First fire the error event at all SharedWorker objects. This may include
-  // multiple objects in a single window as well as objects in different
-  // windows.
-  for (uint32_t index = 0; index < sharedWorkers.Length(); index++) {
-    nsRefPtr<SharedWorker>& sharedWorker = sharedWorkers[index];
-
-    // May be null.
-    nsPIDOMWindow* window = sharedWorker->GetOwner();
-
-    uint32_t actionsIndex = windowActions.LastIndexOf(WindowAction(window));
-
-    // Get the context for this window so that we can report errors correctly.
-    JSContext* cx;
-    rv = NS_OK;
-
-    if (actionsIndex == windowActions.NoIndex) {
-      nsIScriptContext* scx = sharedWorker->GetContextForEventHandlers(&rv);
-      cx = (NS_SUCCEEDED(rv) && scx) ?
-           scx->GetNativeContext() :
-           nsContentUtils::GetSafeJSContext();
-    } else {
-      cx = windowActions[actionsIndex].mJSContext;
-    }
-
-    MOZ_ASSERT(cx);
-
-    AutoPushJSContext autoPush(cx);
-
-    if (NS_FAILED(rv)) {
-      Throw(cx, rv);
-      JS_ReportPendingException(cx);
-      continue;
-    }
-
-    ErrorEventInit errorInit;
-    errorInit.mBubbles = false;
-    errorInit.mCancelable = true;
-    errorInit.mMessage = aMessage;
-    errorInit.mFilename = aFilename;
-    errorInit.mLineno = aLineNumber;
-    errorInit.mColumn = aColumnNumber;
-
-    nsRefPtr<ErrorEvent> errorEvent =
-      ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"),
-                              errorInit);
-    if (!errorEvent) {
-      Throw(cx, NS_ERROR_UNEXPECTED);
-      JS_ReportPendingException(cx);
-      continue;
-    }
-
-    errorEvent->SetTrusted(true);
-
-    bool defaultActionEnabled;
-    rv = sharedWorker->DispatchEvent(errorEvent, &defaultActionEnabled);
-    if (NS_FAILED(rv)) {
-      Throw(cx, rv);
-      JS_ReportPendingException(cx);
-      continue;
-    }
-
-    if (defaultActionEnabled) {
-      // Add the owning window to our list so that we will fire an error event
-      // at it later.
-      if (!windowActions.Contains(window)) {
-        windowActions.AppendElement(WindowAction(window, cx));
-      }
-    } else if (actionsIndex != windowActions.NoIndex) {
-      // Any listener that calls preventDefault() will prevent the window from
-      // receiving the error event.
-      windowActions[actionsIndex].mDefaultAction = false;
-    }
-  }
-
-  // If there are no windows to consider further then we're done.
-  if (windowActions.IsEmpty()) {
-    return;
-  }
-
-  bool shouldLogErrorToConsole = true;
-
-  // Now fire error events at all the windows remaining.
-  for (uint32_t index = 0; index < windowActions.Length(); index++) {
-    WindowAction& windowAction = windowActions[index];
-
-    // If there is no window or the script already called preventDefault then
-    // skip this window.
-    if (!windowAction.mWindow || !windowAction.mDefaultAction) {
-      continue;
-    }
-
-    AutoPushJSContext cx(windowAction.mJSContext);
-    MOZ_ASSERT(cx);
-
-    nsCOMPtr<nsIScriptGlobalObject> sgo =
-      do_QueryInterface(windowAction.mWindow);
-    MOZ_ASSERT(sgo);
-
-    InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
-    event.lineNr = aLineNumber;
-    event.errorMsg = aMessage.BeginReading();
-    event.fileName = aFilename.BeginReading();
-
-    nsEventStatus status = nsEventStatus_eIgnore;
-    rv = sgo->HandleScriptError(&event, &status);
-    if (NS_FAILED(rv)) {
-      Throw(cx, rv);
-      JS_ReportPendingException(cx);
-      continue;
-    }
-
-    if (status == nsEventStatus_eConsumeNoDefault) {
-      shouldLogErrorToConsole = false;
-    }
-  }
-
-  // Finally log a warning in the console if no window tried to prevent it.
-  if (shouldLogErrorToConsole) {
-    LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber,
-                      aFlags, 0);
-  }
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::GetAllSharedWorkers(
-                              nsTArray<nsRefPtr<SharedWorker> >& aSharedWorkers)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(IsSharedWorker());
-
-  struct Helper
-  {
-    static PLDHashOperator
-    Collect(const uint64_t& aKey,
-            SharedWorker* aSharedWorker,
-            void* aClosure)
-    {
-      AssertIsOnMainThread();
-      MOZ_ASSERT(aSharedWorker);
-      MOZ_ASSERT(aClosure);
-
-      auto array = static_cast<nsTArray<nsRefPtr<SharedWorker> >*>(aClosure);
-      array->AppendElement(aSharedWorker);
-
-      return PL_DHASH_NEXT;
-    }
-  };
-
-  if (!aSharedWorkers.IsEmpty()) {
-    aSharedWorkers.Clear();
-  }
-
-  mSharedWorkers.EnumerateRead(Helper::Collect, &aSharedWorkers);
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::CloseSharedWorkersForWindow(
-                                                         nsPIDOMWindow* aWindow)
-{
-  AssertIsOnMainThread();
-  MOZ_ASSERT(IsSharedWorker());
-  MOZ_ASSERT(aWindow);
-
-  struct Closure
-  {
-    nsPIDOMWindow* mWindow;
-    nsAutoTArray<nsRefPtr<SharedWorker>, 10> mSharedWorkers;
-
-    Closure(nsPIDOMWindow* aWindow)
-    : mWindow(aWindow)
-    {
-      AssertIsOnMainThread();
-      MOZ_ASSERT(aWindow);
-    }
-
-    static PLDHashOperator
-    Collect(const uint64_t& aKey,
-            SharedWorker* aSharedWorker,
-            void* aClosure)
-    {
-      AssertIsOnMainThread();
-      MOZ_ASSERT(aSharedWorker);
-      MOZ_ASSERT(aClosure);
-
-      auto closure = static_cast<Closure*>(aClosure);
-      MOZ_ASSERT(closure->mWindow);
-
-      if (aSharedWorker->GetOwner() == closure->mWindow) {
-        closure->mSharedWorkers.AppendElement(aSharedWorker);
-      } else {
-        MOZ_ASSERT(!SameCOMIdentity(aSharedWorker->GetOwner(),
-                                    closure->mWindow));
-      }
-
-      return PL_DHASH_NEXT;
-    }
-  };
-
-  Closure closure(aWindow);
-
-  mSharedWorkers.EnumerateRead(Closure::Collect, &closure);
-
-  for (uint32_t index = 0; index < closure.mSharedWorkers.Length(); index++) {
-    closure.mSharedWorkers[index]->Close();
-  }
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::WorkerScriptLoaded()
-{
-  AssertIsOnMainThread();
-
-  if (IsSharedWorker()) {
-    // No longer need to hold references to the window or document we came from.
-    mLoadInfo.mWindow = nullptr;
-    mLoadInfo.mScriptContext = nullptr;
-  }
-}
-
-template <class Derived>
 void
 WorkerPrivateParent<Derived>::SetBaseURI(nsIURI* aBaseURI)
 {
   AssertIsOnMainThread();
 
-  if (!mLoadInfo.mBaseURI) {
-    NS_ASSERTION(GetParent(), "Shouldn't happen without a parent!");
-    mLoadInfo.mResolvedScriptURI = aBaseURI;
-  }
-
-  mLoadInfo.mBaseURI = aBaseURI;
+  mBaseURI = aBaseURI;
 
   if (NS_FAILED(aBaseURI->GetSpec(mLocationInfo.mHref))) {
     mLocationInfo.mHref.Truncate();
   }
 
   if (NS_FAILED(aBaseURI->GetHost(mLocationInfo.mHostname))) {
     mLocationInfo.mHostname.Truncate();
   }
@@ -3134,313 +2471,324 @@ WorkerPrivateParent<Derived>::SetBaseURI
 }
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::SetPrincipal(nsIPrincipal* aPrincipal)
 {
   AssertIsOnMainThread();
 
-  mLoadInfo.mPrincipal = aPrincipal;
-  mLoadInfo.mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal);
+  mPrincipal = aPrincipal;
+  mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal);
 }
 
 template <class Derived>
 JSContext*
 WorkerPrivateParent<Derived>::ParentJSContext() const
 {
   AssertIsOnParentThread();
 
-  if (mParent) {
-    return mParent->GetJSContext();
+  if (!mParent) {
+    AssertIsOnMainThread();
+
+    if (!mScriptContext) {
+      NS_ASSERTION(!mParentJSContext, "Shouldn't have a parent context!");
+      return nsContentUtils::GetSafeJSContext();
+    }
+
+    NS_ASSERTION(mParentJSContext == mScriptContext->GetNativeContext(),
+                 "Native context has changed!");
   }
 
-  AssertIsOnMainThread();
-
-  return mLoadInfo.mScriptContext ?
-         mLoadInfo.mScriptContext->GetNativeContext() :
-         nsContentUtils::GetSafeJSContext();
+  return mParentJSContext;
 }
 
-WorkerPrivate::WorkerPrivate(JSContext* aCx, JS::HandleObject aObject,
+WorkerPrivate::WorkerPrivate(JSContext* aCx, JS::Handle<JSObject*> aObject,
                              WorkerPrivate* aParent,
-                             const nsAString& aScriptURL,
-                             bool aIsChromeWorker, bool aIsSharedWorker,
-                             const nsAString& aSharedWorkerName,
-                             LoadInfo& aLoadInfo)
-: WorkerPrivateParent<WorkerPrivate>(aCx, aObject, aParent, aScriptURL,
-                                     aIsChromeWorker, aIsSharedWorker,
-                                     aSharedWorkerName, aLoadInfo),
+                             JSContext* aParentJSContext,
+                             const nsAString& aScriptURL, bool aIsChromeWorker,
+                             const nsACString& aDomain,
+                             nsCOMPtr<nsPIDOMWindow>& aWindow,
+                             nsCOMPtr<nsIScriptContext>& aParentScriptContext,
+                             nsCOMPtr<nsIURI>& aBaseURI,
+                             nsCOMPtr<nsIPrincipal>& aPrincipal,
+                             nsCOMPtr<nsIChannel>& aChannel,
+                             nsCOMPtr<nsIContentSecurityPolicy>& aCSP,
+                             bool aEvalAllowed,
+                             bool aReportCSPViolations,
+                             bool aXHRParamsAllowed)
+: WorkerPrivateParent<WorkerPrivate>(aCx, aObject, aParent, aParentJSContext,
+                                     aScriptURL, aIsChromeWorker, aDomain,
+                                     aWindow, aParentScriptContext, aBaseURI,
+                                     aPrincipal, aChannel, aCSP, aEvalAllowed,
+                                     aReportCSPViolations),
   mJSContext(nullptr), mErrorHandlerRecursionCount(0), mNextTimeoutId(1),
   mStatus(Pending), mSuspended(false), mTimerRunning(false),
   mRunningExpiredTimeouts(false), mCloseHandlerStarted(false),
   mCloseHandlerFinished(false), mMemoryReporterRunning(false),
-  mBlockedForMemoryReporter(false)
+  mBlockedForMemoryReporter(false), mXHRParamsAllowed(aXHRParamsAllowed)
 {
   MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerPrivate);
-  MOZ_ASSERT_IF(aIsSharedWorker, !aObject && !aSharedWorkerName.IsVoid());
-  MOZ_ASSERT_IF(!aIsSharedWorker, aObject && aSharedWorkerName.IsEmpty());
 }
 
 WorkerPrivate::~WorkerPrivate()
 {
   MOZ_COUNT_DTOR(mozilla::dom::workers::WorkerPrivate);
 }
 
 // static
 already_AddRefed<WorkerPrivate>
-WorkerPrivate::Create(JSContext* aCx, JS::HandleObject aObject,
-                      WorkerPrivate* aParent, const nsAString& aScriptURL,
-                      bool aIsChromeWorker, bool aIsSharedWorker,
-                      const nsAString& aSharedWorkerName, LoadInfo* aLoadInfo)
+WorkerPrivate::Create(JSContext* aCx, JS::Handle<JSObject*> aObj, WorkerPrivate* aParent,
+                      JS::Handle<JSString*> aScriptURL, bool aIsChromeWorker)
 {
-  if (aParent) {
-    aParent->AssertIsOnWorkerThread();
-  } else {
-    AssertIsOnMainThread();
-  }
-
-  MOZ_ASSERT_IF(aIsSharedWorker, !aObject && !aSharedWorkerName.IsVoid());
-  MOZ_ASSERT_IF(!aIsSharedWorker, aObject && aSharedWorkerName.IsEmpty());
-
-  mozilla::Maybe<LoadInfo> stackLoadInfo;
-  if (!aLoadInfo) {
-    stackLoadInfo.construct();
-
-    nsresult rv = GetLoadInfo(aCx, nullptr, aParent, aScriptURL,
-                              aIsChromeWorker, stackLoadInfo.addr());
-    if (NS_FAILED(rv)) {
-      scriptloader::ReportLoadError(aCx, aScriptURL, rv, !aParent);
-      return nullptr;
-    }
-
-    aLoadInfo = stackLoadInfo.addr();
-  }
-
-  nsRefPtr<WorkerPrivate> worker =
-    new WorkerPrivate(aCx, aObject, aParent, aScriptURL, aIsChromeWorker,
-                      aIsSharedWorker, aSharedWorkerName, *aLoadInfo);
-
-  nsRefPtr<CompileScriptRunnable> compiler = new CompileScriptRunnable(worker);
-  if (!compiler->Dispatch(aCx)) {
-    return nullptr;
-  }
-
-  return worker.forget();
-}
-
-// static
-nsresult
-WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
-                           WorkerPrivate* aParent, const nsAString& aScriptURL,
-                           bool aIsChromeWorker, LoadInfo* aLoadInfo)
-{
-  using namespace mozilla::dom::workers::scriptloader;
-
-  MOZ_ASSERT(aCx);
-
-  if (aWindow) {
-    AssertIsOnMainThread();
-  }
-
-  LoadInfo loadInfo;
-  nsresult rv;
+  nsCString domain;
+  nsCOMPtr<nsIURI> baseURI;
+  nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIScriptContext> scriptContext;
+  nsCOMPtr<nsIDocument> document;
+  nsCOMPtr<nsPIDOMWindow> window;
+  nsCOMPtr<nsIContentSecurityPolicy> csp;
+
+  bool evalAllowed = true;
+  bool reportEvalViolations = false;
+
+  JSContext* parentContext;
+
+  bool xhrParamsAllowed = false;
 
   if (aParent) {
     aParent->AssertIsOnWorkerThread();
 
     // If the parent is going away give up now.
-    Status parentStatus;
+    Status currentStatus;
     {
       MutexAutoLock lock(aParent->mMutex);
-      parentStatus = aParent->mStatus;
+      currentStatus = aParent->mStatus;
     }
 
-    if (parentStatus > Running) {
-      NS_WARNING("Cannot create child workers from the close handler!");
-      return NS_ERROR_FAILURE;
+    if (currentStatus > Running) {
+      JS_ReportError(aCx, "Cannot create child workers from the close handler!");
+      return nullptr;
     }
 
-    rv = ChannelFromScriptURLWorkerThread(aCx, aParent, aScriptURL,
-                                          getter_AddRefs(loadInfo.mChannel));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Now that we've spun the loop there's no guarantee that our parent is
-    // still alive.  We may have received control messages initiating shutdown.
-    {
-      MutexAutoLock lock(aParent->mMutex);
-      parentStatus = aParent->mStatus;
-    }
-
-    if (parentStatus > Running) {
-      nsCOMPtr<nsIThread> mainThread;
-      if (NS_FAILED(NS_GetMainThread(getter_AddRefs(mainThread))) ||
-          NS_FAILED(NS_ProxyRelease(mainThread, loadInfo.mChannel))) {
-        NS_WARNING("Failed to proxy release of channel, leaking instead!");
-      }
-      return NS_ERROR_FAILURE;
-    }
-
-    loadInfo.mDomain = aParent->Domain();
-  } else {
+    parentContext = aCx;
+
+    // Domain is the only thing we can touch here. The rest will be handled by
+    // the ScriptLoader.
+    domain = aParent->Domain();
+  }
+  else {
     AssertIsOnMainThread();
 
     nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
-    MOZ_ASSERT(ssm);
+    NS_ASSERTION(ssm, "This should never be null!");
 
     bool isChrome = nsContentUtils::IsCallerChrome();
 
-    // First check to make sure the caller has permission to make a privileged
-    // worker if they called the ChromeWorker/ChromeSharedWorker constructor.
+    // First check to make sure the caller has permission to make a
+    // ChromeWorker if they called the ChromeWorker constructor.
     if (aIsChromeWorker && !isChrome) {
-      return NS_ERROR_DOM_SECURITY_ERR;
+      xpc::Throw(aCx, NS_ERROR_DOM_SECURITY_ERR);
+      return nullptr;
     }
 
     // Chrome callers (whether ChromeWorker of Worker) always get the system
     // principal here as they're allowed to load anything. The script loader may
     // change the principal later depending on the script uri.
-    if (isChrome) {
-      rv = ssm->GetSystemPrincipal(getter_AddRefs(loadInfo.mPrincipal));
-      NS_ENSURE_SUCCESS(rv, rv);
+    if (isChrome &&
+        NS_FAILED(ssm->GetSystemPrincipal(getter_AddRefs(principal)))) {
+      JS_ReportError(aCx, "Could not get system principal!");
+      return nullptr;
     }
 
-    // See if we're being called from a window.
-    nsCOMPtr<nsPIDOMWindow> globalWindow = aWindow;
-    if (!globalWindow) {
-      nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
-        nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
-      if (scriptGlobal) {
-        globalWindow = do_QueryInterface(scriptGlobal);
-        MOZ_ASSERT(globalWindow);
-      }
-    }
-
-    nsCOMPtr<nsIDocument> document;
-
-    if (globalWindow) {
+    // See if we're being called from a window or from somewhere else.
+    nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
+      nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
+    if (scriptGlobal) {
+      // Window!
+      nsCOMPtr<nsPIDOMWindow> globalWindow = do_QueryInterface(scriptGlobal);
+
       // Only use the current inner window, and only use it if the caller can
       // access it.
-      nsPIDOMWindow* outerWindow = globalWindow->GetOuterWindow();
-      if (outerWindow) {
-        loadInfo.mWindow = outerWindow->GetCurrentInnerWindow();
+      nsPIDOMWindow* outerWindow = globalWindow ?
+                                   globalWindow->GetOuterWindow() :
+                                   nullptr;
+      window = outerWindow ? outerWindow->GetCurrentInnerWindow() : nullptr;
+      if (!window ||
+          (globalWindow != window &&
+           !nsContentUtils::CanCallerAccess(window))) {
+        xpc::Throw(aCx, NS_ERROR_DOM_SECURITY_ERR);
+        return nullptr;
       }
 
-      if (!loadInfo.mWindow ||
-          (globalWindow != loadInfo.mWindow &&
-            !nsContentUtils::CanCallerAccess(loadInfo.mWindow))) {
-        return NS_ERROR_DOM_SECURITY_ERR;
+      scriptContext = scriptGlobal->GetContext();
+      if (!scriptContext) {
+        JS_ReportError(aCx, "Couldn't get script context for this worker!");
+        return nullptr;
       }
 
-      nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(loadInfo.mWindow);
-      MOZ_ASSERT(sgo);
-
-      loadInfo.mScriptContext = sgo->GetContext();
-      NS_ENSURE_TRUE(loadInfo.mScriptContext, NS_ERROR_FAILURE);
+      parentContext = scriptContext->GetNativeContext();
 
       // If we're called from a window then we can dig out the principal and URI
       // from the document.
-      document = loadInfo.mWindow->GetExtantDoc();
-      NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
-
-      loadInfo.mBaseURI = document->GetDocBaseURI();
+      document = window->GetExtantDoc();
+      if (!document) {
+        JS_ReportError(aCx, "No document in this window!");
+        return nullptr;
+      }
+
+      baseURI = document->GetDocBaseURI();
 
       // Use the document's NodePrincipal as our principal if we're not being
       // called from chrome.
-      if (!loadInfo.mPrincipal) {
-        loadInfo.mPrincipal = document->NodePrincipal();
-        NS_ENSURE_TRUE(loadInfo.mPrincipal, NS_ERROR_FAILURE);
+      if (!principal) {
+        if (!(principal = document->NodePrincipal())) {
+          JS_ReportError(aCx, "Could not get document principal!");
+          return nullptr;
+        }
 
         // We use the document's base domain to limit the number of workers
         // each domain can create. For sandboxed documents, we use the domain
         // of their first non-sandboxed document, walking up until we find
         // one. If we can't find one, we fall back to using the GUID of the
         // null principal as the base domain.
         if (document->GetSandboxFlags() & SANDBOXED_ORIGIN) {
           nsCOMPtr<nsIDocument> tmpDoc = document;
           do {
             tmpDoc = tmpDoc->GetParentDocument();
           } while (tmpDoc && tmpDoc->GetSandboxFlags() & SANDBOXED_ORIGIN);
 
           if (tmpDoc) {
             // There was an unsandboxed ancestor, yay!
             nsCOMPtr<nsIPrincipal> tmpPrincipal = tmpDoc->NodePrincipal();
-            rv = tmpPrincipal->GetBaseDomain(loadInfo.mDomain);
-            NS_ENSURE_SUCCESS(rv, rv);
+
+            if (NS_FAILED(tmpPrincipal->GetBaseDomain(domain))) {
+              JS_ReportError(aCx, "Could not determine base domain!");
+              return nullptr;
+            }
           } else {
             // No unsandboxed ancestor, use our GUID.
-            rv = loadInfo.mPrincipal->GetBaseDomain(loadInfo.mDomain);
-            NS_ENSURE_SUCCESS(rv, rv);
+            if (NS_FAILED(principal->GetBaseDomain(domain))) {
+              JS_ReportError(aCx, "Could not determine base domain!");
+             return nullptr;
+            }
           }
         } else {
           // Document creating the worker is not sandboxed.
-          rv = loadInfo.mPrincipal->GetBaseDomain(loadInfo.mDomain);
-          NS_ENSURE_SUCCESS(rv, rv);
+          if (NS_FAILED(principal->GetBaseDomain(domain))) {
+            JS_ReportError(aCx, "Could not determine base domain!");
+            return nullptr;
+          }
         }
       }
 
-      nsCOMPtr<nsIPermissionManager> permMgr =
-        do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      uint32_t perm;
-      rv = permMgr->TestPermissionFromPrincipal(loadInfo.mPrincipal, "systemXHR",
-                                                &perm);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      loadInfo.mXHRParamsAllowed = perm == nsIPermissionManager::ALLOW_ACTION;
-    } else {
+      xhrParamsAllowed = CheckXHRParamsAllowed(window);
+    }
+    else {
       // Not a window
-      MOZ_ASSERT(isChrome);
+      NS_ASSERTION(isChrome, "Should be chrome only!");
+
+      parentContext = nullptr;
 
       // We're being created outside of a window. Need to figure out the script
       // that is creating us in order for us to use relative URIs later on.
       JS::RootedScript script(aCx);
       if (JS_DescribeScriptedCaller(aCx, &script, nullptr)) {
-        rv = NS_NewURI(getter_AddRefs(loadInfo.mBaseURI),
-                       JS_GetScriptFilename(aCx, script));
-        NS_ENSURE_SUCCESS(rv, rv);
+        if (NS_FAILED(NS_NewURI(getter_AddRefs(baseURI),
+                                JS_GetScriptFilename(aCx, script)))) {
+          JS_ReportError(aCx, "Failed to construct base URI!");
+          return nullptr;
         }
-
-      loadInfo.mXHRParamsAllowed = true;
+      }
+
+      xhrParamsAllowed = true;
     }
 
-    MOZ_ASSERT(loadInfo.mPrincipal);
-    MOZ_ASSERT(isChrome || !loadInfo.mDomain.IsEmpty());
-
-    // XXXbent Use subject principal here instead of the one we already have?
-    nsCOMPtr<nsIPrincipal> subjectPrincipal = ssm->GetCxSubjectPrincipal(aCx);
-    MOZ_ASSERT(subjectPrincipal);
-
-    if (!nsContentUtils::GetContentSecurityPolicy(aCx,
-                                               getter_AddRefs(loadInfo.mCSP))) {
-      NS_WARNING("Failed to get CSP!");
-      return NS_ERROR_FAILURE;
+    NS_ASSERTION(principal, "Must have a principal now!");
+
+    if (!isChrome && domain.IsEmpty()) {
+      NS_ERROR("Must be chrome or have an domain!");
+      return nullptr;
+    }
+
+    if (!nsContentUtils::GetContentSecurityPolicy(aCx, getter_AddRefs(csp))) {
+      return nullptr;
+    }
+
+    if (csp && NS_FAILED(csp->GetAllowsEval(&reportEvalViolations, &evalAllowed))) {
+      NS_ERROR("CSP: failed to get allowsEval");
+      return nullptr;
     }
-
-    if (loadInfo.mCSP) {
-      rv = loadInfo.mCSP->GetAllowsEval(&loadInfo.mReportCSPViolations,
-                                        &loadInfo.mEvalAllowed);
-      NS_ENSURE_SUCCESS(rv, rv);
-    } else {
-      loadInfo.mEvalAllowed = true;
-      loadInfo.mReportCSPViolations = false;
+  }
+
+  size_t urlLength;
+  const jschar* urlChars = JS_GetStringCharsZAndLength(aCx, aScriptURL,
+                                                       &urlLength);
+  if (!urlChars) {
+    return nullptr;
+  }
+
+  nsDependentString scriptURL(urlChars, urlLength);
+  nsCOMPtr<nsIChannel> channel;
+  nsresult rv;
+  if (aParent) {
+    rv =
+      scriptloader::ChannelFromScriptURLWorkerThread(aCx, aParent, scriptURL,
+                                                     getter_AddRefs(channel));
+
+    // Now that we've spun the loop there's no guarantee that our parent is
+    // still alive.  We may have received control messages initiating shutdown.
+
+    Status currentStatus;
+    {
+      MutexAutoLock lock(aParent->mMutex);
+      currentStatus = aParent->mStatus;
     }
 
-    rv = ChannelFromScriptURLMainThread(loadInfo.mPrincipal, loadInfo.mBaseURI,
-                                        document, aScriptURL,
-                                        getter_AddRefs(loadInfo.mChannel));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = NS_GetFinalChannelURI(loadInfo.mChannel,
-                               getter_AddRefs(loadInfo.mResolvedScriptURI));
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (currentStatus > Running) {
+      nsCOMPtr<nsIThread> mainThread;
+      NS_GetMainThread(getter_AddRefs(mainThread));
+      if (!mainThread) {
+        MOZ_CRASH();
+      }
+
+      nsIChannel* rawChannel;
+      channel.forget(&rawChannel);
+      // If this fails we accept the leak.
+      NS_ProxyRelease(mainThread, rawChannel);
+
+      return nullptr;
+    }
+  }
+  else {
+    rv =
+      scriptloader::ChannelFromScriptURLMainThread(principal, baseURI,
+                                                   document, scriptURL,
+                                                   getter_AddRefs(channel));
   }
-
-  aLoadInfo->StealFrom(loadInfo);
-  return NS_OK;
+  if (NS_FAILED(rv)) {
+    scriptloader::ReportLoadError(aCx, scriptURL, rv, !aParent);
+    return nullptr;
+  }
+
+  nsRefPtr<WorkerPrivate> worker =
+    new WorkerPrivate(aCx, aObj, aParent, parentContext, scriptURL,
+                      aIsChromeWorker, domain, window, scriptContext, baseURI,
+                      principal, channel, csp, evalAllowed, reportEvalViolations,
+                      xhrParamsAllowed);
+
+  worker->SetIsDOMBinding();
+  worker->SetWrapper(aObj);
+
+  nsRefPtr<CompileScriptRunnable> compiler = new CompileScriptRunnable(worker);
+  if (!compiler->Dispatch(aCx)) {
+    return nullptr;
+  }
+
+  return worker.forget();
 }
 
 void
 WorkerPrivate::DoRunLoop(JSContext* aCx)
 {
   AssertIsOnWorkerThread();
 
   {
@@ -3620,23 +2968,17 @@ WorkerPrivate::OperationCallback(JSConte
   AssertIsOnWorkerThread();
 
   bool mayContinue = true;
 
   for (;;) {
     // Run all control events now.
     mayContinue = ProcessAllControlRunnables();
 
-    bool maySuspend = mSuspended;
-    if (maySuspend) {
-      MutexAutoLock lock(mMutex);
-      maySuspend = mStatus <= Running;
-    }
-
-    if (!mayContinue || !maySuspend) {
+    if (!mayContinue || !mSuspended) {
       break;
     }
 
     // Clean up before suspending.
     JS_GC(JS_GetRuntime(aCx));
 
     while ((mayContinue = MayContinueRunning())) {
       MutexAutoLock lock(mMutex);
@@ -3891,16 +3233,46 @@ WorkerPrivate::ProcessAllControlRunnable
 
     NS_RELEASE(event);
   }
 
   return result;
 }
 
 bool
+WorkerPrivate::CheckXHRParamsAllowed(nsPIDOMWindow* aWindow)
+{
+  AssertIsOnMainThread();
+  NS_ASSERTION(aWindow, "Wrong cannot be null");
+
+  if (!aWindow->GetDocShell()) {
+    return false;
+  }
+
+  nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
+  if (!doc) {
+    return false;
+  }
+
+  nsCOMPtr<nsIPermissionManager> permMgr = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+  if (!permMgr) {
+    return false;
+  }
+
+  uint32_t permission;
+  nsresult rv = permMgr->TestPermissionFromPrincipal(doc->NodePrincipal(),
+                                                     "systemXHR", &permission);
+  if (NS_FAILED(rv) || permission != nsIPermissionManager::ALLOW_ACTION) {
+    return false;
+  }
+
+  return true;
+}
+
+bool
 WorkerPrivate::Dispatch(WorkerRunnable* aEvent, EventQueue* aQueue)
 {
   nsRefPtr<WorkerRunnable> event(aEvent);
 
   {
     MutexAutoLock lock(mMutex);
 
     if (mStatus == Dead) {
@@ -4018,30 +3390,16 @@ WorkerPrivate::TraceInternal(JSTracer* a
     TimeoutInfo* info = mTimeouts[index];
     JS_CallHeapValueTracer(aTrc, &info->mTimeoutVal,
                            "WorkerPrivate timeout value");
     for (uint32_t index2 = 0; index2 < info->mExtraArgVals.Length(); index2++) {
       JS_CallHeapValueTracer(aTrc, &info->mExtraArgVals[index2],
                              "WorkerPrivate timeout extra argument value");
     }
   }
-
-  // MessagePort objects are basically held alive as long as the global.
-  mWorkerPorts.EnumerateRead(TraceMessagePorts, aTrc);
-}
-
-// static
-PLDHashOperator
-WorkerPrivate::TraceMessagePorts(const uint64_t& aKey,
-                                 WorkerMessagePort* aData,
-                                 void* aUserArg)
-{
-  JSTracer* trc = static_cast<JSTracer*>(aUserArg);
-  aData->TraceJSObject(trc, "mWorkerPorts");
-  return PL_DHASH_NEXT;
 }
 
 bool
 WorkerPrivate::ModifyBusyCountFromWorker(JSContext* aCx, bool aIncrease)
 {
   AssertIsOnWorkerThread();
 
   {
@@ -4278,21 +3636,19 @@ void
 WorkerPrivate::DestroySyncLoop(uint32_t aSyncLoopKey)
 {
   AssertIsOnWorkerThread();
 
   mSyncQueues.RemoveElementAt(aSyncLoopKey);
 }
 
 bool
-WorkerPrivate::PostMessageToParentInternal(JSContext* aCx,
+WorkerPrivate::PostMessageToParent(JSContext* aCx,
                                    JS::Handle<JS::Value> aMessage,
-                                           JS::Handle<JS::Value> aTransferable,
-                                           bool aToMessagePort,
-                                           uint64_t aMessagePortSerial)
+                                   JS::Handle<JS::Value> aTransferable)
 {
   AssertIsOnWorkerThread();
 
   JSStructuredCloneCallbacks* callbacks =
     IsChromeWorker() ?
     &gChromeWorkerStructuredCloneCallbacks :
     &gWorkerStructuredCloneCallbacks;
 
@@ -4300,55 +3656,20 @@ WorkerPrivate::PostMessageToParentIntern
 
   JSAutoStructuredCloneBuffer buffer;
   if (!buffer.write(aCx, aMessage, aTransferable, callbacks, &clonedObjects)) {
     return false;
   }
 
   nsRefPtr<MessageEventRunnable> runnable =
     new MessageEventRunnable(this, WorkerRunnable::ParentThread, buffer,
-                             clonedObjects, aToMessagePort, aMessagePortSerial);
+                             clonedObjects);
   return runnable->Dispatch(aCx);
 }
 
-void
-WorkerPrivate::PostMessageToParentMessagePort(
-                           JSContext* aCx,
-                           uint64_t aMessagePortSerial,
-                           JS::Handle<JS::Value> aMessage,
-                           const Optional<Sequence<JS::Value > >& aTransferable,
-                           ErrorResult& aRv)
-{
-  AssertIsOnWorkerThread();
-
-  if (!mWorkerPorts.Get(aMessagePortSerial)) {
-    // This port has been closed from the main thread. There's no point in
-    // sending this message so just bail.
-    return;
-  }
-
-  JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
-  if (aTransferable.WasPassed()) {
-    const Sequence<JS::Value>& realTransferable = aTransferable.Value();
-    JSObject* array =
-      JS_NewArrayObject(aCx, realTransferable.Length(),
-                        const_cast<jsval*>(realTransferable.Elements()));
-    if (!array) {
-      aRv = NS_ERROR_OUT_OF_MEMORY;
-      return;
-    }
-    transferable.setObject(*array);
-  }
-
-  if (!PostMessageToParentInternal(aCx, aMessage, transferable, true,
-                                   aMessagePortSerial)) {
-    aRv = NS_ERROR_FAILURE;
-  }
-}
-
 bool
 WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
 {
   AssertIsOnWorkerThread();
 
   NS_ASSERTION(aStatus > Running && aStatus < Dead, "Bad status!");
 
   // Save the old status and set the new status.
@@ -4949,16 +4270,62 @@ WorkerPrivate::GarbageCollectInternal(JS
 
   if (aCollectChildren) {
     for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
       mChildWorkers[index]->GarbageCollect(aCx, aShrinking);
     }
   }
 }
 
+#ifdef DEBUG
+template <class Derived>
+void
+WorkerPrivateParent<Derived>::AssertIsOnParentThread() const
+{
+  if (GetParent()) {
+    GetParent()->AssertIsOnWorkerThread();
+  }
+  else {
+    AssertIsOnMainThread();
+  }
+}
+
+template <class Derived>
+void
+WorkerPrivateParent<Derived>::AssertInnerWindowIsCorrect() const
+{
+  AssertIsOnParentThread();
+
+  // Only care about top level workers from windows.
+  if (mParent || !mWindow) {
+    return;
+  }
+
+  AssertIsOnMainThread();
+
+  nsPIDOMWindow* outer = mWindow->GetOuterWindow();
+  NS_ASSERTION(outer && outer->GetCurrentInnerWindow() == mWindow,
+               "Inner window no longer correct!");
+}
+
+void
+WorkerPrivate::AssertIsOnWorkerThread() const
+{
+  if (mThread) {
+    bool current;
+    if (NS_FAILED(mThread->IsOnCurrentThread(&current)) || !current) {
+      NS_ERROR("Wrong thread!");
+    }
+  }
+  else {
+    NS_ERROR("Trying to assert thread identity after thread has been "
+             "shutdown!");
+  }
+}
+#endif
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::RegisterHostObjectURI(const nsACString& aURI)
 {
   AssertIsOnMainThread();
   mHostObjectURIs.AppendElement(aURI);
 }
@@ -4973,34 +4340,23 @@ WorkerPrivateParent<Derived>::Unregister
 
 template <class Derived>
 void
 WorkerPrivateParent<Derived>::StealHostObjectURIs(nsTArray<nsCString>& aArray)
 {
   aArray.SwapElements(mHostObjectURIs);
 }
 
-template <class Derived>
-JSObject*
-WorkerPrivateParent<Derived>::WrapObject(JSContext* aCx,
-                                         JS::HandleObject aScope)
-{
-  MOZ_CRASH("This should never be called!");
-  return nullptr;
-}
-
 WorkerCrossThreadDispatcher*
 WorkerPrivate::GetCrossThreadDispatcher()
 {
-  MutexAutoLock lock(mMutex);
-
+  mozilla::MutexAutoLock lock(mMutex);
   if (!mCrossThreadDispatcher && mStatus <= Running) {
     mCrossThreadDispatcher = new WorkerCrossThreadDispatcher(this);
   }
-
   return mCrossThreadDispatcher;
 }
 
 void
 WorkerPrivate::BeginCTypesCall()
 {
   AssertIsOnWorkerThread();
 
@@ -5034,117 +4390,16 @@ WorkerPrivate::EndCTypesCall()
     mMemoryReportCondVar.Wait();
   }
 
   // No need to notify the main thread here as it shouldn't be waiting to see
   // this state.
   mBlockedForMemoryReporter = false;
 }
 
-bool
-WorkerPrivate::ConnectMessagePort(JSContext* aCx, uint64_t aMessagePortSerial)
-{
-  AssertIsOnWorkerThread();
-
-  NS_ASSERTION(!mWorkerPorts.Get(aMessagePortSerial),
-               "Already have this port registered!");
-
-  nsRefPtr<WorkerMessagePort> port =
-    new WorkerMessagePort(aCx, aMessagePortSerial);
-
-  JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
-
-  JS::Rooted<JSObject*> portObj(aCx, Wrap(aCx, global, port));
-  if (!portObj) {
-    return false;
-  }
-
-  JS::Rooted<JSObject*> event(aCx, CreateConnectEvent(aCx, portObj));
-  if (!event) {
-    return false;
-  }
-
-  mWorkerPorts.Put(aMessagePortSerial, port);
-
-  bool dummy;
-  if (!DispatchEventToTarget(aCx, global, event, &dummy)) {
-    mWorkerPorts.Remove(aMessagePortSerial);
-    return false;
-  }
-
-  return true;
-}
-
-void
-WorkerPrivate::DisconnectMessagePort(uint64_t aMessagePortSerial)
-{
-  AssertIsOnWorkerThread();
-
-  // The port may have already been removed from this list since either the main
-  // thread or the worker thread can remove it.
-  mWorkerPorts.Remove(aMessagePortSerial);
-}
-
-WorkerMessagePort*
-WorkerPrivate::GetMessagePort(uint64_t aMessagePortSerial)
-{
-  AssertIsOnWorkerThread();
-
-  WorkerMessagePort* port;
-  if (mWorkerPorts.Get(aMessagePortSerial, &port)) {
-    return port;
-  }
-
-  return nullptr;
-}
-
-#ifdef DEBUG
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::AssertIsOnParentThread() const
-{
-  if (GetParent()) {
-    GetParent()->AssertIsOnWorkerThread();
-  }
-  else {
-    AssertIsOnMainThread();
-  }
-}
-
-template <class Derived>
-void
-WorkerPrivateParent<Derived>::AssertInnerWindowIsCorrect() const
-{
-  AssertIsOnParentThread();
-
-  // Only care about top level workers from windows.
-  if (mParent || !mLoadInfo.mWindow) {
-    return;
-  }
-
-  AssertIsOnMainThread();
-
-  nsPIDOMWindow* outer = mLoadInfo.mWindow->GetOuterWindow();
-  NS_ASSERTION(outer && outer->GetCurrentInnerWindow() == mLoadInfo.mWindow,
-               "Inner window no longer correct!");
-}
-
-void
-WorkerPrivate::AssertIsOnWorkerThread() const
-{
-  MOZ_ASSERT(mThread,
-             "Trying to assert thread identity after thread has been "
-             "shutdown!");
-
-  bool current;
-  MOZ_ASSERT(NS_SUCCEEDED(mThread->IsOnCurrentThread(&current)));
-  MOZ_ASSERT(current, "Wrong thread!");
-}
-#endif // DEBUG
-
 BEGIN_WORKERS_NAMESPACE
 
 // Force instantiation.
 template class WorkerPrivateParent<WorkerPrivate>;
 
 JSStructuredCloneCallbacks*
 WorkerStructuredCloneCallbacks(bool aMainRuntime)
 {
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -14,49 +14,43 @@
 #include "nsIThread.h"
 #include "nsIThreadInternal.h"
 #include "nsPIDOMWindow.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsDataHashtable.h"
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
 #include "nsEventQueue.h"
-#include "nsHashKeys.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsTPriorityQueue.h"
 #include "StructuredCloneTags.h"
 
 #include "EventTarget.h"
 #include "Queue.h"
 #include "WorkerFeature.h"
 
 class JSAutoStructuredCloneBuffer;
 class nsIChannel;
-class nsIContentSecurityPolicy;
 class nsIDocument;
 class nsIPrincipal;
 class nsIScriptContext;
 class nsIURI;
 class nsPIDOMWindow;
 class nsITimer;
 
 namespace JS {
 class RuntimeStats;
 }
 
 BEGIN_WORKERS_NAMESPACE
 
-class MessagePort;
-class SharedWorker;
-class WorkerMessagePort;
 class WorkerPrivate;
 
 class WorkerRunnable : public nsIRunnable
 {
 public:
   enum Target { ParentThread, WorkerThread };
   enum BusyBehavior { ModifyBusyCount, UnchangedBusyCount };
   enum ClearingBehavior { SkipWhenClearing, RunWhenClearing };
@@ -247,99 +241,69 @@ public:
     nsCString mHost;
     nsCString mHostname;
     nsCString mPort;
     nsCString mPathname;
     nsCString mSearch;
     nsCString mHash;
   };
 
-  struct LoadInfo
-  {
-    // All of these should be released in ForgetMainThreadObjects.
-    nsCOMPtr<nsIURI> mBaseURI;
-    nsCOMPtr<nsIURI> mResolvedScriptURI;
-    nsCOMPtr<nsIPrincipal> mPrincipal;
-    nsCOMPtr<nsIScriptContext> mScriptContext;
-    nsCOMPtr<nsPIDOMWindow> mWindow;
-    nsCOMPtr<nsIContentSecurityPolicy> mCSP;
-    nsCOMPtr<nsIChannel> mChannel;
-
-    nsCString mDomain;
-
-    bool mEvalAllowed;
-    bool mReportCSPViolations;
-    bool mXHRParamsAllowed;
-    bool mPrincipalIsSystem;
-
-    LoadInfo()
-    : mEvalAllowed(false), mReportCSPViolations(false),
-      mXHRParamsAllowed(false), mPrincipalIsSystem(false)
-    { }
-
-    void
-    StealFrom(LoadInfo& aOther)
-    {
-      mBaseURI = aOther.mBaseURI.forget();
-      mResolvedScriptURI = aOther.mResolvedScriptURI.forget();
-      mPrincipal = aOther.mPrincipal.forget();
-      mScriptContext = aOther.mScriptContext.forget();
-      mWindow = aOther.mWindow.forget();
-      mCSP = aOther.mCSP.forget();
-      mChannel = aOther.mChannel.forget();
-      mDomain = aOther.mDomain;
-      mEvalAllowed = aOther.mEvalAllowed;
-      mReportCSPViolations = aOther.mReportCSPViolations;
-      mXHRParamsAllowed = aOther.mXHRParamsAllowed;
-      mPrincipalIsSystem = aOther.mPrincipalIsSystem;
-    }
-  };
-
 protected:
-  typedef mozilla::ErrorResult ErrorResult;
-
   SharedMutex mMutex;
   mozilla::CondVar mCondVar;
   mozilla::CondVar mMemoryReportCondVar;
 
 private:
   JSObject* mJSObject;
   WorkerPrivate* mParent;
+  JSContext* mParentJSContext;
   nsString mScriptURL;
-  nsString mSharedWorkerName;
+  nsCString mDomain;
   LocationInfo mLocationInfo;
-  LoadInfo mLoadInfo;
+
+  // Main-thread things.
+  nsCOMPtr<nsPIDOMWindow> mWindow;
+  nsCOMPtr<nsIScriptContext> mScriptContext;
+  nsCOMPtr<nsIURI> mBaseURI;
+  nsCOMPtr<nsIURI> mScriptURI;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
+  nsCOMPtr<nsIChannel> mChannel;
+  nsCOMPtr<nsIContentSecurityPolicy> mCSP;
 
   // Only used for top level workers.
   nsTArray<nsRefPtr<WorkerRunnable> > mQueuedRunnables;
 
   // Only for ChromeWorkers without window and only touched on the main thread.
   nsTArray<nsCString> mHostObjectURIs;
 
   // Protected by mMutex.
   JSSettings mJSSettings;
 
-  // Only touched on the parent thread (currently this is always the main
-  // thread as SharedWorkers are always top-level).
-  nsDataHashtable<nsUint64HashKey, SharedWorker*> mSharedWorkers;
-
   uint64_t mBusyCount;
-  uint64_t mMessagePortSerial;
   Status mParentStatus;
   bool mJSObjectRooted;
   bool mParentSuspended;
   bool mIsChromeWorker;
+  bool mPrincipalIsSystem;
   bool mMainThreadObjectsForgotten;
-  bool mIsSharedWorker;
+  bool mEvalAllowed;
+  bool mReportCSPViolations;
 
 protected:
-  WorkerPrivateParent(JSContext* aCx, JS::HandleObject aObject,
-                      WorkerPrivate* aParent, const nsAString& aScriptURL,
-                      bool aIsChromeWorker, bool aIsSharedWorker,
-                      const nsAString& aSharedWorkerName, LoadInfo& aLoadInfo);
+  WorkerPrivateParent(JSContext* aCx, JS::Handle<JSObject*> aObject, WorkerPrivate* aParent,
+                      JSContext* aParentJSContext, const nsAString& aScriptURL,
+                      bool aIsChromeWorker, const nsACString& aDomain,
+                      nsCOMPtr<nsPIDOMWindow>& aWindow,
+                      nsCOMPtr<nsIScriptContext>& aScriptContext,
+                      nsCOMPtr<nsIURI>& aBaseURI,
+                      nsCOMPtr<nsIPrincipal>& aPrincipal,
+                      nsCOMPtr<nsIChannel>& aChannel,
+                      nsCOMPtr<nsIContentSecurityPolicy>& aCSP,
+                      bool aEvalAllowed,
+                      bool aReportCSPViolations);
 
   ~WorkerPrivateParent();
 
 private:
   Derived*
   ParentAsWorkerPrivate() const
   {
     return static_cast<Derived*>(const_cast<WorkerPrivateParent*>(this));
@@ -351,21 +315,16 @@ private:
 
   // aCx is null when called from the finalizer
   bool
   TerminatePrivate(JSContext* aCx)
   {
     return NotifyPrivate(aCx, Terminating);
   }
 
-  bool
-  PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
-                      JS::Handle<JS::Value> aTransferable,
-                      bool aToMessagePort, uint64_t aMessagePortSerial);
-
 public:
   // May be called on any thread...
   bool
   Start();
 
   // Called on the parent thread.
   bool
   Notify(JSContext* aCx, Status aStatus)
@@ -381,24 +340,23 @@ public:
 
   bool
   Kill(JSContext* aCx)
   {
     return Notify(aCx, Killing);
   }
 
   bool
-  Suspend(JSContext* aCx, nsPIDOMWindow* aWindow);
+  Suspend(JSContext* aCx);
+
+  void
+  Resume(JSContext* aCx);
 
   bool
-  Resume(JSContext* aCx, nsPIDOMWindow* aWindow);
-
-  bool
-  SynchronizeAndResume(JSContext* aCx, nsPIDOMWindow* aWindow,
-                       nsIScriptContext* aScriptContext);
+  SynchronizeAndResume(nsIScriptContext* aCx);
 
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   void
@@ -424,34 +382,17 @@ public:
   bool
   RootJSObject(JSContext* aCx, bool aRoot);
 
   void
   ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
 
   bool
   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
-              JS::Handle<JS::Value> aTransferable)
-  {
-    return PostMessageInternal(aCx, aMessage, aTransferable, false, 0);
-  }
-
-  void
-  PostMessageToMessagePort(JSContext* aCx,
-                           uint64_t aMessagePortSerial,
-                           JS::Handle<JS::Value> aMessage,
-                           const Optional<Sequence<JS::Value > >& aTransferable,
-                           ErrorResult& aRv);
-
-  bool
-  DispatchMessageEventToMessagePort(
-                              JSContext* aCx,
-                              uint64_t aMessagePortSerial,
-                              JSAutoStructuredCloneBuffer& aBuffer,
-                              nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects);
+              JS::Handle<JS::Value> aTransferable);
 
   uint64_t
   GetInnerWindowId();
 
   void
   UpdateJSContextOptions(JSContext* aCx, uint32_t aChromeOptions,
                          uint32_t aContentOptions);
 
@@ -465,34 +406,16 @@ public:
 #endif
 
   void
   UpdateJITHardening(JSContext* aCx, bool aJITHardening);
 
   void
   GarbageCollect(JSContext* aCx, bool aShrinking);
 
-  bool
-  RegisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
-
-  void
-  UnregisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
-
-  void
-  BroadcastErrorToSharedWorkers(JSContext* aCx,
-                                const nsAString& aMessage,
-                                const nsAString& aFilename,
-                                const nsAString& aLine,
-                                uint32_t aLineNumber,
-                                uint32_t aColumnNumber,
-                                uint32_t aFlags);
-
-  void
-  WorkerScriptLoaded();
-
   void
   QueueRunnable(WorkerRunnable* aRunnable)
   {
     AssertIsOnMainThread();
     mQueuedRunnables.AppendElement(aRunnable);
   }
 
   WorkerPrivate*
@@ -529,17 +452,17 @@ public:
 
   JSContext*
   ParentJSContext() const;
 
   nsIScriptContext*
   GetScriptContext() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mScriptContext;
+    return mScriptContext;
   }
 
   JSObject*
   GetJSObject() const
   {
     return mJSObject;
   }
 
@@ -547,115 +470,110 @@ public:
   ScriptURL() const
   {
     return mScriptURL;
   }
 
   const nsCString&
   Domain() const
   {
-    return mLoadInfo.mDomain;
+    return mDomain;
   }
 
   nsIURI*
   GetBaseURI() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mBaseURI;
+    return mBaseURI;
   }
 
   void
   SetBaseURI(nsIURI* aBaseURI);
 
   nsIURI*
-  GetResolvedScriptURI() const
+  GetScriptURI() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mResolvedScriptURI;
+    return mScriptURI;
+  }
+
+  void
+  SetScriptURI(nsIURI* aScriptURI)
+  {
+    AssertIsOnMainThread();
+    mScriptURI = aScriptURI;
   }
 
   nsIPrincipal*
   GetPrincipal() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mPrincipal;
+    return mPrincipal;
   }
 
   void
   SetPrincipal(nsIPrincipal* aPrincipal);
 
   bool
   UsesSystemPrincipal() const
   {
-    return mLoadInfo.mPrincipalIsSystem;
+    return mPrincipalIsSystem;
   }
 
-  already_AddRefed<nsIChannel>
-  ForgetWorkerChannel()
+  nsIChannel*
+  GetChannel() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mChannel.forget();
+    return mChannel;
   }
 
   nsIDocument*
   GetDocument() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mWindow ? mLoadInfo.mWindow->GetExtantDoc() : nullptr;
+    return mWindow ? mWindow->GetExtantDoc() : nullptr;
   }
 
   nsPIDOMWindow*
   GetWindow()
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mWindow;
+    return mWindow;
   }
 
   nsIContentSecurityPolicy*
   GetCSP() const
   {
     AssertIsOnMainThread();
-    return mLoadInfo.mCSP;
+    return mCSP;
   }
 
   void
   SetCSP(nsIContentSecurityPolicy* aCSP)
   {
     AssertIsOnMainThread();
-    mLoadInfo.mCSP = aCSP;
+    mCSP = aCSP;
   }
 
   bool
   IsEvalAllowed() const
   {
-    return mLoadInfo.mEvalAllowed;
+    return mEvalAllowed;
   }
 
   void
   SetEvalAllowed(bool aEvalAllowed)
   {
-    mLoadInfo.mEvalAllowed = aEvalAllowed;
+    mEvalAllowed = aEvalAllowed;
   }
 
   bool
   GetReportCSPViolations() const
   {
-    return mLoadInfo.mReportCSPViolations;
-  }
-
-  bool
-  XHRParamsAllowed() const
-  {
-    return mLoadInfo.mXHRParamsAllowed;
-  }
-
-  void
-  SetXHRParamsAllowed(bool aAllowed)
-  {
-    mLoadInfo.mXHRParamsAllowed = aAllowed;
+    return mReportCSPViolations;
   }
 
   LocationInfo&
   GetLocationInfo()
   {
     return mLocationInfo;
   }
 
@@ -667,68 +585,35 @@ public:
   }
 
   bool
   IsChromeWorker() const
   {
     return mIsChromeWorker;
   }
 
-  bool
-  IsSharedWorker() const
-  {
-    return mIsSharedWorker;
-  }
-
-  const nsString&
-  SharedWorkerName() const
-  {
-    return mSharedWorkerName;
-  }
-
-  uint64_t
-  NextMessagePortSerial()
-  {
-    AssertIsOnMainThread();
-    return mMessagePortSerial++;
-  }
-
-  void
-  GetAllSharedWorkers(nsTArray<nsRefPtr<SharedWorker> >& aSharedWorkers);
-
-  void
-  CloseSharedWorkersForWindow(nsPIDOMWindow* aWindow);
-
-  void
-  RegisterHostObjectURI(const nsACString& aURI);
-
-  void
-  UnregisterHostObjectURI(const nsACString& aURI);
-
-  void
-  StealHostObjectURIs(nsTArray<nsCString>& aArray);
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::HandleObject aScope) MOZ_OVERRIDE;
-
 #ifdef DEBUG
   void
   AssertIsOnParentThread() const;
 
   void
   AssertInnerWindowIsCorrect() const;
 #else
   void
   AssertIsOnParentThread() const
   { }
 
   void
   AssertInnerWindowIsCorrect() const
   { }
 #endif
+
+  void RegisterHostObjectURI(const nsACString& aURI);
+  void UnregisterHostObjectURI(const nsACString& aURI);
+  void StealHostObjectURIs(nsTArray<nsCString>& aArray);
 };
 
 class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
 {
   friend class WorkerPrivateParent<WorkerPrivate>;
   typedef WorkerPrivateParent<WorkerPrivate> ParentType;
 
   struct TimeoutInfo;
@@ -768,47 +653,39 @@ class WorkerPrivate : public WorkerPriva
   // Things touched on worker thread only.
   nsTArray<ParentType*> mChildWorkers;
   nsTArray<WorkerFeature*> mFeatures;
   nsTArray<nsAutoPtr<TimeoutInfo> > mTimeouts;
 
   nsCOMPtr<nsITimer> mTimer;
   nsRefPtr<MemoryReporter> mMemoryReporter;
 
-  nsDataHashtable<nsUint64HashKey, WorkerMessagePort*> mWorkerPorts;
-
   mozilla::TimeStamp mKillTime;
   uint32_t mErrorHandlerRecursionCount;
   uint32_t mNextTimeoutId;
   Status mStatus;
   bool mSuspended;
   bool mTimerRunning;
   bool mRunningExpiredTimeouts;
   bool mCloseHandlerStarted;
   bool mCloseHandlerFinished;
   bool mMemoryReporterRunning;
   bool mBlockedForMemoryReporter;
+  bool mXHRParamsAllowed;
 
 #ifdef DEBUG
   nsCOMPtr<nsIThread> mThread;
 #endif
 
 public:
   ~WorkerPrivate();
 
   static already_AddRefed<WorkerPrivate>
-  Create(JSContext* aCx, JS::HandleObject aObject, WorkerPrivate* aParent,
-         const nsAString& aScriptURL, bool aIsChromeWorker,
-         bool aIsSharedWorker, const nsAString& aSharedWorkerName,
-         LoadInfo* aLoadInfo = nullptr);
-
-  static nsresult
-  GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
-              const nsAString& aScriptURL, bool aIsChromeWorker,
-              LoadInfo* aLoadInfo);
+  Create(JSContext* aCx, JS::Handle<JSObject*> aObj, WorkerPrivate* aParent,
+         JS::Handle<JSString*> aScriptURL, bool aIsChromeWorker);
 
   void
   DoRunLoop(JSContext* aCx);
 
   bool
   OperationCallback(JSContext* aCx);
 
   bool
@@ -882,30 +759,18 @@ public:
 
   void
   StopSyncLoop(uint32_t aSyncLoopKey, bool aSyncResult);
 
   void
   DestroySyncLoop(uint32_t aSyncLoopKey);
 
   bool
-  PostMessageToParent(JSContext* aCx,
-                      JS::Handle<JS::Value> aMessage,
-                      JS::Handle<JS::Value> aTransferable)
-  {
-    return PostMessageToParentInternal(aCx, aMessage, aTransferable, false, 0);
-  }
-
-  void
-  PostMessageToParentMessagePort(
-                           JSContext* aCx,
-                           uint64_t aMessagePortSerial,
-                           JS::Handle<JS::Value> aMessage,
-                           const Optional<Sequence<JS::Value > >& aTransferable,
-                           ErrorResult& aRv);
+  PostMessageToParent(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+                      JS::Handle<JS::Value> transferable);
 
   bool
   NotifyInternal(JSContext* aCx, Status aStatus);
 
   void
   ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
 
   bool
@@ -942,16 +807,28 @@ public:
   UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
 
   void
   ScheduleDeletion(bool aWasPending);
 
   bool
   BlockAndCollectRuntimeStats(JS::RuntimeStats* aRtStats);
 
+  bool
+  XHRParamsAllowed() const
+  {
+    return mXHRParamsAllowed;
+  }
+
+  void
+  SetXHRParamsAllowed(bool aAllowed)
+  {
+    mXHRParamsAllowed = aAllowed;
+  }
+
 #ifdef JS_GC_ZEAL
   void
   UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
 #endif
 
   void
   UpdateJITHardeningInternal(JSContext* aCx, bool aJITHardening);
 
@@ -1003,30 +880,26 @@ public:
   void
   EndCTypesCallback()
   {
     // If a callback is ending then we need to do the exact same thing as
     // when a ctypes call begins.
     BeginCTypesCall();
   }
 
-  bool
-  ConnectMessagePort(JSContext* aCx, uint64_t aMessagePortSerial);
-
-  void
-  DisconnectMessagePort(uint64_t aMessagePortSerial);
-
-  WorkerMessagePort*
-  GetMessagePort(uint64_t aMessagePortSerial);
-
 private:
-  WorkerPrivate(JSContext* aCx, JS::HandleObject aObject,
-                WorkerPrivate* aParent, const nsAString& aScriptURL,
-                bool aIsChromeWorker, bool aIsSharedWorker,
-                const nsAString& aSharedWorkerName, LoadInfo& aLoadInfo);
+  WorkerPrivate(JSContext* aCx, JS::Handle<JSObject*> aObject, WorkerPrivate* aParent,
+                JSContext* aParentJSContext, const nsAString& aScriptURL,
+                bool aIsChromeWorker, const nsACString& aDomain,
+                nsCOMPtr<nsPIDOMWindow>& aWindow,
+                nsCOMPtr<nsIScriptContext>& aScriptContext,
+                nsCOMPtr<nsIURI>& aBaseURI, nsCOMPtr<nsIPrincipal>& aPrincipal,
+                nsCOMPtr<nsIChannel>& aChannel,
+                nsCOMPtr<nsIContentSecurityPolicy>& aCSP, bool aEvalAllowed,
+                bool aReportCSPViolations, bool aXHRParamsAllowed);
 
   bool
   Dispatch(WorkerRunnable* aEvent, EventQueue* aQueue);
 
   bool
   DispatchToSyncQueue(WorkerSyncRunnable* aEvent);
 
   void
@@ -1082,27 +955,18 @@ private:
   EnableMemoryReporter();
 
   void
   DisableMemoryReporter();
 
   void
   WaitForWorkerEvents(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
 
-  static PLDHashOperator
-  TraceMessagePorts(const uint64_t& aKey,
-                    WorkerMessagePort* aData,
-                    void* aUserArg);
-
-  bool
-  PostMessageToParentInternal(JSContext* aCx,
-                              JS::Handle<JS::Value> aMessage,
-                              JS::Handle<JS::Value> aTransferable,
-                              bool aToMessagePort,
-                              uint64_t aMessagePortSerial);
+  static bool
+  CheckXHRParamsAllowed(nsPIDOMWindow* aWindow);
 };
 
 WorkerPrivate*
 GetWorkerPrivateFromContext(JSContext* aCx);
 
 bool
 IsCurrentThreadRunningChromeWorker();
 
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -136,18 +136,17 @@ protected:
     mWorker->AssertIsOnWorkerThread();
     return GetJSObject();
   }
 
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE
   {
     for (int32_t i = 0; i < SLOT_COUNT; i++) {
-      JS_CallHeapValueTracer(aTrc, &mSlots[i],
-                             "WorkerGlobalScope instance slot");
+      JS_CallHeapValueTracer(aTrc, &mSlots[i], "WorkerGlobalScope instance slot");
     }
     mWorker->TraceInternal(aTrc);
     EventTarget::_trace(aTrc);
   }
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE
   {
@@ -292,20 +291,18 @@ private:
   UnwrapErrorEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ASSERT(aArgc == 1);
     JS_ASSERT((JS_ARGV(aCx, aVp)[0]).isObject());
 
     JSObject* wrapper = &JS_CALLEE(aCx, aVp).toObject();
     JS_ASSERT(JS_ObjectIsFunction(aCx, wrapper));
 
-    JS::Rooted<JS::Value> scope(aCx,
-      js::GetFunctionNativeReserved(wrapper, SLOT_wrappedScope));
-    JS::Rooted<JS::Value> listener(aCx,
-      js::GetFunctionNativeReserved(wrapper, SLOT_wrappedFunction));
+    JS::Rooted<JS::Value> scope(aCx, js::GetFunctionNativeReserved(wrapper, SLOT_wrappedScope));
+    JS::Rooted<JS::Value> listener(aCx, js::GetFunctionNativeReserved(wrapper, SLOT_wrappedFunction));
 
     JS_ASSERT(scope.isObject());
 
     JS::Rooted<JSObject*> event(aCx, &JS_ARGV(aCx, aVp)[0].toObject());
 
     jsval argv[3] = { JSVAL_VOID, JSVAL_VOID, JSVAL_VOID };
     JS::AutoArrayRooter rootedArgv(aCx, ArrayLength(argv), argv);
     if (!JS_GetProperty(aCx, event, "message", rootedArgv.handleAt(0)) ||
@@ -317,35 +314,34 @@ private:
     JS::Rooted<JS::Value> rval(aCx, JS::UndefinedValue());
     if (!JS_CallFunctionValue(aCx, JSVAL_TO_OBJECT(scope), listener,
                               ArrayLength(argv), argv, rval.address())) {
       JS_ReportPendingException(aCx);
       return false;
     }
 
     if (JSVAL_IS_BOOLEAN(rval) && JSVAL_TO_BOOLEAN(rval) &&
-        !JS_CallFunctionName(aCx, event, "preventDefault", 0, NULL,
-                             rval.address())) {
+        !JS_CallFunctionName(aCx, event, "preventDefault", 0, NULL, rval.address())) {
       return false;
     }
 
     return true;
   }
 
   static bool
   GetOnErrorListenerImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
     const char* name = sEventStrings[STRING_onerror];
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
     MOZ_ASSERT(scope);
 
     ErrorResult rv;
-
     nsRefPtr<EventHandlerNonNull> adaptor =
       scope->GetEventListener(NS_ConvertASCIItoUTF16(name + 2), rv);
+
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to get event listener!");
       return false;
     }
 
     if (!adaptor) {
       aArgs.rval().setNull();
       return true;
@@ -444,17 +440,17 @@ private:
   {
     JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
     return JS::CallNonGenericMethod<IsWorkerGlobalScope, GetNavigatorImpl>(aCx, args);
   }
 
   static bool
   Close(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!scope) {
       return false;
     }
@@ -465,17 +461,17 @@ private:
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
   static bool
   ImportScripts(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[1].name);
     if (!scope) {
       return false;
     }
@@ -486,39 +482,38 @@ private:
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
   static bool
   SetTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[2].name);
     if (!scope) {
       return false;
     }
 
     JS::Rooted<JS::Value> dummy(aCx);
-    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v",
-                             dummy.address())) {
+    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", dummy.address())) {
       return false;
     }
 
     return scope->mWorker->SetTimeout(aCx, aArgc, aVp, false);
   }
 
   static bool
   ClearTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[3].name);
     if (!scope) {
       return false;
     }
@@ -534,39 +529,38 @@ private:
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
   static bool
   SetInterval(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[4].name);
     if (!scope) {
       return false;
     }
 
     JS::Rooted<JS::Value> dummy(aCx);
-    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v",
-                             dummy.address())) {
+    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", dummy.address())) {
       return false;
     }
 
     return scope->mWorker->SetTimeout(aCx, aArgc, aVp, true);
   }
 
   static bool
   ClearInterval(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[5].name);
     if (!scope) {
       return false;
     }
@@ -582,17 +576,17 @@ private:
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
   static bool
   Dump(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[6].name)) {
       return false;
     }
 
@@ -616,55 +610,53 @@ private:
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
   static bool
   AtoB(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[7].name)) {
       return false;
     }
 
     JS::Rooted<JS::Value> string(aCx);
-    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v",
-                             string.address())) {
+    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", string.address())) {
       return false;
     }
 
     JS::Rooted<JS::Value> result(aCx);
     if (!xpc::Base64Decode(aCx, string, result.address())) {
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, result);
     return true;
   }
 
   static bool
   BtoA(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[8].name)) {
       return false;
     }
 
     JS::Rooted<JS::Value> binary(aCx);
-    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v",
-                             binary.address())) {
+    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", binary.address())) {
       return false;
     }
 
     JS::Rooted<JS::Value> result(aCx);
     if (!xpc::Base64Encode(aCx, binary, result.address())) {
       return false;
     }
 
@@ -679,18 +671,18 @@ NS_IMPL_RELEASE_INHERITED(WorkerGlobalSc
 NS_INTERFACE_MAP_BEGIN(WorkerGlobalScope)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMBindingBase)
 NS_INTERFACE_MAP_END
 
 const JSClass WorkerGlobalScope::sClass = {
   "WorkerGlobalScope",
   0,
-  JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub,
-  JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
+  JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
+  JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 const JSPropertySpec WorkerGlobalScope::sProperties[] = {
   JS_PSGS("location", GetLocation, GetterOnlyJSNative, JSPROP_ENUMERATE),
   JS_PSGS(sEventStrings[STRING_onerror], GetOnErrorListener, SetOnErrorListener,
           JSPROP_ENUMERATE),
   JS_PSGS(sEventStrings[STRING_onclose], GetOnClose, SetOnClose,
           JSPROP_ENUMERATE),
@@ -750,23 +742,22 @@ public:
   DOMClassStruct()
   {
     return &sClass.mClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
-    JS::Rooted<JSObject*> proto(aCx,
+    JSObject* proto =
       JS_InitClass(aCx, aObj, aParentProto, ProtoClass(), Construct, 0,
-                   sProperties, sFunctions, NULL, NULL));
+                   sProperties, sFunctions, NULL, NULL);
     if (proto) {
-      void* domClass = const_cast<DOMClass *>(DOMClassStruct());
       js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
-                          JS::PrivateValue(domClass));
+                          JS::PrivateValue(const_cast<DOMClass *>(DOMClassStruct())));
     }
     return proto;
   }
 
   static bool
   InitPrivate(JSContext* aCx, JSObject* aObj, WorkerPrivate* aWorkerPrivate)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
@@ -811,19 +802,19 @@ private:
   GetOnMessageImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
     const char* name = sEventStrings[STRING_onmessage];
     DedicatedWorkerGlobalScope* scope =
       GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
     MOZ_ASSERT(scope);
 
     ErrorResult rv;
-
     nsRefPtr<EventHandlerNonNull> handler =
       scope->GetEventListener(NS_ConvertASCIItoUTF16(name + 2), rv);
+
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to get event listener!");
       return false;
     }
 
     if (!handler) {
       aArgs.rval().setNull();
     } else {
@@ -856,17 +847,18 @@ private:
 
     JS::Rooted<JSObject*> listenerObj(aCx, aArgs[0].toObjectOrNull());
     nsRefPtr<EventHandlerNonNull> handler;
     if (listenerObj && JS_ObjectIsCallable(aCx, listenerObj)) {
       handler = new EventHandlerNonNull(listenerObj);
     } else {
       handler = nullptr;
     }
-    scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2), handler, rv);
+    scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2),
+                            handler, rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set event listener!");
       return false;
     }
 
     aArgs.rval().setUndefined();
     return true;
@@ -897,18 +889,18 @@ private:
   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          Class()->name);
     return false;
   }
 
   static bool
-  Resolve(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
-          unsigned aFlags, JS::MutableHandle<JSObject*> aObjp)
+  Resolve(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId, unsigned aFlags,
+          JS::MutableHandle<JSObject*> aObjp)
   {
     bool resolved;
     if (!JS_ResolveStandardClass(aCx, aObj, aId, &resolved)) {
       return false;
     }
 
     aObjp.set(resolved ? aObj.get() : NULL);
     return true;
@@ -936,17 +928,17 @@ private:
       TraceProtoAndIfaceCache(aTrc, aObj);
       scope->_trace(aTrc);
     }
   }
 
   static bool
   PostMessage(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
+    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     const char* name = sFunctions[0].name;
     DedicatedWorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, name);
     if (!scope) {
       return false;
@@ -970,20 +962,19 @@ private:
 
 const DOMJSClass DedicatedWorkerGlobalScope::sClass = {
   {
     // We don't have to worry about Xray expando slots here because we'll never
     // have an Xray wrapper to a worker global scope.
     "DedicatedWorkerGlobalScope",
     JSCLASS_DOM_GLOBAL | JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_NEW_RESOLVE,
-    JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub,
-    JS_StrictPropertyStub, JS_EnumerateStub,
-    reinterpret_cast<JSResolveOp>(Resolve), JS_ConvertStub, Finalize, nullptr,
-    nullptr, nullptr, nullptr, Trace
+    JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
+    JS_EnumerateStub, reinterpret_cast<JSResolveOp>(Resolve), JS_ConvertStub,
+    Finalize, NULL, NULL, NULL, NULL, Trace
   },
   {
     INTERFACE_CHAIN_1(prototypes::id::EventTarget_workers),
     false,
     &sWorkerNativePropertyHooks
   }
 };
 
@@ -1027,472 +1018,142 @@ const JSFunctionSpec DedicatedWorkerGlob
   JS_FN("postMessage", PostMessage, 1, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 const char* const DedicatedWorkerGlobalScope::sEventStrings[STRING_COUNT] = {
   "onmessage",
 };
 
-class SharedWorkerGlobalScope : public WorkerGlobalScope
-{
-  static DOMJSClass sClass;
-  static DOMIfaceAndProtoJSClass sProtoClass;
-  static const JSPropertySpec sProperties[];
-
-  enum
-  {
-    STRING_onconnect = 0,
-
-    STRING_COUNT
-  };
-
-  static const char* const sEventStrings[STRING_COUNT];
-
-public:
-  static const JSClass*
-  Class()
-  {
-    return sClass.ToJSClass();
-  }
-
-  static const JSClass*
-  ProtoClass()
-  {
-    return sProtoClass.ToJSClass();
-  }
-
-  static const DOMClass*
-  DOMClassStruct()
-  {
-    return &sClass.mClass;
-  }
-
-  static JSObject*
-  InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
-  {
-    JS::Rooted<JSObject*> proto(aCx,
-      JS_InitClass(aCx, aObj, aParentProto, ProtoClass(), Construct, 0,
-                   sProperties, nullptr, nullptr, nullptr));
-    if (proto) {
-      void* domClass = const_cast<DOMClass *>(DOMClassStruct());
-      js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
-                          JS::PrivateValue(domClass));
-    }
-    return proto;
-  }
-
-  static bool
-  InitPrivate(JSContext* aCx, JSObject* aObj, WorkerPrivate* aWorkerPrivate)
-  {
-    MOZ_ASSERT(JS_GetClass(aObj) == Class());
-
-    dom::AllocateProtoAndIfaceCache(aObj);
-
-    nsRefPtr<SharedWorkerGlobalScope> scope =
-      new SharedWorkerGlobalScope(aCx, aWorkerPrivate);
-
-    js::SetReservedSlot(aObj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(scope));
-
-    scope->SetIsDOMBinding();
-    scope->SetWrapper(aObj);
-
-    scope.forget();
-    return true;
-  }
-
-protected:
-  SharedWorkerGlobalScope(JSContext* aCx, WorkerPrivate* aWorker)
-  : WorkerGlobalScope(aCx, aWorker)
-  {
-    MOZ_COUNT_CTOR(mozilla::dom::workers::SharedWorkerGlobalScope);
-  }
-
-  ~SharedWorkerGlobalScope()
-  {
-    MOZ_COUNT_DTOR(mozilla::dom::workers::SharedWorkerGlobalScope);
-  }
-
-private:
-  using EventTarget::GetEventListener;
-  using EventTarget::SetEventListener;
-
-  static bool
-  IsSharedWorkerGlobalScope(JS::Handle<JS::Value> aVal)
-  {
-    return aVal.isObject() && JS_GetClass(&aVal.toObject()) == Class();
-  }
-
-  static bool
-  GetOnconnectImpl(JSContext* aCx, JS::CallArgs aArgs)
-  {
-    auto name = sEventStrings[STRING_onconnect];
-
-    auto scope = GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
-    MOZ_ASSERT(scope);
-
-    ErrorResult rv;
-
-    nsRefPtr<EventHandlerNonNull> handler =
-      scope->GetEventListener(NS_ConvertASCIItoUTF16(name + 2), rv);
-    if (rv.Failed()) {
-      JS_ReportError(aCx, "Failed to get event listener!");
-      return false;
-    }
-
-    if (!handler) {
-      aArgs.rval().setNull();
-    } else {
-      aArgs.rval().setObject(*handler->Callable());
-    }
-
-    return true;
-  }
-
-  static bool
-  GetOnconnect(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
-  {
-    auto args = JS::CallArgsFromVp(aArgc, aVp);
-    return JS::CallNonGenericMethod<IsSharedWorkerGlobalScope,
-                                    GetOnconnectImpl>(aCx, args);
-  }
-
-  static bool
-  SetOnconnectImpl(JSContext* aCx, JS::CallArgs aArgs)
-  {
-    auto name = sEventStrings[STRING_onconnect];
-
-    auto scope = GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
-    MOZ_ASSERT(scope);
-
-    if (aArgs.length() == 0 || !aArgs[0].isObject()) {
-      JS_ReportError(aCx, "Not an event listener!");
-      return false;
-    }
-
-
-    ErrorResult rv;
-
-    JS::Rooted<JSObject*> listenerObj(aCx, aArgs[0].toObjectOrNull());
-    nsRefPtr<EventHandlerNonNull> handler;
-    if (listenerObj && JS_ObjectIsCallable(aCx, listenerObj)) {
-      handler = new EventHandlerNonNull(listenerObj);
-    } else {
-      handler = nullptr;
-    }
-    scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2), handler, rv);
-
-    if (rv.Failed()) {
-      JS_ReportError(aCx, "Failed to set event listener!");
-      return false;
-    }
-
-    aArgs.rval().setUndefined();
-    return true;
-  }
-
-  static bool
-  SetOnconnect(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
-  {
-    auto args = JS::CallArgsFromVp(aArgc, aVp);
-    return JS::CallNonGenericMethod<IsSharedWorkerGlobalScope,
-                                    SetOnconnectImpl>(aCx, args);
-  }
-
-  static bool
-  GetNameImpl(JSContext* aCx, JS::CallArgs aArgs)
-  {
-    auto scope = GetInstancePrivate(aCx, &aArgs.thisv().toObject(), "name");
-    MOZ_ASSERT(scope);
-
-    auto name = scope->mWorker->SharedWorkerName();
-    MOZ_ASSERT(!name.IsVoid());
-
-    JS::Rooted<JSString*> nameStr(aCx,
-      JS_InternUCStringN(aCx, name.get(), name.Length()));
-    if (!nameStr) {
-      return false;
-    }
-
-    aArgs.rval().setString(nameStr);
-    return true;
-  }
-
-  static bool
-  GetName(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
-  {
-    auto args = JS::CallArgsFromVp(aArgc, aVp);
-    return JS::CallNonGenericMethod<IsSharedWorkerGlobalScope,
-                                    GetNameImpl>(aCx, args);
-  }
-
-
-  static SharedWorkerGlobalScope*
-  GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
-  {
-    const JSClass* classPtr = JS_GetClass(aObj);
-    if (classPtr == Class()) {
-      return UnwrapDOMObject<SharedWorkerGlobalScope>(aObj);
-    }
-
-    JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
-                         JSMSG_INCOMPATIBLE_PROTO, Class()->name, aFunctionName,
-                         classPtr->name);
-    return nullptr;
-  }
-
-  static bool
-  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
-  {
-    JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
-                         JSMSG_WRONG_CONSTRUCTOR, Class()->name);
-    return false;
-  }
-
-  static bool
-  Resolve(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
-          unsigned aFlags, JS::MutableHandle<JSObject*> aObjp)
-  {
-    bool resolved;
-    if (!JS_ResolveStandardClass(aCx, aObj, aId, &resolved)) {
-      return false;
-    }
-
-    aObjp.set(resolved ? aObj.get() : nullptr);
-    return true;
-  }
-
-  static void
-  Finalize(JSFreeOp* aFop, JSObject* aObj)
-  {
-    MOZ_ASSERT(JS_GetClass(aObj) == Class());
-    SharedWorkerGlobalScope* scope =
-      UnwrapDOMObject<SharedWorkerGlobalScope>(aObj);
-    if (scope) {
-      DestroyProtoAndIfaceCache(aObj);
-      scope->_finalize(aFop);
-    }
-  }
-
-  static void
-  Trace(JSTracer* aTrc, JSObject* aObj)
-  {
-    MOZ_ASSERT(JS_GetClass(aObj) == Class());
-    SharedWorkerGlobalScope* scope =
-      UnwrapDOMObject<SharedWorkerGlobalScope>(aObj);
-    if (scope) {
-      TraceProtoAndIfaceCache(aTrc, aObj);
-      scope->_trace(aTrc);
-    }
-  }
-};
-
-DOMJSClass SharedWorkerGlobalScope::sClass = {
-  {
-    // We don't have to worry about Xray expando slots here because we'll never
-    // have an Xray wrapper to a worker global scope.
-    "SharedWorkerGlobalScope",
-    JSCLASS_DOM_GLOBAL | JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS |
-    JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_NEW_RESOLVE,
-    JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub,
-    JS_StrictPropertyStub, JS_EnumerateStub,
-    reinterpret_cast<JSResolveOp>(Resolve), JS_ConvertStub, Finalize, nullptr,
-    nullptr, nullptr, nullptr, Trace
-  },
-  {
-    INTERFACE_CHAIN_1(prototypes::id::EventTarget_workers),
-    false,
-    &sWorkerNativePropertyHooks
-  }
-};
-
-DOMIfaceAndProtoJSClass SharedWorkerGlobalScope::sProtoClass = {
-  {
-    // XXXbz we use "SharedWorkerGlobalScope" here to match sClass
-    // so that we can JS_InitClass this JSClass and then
-    // call JS_NewObject with our sClass and have it find the right
-    // prototype.
-    "SharedWorkerGlobalScope",
-    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2),
-    JS_PropertyStub,       /* addProperty */
-    JS_DeletePropertyStub, /* delProperty */
-    JS_PropertyStub,       /* getProperty */
-    JS_StrictPropertyStub, /* setProperty */
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub,
-    nullptr,               /* finalize */
-    nullptr,               /* checkAccess */
-    nullptr,               /* call */
-    nullptr,               /* hasInstance */
-    nullptr,               /* construct */
-    nullptr,               /* trace */
-    JSCLASS_NO_INTERNAL_MEMBERS
-  },
-  eInterfacePrototype,
-  &sWorkerNativePropertyHooks,
-  "[object SharedWorkerGlobalScope]",
-  prototypes::id::_ID_Count,
-  0
-};
-
-const JSPropertySpec SharedWorkerGlobalScope::sProperties[] = {
-  JS_PSGS(sEventStrings[STRING_onconnect], GetOnconnect, SetOnconnect,
-          JSPROP_ENUMERATE),
-  JS_PSGS("name", GetName, GetterOnlyJSNative, JSPROP_ENUMERATE),
-  JS_PS_END
-};
-
-const char* const SharedWorkerGlobalScope::sEventStrings[STRING_COUNT] = {
-  "onconnect",
-};
-
 WorkerGlobalScope*
 WorkerGlobalScope::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
                                       const char* aFunctionName)
 {
   const JSClass* classPtr = JS_GetClass(aObj);
 
-  // We can only make [Dedicated|Shared]WorkerGlobalScope, not
-  // WorkerGlobalScope, so this should never happen.
-  MOZ_ASSERT(classPtr != Class());
+  // We can only make DedicatedWorkerGlobalScope, not WorkerGlobalScope, so this
+  // should never happen.
+  JS_ASSERT(classPtr != Class());
 
   if (classPtr == DedicatedWorkerGlobalScope::Class()) {
     return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
   }
 
-  if (classPtr == SharedWorkerGlobalScope::Class()) {
-    return UnwrapDOMObject<SharedWorkerGlobalScope>(aObj);
-  }
-
-  JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
-                       JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
-                       classPtr->name);
-  return nullptr;
+  JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
+                       sClass.name, aFunctionName, classPtr->name);
+  return NULL;
 }
 
 bool
-WorkerGlobalScope::IsWorkerGlobalScope(JS::Handle<JS::Value> aVal)
+WorkerGlobalScope::IsWorkerGlobalScope(JS::Handle<JS::Value> v)
 {
-  if (!aVal.isObject()) {
-    return false;
-  }
-
-  auto classPtr = JS_GetClass(&aVal.toObject());
-
-  return classPtr == DedicatedWorkerGlobalScope::Class() ||
-         classPtr == SharedWorkerGlobalScope::Class();
+  return v.isObject() && JS_GetClass(&v.toObject()) == DedicatedWorkerGlobalScope::Class();
 }
 
 } /* anonymous namespace */
 
 BEGIN_WORKERS_NAMESPACE
 
 JSObject*
-CreateGlobalScope(JSContext* aCx)
+CreateDedicatedWorkerGlobalScope(JSContext* aCx)
 {
   using namespace mozilla::dom;
 
   WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
-  MOZ_ASSERT(worker);
-
-  const JSClass* classPtr = worker->IsSharedWorker() ?
-                            SharedWorkerGlobalScope::Class() :
-                            DedicatedWorkerGlobalScope::Class();
+  JS_ASSERT(worker);
 
   JS::CompartmentOptions options;
-  if (worker->IsChromeWorker()) {
+  if (worker->IsChromeWorker())
     options.setVersion(JSVERSION_LATEST);
-  }
-
   JS::Rooted<JSObject*> global(aCx,
-    JS_NewGlobalObject(aCx, classPtr, GetWorkerPrincipal(),
-                       JS::DontFireOnNewGlobalHook, options));
+    JS_NewGlobalObject(aCx, DedicatedWorkerGlobalScope::Class(),
+                       GetWorkerPrincipal(), JS::DontFireOnNewGlobalHook, options));
   if (!global) {
-    return nullptr;
+    return NULL;
   }
 
   JSAutoCompartment ac(aCx, global);
 
   // Make the private slots now so that all our instance checks succeed.
-  if (worker->IsSharedWorker()) {
-    if (!SharedWorkerGlobalScope::InitPrivate(aCx, global, worker)) {
-      return nullptr;
-  }
-  } else if (!DedicatedWorkerGlobalScope::InitPrivate(aCx, global, worker)) {
-    return nullptr;
+  if (!DedicatedWorkerGlobalScope::InitPrivate(aCx, global, worker)) {
+    return NULL;
   }
 
   // Proto chain should be:
-  //   global -> [Dedicated|Shared]WorkerGlobalScope
+  //   global -> DedicatedWorkerGlobalScope
   //          -> WorkerGlobalScope
   //          -> EventTarget
   //          -> Object
 
   JS::Rooted<JSObject*> eventTargetProto(aCx,
     EventTargetBinding_workers::GetProtoObject(aCx, global));
   if (!eventTargetProto) {
-    return nullptr;
+    return NULL;
   }
 
   JS::Rooted<JSObject*> scopeProto(aCx,
     WorkerGlobalScope::InitClass(aCx, global, eventTargetProto));
   if (!scopeProto) {
-    return nullptr;
+    return NULL;
+  }
+
+  JS::Rooted<JSObject*> dedicatedScopeProto(aCx,
+    DedicatedWorkerGlobalScope::InitClass(aCx, global, scopeProto));
+  if (!dedicatedScopeProto) {
+    return NULL;
   }
 
-  JS::Rooted<JSObject*> finalScopeProto(aCx,
-    worker->IsSharedWorker() ?
-    SharedWorkerGlobalScope::InitClass(aCx, global, scopeProto) :
-    DedicatedWorkerGlobalScope::InitClass(aCx, global, scopeProto));
-  if (!finalScopeProto) {
-    return nullptr;
+  if (!JS_SetPrototype(aCx, global, dedicatedScopeProto)) {
+    return NULL;
   }
 
-  if (!JS_SetPrototype(aCx, global, finalScopeProto)) {
-    return nullptr;
-  }
-
-  JS::Rooted<JSObject*> workerProto(aCx,
-    worker::InitClass(aCx, global, eventTargetProto, false));
+  JSObject* workerProto = worker::InitClass(aCx, global, eventTargetProto,
+                                            false);
   if (!workerProto) {
-    return nullptr;
+    return NULL;
   }
 
   if (worker->IsChromeWorker()) {
     if (!chromeworker::InitClass(aCx, global, workerProto, false) ||
         !DefineChromeWorkerFunctions(aCx, global) ||
         !DefineOSFileConstants(aCx, global)) {
-      return nullptr;
+      return NULL;
     }
   }
 
   // Init other classes we care about.
   if (!events::InitClasses(aCx, global, false) ||
       !file::InitClasses(aCx, global)) {
-    return nullptr;
+    return NULL;
   }
 
   // Init other paris-bindings.
   if (!DOMExceptionBinding::GetConstructorObject(aCx, global) ||
       !EventBinding::GetConstructorObject(aCx, global) ||
       !FileReaderSyncBinding_workers::GetConstructorObject(aCx, global) ||
       !ImageDataBinding::GetConstructorObject(aCx, global) ||
       !TextDecoderBinding::GetConstructorObject(aCx, global) ||
       !TextEncoderBinding::GetConstructorObject(aCx, global) ||
       !XMLHttpRequestBinding_workers::GetConstructorObject(aCx, global) ||
       !XMLHttpRequestUploadBinding_workers::GetConstructorObject(aCx, global) ||
       !URLBinding_workers::GetConstructorObject(aCx, global) ||
       !WorkerLocationBinding_workers::GetConstructorObject(aCx, global) ||
       !WorkerNavigatorBinding_workers::GetConstructorObject(aCx, global)) {
-    return nullptr;
+    return NULL;
   }
 
   if (!JS_DefineProfilingFunctions(aCx, global)) {
-    return nullptr;
+    return NULL;
   }
 
   JS_FireOnNewGlobalObject(aCx, global);
 
   return global;
 }
 
+bool
+ClassIsWorkerGlobalScope(const JSClass* aClass)
+{
+  return WorkerGlobalScope::Class() == aClass ||
+         DedicatedWorkerGlobalScope::Class() == aClass;
+}
+
 END_WORKERS_NAMESPACE
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -6,13 +6,16 @@
 #ifndef mozilla_dom_workers_workerscope_h__
 #define mozilla_dom_workers_workerscope_h__
 
 #include "Workers.h"
 
 BEGIN_WORKERS_NAMESPACE
 
 JSObject*
-CreateGlobalScope(JSContext* aCx);
+CreateDedicatedWorkerGlobalScope(JSContext* aCx);
+
+bool
+ClassIsWorkerGlobalScope(const JSClass* aClass);
 
 END_WORKERS_NAMESPACE
 
-#endif /* mozilla_dom_workers_workerscope_h__ */
\ No newline at end of file
+#endif /* mozilla_dom_workers_workerscope_h__ */
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -163,23 +163,23 @@ struct JSSettings
 };
 
 // All of these are implemented in RuntimeService.cpp
 bool
 ResolveWorkerClasses(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
                      unsigned aFlags, JS::MutableHandle<JSObject*> aObjp);
 
 void
-CancelWorkersForWindow(nsPIDOMWindow* aWindow);
+CancelWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
 void
-SuspendWorkersForWindow(nsPIDOMWindow* aWindow);
+SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
 void
-ResumeWorkersForWindow(nsPIDOMWindow* aWindow);
+ResumeWorkersForWindow(nsIScriptContext* aCx, nsPIDOMWindow* aWindow);
 
 class WorkerTask {
 public:
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask)
 
     virtual ~WorkerTask() { }
 
     virtual bool RunTask(JSContext* aCx) = 0;
--- a/dom/workers/moz.build
+++ b/dom/workers/moz.build
@@ -15,45 +15,39 @@ EXPORTS.mozilla.dom.workers += [
 
 # Stuff needed for the bindings, not really public though.
 EXPORTS.mozilla.dom.workers.bindings += [
     'DOMBindingBase.h',
     'EventListenerManager.h',
     'EventTarget.h',
     'FileReaderSync.h',
     'Location.h',
-    'MessagePort.h',
     'Navigator.h',
-    'SharedWorker.h',
     'URL.h',
     'WorkerFeature.h',
-    'WorkerMessagePort.h',
     'XMLHttpRequest.h',
     'XMLHttpRequestEventTarget.h',
     'XMLHttpRequestUpload.h',
 ]
 
 CPP_SOURCES += [
     'ChromeWorkerScope.cpp',
     'DOMBindingBase.cpp',
     'EventListenerManager.cpp',
     'EventTarget.cpp',
     'Events.cpp',
     'File.cpp',
     'FileReaderSync.cpp',
     'Location.cpp',
-    'MessagePort.cpp',
     'Navigator.cpp',
     'Principal.cpp',
     'RuntimeService.cpp',
     'ScriptLoader.cpp',
-    'SharedWorker.cpp',
     'URL.cpp',
     'Worker.cpp',
-    'WorkerMessagePort.cpp',
     'WorkerPrivate.cpp',
     'WorkerScope.cpp',
     'XMLHttpRequest.cpp',
     'XMLHttpRequestEventTarget.cpp',
     'XMLHttpRequestUpload.cpp',
 ]
 
 LIBRARY_NAME = 'domworkers_s'
@@ -65,9 +59,9 @@ LIBXUL_LIBRARY = True
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '../base',
     '../system',
     '/content/base/src',
     '/content/events/src',
     '/xpcom/build',
-]
\ No newline at end of file
+]
--- a/dom/workers/test/Makefile.in
+++ b/dom/workers/test/Makefile.in
@@ -3,8 +3,9 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Bug 842344, 842386 - Disabled on Windows & OSX for intermittent failures.
 ifeq (,$(filter Darwin WINNT,$(OS_ARCH)))
 MOCHITEST_FILES += \
   test_xhr_timeout.html \
   $(NULL)
 endif
+
--- a/dom/workers/test/mochitest.ini
+++ b/dom/workers/test/mochitest.ini
@@ -17,27 +17,24 @@ support-files =
   importScripts_worker_imported1.js
   importScripts_worker_imported2.js
   importScripts_worker_imported3.js
   importScripts_worker_imported4.js
   instanceof_worker.js
   json_worker.js
   location_worker.js
   longThread_worker.js
-  multi_sharedWorker_frame.html
-  multi_sharedWorker_sharedWorker.js
   navigator_worker.js
   newError_worker.js
   recursion_worker.js
   recursiveOnerror_worker.js
   relativeLoad_import.js
   relativeLoad_worker.js
   relativeLoad_worker2.js
   rvals_worker.js
-  sharedWorker_sharedWorker.js
   simpleThread_worker.js
   suspend_iframe.html
   suspend_worker.js
   terminate_worker.js
   testXHR.txt
   threadErrors_worker1.js
   threadErrors_worker2.js
   threadErrors_worker3.js
@@ -71,27 +68,24 @@ support-files =
 [test_eventDispatch.html]
 [test_fibonacci.html]
 [test_importScripts.html]
 [test_instanceof.html]
 [test_json.html]
 [test_loadError.html]
 [test_location.html]
 [test_longThread.html]
-[test_multi_sharedWorker.html]
-[test_multi_sharedWorker_lifetimes.html]
 [test_navigator.html]
 [test_newError.html]
 [test_recursion.html]
 [test_recursiveOnerror.html]
 [test_relativeLoad.html]
 [test_resolveWorker-assignment.html]
 [test_resolveWorker.html]
 [test_rvals.html]
-[test_sharedWorker.html]
 [test_simpleThread.html]
 [test_suspend.html]
 [test_terminate.html]
 [test_threadErrors.html]
 [test_threadTimeouts.html]
 [test_throwingOnerror.html]
 [test_transferable.html]
 [test_url.html]
deleted file mode 100644
--- a/dom/workers/test/multi_sharedWorker_frame.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <title>Test for SharedWorker</title>
-  </head>
-  <body>
-    <script type="text/javascript;version=1.7">
-"use strict";
-
-function debug(message) {
-  if (typeof(message) != "string") {
-    throw new Error("debug() only accepts strings!");
-  }
-  parent.postMessage(message, "*");
-}
-
-let worker;
-
-window.addEventListener("message", function(event) {
-  if (!worker) {
-    worker = new SharedWorker("multi_sharedWorker_sharedWorker.js",
-                              "FrameWorker");
-    worker.onerror = function(event) {
-      debug("Worker error: " + event.message);
-      event.preventDefault();
-
-      let data = {
-        type: "error",
-        message: event.message,
-        filename: event.filename,
-        lineno: event.lineno,
-        isErrorEvent: event instanceof ErrorEvent
-      };
-      parent.postMessage(data, "*");
-    };
-
-    worker.port.onmessage = function(event) {
-      debug("Worker message: " + JSON.stringify(event.data));
-      parent.postMessage(event.data, "*");
-    };
-  }
-
-  debug("Posting message: " + JSON.stringify(event.data));
-  worker.port.postMessage(event.data);
-});
-    </script>
-  </body>
-</html>
deleted file mode 100644
--- a/dom/workers/test/multi_sharedWorker_sharedWorker.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-"use strict";
-
-if (self.name != "FrameWorker") {
-  throw new Error("Bad worker name: " + self.name);
-}
-
-var registeredPorts = [];
-var errorCount = 0;
-var storedData;
-
-self.onconnect = function(event) {
-  var port = event.ports[0];
-
-  if (registeredPorts.length) {
-    var data = {
-      type: "connect"
-    };
-
-    registeredPorts.forEach(function(registeredPort) {
-      registeredPort.postMessage(data);
-    });
-  }
-
-  port.onmessage = function(event) {
-    switch (event.data.command) {
-      case "start":
-        break;
-
-      case "error":
-        throw new Error("Expected");
-
-      case "store":
-        storedData = event.data.data;
-        break;
-
-      case "retrieve":
-        var data = {
-          type: "result",
-          data: storedData
-        };
-        port.postMessage(data);
-        break;
-
-      default:
-        throw new Error("Unknown command '" + error.data.command + "'");
-    }
-  };
-
-  registeredPorts.push(port);
-};
-
-self.onerror = function(message, filename, lineno) {
-  if (!errorCount++) {
-    var data = {
-      type: "worker-error",
-      message: message,
-      filename: filename,
-      lineno: lineno
-    };
-
-    registeredPorts.forEach(function (registeredPort) {
-      registeredPort.postMessage(data);
-    });
-
-    // Prevent the error from propagating the first time only.
-    return true;
-  }
-};
deleted file mode 100644
--- a/dom/workers/test/sharedWorker_sharedWorker.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-"use strict";
-
-if (!("self" in this)) {
-  throw new Error("No 'self' exists on SharedWorkerGlobalScope!");
-}
-if (this !== self) {
-  throw new Error("'self' not equal to global object!");
-}
-if (!(self instanceof SharedWorkerGlobalScope)) {
-  throw new Error("self not a SharedWorkerGlobalScope instance!");
-}
-
-var propsToCheck = [
-  "location",
-  "navigator",
-  "close",
-  "importScripts",
-  "setTimeout",
-  "clearTimeout",
-  "setInterval",
-  "clearInterval",
-  "dump",
-  "atob",
-  "btoa"
-];
-
-for (var index = 0; index < propsToCheck.length; index++) {
-  var prop = propsToCheck[index];
-  if (!(prop in self)) {
-    throw new Error("SharedWorkerGlobalScope has no '" + prop + "' property!");
-  }
-}
-
-onconnect = function(event) {
-  if (!(event instanceof WorkerMessageEvent)) {
-    throw new Error("'connect' event is not a WorkerMessageEvent!");
-  }
-  if (!("ports" in event)) {
-    throw new Error("'connect' event doesn't have a 'ports' property!");
-  }
-  if (!Array.isArray(event.ports)) {
-    throw new Error("'connect' event has 'ports' property that isn't an " +
-                    "Array!");
-  }
-  if (event.ports.length != 1) {
-    throw new Error("'connect' event has a 'ports' property with length '" +
-                    event.ports.length + "'!");
-  }
-  if (!event.ports[0]) {
-    throw new Error("'connect' event has a null 'ports[0]' property!");
-  }
-  if (!(event.ports[0] instanceof WorkerMessagePort)) {
-    throw new Error("'connect' event has a 'ports[0]' property that isn't a " +
-                    "MessagePort!");
-  }
-  if (event.data) {
-    throw new Error("'connect' event has data: " + event.data);
-  }
-
-  event.ports[0].onmessage = function(event) {
-    if (!(event instanceof WorkerMessageEvent)) {
-      throw new Error("'message' event is not a WorkerMessageEvent!");
-    }
-    if (!("ports" in event)) {
-      throw new Error("'message' event doesn't have a 'ports' property!");
-    }
-    if (!Array.isArray(event.ports)) {
-      throw new Error("'message' event has 'ports' property that isn't an " +
-                      "Array!");
-    }
-    if (event.ports.length) {
-      throw new Error("'message' event has a 'ports' property with length '" +
-                      event.ports.length + "'!");
-    }
-    event.target.postMessage(event.data);
-    throw new Error(event.data);
-  };
-};
deleted file mode 100644
--- a/dom/workers/test/test_multi_sharedWorker.html
+++ /dev/null
@@ -1,251 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <title>Test for SharedWorker</title>
-    <script src="/tests/SimpleTest/SimpleTest.js"></script>
-    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-      <script class="testbody" type="text/javascript;version=1.7">
-        "use strict";
-
-        const swPref = "dom.workers.sharedWorkers.enabled";
-
-        const basePath =
-          location.pathname.substring(0,
-                                      location.pathname.lastIndexOf("/") + 1);
-        const baseURL = location.origin + basePath;
-
-        const frameRelativeURL = "multi_sharedWorker_frame.html";
-        const frameAbsoluteURL = baseURL + frameRelativeURL;
-        const workerAbsoluteURL =
-          baseURL + "multi_sharedWorker_sharedWorker.js";
-
-        const storedData = "0123456789abcdefghijklmnopqrstuvwxyz";
-        const errorMessage = "Error: Expected";
-        const errorLineno = 34;
-
-        let testGenerator = (function() {
-          SimpleTest.waitForExplicitFinish();
-
-          ok(!("SharedWorker" in window), "No SharedWorker without pref set");
-          ok(!("WorkerMessagePort" in window),
-             "No WorkerMessagePort without pref set");
-
-          SpecialPowers.pushPrefEnv({ set: [[swPref, true]] }, sendToGenerator);
-          yield undefined;
-
-          window.addEventListener("message", function(event) {
-            if (typeof(event.data) == "string") {
-              info(event.data);
-            } else {
-              sendToGenerator(event);
-            }
-          });
-
-          let frame1 = document.getElementById("frame1");
-          frame1.src = frameRelativeURL;
-          frame1.onload = sendToGenerator;
-
-          yield undefined;
-
-          frame1 = frame1.contentWindow;
-
-          let frame2 = document.getElementById("frame2");
-          frame2.src = frameAbsoluteURL;
-          frame2.onload = sendToGenerator;
-
-          yield undefined;
-
-          frame2 = frame2.contentWindow;
-
-          let data = {
-            command: "start"
-          };
-
-          frame1.postMessage(data, "*");
-          frame2.postMessage(data, "*");
-
-          let event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame1, "First window got the event");
-          is(event.data.type, "connect", "Got a connect message");
-
-          data = {
-            command: "retrieve"
-          };
-          frame1.postMessage(data, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame1, "First window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, undefined, "No data stored yet");
-
-          frame2.postMessage(data, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame2, "Second window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, undefined, "No data stored yet");
-
-          data = {
-            command: "store",
-            data: storedData
-          };
-          frame2.postMessage(data, "*");
-
-          data = {
-            command: "retrieve"
-          };
-          frame1.postMessage(data, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame1, "First window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, storedData, "Got stored data");
-
-          // This will generate two MessageEvents, one for each window.
-          let sawFrame1Error = false;
-          let sawFrame2Error = false;
-
-          data = {
-            command: "error"
-          };
-          frame1.postMessage(data, "*");
-
-          // First event.
-          event = yield undefined;
-
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.data.type, "worker-error", "Got an error message");
-          is(event.data.message, errorMessage, "Got correct error message");
-          is(event.data.filename, workerAbsoluteURL, "Got correct filename");
-          is(event.data.lineno, errorLineno, "Got correct lineno");
-          if (event.source == frame1) {
-            is(sawFrame1Error, false, "Haven't seen error for frame1 yet");
-            sawFrame1Error = true;
-          } else if (event.source == frame2) {
-            is(sawFrame2Error, false, "Haven't seen error for frame1 yet");
-            sawFrame2Error = true;
-          } else {
-            ok(false, "Saw error from unknown window");
-          }
-
-          // Second event
-          event = yield undefined;
-
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.data.type, "worker-error", "Got an error message");
-          is(event.data.message, errorMessage, "Got correct error message");
-          is(event.data.filename, workerAbsoluteURL, "Got correct filename");
-          is(event.data.lineno, errorLineno, "Got correct lineno");
-          if (event.source == frame1) {
-            is(sawFrame1Error, false, "Haven't seen error for frame1 yet");
-            sawFrame1Error = true;
-          } else if (event.source == frame2) {
-            is(sawFrame2Error, false, "Haven't seen error for frame1 yet");
-            sawFrame2Error = true;
-          } else {
-            ok(false, "Saw error from unknown window");
-          }
-
-          is(sawFrame1Error, true, "Saw error for frame1");
-          is(sawFrame2Error, true, "Saw error for frame2");
-
-          // This will generate two MessageEvents, one for each window.
-          sawFrame1Error = false;
-          sawFrame2Error = false;
-
-          data = {
-            command: "error"
-          };
-          frame1.postMessage(data, "*");
-
-          // First event.
-          event = yield undefined;
-
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.data.type, "error", "Got an error message");
-          is(event.data.message, errorMessage, "Got correct error message");
-          is(event.data.filename, workerAbsoluteURL, "Got correct filename");
-          is(event.data.lineno, errorLineno, "Got correct lineno");
-          is(event.data.isErrorEvent, true, "Frame got an ErrorEvent");
-          if (event.source == frame1) {
-            is(sawFrame1Error, false, "Haven't seen error for frame1 yet");
-            sawFrame1Error = true;
-          } else if (event.source == frame2) {
-            is(sawFrame2Error, false, "Haven't seen error for frame1 yet");
-            sawFrame2Error = true;
-          } else {
-            ok(false, "Saw error from unknown window");
-          }
-
-          // Second event
-          event = yield undefined;
-
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.data.type, "error", "Got an error message");
-          is(event.data.message, errorMessage, "Got correct error message");
-          is(event.data.filename, workerAbsoluteURL, "Got correct filename");
-          is(event.data.lineno, errorLineno, "Got correct lineno");
-          is(event.data.isErrorEvent, true, "Frame got an ErrorEvent");
-          if (event.source == frame1) {
-            is(sawFrame1Error, false, "Haven't seen error for frame1 yet");
-            sawFrame1Error = true;
-          } else if (event.source == frame2) {
-            is(sawFrame2Error, false, "Haven't seen error for frame1 yet");
-            sawFrame2Error = true;
-          } else {
-            ok(false, "Saw error from unknown window");
-          }
-
-          is(sawFrame1Error, true, "Saw error for frame1");
-          is(sawFrame2Error, true, "Saw error for frame2");
-
-          // Try a shared worker in a different origin.
-          frame1 = document.getElementById("frame1");
-          frame1.src = "http://example.org" + basePath + frameRelativeURL;
-          frame1.onload = sendToGenerator;
-          yield undefined;
-
-          frame1 = frame1.contentWindow;
-
-          data = {
-            command: "retrieve"
-          };
-          frame1.postMessage(data, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame1, "First window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, undefined, "No data stored yet");
-
-          frame2.postMessage(data, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame2, "First window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, storedData, "Got stored data");
-
-          window.removeEventListener("message", sendToGenerator);
-
-          SimpleTest.finish();
-          yield undefined;
-        })();
-
-        let sendToGenerator = testGenerator.send.bind(testGenerator);
-
-      </script>
-  </head>
-  <body onload="testGenerator.next();">
-    <iframe id="frame1"></iframe>
-    <iframe id="frame2"></iframe>
-  </body>
-</html>
deleted file mode 100644
--- a/dom/workers/test/test_multi_sharedWorker_lifetimes.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <title>Test for SharedWorker</title>
-    <script src="/tests/SimpleTest/SimpleTest.js"></script>
-    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-      <script class="testbody" type="text/javascript;version=1.7">
-        "use strict";
-
-        const swPref = "dom.workers.sharedWorkers.enabled";
-        const bfCachePref = "browser.sessionhistory.cache_subframes";
-
-        const frameRelativeURL = "multi_sharedWorker_frame.html";
-        const storedData = "0123456789abcdefghijklmnopqrstuvwxyz";
-
-        let testGenerator = (function() {
-          SimpleTest.waitForExplicitFinish();
-
-          ok(!("SharedWorker" in window), "No SharedWorker without pref set");
-          ok(!("WorkerMessagePort" in window),
-             "No WorkerMessagePort without pref set");
-
-          SpecialPowers.pushPrefEnv({ set: [[swPref, true]] }, sendToGenerator);
-          yield undefined;
-
-          window.addEventListener("message", function(event) {
-            if (typeof(event.data) == "string") {
-              info(event.data);
-            } else {
-              sendToGenerator(event);
-            }
-          });
-
-          let frame = document.getElementById("frame");
-          frame.src = frameRelativeURL;
-          frame.onload = sendToGenerator;
-
-          yield undefined;
-
-          frame = frame.contentWindow;
-          frame.postMessage({ command: "retrieve" }, "*");
-
-          let event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, undefined, "No data stored yet");
-
-          frame.postMessage({ command: "store", data: storedData }, "*");
-          frame.postMessage({ command: "retrieve" }, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, storedData, "Got stored data");
-
-          // Navigate when the bfcache is disabled.
-          info("Navigating to about:blank");
-          let frame = document.getElementById("frame");
-          frame.onload = sendToGenerator;
-          frame.src = "about:blank";
-          frame.contentWindow.document.body.offsetTop;
-
-          yield undefined;
-
-          info("Navigating to " + frameRelativeURL);
-          frame.src = frameRelativeURL;
-          frame.contentWindow.document.body.offsetTop;
-
-          yield undefined;
-
-          frame = frame.contentWindow;
-          frame.postMessage({ command: "retrieve" }, "*");
-
-          let event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, undefined, "No data stored");
-
-          frame.postMessage({ command: "store", data: storedData }, "*");
-          frame.postMessage({ command: "retrieve" }, "*");
-
-          event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, storedData, "Got stored data");
-
-          info("Enabling '" + bfCachePref + "' pref");
-          SpecialPowers.pushPrefEnv({ set: [[bfCachePref, true]] },
-                                    sendToGenerator);
-          yield undefined;
-
-          // Navigate when the bfcache is enabled.
-          let frame = document.getElementById("frame");
-          frame.onload = sendToGenerator;
-
-          info("Navigating to about:blank");
-          frame.src = "about:blank";
-          frame.contentWindow.document.body.offsetTop;
-
-          yield undefined;
-
-          for (let i = 0; i < 3; i++) {
-            info("Running GC");
-            SpecialPowers.gc();
-
-            info("Waiting the event queue to clear");
-            SpecialPowers.executeSoon(sendToGenerator);
-            yield undefined;
-          }
-
-          info("Navigating to " + frameRelativeURL);
-          frame.src = frameRelativeURL;
-          frame.contentWindow.document.body.offsetTop;
-
-          yield undefined;
-
-          frame = frame.contentWindow;
-          frame.postMessage({ command: "retrieve" }, "*");
-
-          let event = yield undefined;
-          ok(event instanceof MessageEvent, "Got a MessageEvent");
-          is(event.source, frame, "Correct window got the event");
-          is(event.data.type, "result", "Got a result message");
-          is(event.data.data, storedData, "Still have data stored");
-
-          info("Resetting '" + bfCachePref + "' pref");
-          SpecialPowers.popPrefEnv(sendToGenerator);
-          yield undefined;
-
-          window.removeEventListener("message", sendToGenerator);
-
-          SimpleTest.finish();
-          yield undefined;
-        })();
-
-        let sendToGenerator = testGenerator.send.bind(testGenerator);
-
-      </script>
-  </head>
-  <body onload="testGenerator.next();">
-    <iframe id="frame"></iframe>
-  </body>
-</html>
deleted file mode 100644
--- a/dom/workers/test/test_sharedWorker.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <title>Test for SharedWorker</title>
-    <script src="/tests/SimpleTest/SimpleTest.js">
-    </script>
-    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-  </head>
-  <body>
-    <p id="display"></p>
-    <div id="content" style="display: none"></div>
-    <pre id="test">
-      <script class="testbody">
-        "use strict";
-
-        const swPref = "dom.workers.sharedWorkers.enabled";
-
-        const href = window.location.href;
-        const filename = "sharedWorker_sharedWorker.js";
-        const sentMessage = "ping";
-        const errorFilename = href.substring(0, href.lastIndexOf("/") + 1) +
-                              filename;
-        const errorLine = 80;
-        const errorColumn = 0;
-
-        ok(!("SharedWorker" in window), "No SharedWorker without pref set");
-        ok(!("WorkerMessagePort" in window),
-           "No WorkerMessagePort without pref set");
-
-        SpecialPowers.pushPrefEnv({ set: [[swPref, true]] }, function() {
-          var worker = new SharedWorker(filename);
-
-          ok(worker instanceof SharedWorker, "Got SharedWorker instance");
-          ok(!("postMessage" in worker), "SharedWorker has no 'postMessage'");
-          ok(worker.port instanceof WorkerMessagePort,
-            "Shared worker has MessagePort");
-
-          var receivedMessage;
-          var receivedError;
-
-          worker.port.onmessage = function(event) {
-            ok(event instanceof MessageEvent, "Got a MessageEvent");
-            ok(event.target === worker.port,
-               "MessageEvent has correct 'target' property");
-            is(event.data, sentMessage, "Got correct message");
-            ok(receivedMessage === undefined, "Haven't gotten message yet");
-            ok(receivedError === undefined, "Haven't gotten error yet");
-            receivedMessage = event.data;
-          };
-
-          worker.onerror = function(event) {
-            ok(event instanceof ErrorEvent, "Got an ErrorEvent");
-            is(event.message, "Error: " + sentMessage, "Got correct error");
-            is(event.filename, errorFilename, "Got correct filename");
-            is(event.lineno, errorLine, "Got correct lineno");
-            is(event.column, errorColumn, "Got correct column");
-            ok(receivedMessage !== undefined, "Got message already");
-            ok(receivedError === undefined, "Haven't gotten error yet");
-            receivedError = event.message;
-            event.preventDefault();
-            SimpleTest.finish();
-          };
-
-          worker.port.postMessage(sentMessage);
-        });
-
-        SimpleTest.waitForExplicitFinish();
-
-      </script>
-    </pre>
-  </body>
-</html>
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -98,19 +98,16 @@ pref("dom.indexedDB.warningQuota", 50);
 // Whether or not indexedDB experimental features are enabled.
 pref("dom.indexedDB.experimental", false);
 
 // Whether or not Web Workers are enabled.
 pref("dom.workers.enabled", true);
 // The number of workers per domain allowed to run concurrently.
 pref("dom.workers.maxPerDomain", 20);
 
-// Whether or not Shared Web Workers are enabled.
-pref("dom.workers.sharedWorkers.enabled", false);
-
 // Whether nonzero values can be returned from performance.timing.*
 pref("dom.enable_performance", true);
 
 // Whether the Gamepad API is enabled
 #ifdef RELEASE_BUILD
 pref("dom.gamepad.enabled", false);
 pref("dom.gamepad.non_standard_events.enabled", false);
 #else