Bug 899687 - crash in (anonymous namespace)::Worker::Trace(JSTracer*, JSObject*) r=khuey
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 02 Aug 2013 13:15:39 +0100
changeset 141133 284946982e36a7341b7294be06645dc91df8bbc7
parent 141132 5ee8be4e4815f7c7a87fc7b7734576680b285f32
child 141134 c116372d7ad481f81b44dcd3c364d0e220dac6b0
push id25048
push userryanvm@gmail.com
push dateFri, 02 Aug 2013 20:52:37 +0000
treeherdermozilla-central@d2ce76654a6a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs899687
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 899687 - crash in (anonymous namespace)::Worker::Trace(JSTracer*, JSObject*) r=khuey
dom/workers/Worker.cpp
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -137,23 +137,24 @@ protected:
       parent->AssertIsOnWorkerThread();
     }
 
     JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, aClass, nullptr, nullptr));
     if (!obj) {
       return false;
     }
 
+    // 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) {
-      // 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.
-      js::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::PrivateValue(nullptr));
       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)) {