mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
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:
parent
13aaea78f8
commit
8f11df0a9b
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user