Bug 1134255 - Add breakdown of allocated and unused GC things by kind in memory reports r=njn

This commit is contained in:
Jon Coppeard 2015-02-19 11:56:00 +00:00
parent fce9ca6683
commit 44aa408ed4
3 changed files with 154 additions and 13 deletions

View File

@ -435,12 +435,66 @@ struct RuntimeSizes
#undef FOR_EACH_SIZE
};
struct GCThingSizes
{
#define FOR_EACH_SIZE(macro) \
macro(_, _, object) \
macro(_, _, script) \
macro(_, _, lazyScript) \
macro(_, _, shape) \
macro(_, _, baseShape) \
macro(_, _, objectGroup) \
macro(_, _, string) \
macro(_, _, symbol) \
macro(_, _, jitcode) \
GCThingSizes()
: FOR_EACH_SIZE(ZERO_SIZE)
dummy()
{}
GCThingSizes(GCThingSizes &&other)
: FOR_EACH_SIZE(COPY_OTHER_SIZE)
dummy()
{}
void addToKind(JSGCTraceKind kind, intptr_t n) {
switch (kind) {
case JSTRACE_OBJECT: object += n; break;
case JSTRACE_STRING: string += n; break;
case JSTRACE_SYMBOL: symbol += n; break;
case JSTRACE_SCRIPT: script += n; break;
case JSTRACE_SHAPE: shape += n; break;
case JSTRACE_BASE_SHAPE: baseShape += n; break;
case JSTRACE_JITCODE: jitcode += n; break;
case JSTRACE_LAZY_SCRIPT: lazyScript += n; break;
case JSTRACE_OBJECT_GROUP: objectGroup += n; break;
default:
MOZ_CRASH("Bad trace kind for GCThingSizes");
}
}
void addSizes(const GCThingSizes &other) {
FOR_EACH_SIZE(ADD_OTHER_SIZE)
}
size_t totalSize() const {
size_t n = 0;
FOR_EACH_SIZE(ADD_SIZE_TO_N)
return n;
}
FOR_EACH_SIZE(DECL_SIZE)
int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
#undef FOR_EACH_SIZE
};
struct ZoneStats
{
#define FOR_EACH_SIZE(macro) \
macro(Other, IsLiveGCThing, symbolsGCHeap) \
macro(Other, NotLiveGCThing, gcHeapArenaAdmin) \
macro(Other, NotLiveGCThing, unusedGCThings) \
macro(Other, IsLiveGCThing, lazyScriptsGCHeap) \
macro(Other, NotLiveGCThing, lazyScriptsMallocHeap) \
macro(Other, IsLiveGCThing, jitCodesGCHeap) \
@ -451,6 +505,7 @@ struct ZoneStats
ZoneStats()
: FOR_EACH_SIZE(ZERO_SIZE)
unusedGCThings(),
stringInfo(),
extra(),
allStrings(nullptr),
@ -460,6 +515,7 @@ struct ZoneStats
ZoneStats(ZoneStats &&other)
: FOR_EACH_SIZE(COPY_OTHER_SIZE)
unusedGCThings(mozilla::Move(other.unusedGCThings)),
stringInfo(mozilla::Move(other.stringInfo)),
extra(other.extra),
allStrings(other.allStrings),
@ -482,6 +538,7 @@ struct ZoneStats
void addSizes(const ZoneStats &other) {
MOZ_ASSERT(isTotals);
FOR_EACH_SIZE(ADD_OTHER_SIZE)
unusedGCThings.addSizes(other.unusedGCThings);
stringInfo.add(other.stringInfo);
}
@ -496,6 +553,7 @@ struct ZoneStats
void addToTabSizes(JS::TabSizes *sizes) const {
MOZ_ASSERT(isTotals);
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
sizes->add(JS::TabSizes::Other, unusedGCThings.totalSize());
stringInfo.addToTabSizes(sizes);
}
@ -504,6 +562,7 @@ struct ZoneStats
// measurements of the notable script sources and move them into
// |notableStrings|.
FOR_EACH_SIZE(DECL_SIZE)
GCThingSizes unusedGCThings;
StringInfo stringInfo;
void *extra; // This field can be used by embedders.

View File

@ -358,7 +358,7 @@ StatsArenaCallback(JSRuntime *rt, void *data, gc::Arena *arena,
// unused space like this: arenaUnused = maxArenaUnused - arenaUsed.
// We do this by setting arenaUnused to maxArenaUnused here, and then
// subtracting thingSize for every used cell, in StatsCellCallback().
rtStats->currZoneStats->unusedGCThings += allocationSpace;
rtStats->currZoneStats->unusedGCThings.addToKind(traceKind, allocationSpace);
}
static CompartmentStats *
@ -561,7 +561,7 @@ StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKin
}
// Yes, this is a subtraction: see StatsArenaCallback() for details.
zStats->unusedGCThings -= thingSize;
zStats->unusedGCThings.addToKind(traceKind, -thingSize);
}
bool
@ -763,7 +763,7 @@ JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisit
#ifdef DEBUG
// Check that the in-arena measurements look ok.
size_t totalArenaSize = rtStats->zTotals.gcHeapArenaAdmin +
rtStats->zTotals.unusedGCThings +
rtStats->zTotals.unusedGCThings.totalSize() +
rtStats->gcHeapGCThings;
MOZ_ASSERT(totalArenaSize % gc::ArenaSize == 0);
#endif
@ -782,7 +782,7 @@ JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisit
rtStats->gcHeapUnusedArenas = rtStats->gcHeapChunkTotal -
rtStats->gcHeapDecommittedArenas -
rtStats->gcHeapUnusedChunks -
rtStats->zTotals.unusedGCThings -
rtStats->zTotals.unusedGCThings.totalSize() -
rtStats->gcHeapChunkAdmin -
rtStats->zTotals.gcHeapArenaAdmin -
rtStats->gcHeapGCThings;

View File

@ -1887,6 +1887,19 @@ NS_IMPL_ISUPPORTS(JSMainRuntimeTemporaryPeakReporter, nsIMemoryReporter)
rtTotal += amount; \
} while (0)
// Report GC thing bytes.
#define MREPORT_BYTES(_path, _kind, _amount, _desc) \
do { \
size_t amount = _amount; /* evaluate _amount only once */ \
nsresult rv; \
rv = cb->Callback(EmptyCString(), _path, \
nsIMemoryReporter::_kind, \
nsIMemoryReporter::UNITS_BYTES, amount, \
NS_LITERAL_CSTRING(_desc), closure); \
NS_ENSURE_SUCCESS(rv, rv); \
gcThingTotal += amount; \
} while (0)
MOZ_DEFINE_MALLOC_SIZE_OF(JSMallocSizeOf)
namespace xpc {
@ -1913,8 +1926,8 @@ ReportZoneStats(const JS::ZoneStats &zStats,
"Bookkeeping information and alignment padding within GC arenas.");
ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("unused-gc-things"),
zStats.unusedGCThings,
"Empty GC thing cells within non-empty arenas.");
zStats.unusedGCThings.totalSize(),
"Unused GC thing cells within non-empty arenas.");
ZCREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/gc-heap"),
zStats.lazyScriptsGCHeap,
@ -2926,9 +2939,41 @@ JSReporter::CollectReports(WindowPaths *windowPaths,
KIND_OTHER, rtStats.gcHeapUnusedArenas,
"The same as 'explicit/js-non-window/gc-heap/unused-arenas'.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things"),
KIND_OTHER, rtStats.zTotals.unusedGCThings,
"The same as 'js-main-runtime/zones/unused-gc-things'.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/objects"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.object,
"Unused object cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/strings"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.string,
"Unused string cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/symbols"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.symbol,
"Unused symbol cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/shapes"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.shape,
"Unused shape cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.baseShape,
"Unused base shape cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.objectGroup,
"Unused object group cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/scripts"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.script,
"Unused script cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.lazyScript,
"Unused lazy script cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"),
KIND_OTHER, rtStats.zTotals.unusedGCThings.jitcode,
"Unused jitcode cells within non-empty arenas.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/chunk-admin"),
KIND_OTHER, rtStats.gcHeapChunkAdmin,
@ -2938,9 +2983,46 @@ JSReporter::CollectReports(WindowPaths *windowPaths,
KIND_OTHER, rtStats.zTotals.gcHeapArenaAdmin,
"The same as 'js-main-runtime/zones/gc-heap-arena-admin'.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things"),
KIND_OTHER, rtStats.gcHeapGCThings,
"GC things: objects, strings, scripts, etc.");
size_t gcThingTotal = 0;
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/objects"),
KIND_OTHER, rtStats.cTotals.classInfo.objectsGCHeap,
"Used object cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/strings"),
KIND_OTHER, rtStats.zTotals.stringInfo.sizeOfLiveGCThings(),
"Used string cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/symbols"),
KIND_OTHER, rtStats.zTotals.symbolsGCHeap,
"Used symbol cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/shapes"),
KIND_OTHER,
rtStats.cTotals.classInfo.shapesGCHeapTree + rtStats.cTotals.classInfo.shapesGCHeapDict,
"Used shape cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"),
KIND_OTHER, rtStats.cTotals.classInfo.shapesGCHeapBase,
"Used base shape cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/object-groups"),
KIND_OTHER, rtStats.zTotals.objectGroupsGCHeap,
"Used object group cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/scripts"),
KIND_OTHER, rtStats.cTotals.scriptsGCHeap,
"Used script cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/lazy-scripts"),
KIND_OTHER, rtStats.zTotals.lazyScriptsGCHeap,
"Used lazy script cells.");
MREPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things/jitcode"),
KIND_OTHER, rtStats.zTotals.jitCodesGCHeap,
"Used jitcode cells.");
MOZ_ASSERT(gcThingTotal == rtStats.gcHeapGCThings);
// Report xpconnect.