Bug 650161 - Don't move objects in the self hosting zone as it can be shared between runtimes r=terrence
--- 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();