Bug 1574986 - Report count of GC slices r=jonco

Depends on D42534

Differential Revision: https://phabricator.services.mozilla.com/D42535

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Steve Fink 2019-08-21 10:16:26 +00:00
parent 13aaea78f8
commit 8f11df0a9b
3 changed files with 33 additions and 13 deletions

View File

@ -8,6 +8,7 @@ var delays = new Array(numSamples);
var gcs = new Array(numSamples);
var minorGCs = new Array(numSamples);
var majorGCs = new Array(numSamples);
var slices = new Array(numSamples);
var gcBytes = new Array(numSamples);
var mallocBytes = new Array(numSamples);
var sampleIndex = 0;
@ -167,20 +168,15 @@ LatencyGraph.prototype.draw = function () {
ctx.strokeStyle = stroke.gcslice;
var idx = sampleIndex % numSamples;
const count = {major: majorGCs[idx], minor: 0, any: gcs[idx]};
const count = {
major: majorGCs[idx],
minor: 0,
slice: slices[idx]
};
for (var i = 0; i < numSamples; i++) {
// A minor GC bumps count.minor and count.any. A major GC slice
// bumps count.any only (though it might run a minor GC too.) The
// first slice of a major GC bumps count.major and count.any, and
// will also do a minor GC and so ends up bumping count.minor as
// well.
//
// So there's no way to distinguish a minor GC from a major GC
// slice that also runs a minor GC! Both bump count.any and
// count.minor and not count.major.
idx = (sampleIndex + i) % numSamples;
const isMajorStart = count.major < majorGCs[idx];
if (count.any < gcs[idx]) {
if (count.slice < slices[idx]) {
if (isMajorStart) ctx.strokeStyle = stroke.initialMajor;
ctx.beginPath();
ctx.moveTo(this.xpos(idx), 0);
@ -188,8 +184,8 @@ LatencyGraph.prototype.draw = function () {
ctx.stroke();
if (isMajorStart) ctx.strokeStyle = stroke.gcslice;
}
count.any = gcs[idx];
count.major = majorGCs[idx];
count.slice = slices[idx];
}
ctx.strokeStyle = stroke.minor;
@ -368,6 +364,14 @@ function handler(timestamp)
gcs[idx] = performance.mozMemory.gcNumber;
minorGCs[idx] = performance.mozMemory.minorGCCount;
majorGCs[idx] = performance.mozMemory.majorGCCount;
// Previous versions lacking sliceCount will fall back to assuming
// any GC activity was a major GC slice, even though that
// incorrectly includes minor GCs. Although this file is versioned
// with the code that implements the new sliceCount field, it is
// common to load the gc-ubench index.html with different browser
// versions.
slices[idx] = performance.mozMemory.sliceCount || performance.mozMemory.gcNumber;
}
}

View File

@ -986,6 +986,7 @@ GCRuntime::GCRuntime(JSRuntime* rt)
minorGCNumber(0),
majorGCNumber(0),
number(0),
sliceNumber(0),
isFull(false),
incrementalState(gc::State::NotActive),
initialState(gc::State::NotActive),
@ -7084,6 +7085,8 @@ void GCRuntime::incrementalSlice(SliceBudget& budget,
budget.makeUnlimited();
}
incGcSliceNumber();
switch (incrementalState) {
case State::NotActive:
incMajorGcNumber();
@ -8893,6 +8896,12 @@ static bool MinorGCCountGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
static bool GCSliceCountGetter(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setNumber(double(cx->runtime()->gc.gcSliceCount()));
return true;
}
static bool ZoneGCBytesGetter(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setNumber(double(cx->zone()->zoneSize.gcBytes()));
@ -8964,7 +8973,8 @@ JSObject* NewMemoryInfoObject(JSContext* cx) {
{"gcIsHighFrequencyMode", GCHighFreqGetter},
{"gcNumber", GCNumberGetter},
{"majorGCCount", MajorGCCountGetter},
{"minorGCCount", MinorGCCountGetter}};
{"minorGCCount", MinorGCCountGetter},
{"sliceCount", GCSliceCountGetter}};
for (auto pair : getters) {
#ifdef JS_MORE_DETERMINISTIC

View File

@ -409,6 +409,9 @@ class GCRuntime {
uint64_t majorGCCount() const { return majorGCNumber; }
void incMajorGcNumber() { ++majorGCNumber; }
uint64_t gcSliceCount() const { return sliceNumber; }
void incGcSliceNumber() { ++sliceNumber; }
int64_t defaultSliceBudgetMS() const { return defaultTimeBudgetMS_; }
bool isIncrementalGc() const { return isIncremental; }
@ -832,6 +835,9 @@ class GCRuntime {
/* Incremented on every GC slice or minor collection. */
MainThreadData<uint64_t> number;
/* Incremented on every GC slice. */
MainThreadData<uint64_t> sliceNumber;
/* Whether the currently running GC can finish in multiple slices. */
MainThreadData<bool> isIncremental;