mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 02:05:42 +00:00
Bug 1340597 - Avoid triggering read barrier in DumpHeap and when collecting stats r=sfink
This commit is contained in:
parent
4c4d2e43e2
commit
383736d564
@ -20,10 +20,10 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
static void
|
||||
IterateCompartmentsArenasCells(JSContext* cx, Zone* zone, void* data,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback)
|
||||
IterateCompartmentsArenasCellsUnbarriered(JSContext* cx, Zone* zone, void* data,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback)
|
||||
{
|
||||
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next())
|
||||
(*compartmentCallback)(cx, data, comp);
|
||||
@ -35,40 +35,40 @@ IterateCompartmentsArenasCells(JSContext* cx, Zone* zone, void* data,
|
||||
for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) {
|
||||
Arena* arena = aiter.get();
|
||||
(*arenaCallback)(cx->runtime(), data, arena, traceKind, thingSize);
|
||||
for (ArenaCellIter iter(arena); !iter.done(); iter.next())
|
||||
for (ArenaCellIterUnbarriered iter(arena); !iter.done(); iter.next())
|
||||
(*cellCallback)(cx->runtime(), data, iter.getCell(), traceKind, thingSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
js::IterateZonesCompartmentsArenasCells(JSContext* cx, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback)
|
||||
js::IterateHeapUnbarriered(JSContext* cx, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback)
|
||||
{
|
||||
AutoPrepareForTracing prop(cx, WithAtoms);
|
||||
|
||||
for (ZonesIter zone(cx->runtime(), WithAtoms); !zone.done(); zone.next()) {
|
||||
(*zoneCallback)(cx->runtime(), data, zone);
|
||||
IterateCompartmentsArenasCells(cx, zone, data,
|
||||
compartmentCallback, arenaCallback, cellCallback);
|
||||
IterateCompartmentsArenasCellsUnbarriered(cx, zone, data,
|
||||
compartmentCallback, arenaCallback, cellCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
js::IterateZoneCompartmentsArenasCells(JSContext* cx, Zone* zone, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback)
|
||||
js::IterateHeapUnbarrieredForZone(JSContext* cx, Zone* zone, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback)
|
||||
{
|
||||
AutoPrepareForTracing prop(cx, WithAtoms);
|
||||
|
||||
(*zoneCallback)(cx->runtime(), data, zone);
|
||||
IterateCompartmentsArenasCells(cx, zone, data,
|
||||
compartmentCallback, arenaCallback, cellCallback);
|
||||
IterateCompartmentsArenasCellsUnbarriered(cx, zone, data,
|
||||
compartmentCallback, arenaCallback, cellCallback);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1184,11 +1184,11 @@ js::DumpHeap(JSContext* cx, FILE* fp, js::DumpHeapNurseryBehaviour nurseryBehavi
|
||||
fprintf(dtrc.output, "==========\n");
|
||||
|
||||
dtrc.prefix = "> ";
|
||||
IterateZonesCompartmentsArenasCells(cx, &dtrc,
|
||||
DumpHeapVisitZone,
|
||||
DumpHeapVisitCompartment,
|
||||
DumpHeapVisitArena,
|
||||
DumpHeapVisitCell);
|
||||
IterateHeapUnbarriered(cx, &dtrc,
|
||||
DumpHeapVisitZone,
|
||||
DumpHeapVisitCompartment,
|
||||
DumpHeapVisitArena,
|
||||
DumpHeapVisitCell);
|
||||
|
||||
fflush(dtrc.output);
|
||||
}
|
||||
|
@ -1018,24 +1018,27 @@ typedef void (*IterateCellCallback)(JSRuntime* rt, void* data, void* thing,
|
||||
* This function calls |zoneCallback| on every zone, |compartmentCallback| on
|
||||
* every compartment, |arenaCallback| on every in-use arena, and |cellCallback|
|
||||
* on every in-use cell in the GC heap.
|
||||
*
|
||||
* Note that no read barrier is triggered on the cells passed to cellCallback,
|
||||
* so no these pointers must not escape the callback.
|
||||
*/
|
||||
extern void
|
||||
IterateZonesCompartmentsArenasCells(JSContext* cx, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback);
|
||||
IterateHeapUnbarriered(JSContext* cx, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback);
|
||||
|
||||
/*
|
||||
* This function is like IterateZonesCompartmentsArenasCells, but does it for a
|
||||
* single zone.
|
||||
*/
|
||||
extern void
|
||||
IterateZoneCompartmentsArenasCells(JSContext* cx, Zone* zone, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback);
|
||||
IterateHeapUnbarrieredForZone(JSContext* cx, Zone* zone, void* data,
|
||||
IterateZoneCallback zoneCallback,
|
||||
JSIterateCompartmentCallback compartmentCallback,
|
||||
IterateArenaCallback arenaCallback,
|
||||
IterateCellCallback cellCallback);
|
||||
|
||||
/*
|
||||
* Invoke chunkCallback on every in-use chunk.
|
||||
|
@ -154,8 +154,6 @@ class ArenaCellIterImpl
|
||||
void init(Arena* arena, CellIterNeedsBarrier mayNeedBarrier) {
|
||||
MOZ_ASSERT(!initialized);
|
||||
MOZ_ASSERT(arena);
|
||||
MOZ_ASSERT_IF(!mayNeedBarrier,
|
||||
CurrentThreadIsPerformingGC() || CurrentThreadIsGCSweeping());
|
||||
initialized = true;
|
||||
AllocKind kind = arena->getAllocKind();
|
||||
firstThingOffset = Arena::firstThingOffset(kind);
|
||||
@ -243,6 +241,14 @@ class ArenaCellIterUnderFinalize : public ArenaCellIterImpl
|
||||
}
|
||||
};
|
||||
|
||||
class ArenaCellIterUnbarriered : public ArenaCellIterImpl
|
||||
{
|
||||
public:
|
||||
explicit ArenaCellIterUnbarriered(Arena* arena)
|
||||
: ArenaCellIterImpl(arena, CellIterDoesntNeedBarrier)
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ZoneCellIter;
|
||||
|
||||
|
@ -760,11 +760,11 @@ CollectRuntimeStatsHelper(JSContext* cx, RuntimeStats* rtStats, ObjectPrivateVis
|
||||
StatsClosure closure(rtStats, opv, anonymize);
|
||||
if (!closure.init())
|
||||
return false;
|
||||
IterateZonesCompartmentsArenasCells(cx, &closure,
|
||||
StatsZoneCallback,
|
||||
StatsCompartmentCallback,
|
||||
StatsArenaCallback,
|
||||
statsCellCallback);
|
||||
IterateHeapUnbarriered(cx, &closure,
|
||||
StatsZoneCallback,
|
||||
StatsCompartmentCallback,
|
||||
StatsArenaCallback,
|
||||
statsCellCallback);
|
||||
|
||||
// Take the "explicit/js/runtime/" measurements.
|
||||
rt->addSizeOfIncludingThis(rtStats->mallocSizeOf_, &rtStats->runtime);
|
||||
@ -906,11 +906,11 @@ AddSizeOfTab(JSContext* cx, HandleObject obj, MallocSizeOf mallocSizeOf, ObjectP
|
||||
StatsClosure closure(&rtStats, opv, /* anonymize = */ false);
|
||||
if (!closure.init())
|
||||
return false;
|
||||
IterateZoneCompartmentsArenasCells(cx, zone, &closure,
|
||||
StatsZoneCallback,
|
||||
StatsCompartmentCallback,
|
||||
StatsArenaCallback,
|
||||
StatsCellCallback<CoarseGrained>);
|
||||
IterateHeapUnbarrieredForZone(cx, zone, &closure,
|
||||
StatsZoneCallback,
|
||||
StatsCompartmentCallback,
|
||||
StatsArenaCallback,
|
||||
StatsCellCallback<CoarseGrained>);
|
||||
|
||||
MOZ_ASSERT(rtStats.zoneStatsVector.length() == 1);
|
||||
rtStats.zTotals.addSizes(rtStats.zoneStatsVector[0]);
|
||||
|
Loading…
Reference in New Issue
Block a user