mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 650161 - Add new stats phases for compacting GC r=terrence
This commit is contained in:
parent
5ae930f7bd
commit
64e065fab8
@ -499,10 +499,10 @@ class GCRuntime
|
||||
bool drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase);
|
||||
template <class CompartmentIterT> void markWeakReferences(gcstats::Phase phase);
|
||||
void markWeakReferencesInCurrentGroup(gcstats::Phase phase);
|
||||
template <class ZoneIterT, class CompartmentIterT> void markGrayReferences();
|
||||
void markGrayReferencesInCurrentGroup();
|
||||
template <class ZoneIterT, class CompartmentIterT> void markGrayReferences(gcstats::Phase phase);
|
||||
void markGrayReferencesInCurrentGroup(gcstats::Phase phase);
|
||||
void markAllWeakReferences(gcstats::Phase phase);
|
||||
void markAllGrayReferences();
|
||||
void markAllGrayReferences(gcstats::Phase phase);
|
||||
|
||||
void beginSweepPhase(bool lastGC);
|
||||
void findZoneGroups();
|
||||
@ -523,6 +523,7 @@ class GCRuntime
|
||||
bool shouldCompact();
|
||||
#ifdef JSGC_COMPACTING
|
||||
void compactPhase();
|
||||
ArenaHeader *relocateArenas();
|
||||
void updatePointersToRelocatedCells();
|
||||
void releaseRelocatedArenas(ArenaHeader *relocatedList);
|
||||
#endif
|
||||
|
@ -307,6 +307,10 @@ static const PhaseInfo phases[] = {
|
||||
{ PHASE_SWEEP_SCRIPT, "Sweep Script", PHASE_SWEEP },
|
||||
{ PHASE_SWEEP_SHAPE, "Sweep Shape", PHASE_SWEEP },
|
||||
{ PHASE_SWEEP_JITCODE, "Sweep JIT code", PHASE_SWEEP },
|
||||
{ PHASE_COMPACT, "Compact", PHASE_NO_PARENT },
|
||||
{ PHASE_COMPACT_MOVE, "Compact Move", PHASE_COMPACT },
|
||||
{ PHASE_COMPACT_UPDATE, "Compact Update", PHASE_COMPACT, },
|
||||
{ PHASE_COMPACT_UPDATE_GRAY, "Compact Update Gray", PHASE_COMPACT_UPDATE, },
|
||||
{ PHASE_FINALIZE_END, "Finalize End Callback", PHASE_SWEEP },
|
||||
{ PHASE_DESTROY, "Deallocate", PHASE_SWEEP },
|
||||
{ PHASE_GC_END, "End Callback", PHASE_NO_PARENT },
|
||||
|
@ -58,6 +58,10 @@ enum Phase {
|
||||
PHASE_SWEEP_SCRIPT,
|
||||
PHASE_SWEEP_SHAPE,
|
||||
PHASE_SWEEP_JITCODE,
|
||||
PHASE_COMPACT,
|
||||
PHASE_COMPACT_MOVE,
|
||||
PHASE_COMPACT_UPDATE,
|
||||
PHASE_COMPACT_UPDATE_GRAY,
|
||||
PHASE_FINALIZE_END,
|
||||
PHASE_DESTROY,
|
||||
PHASE_GC_END,
|
||||
@ -227,17 +231,16 @@ struct AutoPhase
|
||||
|
||||
struct MaybeAutoPhase
|
||||
{
|
||||
explicit MaybeAutoPhase(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
explicit MaybeAutoPhase(Statistics &statsArg, bool condition, Phase phaseArg
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: stats(nullptr)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
void construct(Statistics &statsArg, Phase phaseArg)
|
||||
{
|
||||
JS_ASSERT(!stats);
|
||||
stats = &statsArg;
|
||||
phase = phaseArg;
|
||||
stats->beginPhase(phase);
|
||||
if (condition) {
|
||||
stats = &statsArg;
|
||||
phase = phaseArg;
|
||||
stats->beginPhase(phase);
|
||||
}
|
||||
}
|
||||
~MaybeAutoPhase() {
|
||||
if (stats)
|
||||
|
@ -554,9 +554,8 @@ GCMarker::markDelayedChildren(ArenaHeader *aheader)
|
||||
bool
|
||||
GCMarker::markDelayedChildren(SliceBudget &budget)
|
||||
{
|
||||
gcstats::MaybeAutoPhase ap;
|
||||
if (runtime()->gc.state() == MARK)
|
||||
ap.construct(runtime()->gc.stats, gcstats::PHASE_MARK_DELAYED);
|
||||
GCRuntime &gc = runtime()->gc;
|
||||
gcstats::MaybeAutoPhase ap(gc.stats, gc.state() == MARK, gcstats::PHASE_MARK_DELAYED);
|
||||
|
||||
JS_ASSERT(unmarkedArenaStackTop);
|
||||
do {
|
||||
|
@ -113,13 +113,21 @@ Zone::sweep(FreeOp *fop, bool releaseTypes, bool *oom)
|
||||
if (active)
|
||||
releaseTypes = false;
|
||||
|
||||
GCRuntime &gc = fop->runtime()->gc;
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap(fop->runtime()->gc.stats, gcstats::PHASE_DISCARD_ANALYSIS);
|
||||
gcstats::MaybeAutoPhase ap(gc.stats, !gc.isHeapCompacting(),
|
||||
gcstats::PHASE_DISCARD_ANALYSIS);
|
||||
types.sweep(fop, releaseTypes, oom);
|
||||
}
|
||||
|
||||
if (!fop->runtime()->debuggerList.isEmpty())
|
||||
if (!fop->runtime()->debuggerList.isEmpty()) {
|
||||
gcstats::MaybeAutoPhase ap1(gc.stats, !gc.isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TABLES);
|
||||
gcstats::MaybeAutoPhase ap2(gc.stats, !gc.isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TABLES_BREAKPOINT);
|
||||
sweepBreakpoints(fop);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -130,9 +138,6 @@ Zone::sweepBreakpoints(FreeOp *fop)
|
||||
* to iterate over the scripts belonging to a single compartment in a zone.
|
||||
*/
|
||||
|
||||
gcstats::AutoPhase ap1(fop->runtime()->gc.stats, gcstats::PHASE_SWEEP_TABLES);
|
||||
gcstats::AutoPhase ap2(fop->runtime()->gc.stats, gcstats::PHASE_SWEEP_TABLES_BREAKPOINT);
|
||||
|
||||
JS_ASSERT(isGCSweepingOrCompacting());
|
||||
for (ZoneCellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
|
@ -572,54 +572,53 @@ void
|
||||
JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
|
||||
{
|
||||
JS_ASSERT(!activeAnalysis);
|
||||
|
||||
/* This function includes itself in PHASE_SWEEP_TABLES. */
|
||||
sweepCrossCompartmentWrappers();
|
||||
|
||||
JSRuntime *rt = runtimeFromMainThread();
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_SWEEP_TABLES);
|
||||
|
||||
/* Remove dead references held weakly by the compartment. */
|
||||
|
||||
sweepBaseShapeTable();
|
||||
sweepInitialShapeTable();
|
||||
{
|
||||
gcstats::AutoPhase ap(runtimeFromMainThread()->gc.stats,
|
||||
gcstats::PHASE_SWEEP_TABLES_TYPE_OBJECT);
|
||||
sweepNewTypeObjectTable(newTypeObjects);
|
||||
sweepNewTypeObjectTable(lazyTypeObjects);
|
||||
}
|
||||
sweepCallsiteClones();
|
||||
savedStacks_.sweep(rt);
|
||||
|
||||
if (global_ && IsObjectAboutToBeFinalized(global_.unsafeGet()))
|
||||
global_.set(nullptr);
|
||||
|
||||
if (selfHostingScriptSource &&
|
||||
IsObjectAboutToBeFinalized((JSObject **) selfHostingScriptSource.unsafeGet()))
|
||||
{
|
||||
selfHostingScriptSource.set(nullptr);
|
||||
}
|
||||
|
||||
if (jitCompartment_)
|
||||
jitCompartment_->sweep(fop, this);
|
||||
|
||||
/*
|
||||
* JIT code increments activeUseCount for any RegExpShared used by jit
|
||||
* code for the lifetime of the JIT script. Thus, we must perform
|
||||
* sweeping after clearing jit code.
|
||||
*/
|
||||
regExps.sweep(rt);
|
||||
|
||||
if (debugScopes)
|
||||
debugScopes->sweep(rt);
|
||||
|
||||
/* Finalize unreachable (key,value) pairs in all weak maps. */
|
||||
WeakMapBase::sweepCompartment(this);
|
||||
gcstats::MaybeAutoPhase ap(rt->gc.stats, !rt->isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TABLES_WRAPPER);
|
||||
sweepCrossCompartmentWrappers();
|
||||
}
|
||||
|
||||
/* Remove dead references held weakly by the compartment. */
|
||||
|
||||
sweepBaseShapeTable();
|
||||
sweepInitialShapeTable();
|
||||
{
|
||||
gcstats::MaybeAutoPhase ap(rt->gc.stats, !rt->isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TABLES_TYPE_OBJECT);
|
||||
sweepNewTypeObjectTable(newTypeObjects);
|
||||
sweepNewTypeObjectTable(lazyTypeObjects);
|
||||
}
|
||||
sweepCallsiteClones();
|
||||
savedStacks_.sweep(rt);
|
||||
|
||||
if (global_ && IsObjectAboutToBeFinalized(global_.unsafeGet()))
|
||||
global_.set(nullptr);
|
||||
|
||||
if (selfHostingScriptSource &&
|
||||
IsObjectAboutToBeFinalized((JSObject **) selfHostingScriptSource.unsafeGet()))
|
||||
{
|
||||
selfHostingScriptSource.set(nullptr);
|
||||
}
|
||||
|
||||
if (jitCompartment_)
|
||||
jitCompartment_->sweep(fop, this);
|
||||
|
||||
/*
|
||||
* JIT code increments activeUseCount for any RegExpShared used by jit
|
||||
* code for the lifetime of the JIT script. Thus, we must perform
|
||||
* sweeping after clearing jit code.
|
||||
*/
|
||||
regExps.sweep(rt);
|
||||
|
||||
if (debugScopes)
|
||||
debugScopes->sweep(rt);
|
||||
|
||||
/* Finalize unreachable (key,value) pairs in all weak maps. */
|
||||
WeakMapBase::sweepCompartment(this);
|
||||
|
||||
/* Sweep list of native iterators. */
|
||||
NativeIterator *ni = enumerators->next();
|
||||
while (ni != enumerators) {
|
||||
JSObject *iterObj = ni->iterObj();
|
||||
@ -638,11 +637,6 @@ JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
|
||||
void
|
||||
JSCompartment::sweepCrossCompartmentWrappers()
|
||||
{
|
||||
JSRuntime *rt = runtimeFromMainThread();
|
||||
|
||||
gcstats::AutoPhase ap1(rt->gc.stats, gcstats::PHASE_SWEEP_TABLES);
|
||||
gcstats::AutoPhase ap2(rt->gc.stats, gcstats::PHASE_SWEEP_TABLES_WRAPPER);
|
||||
|
||||
/* Remove dead wrappers from the table. */
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
CrossCompartmentKey key = e.front().key();
|
||||
|
176
js/src/jsgc.cpp
176
js/src/jsgc.cpp
@ -2220,6 +2220,26 @@ ArenaLists::relocateArenas(ArenaHeader *relocatedList)
|
||||
return relocatedList;
|
||||
}
|
||||
|
||||
ArenaHeader *
|
||||
GCRuntime::relocateArenas()
|
||||
{
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT_MOVE);
|
||||
|
||||
ArenaHeader *relocatedList = nullptr;
|
||||
for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
|
||||
JS_ASSERT(zone->isGCFinished());
|
||||
JS_ASSERT(!zone->isPreservingCode());
|
||||
|
||||
// We cannot move atoms as we depend on their addresses being constant.
|
||||
if (!rt->isAtomsZone(zone)) {
|
||||
zone->setGCState(Zone::Compact);
|
||||
relocatedList = zone->allocator.arenas.relocateArenas(relocatedList);
|
||||
}
|
||||
}
|
||||
|
||||
return relocatedList;
|
||||
}
|
||||
|
||||
struct MovingTracer : JSTracer {
|
||||
MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapValues) {}
|
||||
|
||||
@ -2254,8 +2274,6 @@ MovingTracer::Sweep(JSTracer *jstrc)
|
||||
|
||||
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
|
||||
if (zone->isCollecting()) {
|
||||
gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_SWEEP_COMPARTMENTS);
|
||||
|
||||
bool oom = false;
|
||||
zone->sweep(fop, false, &oom);
|
||||
JS_ASSERT(!oom);
|
||||
@ -2301,60 +2319,54 @@ void
|
||||
GCRuntime::updatePointersToRelocatedCells()
|
||||
{
|
||||
JS_ASSERT(rt->currentThreadHasExclusiveAccess());
|
||||
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT_UPDATE);
|
||||
MovingTracer trc(rt);
|
||||
|
||||
{
|
||||
// TODO: Maybe give compaction its own set of phases.
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_MARK);
|
||||
// TODO: We may need to fix up other weak pointers here.
|
||||
|
||||
// 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 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->fixupCrossCompartmentWrappers(&trc);
|
||||
|
||||
// Fixup cross compartment wrappers as we assert the existence of wrappers in the map.
|
||||
for (CompartmentsIter comp(rt, SkipAtoms); !comp.done(); comp.next())
|
||||
comp->fixupCrossCompartmentWrappers(&trc);
|
||||
// Fixup generators as these are not normally traced.
|
||||
for (ContextIter i(rt); !i.done(); i.next()) {
|
||||
for (JSGenerator *gen = i.get()->innermostGenerator(); gen; gen = gen->prevGenerator)
|
||||
gen->obj = MaybeForwarded(gen->obj.get());
|
||||
}
|
||||
|
||||
// Fixup generators as these are not normally traced.
|
||||
for (ContextIter i(rt); !i.done(); i.next()) {
|
||||
for (JSGenerator *gen = i.get()->innermostGenerator(); gen; gen = gen->prevGenerator)
|
||||
gen->obj = MaybeForwarded(gen->obj.get());
|
||||
}
|
||||
|
||||
// Iterate through all allocated cells to update internal pointers.
|
||||
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);
|
||||
}
|
||||
// Iterate through all allocated cells to update internal pointers.
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mark roots to update them.
|
||||
markRuntime(&trc, MarkRuntime);
|
||||
Debugger::markAll(&trc);
|
||||
Debugger::markCrossCompartmentDebuggerObjectReferents(&trc);
|
||||
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (c->watchpointMap)
|
||||
c->watchpointMap->markAll(&trc);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_SWEEP);
|
||||
// Mark roots to update them.
|
||||
markRuntime(&trc, MarkRuntime);
|
||||
Debugger::markAll(&trc);
|
||||
Debugger::markCrossCompartmentDebuggerObjectReferents(&trc);
|
||||
|
||||
markAllGrayReferences();
|
||||
|
||||
MovingTracer::Sweep(&trc);
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (c->watchpointMap)
|
||||
c->watchpointMap->markAll(&trc);
|
||||
}
|
||||
|
||||
markAllGrayReferences(gcstats::PHASE_COMPACT_UPDATE_GRAY);
|
||||
markAllWeakReferences(gcstats::PHASE_COMPACT_UPDATE_GRAY);
|
||||
|
||||
MovingTracer::Sweep(&trc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3742,7 +3754,6 @@ GCRuntime::markWeakReferences(gcstats::Phase phase)
|
||||
{
|
||||
JS_ASSERT(marker.isDrained());
|
||||
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_MARK);
|
||||
gcstats::AutoPhase ap1(stats, phase);
|
||||
|
||||
for (;;) {
|
||||
@ -3770,35 +3781,25 @@ GCRuntime::markWeakReferencesInCurrentGroup(gcstats::Phase phase)
|
||||
|
||||
template <class ZoneIterT, class CompartmentIterT>
|
||||
void
|
||||
GCRuntime::markGrayReferences()
|
||||
GCRuntime::markGrayReferences(gcstats::Phase phase)
|
||||
{
|
||||
{
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_MARK);
|
||||
gcstats::AutoPhase ap1(stats, gcstats::PHASE_SWEEP_MARK_GRAY);
|
||||
marker.setMarkColorGray();
|
||||
if (marker.hasBufferedGrayRoots()) {
|
||||
for (ZoneIterT zone(rt); !zone.done(); zone.next())
|
||||
marker.markBufferedGrayRoots(zone);
|
||||
} else {
|
||||
JS_ASSERT(!isIncremental);
|
||||
if (JSTraceDataOp op = grayRootTracer.op)
|
||||
(*op)(&marker, grayRootTracer.data);
|
||||
}
|
||||
SliceBudget budget;
|
||||
marker.drainMarkStack(budget);
|
||||
gcstats::AutoPhase ap(stats, phase);
|
||||
if (marker.hasBufferedGrayRoots()) {
|
||||
for (ZoneIterT zone(rt); !zone.done(); zone.next())
|
||||
marker.markBufferedGrayRoots(zone);
|
||||
} else {
|
||||
JS_ASSERT(!isIncremental);
|
||||
if (JSTraceDataOp op = grayRootTracer.op)
|
||||
(*op)(&marker, grayRootTracer.data);
|
||||
}
|
||||
|
||||
markWeakReferences<CompartmentIterT>(gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
|
||||
|
||||
JS_ASSERT(marker.isDrained());
|
||||
|
||||
marker.setMarkColorBlack();
|
||||
SliceBudget budget;
|
||||
marker.drainMarkStack(budget);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::markGrayReferencesInCurrentGroup()
|
||||
GCRuntime::markGrayReferencesInCurrentGroup(gcstats::Phase phase)
|
||||
{
|
||||
markGrayReferences<GCZoneGroupIter, GCCompartmentGroupIter>();
|
||||
markGrayReferences<GCZoneGroupIter, GCCompartmentGroupIter>(phase);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3808,9 +3809,9 @@ GCRuntime::markAllWeakReferences(gcstats::Phase phase)
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::markAllGrayReferences()
|
||||
GCRuntime::markAllGrayReferences(gcstats::Phase phase)
|
||||
{
|
||||
markGrayReferences<GCZonesIter, GCCompartmentsIter>();
|
||||
markGrayReferences<GCZonesIter, GCCompartmentsIter>(phase);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -3931,7 +3932,8 @@ js::gc::MarkingValidator::nonIncrementalMark()
|
||||
|
||||
gc->incrementalState = SWEEP;
|
||||
{
|
||||
gcstats::AutoPhase ap(gc->stats, gcstats::PHASE_SWEEP);
|
||||
gcstats::AutoPhase ap1(gc->stats, gcstats::PHASE_SWEEP);
|
||||
gcstats::AutoPhase ap2(gc->stats, gcstats::PHASE_SWEEP_MARK);
|
||||
gc->markAllWeakReferences(gcstats::PHASE_SWEEP_MARK_WEAK);
|
||||
|
||||
/* Update zone state for gray marking. */
|
||||
@ -3939,14 +3941,18 @@ js::gc::MarkingValidator::nonIncrementalMark()
|
||||
JS_ASSERT(zone->isGCMarkingBlack());
|
||||
zone->setGCState(Zone::MarkGray);
|
||||
}
|
||||
gc->marker.setMarkColorGray();
|
||||
|
||||
gc->markAllGrayReferences();
|
||||
gc->markAllGrayReferences(gcstats::PHASE_SWEEP_MARK_GRAY);
|
||||
gc->markAllWeakReferences(gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
|
||||
|
||||
/* Restore zone state. */
|
||||
for (GCZonesIter zone(runtime); !zone.done(); zone.next()) {
|
||||
JS_ASSERT(zone->isGCMarkingGray());
|
||||
zone->setGCState(Zone::Mark);
|
||||
}
|
||||
JS_ASSERT(gc->marker.isDrained());
|
||||
gc->marker.setMarkColorBlack();
|
||||
}
|
||||
|
||||
/* Take a copy of the non-incremental mark state and restore the original. */
|
||||
@ -4347,7 +4353,6 @@ MarkIncomingCrossCompartmentPointers(JSRuntime *rt, const uint32_t color)
|
||||
{
|
||||
JS_ASSERT(color == BLACK || color == GRAY);
|
||||
|
||||
gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_SWEEP_MARK);
|
||||
static const gcstats::Phase statsPhases[] = {
|
||||
gcstats::PHASE_SWEEP_MARK_INCOMING_BLACK,
|
||||
gcstats::PHASE_SWEEP_MARK_INCOMING_GRAY
|
||||
@ -4472,6 +4477,8 @@ js::NotifyGCPostSwap(JSObject *a, JSObject *b, unsigned removedFlags)
|
||||
void
|
||||
GCRuntime::endMarkingZoneGroup()
|
||||
{
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_MARK);
|
||||
|
||||
/*
|
||||
* Mark any incoming black pointers from previously swept compartments
|
||||
* whose referents are not marked. This can occur when gray cells become
|
||||
@ -4491,22 +4498,22 @@ GCRuntime::endMarkingZoneGroup()
|
||||
JS_ASSERT(zone->isGCMarkingBlack());
|
||||
zone->setGCState(Zone::MarkGray);
|
||||
}
|
||||
marker.setMarkColorGray();
|
||||
|
||||
/* Mark incoming gray pointers from previously swept compartments. */
|
||||
marker.setMarkColorGray();
|
||||
MarkIncomingCrossCompartmentPointers(rt, GRAY);
|
||||
marker.setMarkColorBlack();
|
||||
|
||||
/* Mark gray roots and mark transitively inside the current compartment group. */
|
||||
markGrayReferencesInCurrentGroup();
|
||||
markGrayReferencesInCurrentGroup(gcstats::PHASE_SWEEP_MARK_GRAY);
|
||||
markWeakReferencesInCurrentGroup(gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
|
||||
|
||||
/* Restore marking state. */
|
||||
for (GCZoneGroupIter zone(rt); !zone.done(); zone.next()) {
|
||||
JS_ASSERT(zone->isGCMarkingGray());
|
||||
zone->setGCState(Zone::Mark);
|
||||
}
|
||||
|
||||
JS_ASSERT(marker.isDrained());
|
||||
MOZ_ASSERT(marker.isDrained());
|
||||
marker.setMarkColorBlack();
|
||||
}
|
||||
|
||||
void
|
||||
@ -4579,6 +4586,8 @@ GCRuntime::beginSweepingZoneGroup()
|
||||
|
||||
for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
|
||||
gcstats::AutoSCC scc(stats, zoneGroupIndex);
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_TABLES);
|
||||
|
||||
c->sweep(&fop, releaseObservedTypes && !c->zone()->isPreservingCode());
|
||||
}
|
||||
|
||||
@ -4940,18 +4949,9 @@ GCRuntime::compactPhase()
|
||||
JS_ASSERT(rt->gc.nursery.isEmpty());
|
||||
JS_ASSERT(!sweepOnBackgroundThread);
|
||||
|
||||
ArenaHeader *relocatedList = nullptr;
|
||||
for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
|
||||
JS_ASSERT(zone->isGCFinished());
|
||||
JS_ASSERT(!zone->isPreservingCode());
|
||||
|
||||
// We cannot move atoms as we depend on their addresses being constant.
|
||||
if (!rt->isAtomsZone(zone)) {
|
||||
zone->setGCState(Zone::Compact);
|
||||
relocatedList = zone->allocator.arenas.relocateArenas(relocatedList);
|
||||
}
|
||||
}
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT);
|
||||
|
||||
ArenaHeader *relocatedList = relocateArenas();
|
||||
updatePointersToRelocatedCells();
|
||||
releaseRelocatedArenas(relocatedList);
|
||||
|
||||
|
@ -4390,7 +4390,8 @@ TypeZone::sweep(FreeOp *fop, bool releaseTypes, bool *oom)
|
||||
}
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap2(rt->gc.stats, gcstats::PHASE_DISCARD_TI);
|
||||
gcstats::MaybeAutoPhase ap2(rt->gc.stats, !rt->isHeapCompacting(),
|
||||
gcstats::PHASE_DISCARD_TI);
|
||||
|
||||
for (ZoneCellIterUnderGC i(zone(), FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
@ -4421,7 +4422,8 @@ TypeZone::sweep(FreeOp *fop, bool releaseTypes, bool *oom)
|
||||
}
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap2(rt->gc.stats, gcstats::PHASE_SWEEP_TYPES);
|
||||
gcstats::MaybeAutoPhase ap2(rt->gc.stats, !rt->isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TYPES);
|
||||
|
||||
for (gc::ZoneCellIterUnderGC iter(zone(), gc::FINALIZE_TYPE_OBJECT);
|
||||
!iter.done(); iter.next())
|
||||
@ -4449,7 +4451,8 @@ TypeZone::sweep(FreeOp *fop, bool releaseTypes, bool *oom)
|
||||
}
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap2(rt->gc.stats, gcstats::PHASE_FREE_TI_ARENA);
|
||||
gcstats::MaybeAutoPhase ap2(rt->gc.stats, !rt->isHeapCompacting(),
|
||||
gcstats::PHASE_FREE_TI_ARENA);
|
||||
rt->freeLifoAlloc.transferFrom(&oldAlloc);
|
||||
}
|
||||
}
|
||||
|
@ -1542,8 +1542,9 @@ BaseShape::assertConsistency()
|
||||
void
|
||||
JSCompartment::sweepBaseShapeTable()
|
||||
{
|
||||
gcstats::AutoPhase ap(runtimeFromMainThread()->gc.stats,
|
||||
gcstats::PHASE_SWEEP_TABLES_BASE_SHAPE);
|
||||
GCRuntime &gc = runtimeFromMainThread()->gc;
|
||||
gcstats::MaybeAutoPhase ap(gc.stats, !gc.isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TABLES_BASE_SHAPE);
|
||||
|
||||
if (baseShapes.initialized()) {
|
||||
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
|
||||
@ -1839,8 +1840,9 @@ EmptyShape::insertInitialShape(ExclusiveContext *cx, HandleShape shape, HandleOb
|
||||
void
|
||||
JSCompartment::sweepInitialShapeTable()
|
||||
{
|
||||
gcstats::AutoPhase ap(runtimeFromMainThread()->gc.stats,
|
||||
gcstats::PHASE_SWEEP_TABLES_INITIAL_SHAPE);
|
||||
GCRuntime &gc = runtimeFromMainThread()->gc;
|
||||
gcstats::MaybeAutoPhase ap(gc.stats, !gc.isHeapCompacting(),
|
||||
gcstats::PHASE_SWEEP_TABLES_INITIAL_SHAPE);
|
||||
|
||||
if (initialShapes.initialized()) {
|
||||
for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) {
|
||||
|
Loading…
Reference in New Issue
Block a user