Bug 790338 - Update GC stats with time spent marking in the sweep phase and add more detail to sweep tables phase r=billm

--HG--
extra : rebase_source : 1e05d780ec815320985e031250e378a38ce8ab36
This commit is contained in:
Jon Coppeard 2012-10-24 13:08:09 -07:00
parent be07e20611
commit 4198468b8f
6 changed files with 91 additions and 59 deletions

View File

@ -280,14 +280,22 @@ static PhaseInfo phases[] = {
{ PHASE_MARK_ROOTS, "Mark Roots" },
{ PHASE_MARK_TYPES, "Mark Types" },
{ PHASE_MARK_DELAYED, "Mark Delayed" },
{ PHASE_MARK_WEAK, "Mark Weak" },
{ PHASE_MARK_GRAY, "Mark Gray" },
{ PHASE_MARK_GRAY_WEAK, "Mark Gray and Weak" },
{ PHASE_FINALIZE_START, "Finalize Start Callback" },
{ PHASE_SWEEP, "Sweep" },
{ PHASE_SWEEP_MARK_INCOMING_BLACK, "Mark Incoming Black Pointers" },
{ PHASE_SWEEP_MARK_WEAK, "Mark Weak" },
{ PHASE_SWEEP_MARK_GRAY, "Mark Gray" },
{ PHASE_SWEEP_MARK_GRAY_WEAK, "Mark Gray and Weak" },
{ PHASE_SWEEP_MARK_INCOMING_GRAY, "Mark Incoming Gray Pointers" },
{ PHASE_FINALIZE_START, "Finalize Start Callback" },
{ PHASE_SWEEP_ATOMS, "Sweep Atoms" },
{ PHASE_SWEEP_COMPARTMENTS, "Sweep Compartments" },
{ PHASE_SWEEP_TABLES, "Sweep Tables" },
{ PHASE_SWEEP_TABLES_WRAPPER, "Sweep Cross Compartment Wrappers" },
{ PHASE_SWEEP_TABLES_BASE_SHAPE, "Sweep Base Shapes" },
{ PHASE_SWEEP_TABLES_INITIAL_SHAPE, "Sweep Intital Shapes" },
{ PHASE_SWEEP_TABLES_TYPE_OBJECT, "Sweep Type Objects" },
{ PHASE_SWEEP_TABLES_BREAKPOINT, "Sweep Breakpoints" },
{ PHASE_SWEEP_TABLES_REGEXP, "Sweep Regexps" },
{ PHASE_SWEEP_OBJECT, "Sweep Object" },
{ PHASE_SWEEP_STRING, "Sweep String" },
{ PHASE_SWEEP_SCRIPT, "Sweep Script" },
@ -536,7 +544,7 @@ Statistics::endGC()
(*cb)(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK]));
(*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP]));
(*cb)(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(phaseTimes[PHASE_MARK_ROOTS]));
(*cb)(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_MARK_GRAY]));
(*cb)(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_SWEEP_MARK_GRAY]));
(*cb)(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason);
(*cb)(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gcIncrementalEnabled);
(*cb)(JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, t(sccTotal));

View File

@ -28,14 +28,23 @@ enum Phase {
PHASE_MARK_ROOTS,
PHASE_MARK_TYPES,
PHASE_MARK_DELAYED,
PHASE_MARK_WEAK,
PHASE_MARK_GRAY,
PHASE_MARK_GRAY_WEAK,
PHASE_FINALIZE_START,
PHASE_SWEEP,
PHASE_SWEEP_MARK_INCOMING_BLACK,
PHASE_SWEEP_MARK_WEAK,
PHASE_SWEEP_MARK_INCOMING_GRAY,
PHASE_SWEEP_MARK_GRAY,
PHASE_SWEEP_MARK_GRAY_WEAK,
PHASE_SWEEP_FIND_BLACK_GRAY,
PHASE_SWEEP_ATOMS,
PHASE_SWEEP_COMPARTMENTS,
PHASE_SWEEP_TABLES,
PHASE_SWEEP_TABLES_WRAPPER,
PHASE_SWEEP_TABLES_BASE_SHAPE,
PHASE_SWEEP_TABLES_INITIAL_SHAPE,
PHASE_SWEEP_TABLES_TYPE_OBJECT,
PHASE_SWEEP_TABLES_BREAKPOINT,
PHASE_SWEEP_TABLES_REGEXP,
PHASE_SWEEP_OBJECT,
PHASE_SWEEP_STRING,
PHASE_SWEEP_SCRIPT,

View File

@ -687,7 +687,8 @@ JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
void
JSCompartment::sweepCrossCompartmentWrappers()
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_TABLES);
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_SWEEP_TABLES);
gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_WRAPPER);
/* Remove dead wrappers from the table. */
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
@ -888,6 +889,8 @@ JSCompartment::clearTraps(FreeOp *fop)
void
JSCompartment::sweepBreakpoints(FreeOp *fop)
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_BREAKPOINT);
if (JS_CLIST_IS_EMPTY(&rt->debuggerList))
return;

View File

@ -3465,7 +3465,7 @@ BeginMarkPhase(JSRuntime *rt)
}
void
MarkWeakReferences(JSRuntime *rt, gcstats::Phase phase = gcstats::PHASE_MARK_WEAK)
MarkWeakReferences(JSRuntime *rt, gcstats::Phase phase)
{
GCMarker *gcmarker = &rt->gcMarker;
JS_ASSERT(gcmarker->isDrained());
@ -3488,7 +3488,7 @@ MarkGrayReferences(JSRuntime *rt)
GCMarker *gcmarker = &rt->gcMarker;
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK_GRAY);
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_MARK_GRAY);
gcmarker->setMarkColorGray();
if (gcmarker->hasBufferedGrayRoots()) {
gcmarker->markBufferedGrayRoots();
@ -3500,7 +3500,7 @@ MarkGrayReferences(JSRuntime *rt)
gcmarker->drainMarkStack(budget);
}
MarkWeakReferences(rt, gcstats::PHASE_MARK_GRAY_WEAK);
MarkWeakReferences(rt, gcstats::PHASE_SWEEP_MARK_GRAY_WEAK);
JS_ASSERT(gcmarker->isDrained());
@ -3563,7 +3563,7 @@ ValidateIncrementalMarking(JSRuntime *rt)
SliceBudget budget;
rt->gcIncrementalState = MARK;
rt->gcMarker.drainMarkStack(budget);
MarkWeakReferences(rt);
MarkWeakReferences(rt, gcstats::PHASE_SWEEP_MARK_WEAK);
MarkGrayReferences(rt);
/* Now verify that we have the same mark bits as before. */
@ -3791,6 +3791,12 @@ MarkIncomingCrossCompartmentPointers(JSRuntime *rt, const uint32_t color)
{
JS_ASSERT(color == BLACK || color == GRAY);
static const gcstats::Phase statsPhases[] = {
gcstats::PHASE_SWEEP_MARK_INCOMING_BLACK,
gcstats::PHASE_SWEEP_MARK_INCOMING_GRAY
};
gcstats::AutoPhase ap1(rt->gcStats, statsPhases[color]);
bool unlinkList = color == GRAY;
for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
@ -3826,9 +3832,6 @@ MarkIncomingCrossCompartmentPointers(JSRuntime *rt, const uint32_t color)
static void
EndMarkingCompartmentGroup(JSRuntime *rt)
{
{
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_MARK);
/*
* Mark any incoming black pointers from previously swept compartments
* whose referents are not marked. This can occur when gray cells become
@ -3836,7 +3839,7 @@ EndMarkingCompartmentGroup(JSRuntime *rt)
*/
MarkIncomingCrossCompartmentPointers(rt, BLACK);
MarkWeakReferences(rt);
MarkWeakReferences(rt, gcstats::PHASE_SWEEP_MARK_WEAK);
/*
* Change state of current group to MarkGray to restrict marking to this
@ -3862,7 +3865,6 @@ EndMarkingCompartmentGroup(JSRuntime *rt)
JS_ASSERT(c->isGCMarkingGray());
c->setGCState(JSCompartment::Mark);
}
}
#ifdef DEBUG
if (rt->gcIsIncremental && rt->gcValidate && rt->gcCompartmentGroupIndex == 0)
@ -3871,6 +3873,9 @@ EndMarkingCompartmentGroup(JSRuntime *rt)
JS_ASSERT(rt->gcMarker.isDrained());
{
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_SWEEP_FIND_BLACK_GRAY);
/*
* Having black->gray edges violates our promise to the cycle
* collector. This can happen if we're collecting a compartment and it has
@ -3889,6 +3894,7 @@ EndMarkingCompartmentGroup(JSRuntime *rt)
}
}
}
}
}
static void

View File

@ -6264,6 +6264,8 @@ TypeCompartment::sweepCompilerOutputs(FreeOp *fop, bool discardConstraints)
void
JSCompartment::sweepNewTypeObjectTable(TypeObjectSet &table)
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_TYPE_OBJECT);
JS_ASSERT(isGCSweeping());
if (table.initialized()) {
for (TypeObjectSet::Enum e(table); !e.empty(); e.popFront()) {

View File

@ -1146,6 +1146,8 @@ BaseShape::getUnowned(JSContext *cx, const StackBaseShape &base)
void
JSCompartment::sweepBaseShapeTable()
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_BASE_SHAPE);
if (baseShapes.initialized()) {
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
UnownedBaseShape *base = e.front();
@ -1301,6 +1303,8 @@ EmptyShape::insertInitialShape(JSContext *cx, Shape *shape, JSObject *proto)
void
JSCompartment::sweepInitialShapeTable()
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_INITIAL_SHAPE);
if (initialShapes.initialized()) {
for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) {
const InitialShapeEntry &entry = e.front();