Bug 1037666. r=billm, a=abillings
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 04 Aug 2014 17:10:51 -0400
changeset 208239 784c7fb4c431
parent 208234 54fe10b3558d
child 208240 92364eef664a
push id3787
push userryanvm@gmail.com
push date2014-08-05 15:12 +0000
treeherdermozilla-beta@784c7fb4c431 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, abillings
bugs1037666
milestone32.0
Bug 1037666. r=billm, a=abillings
js/src/vm/HelperThreads.cpp
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -580,16 +580,25 @@ GlobalHelperThreadState::canStartCompres
 
 bool
 GlobalHelperThreadState::canStartGCHelperTask()
 {
     return !gcHelperWorklist().empty();
 }
 
 static void
+LeaveParseTaskZone(JSRuntime *rt, ParseTask *task)
+{
+    // Mark the zone as no longer in use by an ExclusiveContext, and available
+    // to be collected by the GC.
+    task->cx->leaveCompartment(task->cx->compartment());
+    rt->clearUsedByExclusiveThread(task->cx->zone());
+}
+
+static void
 CallNewScriptHookForAllScripts(JSContext *cx, HandleScript script)
 {
     // We should never hit this, since nested scripts are also constructed via
     // BytecodeEmitter instances on the stack.
     JS_CHECK_RECURSION(cx, return);
 
     // Recurse to any nested scripts.
     if (script->hasObjects()) {
@@ -626,38 +635,39 @@ GlobalHelperThreadState::finishParseTask
                 parseTask = finished[i];
                 remove(finished, &i);
                 break;
             }
         }
     }
     JS_ASSERT(parseTask);
 
-    // Mark the zone as no longer in use by an ExclusiveContext, and available
-    // to be collected by the GC.
-    parseTask->cx->leaveCompartment(parseTask->cx->compartment());
-    rt->clearUsedByExclusiveThread(parseTask->cx->zone());
     if (!maybecx) {
+        LeaveParseTaskZone(rt, parseTask);
         return nullptr;
     }
+
     JSContext *cx = maybecx;
     JS_ASSERT(cx->compartment());
 
     // Make sure we have all the constructors we need for the prototype
     // remapping below, since we can't GC while that's happening.
     Rooted<GlobalObject*> global(cx, &cx->global()->as<GlobalObject>());
     if (!GlobalObject::ensureConstructor(cx, global, JSProto_Object) ||
         !GlobalObject::ensureConstructor(cx, global, JSProto_Array) ||
         !GlobalObject::ensureConstructor(cx, global, JSProto_Function) ||
         !GlobalObject::ensureConstructor(cx, global, JSProto_RegExp) ||
         !GlobalObject::ensureConstructor(cx, global, JSProto_Iterator))
     {
+        LeaveParseTaskZone(rt, parseTask);
         return nullptr;
     }
 
+    LeaveParseTaskZone(rt, parseTask);
+
     // Point the prototypes of any objects in the script's compartment to refer
     // to the corresponding prototype in the new compartment. This will briefly
     // create cross compartment pointers, which will be fixed by the
     // MergeCompartments call below.
     for (gc::ZoneCellIter iter(parseTask->cx->zone(), gc::FINALIZE_TYPE_OBJECT);
          !iter.done();
          iter.next())
     {