Bug 863523 - Avoid post-barrier on global slots for JIT code; r=billm,terrence
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 20 Mar 2013 16:15:00 -0700
changeset 130538 47ad2545d5f5c420cbc956e340c3968ed625455f
parent 130537 024eef52799d14a434e4e17f6616720859f7dc70
child 130539 3ff6533160bdd48c7acc25131ff857d5ad35b671
push id24621
push userphilringnalda@gmail.com
push dateThu, 02 May 2013 03:27:34 +0000
treeherdermozilla-central@0274ab3783b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, terrence
bugs863523
milestone23.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 863523 - Avoid post-barrier on global slots for JIT code; r=billm,terrence
js/src/gc/RootMarking.cpp
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -644,16 +644,40 @@ JSPropertyDescriptor::trace(JSTracer *tr
     }
     if ((attrs & JSPROP_SETTER) && setter) {
         JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, setter);
         MarkObjectRoot(trc, &tmp, "Descriptor::set");
         setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, tmp);
     }
 }
 
+static inline void
+MarkGlobalForMinorGC(JSTracer *trc, JSCompartment *compartment)
+{
+#ifdef JS_ION
+    /*
+     * Named properties of globals which have had Ion activity are treated as
+     * roots during minor GCs. This allows writes to globals to occur without
+     * needing a write barrier.
+     */
+    JS_ASSERT(trc->runtime->isHeapMinorCollecting());
+
+    if (!compartment->ionCompartment())
+        return;
+
+    GlobalObject *global = compartment->maybeGlobal();
+    if (!global)
+        return;
+
+    /* Global reserved slots never hold nursery things. */
+    for (size_t i = JSCLASS_RESERVED_SLOTS(global->getClass()); i < global->slotSpan(); ++i)
+        MarkValueRoot(trc, global->nativeGetSlotRef(i).unsafeGet(), "MinorGlobalRoot");
+#endif /* JS_ION */
+}
+
 void
 js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
 {
     JSRuntime *rt = trc->runtime;
     JS_ASSERT(trc->callback != GCMarker::GrayCallback);
 
     JS_ASSERT(!rt->mainThread.suppressGC);
 
@@ -732,16 +756,19 @@ js::gc::MarkRuntime(JSTracer *trc, bool 
         }
     }
 
     /* We can't use GCCompartmentsIter if we're called from TraceRuntime. */
     for (CompartmentsIter c(rt); !c.done(); c.next()) {
         if (IS_GC_MARKING_TRACER(trc) && !c->zone()->isCollecting())
             continue;
 
+        if (trc->runtime->isHeapMinorCollecting())
+            MarkGlobalForMinorGC(trc, c);
+
         /* During a GC, these are treated as weak pointers. */
         if (!IS_GC_MARKING_TRACER(trc)) {
             if (c->watchpointMap)
                 c->watchpointMap->markAll(trc);
         }
 
         /* Mark debug scopes, if present */
         if (c->debugScopes)