Bug 650161 - Only update arenas for thing kinds that may contain object pointers r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 24 Oct 2014 08:49:33 +0100
changeset 212088 446fda5c660279cc5762b57e1447449b067997e1
parent 212087 f4bb57ab1f3f968846ad7d5ac7b7959d37226cf8
child 212089 19beeeec9cf32bd902e99ed7534bbf5bff91cc7e
push id27697
push usercbook@mozilla.com
push dateFri, 24 Oct 2014 13:48:53 +0000
treeherdermozilla-central@de805196bbc4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs650161
milestone36.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 650161 - Only update arenas for thing kinds that may contain object pointers r=terrence
js/src/gc/Barrier.h
js/src/jit/IonCode.h
js/src/jsgc.cpp
js/src/jsscript.h
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -156,28 +156,29 @@ class JSFlatString;
 class JSLinearString;
 
 namespace JS {
 class Symbol;
 }
 
 namespace js {
 
-class NativeObject;
+class AccessorShape;
 class ArrayObject;
 class ArgumentsObject;
 class ArrayBufferObjectMaybeShared;
 class ArrayBufferObject;
 class ArrayBufferViewObject;
 class SharedArrayBufferObject;
 class SharedTypedArrayObject;
 class BaseShape;
 class DebugScopeObject;
 class GlobalObject;
 class LazyScript;
+class NativeObject;
 class NestedScopeObject;
 class Nursery;
 class PropertyName;
 class SavedFrame;
 class ScopeObject;
 class ScriptSourceObject;
 class Shape;
 class UnownedBaseShape;
@@ -221,16 +222,17 @@ template <> struct MapTypeToTraceKind<JS
 template <> struct MapTypeToTraceKind<JSScript>         { static const JSGCTraceKind kind = JSTRACE_SCRIPT; };
 template <> struct MapTypeToTraceKind<JSString>         { static const JSGCTraceKind kind = JSTRACE_STRING; };
 template <> struct MapTypeToTraceKind<LazyScript>       { static const JSGCTraceKind kind = JSTRACE_LAZY_SCRIPT; };
 template <> struct MapTypeToTraceKind<NestedScopeObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
 template <> struct MapTypeToTraceKind<PropertyName>     { static const JSGCTraceKind kind = JSTRACE_STRING; };
 template <> struct MapTypeToTraceKind<SavedFrame>       { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
 template <> struct MapTypeToTraceKind<ScopeObject>      { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
 template <> struct MapTypeToTraceKind<Shape>            { static const JSGCTraceKind kind = JSTRACE_SHAPE; };
+template <> struct MapTypeToTraceKind<AccessorShape>    { static const JSGCTraceKind kind = JSTRACE_SHAPE; };
 template <> struct MapTypeToTraceKind<SharedArrayBufferObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
 template <> struct MapTypeToTraceKind<SharedTypedArrayObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
 template <> struct MapTypeToTraceKind<UnownedBaseShape> { static const JSGCTraceKind kind = JSTRACE_BASE_SHAPE; };
 template <> struct MapTypeToTraceKind<jit::JitCode>     { static const JSGCTraceKind kind = JSTRACE_JITCODE; };
 template <> struct MapTypeToTraceKind<types::TypeObject>{ static const JSGCTraceKind kind = JSTRACE_TYPE_OBJECT; };
 
 // Direct value access used by the write barriers and the jits.
 void
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -97,16 +97,17 @@ class JitCode : public gc::TenuredCell
     uint8_t *rawEnd() const {
         return code_ + insnSize_;
     }
     size_t instructionsSize() const {
         return insnSize_;
     }
     void trace(JSTracer *trc);
     void finalize(FreeOp *fop);
+    void fixupAfterMovingGC() {}
     void setInvalidated() {
         invalidated_ = true;
     }
 
     void setHasBytecodeMap() {
         hasBytecodeMap_ = true;
     }
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2404,73 +2404,66 @@ GCRuntime::sweepZoneAfterCompacting(Zone
         c->sweepDebugScopes();
         c->sweepJitCompartment(fop);
         c->sweepWeakMaps();
         c->sweepNativeIterators();
     }
 }
 
 /*
- * Update the interal pointers in a single cell.
+ * Update the interal pointers for all cells of the specified kind in a zone.
  */
+template <typename T>
 static void
-UpdateCellPointers(MovingTracer *trc, Cell *cell, JSGCTraceKind traceKind) {
-    if (traceKind == JSTRACE_OBJECT) {
-        JSObject *obj = static_cast<JSObject *>(cell);
-        obj->fixupAfterMovingGC();
-    } else if (traceKind == JSTRACE_SHAPE) {
-        Shape *shape = static_cast<Shape *>(cell);
-        shape->fixupAfterMovingGC();
-    } else if (traceKind == JSTRACE_BASE_SHAPE) {
-        BaseShape *base = static_cast<BaseShape *>(cell);
-        base->fixupAfterMovingGC();
-    } else if (traceKind == JSTRACE_TYPE_OBJECT) {
-        types::TypeObject *type = static_cast<types::TypeObject *>(cell);
-        type->fixupAfterMovingGC();
-    }
-
-    TraceChildren(trc, cell, traceKind);
+UpdateCellPointersByKind(MovingTracer *trc, ArenaLists &al, AllocKind thingKind) {
+    JSGCTraceKind traceKind = MapAllocToTraceKind(thingKind);
+    MOZ_ASSERT(MapTypeToTraceKind<T>::kind == traceKind);
+    for (ArenaHeader *arena = al.getFirstArena(thingKind); arena; arena = arena->next) {
+        for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
+            T *cell = reinterpret_cast<T*>(i.getCell());
+            cell->fixupAfterMovingGC();
+            TraceChildren(trc, cell, traceKind);
+        }
+    }
 }
 
 /*
  * Update pointers to relocated cells by doing a full heap traversal and sweep.
  *
  * The latter is necessary to update weak references which are not marked as
  * part of the traversal.
  */
 void
 GCRuntime::updatePointersToRelocatedCells()
 {
     MOZ_ASSERT(rt->currentThreadHasExclusiveAccess());
 
     gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT_UPDATE);
     MovingTracer trc(rt);
 
-    // TODO: We may need to fix up other weak pointers here.
-
     // Fixup compartment global pointers as these get accessed during marking.
     for (GCCompartmentsIter comp(rt); !comp.done(); comp.next())
         comp->fixupAfterMovingGC();
 
     // Fixup cross compartment wrappers as we assert the existence of wrappers in the map.
     for (CompartmentsIter comp(rt, SkipAtoms); !comp.done(); comp.next())
         comp->sweepCrossCompartmentWrappers();
 
-    // Iterate through all allocated cells to update internal pointers.
+    // Iterate through all cells that can contain JSObject pointers to update them.
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
         ArenaLists &al = zone->allocator.arenas;
-        for (unsigned i = 0; i < FINALIZE_LIMIT; ++i) {
-            AllocKind thingKind = static_cast<AllocKind>(i);
-            JSGCTraceKind traceKind = MapAllocToTraceKind(thingKind);
-            for (ArenaHeader *arena = al.getFirstArena(thingKind); arena; arena = arena->next) {
-                for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
-                    UpdateCellPointers(&trc, i.getCell(), traceKind);
-                }
-            }
-        }
+        for (unsigned i = 0; i < FINALIZE_OBJECT_LIMIT; ++i)
+            UpdateCellPointersByKind<JSObject>(&trc, al, AllocKind(i));
+        UpdateCellPointersByKind<JSScript>(&trc, al, FINALIZE_SCRIPT);
+        UpdateCellPointersByKind<LazyScript>(&trc, al, FINALIZE_LAZY_SCRIPT);
+        UpdateCellPointersByKind<Shape>(&trc, al, FINALIZE_SHAPE);
+        UpdateCellPointersByKind<AccessorShape>(&trc, al, FINALIZE_ACCESSOR_SHAPE);
+        UpdateCellPointersByKind<BaseShape>(&trc, al, FINALIZE_BASE_SHAPE);
+        UpdateCellPointersByKind<types::TypeObject>(&trc, al, FINALIZE_TYPE_OBJECT);
+        UpdateCellPointersByKind<jit::JitCode>(&trc, al, FINALIZE_JITCODE);
     }
 
     // Mark roots to update them.
     markRuntime(&trc, MarkRuntime);
     Debugger::markAll(&trc);
     Debugger::markCrossCompartmentDebuggerObjectReferents(&trc);
 
     for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1656,16 +1656,17 @@ class JSScript : public js::gc::TenuredC
 
     bool stepModeEnabled() { return hasDebugScript_ && !!debugScript()->stepMode; }
 
 #ifdef DEBUG
     uint32_t stepModeCount() { return hasDebugScript_ ? debugScript()->stepMode : 0; }
 #endif
 
     void finalize(js::FreeOp *fop);
+    void fixupAfterMovingGC() {}
 
     static inline js::ThingRootKind rootKind() { return js::THING_ROOT_SCRIPT; }
 
     void markChildren(JSTracer *trc);
 };
 
 /* If this fails, add/remove padding within JSScript. */
 static_assert(sizeof(JSScript) % js::gc::CellSize == 0,
@@ -1979,16 +1980,17 @@ class LazyScript : public gc::TenuredCel
         return column_;
     }
 
     bool hasUncompiledEnclosingScript() const;
     uint32_t staticLevel(JSContext *cx) const;
 
     void markChildren(JSTracer *trc);
     void finalize(js::FreeOp *fop);
+    void fixupAfterMovingGC() {}
 
     static inline js::ThingRootKind rootKind() { return js::THING_ROOT_LAZY_SCRIPT; }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
     {
         return mallocSizeOf(table_);
     }