Bug 1653914 - Add profiler GC subcategories. r=jonco

Differential Revision: https://phabricator.services.mozilla.com/D85379
This commit is contained in:
Yoshi Cheng-Hao Huang 2020-08-03 09:24:50 +00:00
parent e177990894
commit 86ab9d6661
4 changed files with 72 additions and 2 deletions

View File

@ -5567,6 +5567,8 @@ IncrementalProgress GCRuntime::markUntilBudgetExhausted(
SliceBudget& sliceBudget, GCMarker::ShouldReportMarkTime reportTime) {
// Run a marking slice and return whether the stack is now empty.
AutoMajorGCProfilerEntry s(this);
#ifdef DEBUG
AutoSetThreadIsMarking threadIsMarking;
#endif // DEBUG
@ -6152,6 +6154,7 @@ bool GCRuntime::initSweepActions() {
}
IncrementalProgress GCRuntime::performSweepActions(SliceBudget& budget) {
AutoMajorGCProfilerEntry s(this);
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP);
JSFreeOp fop(rt);
@ -6277,6 +6280,7 @@ IncrementalProgress GCRuntime::compactPhase(JS::GCReason reason,
assertBackgroundSweepingFinished();
MOZ_ASSERT(startedCompacting);
AutoMajorGCProfilerEntry s(this);
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::COMPACT);
// TODO: JSScripts can move. If the sampler interrupts the GC in the
@ -6390,6 +6394,13 @@ static const char* GCHeapStateToLabel(JS::HeapState heapState) {
return nullptr;
}
static JS::ProfilingCategoryPair GCHeapStateToProfilingCategory(
JS::HeapState heapState) {
return heapState == JS::HeapState::MinorCollecting
? JS::ProfilingCategoryPair::GCCC_MinorGC
: JS::ProfilingCategoryPair::GCCC_MajorGC;
}
/* Start a new heap session. */
AutoHeapSession::AutoHeapSession(GCRuntime* gc, JS::HeapState heapState)
: gc(gc), prevState(gc->heapState_) {
@ -6403,7 +6414,7 @@ AutoHeapSession::AutoHeapSession(GCRuntime* gc, JS::HeapState heapState)
heapState == JS::HeapState::MajorCollecting) {
profilingStackFrame.emplace(gc->rt->mainContextFromOwnThread(),
GCHeapStateToLabel(heapState),
JS::ProfilingCategoryPair::GCCC);
GCHeapStateToProfilingCategory(heapState));
}
}
@ -6412,6 +6423,42 @@ AutoHeapSession::~AutoHeapSession() {
gc->heapState_ = prevState;
}
static const char* MajorGCStateToLabel(State state) {
switch (state) {
case State::Mark:
return "js::GCRuntime::markUntilBudgetExhausted";
case State::Sweep:
return "js::GCRuntime::performSweepActions";
case State::Compact:
return "js::GCRuntime::compactPhase";
default:
MOZ_CRASH("Unexpected heap state when pushing GC profiling stack frame");
}
MOZ_ASSERT_UNREACHABLE("Should have exhausted every State variant!");
return nullptr;
}
static JS::ProfilingCategoryPair MajorGCStateToProfilingCategory(State state) {
switch (state) {
case State::Mark:
return JS::ProfilingCategoryPair::GCCC_MajorGC_Mark;
case State::Sweep:
return JS::ProfilingCategoryPair::GCCC_MajorGC_Sweep;
case State::Compact:
return JS::ProfilingCategoryPair::GCCC_MajorGC_Compact;
default:
MOZ_CRASH("Unexpected heap state when pushing GC profiling stack frame");
}
}
AutoMajorGCProfilerEntry::AutoMajorGCProfilerEntry(GCRuntime* gc)
: AutoGeckoProfilerEntry(gc->rt->mainContextFromAnyThread(),
MajorGCStateToLabel(gc->state()),
MajorGCStateToProfilingCategory(gc->state())) {
MOZ_ASSERT(gc->heapState() == JS::HeapState::MajorCollecting);
}
JS_PUBLIC_API JS::HeapState JS::RuntimeHeapState() {
return TlsContext.get()->runtime()->gc.heapState();
}
@ -8399,6 +8446,9 @@ JS_PUBLIC_API void JS::IncrementalPreWriteBarrier(JSObject* obj) {
return;
}
AutoGeckoProfilerEntry profilingStackFrame(
TlsContext.get(), "IncrementalPreWriteBarrier(JSObject*)",
JS::ProfilingCategoryPair::GCCC_Barrier);
JSObject::writeBarrierPre(obj);
}
@ -8407,6 +8457,9 @@ JS_PUBLIC_API void JS::IncrementalPreWriteBarrier(GCCellPtr thing) {
return;
}
AutoGeckoProfilerEntry profilingStackFrame(
TlsContext.get(), "IncrementalPreWriteBarrier(GCCellPtr)",
JS::ProfilingCategoryPair::GCCC_Barrier);
TenuredCell::writeBarrierPre(&thing.asCell()->asTenured());
}

View File

@ -126,6 +126,11 @@ class MOZ_RAII AutoGCSession : public AutoHeapSession {
mozilla::Maybe<AutoCheckCanAccessAtomsDuringGC> maybeCheckAtomsAccess;
};
class MOZ_RAII AutoMajorGCProfilerEntry : public AutoGeckoProfilerEntry {
public:
explicit AutoMajorGCProfilerEntry(GCRuntime* gc);
};
class MOZ_RAII AutoTraceSession : public AutoLockAllAtoms,
public AutoHeapSession {
public:

View File

@ -984,6 +984,10 @@ JS_PUBLIC_API void js::gc::PerformIncrementalReadBarrier(JS::GCCellPtr thing) {
// performing a read barrier. This means we can skip a bunch of checks and
// call info the tracer directly.
AutoGeckoProfilerEntry profilingStackFrame(
TlsContext.get(), "PerformIncrementalReadBarrier",
JS::ProfilingCategoryPair::GCCC_Barrier);
MOZ_ASSERT(thing);
MOZ_ASSERT(!JS::RuntimeHeapIsMajorCollecting());
@ -4269,7 +4273,8 @@ bool js::gc::UnmarkGrayGCThingUnchecked(JSRuntime* rt, JS::GCCellPtr thing) {
MOZ_ASSERT(thing.asCell()->isMarkedGray());
AutoGeckoProfilerEntry profilingStackFrame(
TlsContext.get(), "UnmarkGrayGCThing", JS::ProfilingCategoryPair::GCCC);
TlsContext.get(), "UnmarkGrayGCThing",
JS::ProfilingCategoryPair::GCCC_UnmarkGray);
UnmarkGrayTracer unmarker(rt);
unmarker.unmark(thing);

View File

@ -56,6 +56,13 @@
END_CATEGORY \
BEGIN_CATEGORY(GCCC, "GC / CC", "orange") \
SUBCATEGORY(GCCC, GCCC, "Other") \
SUBCATEGORY(GCCC, GCCC_MinorGC, "Minor GC") \
SUBCATEGORY(GCCC, GCCC_MajorGC, "Major GC (Other)") \
SUBCATEGORY(GCCC, GCCC_MajorGC_Mark, "Major GC (Mark)") \
SUBCATEGORY(GCCC, GCCC_MajorGC_Sweep, "Major GC (Sweep)") \
SUBCATEGORY(GCCC, GCCC_MajorGC_Compact, "Major GC (Compact)") \
SUBCATEGORY(GCCC, GCCC_UnmarkGray, "Unmark Gray") \
SUBCATEGORY(GCCC, GCCC_Barrier, "Barrier") \
END_CATEGORY \
BEGIN_CATEGORY(NETWORK, "Network", "lightblue") \
SUBCATEGORY(NETWORK, NETWORK, "Other") \