Bug 650161 - Don't move objects in the self hosting zone as it can be shared between runtimes r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 20 Oct 2014 09:07:43 +0100
changeset 211202 79b3a9ac83578e145180f8a09332ea18e8f2b9d1
parent 211201 275d7eee096e5c64ecb013e63fd44c2bc6b14576
child 211203 c42ba3f5ac3296b5930f57b5a39ade48134ecc53
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersterrence
bugs650161
milestone36.0a1
Bug 650161 - Don't move objects in the self hosting zone as it can be shared between runtimes r=terrence
js/src/jsgc.cpp
js/src/vm/Runtime.h
js/src/vm/SelfHosting.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2100,16 +2100,24 @@ ArenaContainsGlobal(ArenaHeader *arena)
         if (obj->is<GlobalObject>())
             return true;
     }
 
     return false;
 }
 
 static bool
+CanRelocateZone(JSRuntime *rt, Zone *zone)
+{
+    // We cannot move atoms as we depend on their addresses being constant and
+    // self-hosting objects may be shared by multiple runtimes.
+    return !rt->isAtomsZone(zone) && !rt->isSelfHostingZone(zone);
+}
+
+static bool
 CanRelocateArena(ArenaHeader *arena)
 {
     /*
      * We can't currently move global objects because their address can be baked
      * into compiled code so we skip relocation of any area containing one.
      */
     return arena->getAllocKind() <= FINALIZE_OBJECT_LAST && !ArenaContainsGlobal(arena);
 }
@@ -2304,18 +2312,17 @@ GCRuntime::relocateArenas()
 {
     gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT_MOVE);
 
     ArenaHeader *relocatedList = nullptr;
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
         MOZ_ASSERT(zone->isGCFinished());
         MOZ_ASSERT(!zone->isPreservingCode());
 
-        // We cannot move atoms as we depend on their addresses being constant.
-        if (!rt->isAtomsZone(zone)) {
+        if (CanRelocateZone(rt, zone)) {
             zone->setGCState(Zone::Compact);
             relocatedList = zone->allocator.arenas.relocateArenas(relocatedList);
         }
     }
 
     return relocatedList;
 }
 
@@ -2438,17 +2445,17 @@ GCRuntime::updatePointersToRelocatedCell
     // current set.
     if (JSTraceDataOp op = grayRootTracer.op)
         (*op)(&trc, grayRootTracer.data);
 
     // Sweep everything to fix up weak pointers
     WatchpointMap::sweepAll(rt);
     Debugger::sweepAll(rt->defaultFreeOp());
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
-        if (!rt->isAtomsZone(zone))
+        if (CanRelocateZone(rt, zone))
             rt->gc.sweepZoneAfterCompacting(zone);
     }
 
     // Type inference may put more blocks here to free.
     rt->freeLifoAlloc.freeAll();
 
     // Clear runtime caches that can contain cell pointers.
     // TODO: Should possibly just call PurgeRuntime() here.
@@ -5180,17 +5187,17 @@ GCRuntime::compactPhase()
 
     ArenaHeader *relocatedList = relocateArenas();
     updatePointersToRelocatedCells();
     releaseRelocatedArenas(relocatedList);
 
 #ifdef DEBUG
     CheckHashTablesAfterMovingGC(rt);
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
-        if (!rt->isAtomsZone(zone) && !zone->isPreservingCode())
+        if (CanRelocateZone(rt, zone) && !zone->isPreservingCode())
             zone->allocator.arenas.checkEmptyFreeLists();
     }
 #endif
 }
 #endif // JSGC_COMPACTING
 
 void
 GCRuntime::finishCollection()
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -864,16 +864,17 @@ struct JSRuntime : public JS::shadow::Ru
 
     bool initSelfHosting(JSContext *cx);
     void finishSelfHosting();
     void markSelfHostingGlobal(JSTracer *trc);
     bool isSelfHostingGlobal(JSObject *global) {
         return global == selfHostingGlobal_;
     }
     bool isSelfHostingCompartment(JSCompartment *comp);
+    bool isSelfHostingZone(JS::Zone *zone);
     bool cloneSelfHostedFunctionScript(JSContext *cx, js::Handle<js::PropertyName*> name,
                                        js::Handle<JSFunction*> targetFun);
     bool cloneSelfHostedValue(JSContext *cx, js::Handle<js::PropertyName*> name,
                               js::MutableHandleValue vp);
 
     //-------------------------------------------------------------------------
     // Locale information
     //-------------------------------------------------------------------------
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1310,16 +1310,22 @@ JSRuntime::markSelfHostingGlobal(JSTrace
 }
 
 bool
 JSRuntime::isSelfHostingCompartment(JSCompartment *comp)
 {
     return selfHostingGlobal_->compartment() == comp;
 }
 
+bool
+JSRuntime::isSelfHostingZone(JS::Zone *zone)
+{
+    return selfHostingGlobal_->zoneFromAnyThread() == zone;
+}
+
 static bool
 CloneValue(JSContext *cx, HandleValue selfHostedValue, MutableHandleValue vp);
 
 static bool
 GetUnclonedValue(JSContext *cx, HandleNativeObject selfHostedObject,
                  HandleId id, MutableHandleValue vp)
 {
     vp.setUndefined();