Bug 741378 - Rejigger the js memory reporters to match jemalloc's. r=njn
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -109,23 +109,25 @@ struct RuntimeStats
, runtimeAtomsTable(0)
, runtimeContexts(0)
, runtimeNormal(0)
, runtimeTemporary(0)
, runtimeRegexpCode(0)
, runtimeStackCommitted(0)
, runtimeGCMarker(0)
, gcHeapChunkTotal(0)
+ , gcHeapCommitted(0)
+ , gcHeapUnused(0)
, gcHeapChunkCleanUnused(0)
, gcHeapChunkDirtyUnused(0)
, gcHeapChunkCleanDecommitted(0)
, gcHeapChunkDirtyDecommitted(0)
, gcHeapArenaUnused(0)
, gcHeapChunkAdmin(0)
- , gcHeapUnusedPercentage(0)
+ , gcHeapFragmentationPercentage(0)
, totalObjects(0)
, totalShapes(0)
, totalScripts(0)
, totalStrings(0)
#ifdef JS_METHODJIT
, totalMjit(0)
#endif
, totalTypeInference(0)
@@ -139,23 +141,25 @@ struct RuntimeStats
size_t runtimeAtomsTable;
size_t runtimeContexts;
size_t runtimeNormal;
size_t runtimeTemporary;
size_t runtimeRegexpCode;
size_t runtimeStackCommitted;
size_t runtimeGCMarker;
size_t gcHeapChunkTotal;
+ size_t gcHeapCommitted;
+ size_t gcHeapUnused;
size_t gcHeapChunkCleanUnused;
size_t gcHeapChunkDirtyUnused;
size_t gcHeapChunkCleanDecommitted;
size_t gcHeapChunkDirtyDecommitted;
size_t gcHeapArenaUnused;
size_t gcHeapChunkAdmin;
- size_t gcHeapUnusedPercentage;
+ size_t gcHeapFragmentationPercentage;
size_t totalObjects;
size_t totalShapes;
size_t totalScripts;
size_t totalStrings;
#ifdef JS_METHODJIT
size_t totalMjit;
#endif
size_t totalTypeInference;
--- a/js/src/MemoryMetrics.cpp
+++ b/js/src/MemoryMetrics.cpp
@@ -269,25 +269,31 @@ CollectRuntimeStats(JSRuntime *rt, Runti
size_t numDirtyChunks = (rtStats->gcHeapChunkTotal -
rtStats->gcHeapChunkCleanUnused) /
gc::ChunkSize;
size_t perChunkAdmin =
sizeof(gc::Chunk) - (sizeof(gc::Arena) * gc::ArenasPerChunk);
rtStats->gcHeapChunkAdmin = numDirtyChunks * perChunkAdmin;
rtStats->gcHeapChunkDirtyUnused -= rtStats->gcHeapChunkAdmin;
+ rtStats->gcHeapUnused = rtStats->gcHeapChunkDirtyUnused +
+ rtStats->gcHeapChunkCleanUnused +
+ rtStats->gcHeapArenaUnused;
+
+ rtStats->gcHeapCommitted = rtStats->gcHeapChunkTotal -
+ rtStats->gcHeapChunkCleanDecommitted -
+ rtStats->gcHeapChunkDirtyDecommitted;
+
// Why 10000x? 100x because it's a percentage, and another 100x
// because nsIMemoryReporter requires that for percentage amounts so
// they can be fractional.
- rtStats->gcHeapUnusedPercentage = (rtStats->gcHeapChunkCleanUnused +
- rtStats->gcHeapChunkDirtyUnused +
- rtStats->gcHeapChunkCleanDecommitted +
- rtStats->gcHeapChunkDirtyDecommitted +
- rtStats->gcHeapArenaUnused) * 10000 /
- rtStats->gcHeapChunkTotal;
+ rtStats->gcHeapFragmentationPercentage = (rtStats->gcHeapChunkCleanUnused +
+ rtStats->gcHeapChunkDirtyUnused +
+ rtStats->gcHeapArenaUnused) * 10000 /
+ rtStats->gcHeapCommitted;
return true;
}
static void
ExplicitNonHeapCompartmentCallback(JSRuntime *rt, void *data, JSCompartment *compartment)
{
#ifdef JS_METHODJIT
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1245,34 +1245,16 @@ GetCompartmentName(JSCompartment *c, boo
// treated as path separators. Users of the reporters
// (such as about:memory) have to undo this change.
name.ReplaceChar('/', '\\');
} else {
name.AssignLiteral("null-principal");
}
}
-// We have per-compartment GC heap totals, so we can't put the total GC heap
-// size in the explicit allocations tree. But it's a useful figure, so put it
-// in the "others" list.
-
-static PRInt64
-GetGCChunkTotalBytes()
-{
- JSRuntime *rt = nsXPConnect::GetRuntimeInstance()->GetJSRuntime();
- return PRInt64(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) * js::gc::ChunkSize;
-}
-
-NS_MEMORY_REPORTER_IMPLEMENT(XPConnectJSGCHeap,
- "js-gc-heap",
- KIND_OTHER,
- nsIMemoryReporter::UNITS_BYTES,
- GetGCChunkTotalBytes,
- "Memory used by the garbage-collected JavaScript heap.")
-
static PRInt64
GetJSSystemCompartmentCount()
{
return JS::SystemCompartmentCount(nsXPConnect::GetRuntimeInstance()->GetJSRuntime());
}
static PRInt64
GetJSUserCompartmentCount()
@@ -1385,17 +1367,17 @@ ReportCompartmentStats(const JS::Compart
nsISupports *closure, size_t *gcTotalOut)
{
size_t gcTotal = 0;
REPORT_GC_BYTES0(MakePath(pathPrefix, cStats, "gc-heap/arena/headers"),
cStats.gcHeapArenaHeaders,
"Memory on the compartment's garbage-collected JavaScript "
"heap, within arenas, that is used to hold internal "
- "book-keeping information.");
+ "bookkeeping information.");
REPORT_GC_BYTES0(MakePath(pathPrefix, cStats, "gc-heap/arena/padding"),
cStats.gcHeapArenaPadding,
"Memory on the compartment's garbage-collected JavaScript "
"heap, within arenas, that is unused and present only so "
"that other data is aligned. This constitutes internal "
"fragmentation.");
@@ -1623,17 +1605,17 @@ ReportJSRuntimeExplicitTreeStats(const J
REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap-decommitted"),
rtStats.gcHeapChunkCleanDecommitted + rtStats.gcHeapChunkDirtyDecommitted,
"Memory in the address space of the garbage-collected "
"JavaScript heap that is currently returned to the OS.");
REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap-chunk-admin"),
rtStats.gcHeapChunkAdmin,
"Memory on the garbage-collected JavaScript heap, within "
- "chunks, that is used to hold internal book-keeping "
+ "chunks, that is used to hold internal bookkeeping "
"information.");
// gcTotal is the sum of everything we've reported for the GC heap. It
// should equal rtStats.gcHeapChunkTotal.
JS_ASSERT(gcTotal == rtStats.gcHeapChunkTotal);
return NS_OK;
}
@@ -1774,39 +1756,58 @@ public:
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-chunk-clean-unused"),
nsIMemoryReporter::KIND_OTHER,
rtStats.gcHeapChunkCleanUnused,
"The same as 'explicit/js/gc-heap-chunk-clean-unused'. "
"Shown here for easy comparison with other 'js-gc' "
"reporters.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-decommitted"),
- nsIMemoryReporter::KIND_OTHER,
- rtStats.gcHeapChunkCleanDecommitted + rtStats.gcHeapChunkDirtyDecommitted,
- "The same as 'explicit/js/gc-heap-decommitted'. Shown "
- "here for easy comparison with other 'js-gc' reporters.");
-
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-arena-unused"),
nsIMemoryReporter::KIND_OTHER,
rtStats.gcHeapArenaUnused,
"Memory on the main JSRuntime's garbage-collected "
"JavaScript heap, within arenas, that could be holding "
"useful data but currently isn't. This is the sum of all "
"compartments' 'gc-heap/arena-unused' numbers.");
- REPORT(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-unused-fraction"),
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-unused"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.gcHeapUnused,
+ "Amount of the GC heap that's committed, but that is "
+ "neither part of an active allocation nor being used for "
+ "bookkeeping. Equal to 'gc-heap-chunk-dirty-unused' + "
+ "'gc-heap-chunk-clean-unused' + 'gc-heap-arena-unused'.");
+
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.gcHeapCommitted,
+ "Committed memory (i.e., in physical memory or swap) "
+ "used by the garbage-collected JavaScript heap.");
+
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-allocated"),
+ nsIMemoryReporter::KIND_OTHER,
+ (rtStats.gcHeapCommitted - rtStats.gcHeapUnused),
+ "Amount of the GC heap used for active allocations and "
+ "bookkeeping. This is calculated as 'gc-heap-committed' "
+ "- 'gc-heap-unused'.");
+
+ REPORT(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-fragmentation"),
nsIMemoryReporter::KIND_OTHER,
nsIMemoryReporter::UNITS_PERCENTAGE,
- rtStats.gcHeapUnusedPercentage,
- "Fraction of the main JSRuntime's garbage-collected JavaScript "
- "heap that is unused. Computed as "
- "('js-gc-heap-chunk-clean-unused' + "
- "'js-gc-heap-chunk-dirty-unused' + 'js-gc-heap-decommitted' + "
- "'js-gc-heap-arena-unused') / 'js-gc-heap'.");
+ rtStats.gcHeapFragmentationPercentage,
+ "Fraction of the committed part of the main JSRuntime's "
+ "garbage-collected heap that is unused. Computed as "
+ "'gc-heap-unused' / 'gc-heap-committed'.");
+
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-decommitted"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.gcHeapChunkCleanDecommitted + rtStats.gcHeapChunkDirtyDecommitted,
+ "The same as 'explicit/js/gc-heap-decommitted'. Shown "
+ "here for easy comparison with other 'js-gc' reporters.");
REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-objects"),
nsIMemoryReporter::KIND_OTHER, rtStats.totalObjects,
"Memory used for all object-related data in the main "
"JSRuntime. This is the sum of all compartments' "
"'gc-heap/objects-non-function', "
"'gc-heap/objects-function' and 'object-slots' numbers.");
@@ -2003,17 +2004,16 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect*
xpc::WrapperFactory::PrepareForWrapping);
js::SetPreserveWrapperCallback(mJSRuntime, PreserveWrapper);
#ifdef MOZ_CRASHREPORTER
JS_EnumerateDiagnosticMemoryRegions(DiagnosticMemoryCallback);
#endif
JS_SetAccumulateTelemetryCallback(mJSRuntime, AccumulateTelemetryCallback);
js::SetActivityCallback(mJSRuntime, ActivityCallback, this);
- NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(XPConnectJSGCHeap));
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(XPConnectJSSystemCompartmentCount));
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(XPConnectJSUserCompartmentCount));
NS_RegisterMemoryMultiReporter(new JSMemoryMultiReporter);
NS_RegisterMemoryMultiReporter(new JSCompartmentsMultiReporter);
if (!JS_DHashTableInit(&mJSHolders, JS_DHashGetStubOps(), nsnull,
sizeof(ObjectHolder), 512))
mJSHolders.ops = nsnull;