Bug 1118381: Carefully explain our dance around the incremental GC when draining the Debugger's allocations log. DONTBUILD r=terrence
authorJim Blandy <jimb@mozilla.com>
Tue, 06 Jan 2015 11:10:54 -0800
changeset 222391 4933f14465f24773a30ab5917c0ddaa147c689b4
parent 222390 46bd519c8e2bc42659e71f62a90969be9e188852
child 222392 b434e8ec434c0df22c1384c16e2693abc15621aa
push id10683
push usercbook@mozilla.com
push dateWed, 07 Jan 2015 13:30:50 +0000
treeherderfx-team@3a1103c584cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1118381
milestone37.0a1
Bug 1118381: Carefully explain our dance around the incremental GC when draining the Debugger's allocations log. DONTBUILD r=terrence
js/src/vm/DebuggerMemory.cpp
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -192,27 +192,34 @@ DebuggerMemory::drainAllocationsLog(JSCo
         return false;
     result->ensureDenseInitializedLength(cx, 0, length);
 
     for (size_t i = 0; i < length; i++) {
         RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
         if (!obj)
             return false;
 
+        // Don't pop the AllocationSite yet. The queue's links are followed by
+        // the GC to find the AllocationSite, but are not barried, so we must
+        // edit them with great care. Use the queue entry in place, and then
+        // pop and delete together.
         Debugger::AllocationSite *allocSite = dbg->allocationsLog.getFirst();
         RootedValue frame(cx, ObjectOrNullValue(allocSite->frame));
         if (!JSObject::defineProperty(cx, obj, cx->names().frame, frame))
             return false;
 
         RootedValue timestampValue(cx, NumberValue(allocSite->when));
         if (!JSObject::defineProperty(cx, obj, cx->names().timestamp, timestampValue))
             return false;
 
         result->setDenseElement(i, ObjectValue(*obj));
 
+        // Pop the front queue entry, and delete it immediately, so that
+        // the GC sees the AllocationSite's RelocatablePtr barriers run
+        // atomically with the change to the graph (the queue link).
         MOZ_ALWAYS_TRUE(dbg->allocationsLog.popFirst() == allocSite);
         js_delete(allocSite);
     }
 
     dbg->allocationsLogLength = 0;
     args.rval().setObject(*result);
     return true;
 }