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 248183 4933f14465f24773a30ab5917c0ddaa147c689b4
parent 248182 46bd519c8e2bc42659e71f62a90969be9e188852
child 248184 b434e8ec434c0df22c1384c16e2693abc15621aa
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1118381
milestone37.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 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;
 }