Bug 1153354 - Share SetMaybeAliveFlag between the two places we use it; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Wed, 08 Apr 2015 14:43:39 -0700
changeset 268746 992443bb8bcf83088ae8d7d830bdc6bf803d4956
parent 268745 b896382f53682409156a9ed7e9c23814c2342448
child 268747 40723ea7e393c8ba4c4474c792dcfbf44ac80a5a
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1153354
milestone40.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 1153354 - Share SetMaybeAliveFlag between the two places we use it; r=jonco
js/src/gc/Marking.cpp
js/src/gc/RootMarking.cpp
js/src/jscompartment.h
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -267,43 +267,16 @@ CheckMarkedThing<jsid>(JSTracer* trc, js
 #endif
 }
 
 #define JS_ROOT_MARKING_ASSERT(trc) \
     MOZ_ASSERT_IF(trc->isMarkingTracer(), \
                   trc->runtime()->gc.state() == NO_INCREMENTAL || \
                   trc->runtime()->gc.state() == MARK_ROOTS);
 
-/*
- * We only set the maybeAlive flag for objects and scripts. It's assumed that,
- * if a compartment is alive, then it will have at least some live object or
- * script it in. Even if we get this wrong, the worst that will happen is that
- * scheduledForDestruction will be set on the compartment, which will cause some
- * extra GC activity to try to free the compartment.
- */
-template<typename T>
-static inline void
-SetMaybeAliveFlag(T* thing)
-{
-}
-
-template<>
-void
-SetMaybeAliveFlag(JSObject* thing)
-{
-    thing->compartment()->maybeAlive = true;
-}
-
-template<>
-void
-SetMaybeAliveFlag(JSScript* thing)
-{
-    thing->compartment()->maybeAlive = true;
-}
-
 #define FOR_EACH_GC_LAYOUT(D) \
     D(Object, JSObject) \
     D(String, JSString) \
     D(Symbol, JS::Symbol) \
     D(Script, JSScript) \
     D(Shape, js::Shape) \
     D(BaseShape, js::BaseShape) \
     D(JitCode, js::jit::JitCode) \
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -570,16 +570,23 @@ js::gc::GCRuntime::bufferGrayRoots()
     if (grayBufferer.failed()) {
       grayBufferState = GrayBufferState::Failed;
       resetBufferedGrayRoots();
     } else {
       grayBufferState = GrayBufferState::Okay;
     }
 }
 
+struct SetMaybeAliveFunctor {
+    template <typename T>
+    void operator()(Cell* cell) {
+        SetMaybeAliveFlag<T>(static_cast<T*>(cell));
+    }
+};
+
 void
 BufferGrayRootsTracer::appendGrayRoot(Cell* thing, JSGCTraceKind kind)
 {
     MOZ_ASSERT(runtime()->isHeapBusy());
 
     if (bufferingGrayRootsFailed)
         return;
 
@@ -591,26 +598,18 @@ BufferGrayRootsTracer::appendGrayRoot(Ce
 #endif
 
     Zone* zone = TenuredCell::fromPointer(thing)->zone();
     if (zone->isCollecting()) {
         // See the comment on SetMaybeAliveFlag to see why we only do this for
         // objects and scripts. We rely on gray root buffering for this to work,
         // but we only need to worry about uncollected dead compartments during
         // incremental GCs (when we do gray root buffering).
-        switch (kind) {
-          case JSTRACE_OBJECT:
-            static_cast<JSObject*>(thing)->compartment()->maybeAlive = true;
-            break;
-          case JSTRACE_SCRIPT:
-            static_cast<JSScript*>(thing)->compartment()->maybeAlive = true;
-            break;
-          default:
-            break;
-        }
+        CallTyped(SetMaybeAliveFunctor(), kind, thing);
+
         if (!zone->gcGrayRoots.append(root))
             bufferingGrayRootsFailed = true;
     }
 }
 
 void
 GCRuntime::markBufferedGrayRoots(JS::Zone* zone)
 {
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -607,16 +607,25 @@ struct JSCompartment
 inline bool
 JSRuntime::isAtomsZone(JS::Zone* zone)
 {
     return zone == atomsCompartment_->zone();
 }
 
 namespace js {
 
+// We only set the maybeAlive flag for objects and scripts. It's assumed that,
+// if a compartment is alive, then it will have at least some live object or
+// script it in. Even if we get this wrong, the worst that will happen is that
+// scheduledForDestruction will be set on the compartment, which will cause
+// some extra GC activity to try to free the compartment.
+template<typename T> inline void SetMaybeAliveFlag(T* thing) {}
+template<> inline void SetMaybeAliveFlag(JSObject* thing) {thing->compartment()->maybeAlive = true;}
+template<> inline void SetMaybeAliveFlag(JSScript* thing) {thing->compartment()->maybeAlive = true;}
+
 inline js::Handle<js::GlobalObject*>
 ExclusiveContext::global() const
 {
     /*
      * It's safe to use |unsafeGet()| here because any compartment that is
      * on-stack will be marked automatically, so there's no need for a read
      * barrier on it. Once the compartment is popped, the handle is no longer
      * safe to use.