--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1222,338 +1222,351 @@ static const size_t SUNDRIES_THRESHOLD =
#define REPORT(_path, _kind, _units, _amount, _desc) \
do { \
nsresult rv; \
rv = cb->Callback(EmptyCString(), _path, _kind, _units, _amount, \
NS_LITERAL_CSTRING(_desc), closure); \
NS_ENSURE_SUCCESS(rv, rv); \
} while (0)
-#define CREPORT(_path, _kind, _units, _amount, _desc) \
- do { \
- size_t amount = _amount; /* evaluate _amount only once */ \
- if (amount >= SUNDRIES_THRESHOLD) { \
- nsresult rv; \
- rv = cb->Callback(EmptyCString(), _path, _kind, _units, amount, \
- NS_LITERAL_CSTRING(_desc), closure); \
- NS_ENSURE_SUCCESS(rv, rv); \
- } else { \
- otherSundries += amount; \
- } \
- } while (0)
-
#define REPORT_BYTES(_path, _kind, _amount, _desc) \
REPORT(_path, _kind, nsIMemoryReporter::UNITS_BYTES, _amount, _desc);
-#define CREPORT_BYTES(_path, _kind, _amount, _desc) \
- CREPORT(_path, _kind, nsIMemoryReporter::UNITS_BYTES, _amount, _desc);
-
#define REPORT_GC_BYTES(_path, _amount, _desc) \
do { \
size_t amount = _amount; /* evaluate _amount only once */ \
nsresult rv; \
rv = cb->Callback(EmptyCString(), _path, \
nsIMemoryReporter::KIND_NONHEAP, \
nsIMemoryReporter::UNITS_BYTES, amount, \
NS_LITERAL_CSTRING(_desc), closure); \
NS_ENSURE_SUCCESS(rv, rv); \
gcTotal += amount; \
} while (0)
+// Nb: all non-GC compartment reports are currently KIND_HEAP, and this macro
+// relies on that.
+#define CREPORT_BYTES(_path, _amount, _desc) \
+ do { \
+ size_t amount = _amount; /* evaluate _amount only once */ \
+ if (amount >= SUNDRIES_THRESHOLD) { \
+ nsresult rv; \
+ rv = cb->Callback(EmptyCString(), _path, \
+ nsIMemoryReporter::KIND_HEAP, \
+ nsIMemoryReporter::UNITS_BYTES, amount, \
+ NS_LITERAL_CSTRING(_desc), closure); \
+ NS_ENSURE_SUCCESS(rv, rv); \
+ } else { \
+ otherSundries += amount; \
+ } \
+ } while (0)
+
#define CREPORT_GC_BYTES(_path, _amount, _desc) \
do { \
size_t amount = _amount; /* evaluate _amount only once */ \
if (amount >= SUNDRIES_THRESHOLD) { \
nsresult rv; \
rv = cb->Callback(EmptyCString(), _path, \
nsIMemoryReporter::KIND_NONHEAP, \
nsIMemoryReporter::UNITS_BYTES, amount, \
NS_LITERAL_CSTRING(_desc), closure); \
NS_ENSURE_SUCCESS(rv, rv); \
gcTotal += amount; \
} else { \
gcHeapSundries += amount; \
} \
} while (0)
-template <int N>
-inline const nsCString
-MakePath(const nsACString &pathPrefix, const JS::CompartmentStats &cStats,
- const char (&reporterName)[N])
-{
- const char *name = static_cast<char *>(cStats.extra);
- if (!name)
- name = "error while initializing compartment name";
- return pathPrefix + NS_LITERAL_CSTRING("compartment(") +
- nsDependentCString(name) + NS_LITERAL_CSTRING(")/") +
- nsDependentCString(reporterName);
-}
+#define RREPORT_BYTES(_path, _kind, _amount, _desc) \
+ do { \
+ size_t amount = _amount; /* evaluate _amount only once */ \
+ nsresult rv; \
+ rv = cb->Callback(EmptyCString(), _path, _kind, \
+ nsIMemoryReporter::UNITS_BYTES, amount, \
+ NS_LITERAL_CSTRING(_desc), closure); \
+ NS_ENSURE_SUCCESS(rv, rv); \
+ rtTotal += amount; \
+ } while (0)
namespace xpc {
static nsresult
ReportCompartmentStats(const JS::CompartmentStats &cStats,
const nsACString &pathPrefix,
nsIMemoryMultiReporterCallback *cb,
- nsISupports *closure, size_t *gcTotalOut)
+ nsISupports *closure, size_t *gcTotalOut = NULL)
{
size_t gcTotal = 0, gcHeapSundries = 0, otherSundries = 0;
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/arena-admin"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/arena-admin"),
cStats.gcHeapArenaAdmin,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap, within arenas, that is used (a) to hold internal "
"bookkeeping information, and (b) to provide padding to "
"align GC things.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/unused-gc-things"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/unused-gc-things"),
cStats.gcHeapUnusedGcThings,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap taken by empty GC thing slots within non-empty "
"arenas.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/objects/non-function"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/non-function"),
cStats.gcHeapObjectsNonFunction,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds non-function objects.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/objects/function"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/objects/function"),
cStats.gcHeapObjectsFunction,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds function objects.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/strings"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/strings"),
cStats.gcHeapStrings,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds string headers. String headers contain "
"various pieces of information about a string, but do not "
"contain (except in the case of very short strings) the "
"string characters; characters in longer strings are "
- "counted " "under 'gc-heap/string-chars' instead.");
+ "counted under 'gc-heap/string-chars' instead.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/scripts"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/scripts"),
cStats.gcHeapScripts,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds JSScript instances. A JSScript is "
"created for each user-defined function in a script. One "
"is also created for the top-level code in a script.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/shapes/tree"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/tree"),
cStats.gcHeapShapesTree,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds shapes that are in a property tree.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/shapes/dict"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/dict"),
cStats.gcHeapShapesDict,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds shapes that are in dictionary mode.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/shapes/base"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/shapes/base"),
cStats.gcHeapShapesBase,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that collates data common to many shapes.");
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/type-objects"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/type-objects"),
cStats.gcHeapTypeObjects,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds type inference information.");
#if JS_HAS_XML_SUPPORT
- CREPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/xml"),
+ CREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/xml"),
cStats.gcHeapXML,
- "Memory on the compartment's garbage-collected JavaScript "
+ "Memory on the garbage-collected JavaScript "
"heap that holds E4X XML objects.");
#endif
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "objects/slots"),
- nsIMemoryReporter::KIND_HEAP, cStats.objectSlots,
- "Memory allocated for the compartment's non-fixed object "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("objects/slots"),
+ cStats.objectSlots,
+ "Memory allocated for the non-fixed object "
"slot arrays, which are used to represent object properties. "
"Some objects also contain a fixed number of slots which are "
- "stored on the compartment's JavaScript heap; those slots "
+ "stored on the JavaScript heap; those slots "
"are not counted here, but in 'gc-heap/objects' instead.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "objects/elements"),
- nsIMemoryReporter::KIND_HEAP, cStats.objectElements,
- "Memory allocated for the compartment's object element "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("objects/elements"),
+ cStats.objectElements,
+ "Memory allocated for object element "
"arrays, which are used to represent indexed object "
"properties.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "objects/misc"),
- nsIMemoryReporter::KIND_HEAP, cStats.objectMisc,
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("objects/misc"),
+ cStats.objectMisc,
"Memory allocated for various small, miscellaneous "
"structures that hang off certain kinds of objects.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "string-chars"),
- nsIMemoryReporter::KIND_HEAP, cStats.stringChars,
- "Memory allocated to hold the compartment's string "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("string-chars"),
+ cStats.stringChars,
+ "Memory allocated to hold string "
"characters. Sometimes more memory is allocated than "
"necessary, to simplify string concatenation. Each string "
"also includes a header which is stored on the "
"compartment's JavaScript heap; that header is not counted "
"here, but in 'gc-heap/strings' instead.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "shapes-extra/tree-tables"),
- nsIMemoryReporter::KIND_HEAP, cStats.shapesExtraTreeTables,
- "Memory allocated for the compartment's property tables "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes-extra/tree-tables"),
+ cStats.shapesExtraTreeTables,
+ "Memory allocated for the property tables "
"that belong to shapes that are in a property tree.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "shapes-extra/dict-tables"),
- nsIMemoryReporter::KIND_HEAP, cStats.shapesExtraDictTables,
- "Memory allocated for the compartment's property tables "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes-extra/dict-tables"),
+ cStats.shapesExtraDictTables,
+ "Memory allocated for the property tables "
"that belong to shapes that are in dictionary mode.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "shapes-extra/tree-shape-kids"),
- nsIMemoryReporter::KIND_HEAP, cStats.shapesExtraTreeShapeKids,
- "Memory allocated for the compartment's kid hashes that "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes-extra/tree-shape-kids"),
+ cStats.shapesExtraTreeShapeKids,
+ "Memory allocated for the kid hashes that "
"belong to shapes that are in a property tree.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "shapes-extra/compartment-tables"),
- nsIMemoryReporter::KIND_HEAP, cStats.shapesCompartmentTables,
- "Memory used by compartment wide tables storing shape "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes-extra/compartment-tables"),
+ cStats.shapesCompartmentTables,
+ "Memory used by compartment-wide tables storing shape "
"information for use during object construction.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "script-data"),
- nsIMemoryReporter::KIND_HEAP, cStats.scriptData,
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("script-data"),
+ cStats.scriptData,
"Memory allocated for JSScript bytecode and various "
"variable-length tables.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "mjit-data"),
- nsIMemoryReporter::KIND_HEAP, cStats.mjitData,
- "Memory used by the method JIT for the compartment's "
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("mjit-data"),
+ cStats.mjitData,
+ "Memory used by the method JIT for "
"compilation data: JITScripts, native maps, and inline "
"cache structs.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "cross-compartment-wrappers"),
- nsIMemoryReporter::KIND_HEAP, cStats.crossCompartmentWrappers,
- "Memory used by the compartment's cross-compartment "
- "wrappers.");
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("cross-compartment-wrappers"),
+ cStats.crossCompartmentWrappers,
+ "Memory used by cross-compartment wrappers.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "type-inference/script-main"),
- nsIMemoryReporter::KIND_HEAP,
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-inference/script-main"),
cStats.typeInferenceSizes.scripts,
"Memory used during type inference to store type sets of "
"variables and dynamically observed types.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "type-inference/object-main"),
- nsIMemoryReporter::KIND_HEAP,
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-inference/object-main"),
cStats.typeInferenceSizes.objects,
"Memory used during type inference to store types and "
"possible property types of JS objects.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "type-inference/tables"),
- nsIMemoryReporter::KIND_HEAP,
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-inference/tables"),
cStats.typeInferenceSizes.tables,
"Memory used during type inference for compartment-wide "
"tables.");
- CREPORT_BYTES(MakePath(pathPrefix, cStats, "analysis-temporary"),
- nsIMemoryReporter::KIND_HEAP,
+ CREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("analysis-temporary"),
cStats.typeInferenceSizes.temporary,
"Memory used during type inference and compilation to hold "
"transient analysis information. Cleared on GC.");
if (gcHeapSundries > 0) {
- REPORT_GC_BYTES(MakePath(pathPrefix, cStats, "gc-heap/sundries"),
+ // We deliberately don't use CREPORT_GC_BYTES here.
+ REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/sundries"),
gcHeapSundries,
- "The sum of all this compartment's gc-heap "
+ "The sum of all the gc-heap "
"measurements that are too small to be worth showing "
"individually.");
}
if (otherSundries > 0) {
- REPORT_BYTES(MakePath(pathPrefix, cStats, "other-sundries"),
- nsIMemoryReporter::KIND_HEAP,
- otherSundries,
- "The sum of all this compartment's non-gc-heap "
+ // We deliberately don't use CREPORT_BYTES here.
+ REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("other-sundries"),
+ nsIMemoryReporter::KIND_HEAP, otherSundries,
+ "The sum of all the non-gc-heap "
"measurements that are too small to be worth showing "
"individually.");
}
- *gcTotalOut += gcTotal;
+ if (gcTotalOut) {
+ *gcTotalOut += gcTotal;
+ }
return NS_OK;
}
nsresult
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
const nsACString &pathPrefix,
nsIMemoryMultiReporterCallback *cb,
- nsISupports *closure)
+ nsISupports *closure, size_t *rtTotalOut)
{
nsresult rv;
+
+ // Report each compartment's numbers.
+
size_t gcTotal = 0;
- for (size_t index = 0;
- index < rtStats.compartmentStatsVector.length();
- index++) {
- rv = ReportCompartmentStats(rtStats.compartmentStatsVector[index],
- pathPrefix, cb, closure, &gcTotal);
+ for (size_t i = 0; i < rtStats.compartmentStatsVector.length(); i++) {
+ JS::CompartmentStats cStats = rtStats.compartmentStatsVector[i];
+ const char *name = static_cast<char *>(cStats.extra);
+ nsCString pathPrefix2 = pathPrefix + NS_LITERAL_CSTRING("compartment(") +
+ nsDependentCString(name) + NS_LITERAL_CSTRING(")/");
+
+ rv = ReportCompartmentStats(cStats, pathPrefix2, cb, closure, &gcTotal);
NS_ENSURE_SUCCESS(rv, rv);
}
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/runtime-object"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.object,
- "Memory used by the JSRuntime object.");
+ // Report the rtStats.runtime numbers under "runtime/", and compute their
+ // total for later.
+
+ size_t rtTotal = 0;
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/atoms-table"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.atomsTable,
- "Memory used by the atoms table.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/runtime-object"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.object,
+ "Memory used by the JSRuntime object.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/contexts"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.contexts,
- "Memory used by JSContext objects and certain structures "
- "hanging off them.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/atoms-table"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.atomsTable,
+ "Memory used by the atoms table.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/dtoa"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.dtoa,
- "Memory used by DtoaState, which is used for converting "
- "strings to numbers and vice versa.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/contexts"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.contexts,
+ "Memory used by JSContext objects and certain structures "
+ "hanging off them.");
+
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/dtoa"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.dtoa,
+ "Memory used by DtoaState, which is used for converting "
+ "strings to numbers and vice versa.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/temporary"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.temporary,
- "Memory held transiently in JSRuntime and used during "
- "compilation. It mostly holds parse nodes.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/temporary"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.temporary,
+ "Memory held transiently in JSRuntime and used during "
+ "compilation. It mostly holds parse nodes.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/mjit-code"),
- nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.mjitCode,
- "Memory used by the method JIT to hold the runtime's "
- "generated code.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/mjit-code"),
+ nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.mjitCode,
+ "Memory used by the method JIT to hold the runtime's "
+ "generated code.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/regexp-code"),
- nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.regexpCode,
- "Memory used by the regexp JIT to hold generated code.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/regexp-code"),
+ nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.regexpCode,
+ "Memory used by the regexp JIT to hold generated code.");
+
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/unused-code-memory"),
+ nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.unusedCodeMemory,
+ "Memory allocated by the method and/or regexp JIT to hold the "
+ "runtime's code, but which is currently unused.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/unused-code-memory"),
- nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.unusedCodeMemory,
- "Memory allocated by the method and/or regexp JIT to hold the "
- "runtime's code, but which is currently unused.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/stack-committed"),
+ nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.stackCommitted,
+ "Memory used for the JS call stack. This is the committed "
+ "portion of the stack; the uncommitted portion is not "
+ "measured because it hardly costs anything.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/stack-committed"),
- nsIMemoryReporter::KIND_NONHEAP, rtStats.runtime.stackCommitted,
- "Memory used for the JS call stack. This is the committed "
- "portion of the stack; the uncommitted portion is not "
- "measured because it hardly costs anything.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/gc-marker"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.gcMarker,
+ "Memory used for the GC mark stack and gray roots.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/gc-marker"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.gcMarker,
- "Memory used for the GC mark stack and gray roots.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/math-cache"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.mathCache,
+ "Memory used for the math cache.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/math-cache"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.mathCache,
- "Memory used for the math cache.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/script-filenames"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.scriptFilenames,
+ "Memory used for the table holding script filenames.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/script-filenames"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.scriptFilenames,
- "Memory used for the table holding script filenames.");
+ RREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/compartment-objects"),
+ nsIMemoryReporter::KIND_HEAP, rtStats.runtime.compartmentObjects,
+ "Memory used for JSCompartment objects. These are fairly "
+ "small and all the same size, so they're not worth reporting "
+ "on a per-compartment basis.");
- REPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("runtime/compartment-objects"),
- nsIMemoryReporter::KIND_HEAP, rtStats.runtime.compartmentObjects,
- "Memory used for JSCompartment objects. These are fairly "
- "small and all the same size, so they're not worth reporting "
- "on a per-compartment basis.");
+ if (rtTotalOut) {
+ *rtTotalOut = rtTotal;
+ }
+
+ // Report GC numbers that don't belong to a compartment.
REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/unused-arenas"),
rtStats.gcHeapUnusedArenas,
"Memory on the garbage-collected JavaScript heap taken by "
"empty arenas within non-empty chunks.");
REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("gc-heap/unused-chunks"),
rtStats.gcHeapUnusedChunks,
@@ -1692,135 +1705,93 @@ public:
xpcrt->SizeOfIncludingThis(JsMallocSizeOf) +
XPCWrappedNativeScope::SizeOfAllScopesIncludingThis(JsMallocSizeOf);
NS_NAMED_LITERAL_CSTRING(explicitJs, "explicit/js/");
// This is the second step (see above). First we report stuff in the
// "explicit" tree, then we report other stuff.
+ size_t rtTotal = 0;
nsresult rv =
xpc::ReportJSRuntimeExplicitTreeStats(rtStats, explicitJs, cb,
- closure);
+ closure, &rtTotal);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Report the sums of the compartment numbers.
+ rv = ReportCompartmentStats(rtStats.totals,
+ NS_LITERAL_CSTRING("js-main-runtime/compartments/"),
+ cb, closure);
NS_ENSURE_SUCCESS(rv, rv);
- REPORT_BYTES(explicitJs + NS_LITERAL_CSTRING("xpconnect"),
- nsIMemoryReporter::KIND_HEAP, xpconnect,
- "Memory used by XPConnect.");
+ // Report the sum of the runtime/ numbers.
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/runtime"),
+ nsIMemoryReporter::KIND_OTHER, rtTotal,
+ "The sum of all measurements under 'explicit/js/runtime/'.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-unused-arenas"),
+ // Report the numbers for memory outside of compartments.
+
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/decommitted"),
nsIMemoryReporter::KIND_OTHER,
- rtStats.gcHeapUnusedArenas,
- "The same as 'explicit/js/gc-heap/unused-arenas'. "
- "Shown here for easy comparison with other 'js-gc' "
- "reporters.");
+ rtStats.gcHeapChunkCleanDecommitted + rtStats.gcHeapChunkDirtyDecommitted,
+ "The same as 'explicit/js/gc-heap/decommitted'.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-unused-chunks"),
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/unused-chunks"),
nsIMemoryReporter::KIND_OTHER,
rtStats.gcHeapUnusedChunks,
- "The same as 'explicit/js/gc-heap/unused-chunks'. "
- "Shown here for easy comparison with other 'js-gc' "
- "reporters.");
+ "The same as 'explicit/js/gc-heap/unused-chunks'.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-unused-gc-things"),
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/unused-arenas"),
nsIMemoryReporter::KIND_OTHER,
- rtStats.gcHeapUnusedGcThings,
- "Memory on the main JSRuntime's garbage-collected "
- "JavaScript heap taken by empty GC thing slots within "
- "non-empty arenas. This is the sum of all compartments' "
- "'gc-heap/unused-gc-things' numbers.");
-
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed-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-unused-chunks' + "
- "'gc-heap-unused-arenas' + 'gc-heap-unused-gc-things'.");
+ rtStats.gcHeapUnusedArenas,
+ "The same as 'explicit/js/gc-heap/unused-arenas'.");
- // Why 10000x? 100x because it's a percentage, and another 100x
- // because nsIMemoryReporter requires that for UNITS_PERCENTAGE
- // reporters so we can get two decimal places out of the integer value.
- REPORT(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed-unused-ratio"),
- nsIMemoryReporter::KIND_OTHER,
- nsIMemoryReporter::UNITS_PERCENTAGE,
- (PRInt64) 10000 * rtStats.gcHeapUnused /
- ((double) rtStats.gcHeapCommitted - rtStats.gcHeapUnused),
- "Ratio of committed, unused bytes to allocated bytes; i.e. "
- "'gc-heap-committed-unused' / 'gc-heap-allocated'. This "
- "measures the overhead of the GC heap allocator relative to the "
- "amount of memory allocated.");
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/chunk-admin"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.gcHeapChunkAdmin,
+ "The same as 'explicit/js/gc-heap/chunk-admin'.");
+
+ // Report a breakdown of the committed GC space.
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed"),
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/chunks"),
nsIMemoryReporter::KIND_OTHER,
- rtStats.gcHeapCommitted,
- "Committed memory (i.e., in physical memory or swap) "
- "used by the garbage-collected JavaScript heap.");
+ rtStats.gcHeapUnusedChunks,
+ "The same as 'explicit/js/gc-heap/unused-chunks'.");
- 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_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-decommitted"),
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/arenas"),
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.");
+ rtStats.gcHeapUnusedArenas,
+ "The same as 'explicit/js/gc-heap/unused-arenas'.");
- 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.");
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/gc-things"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.totals.gcHeapUnusedGcThings,
+ "The same as 'js-main-runtime/compartments/gc-heap/unused-gc-things'.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-shapes"),
- nsIMemoryReporter::KIND_OTHER, rtStats.totalShapes,
- "Memory used for all shape-related data in the main "
- "JSRuntime. This is the sum of all compartments' "
- "'gc-heap/shapes/tree', 'gc-heap/shapes/dict', "
- "'gc-heap/shapes/base', 'shapes-extra/tree-tables', "
- "'shapes-extra/dict-tables', "
- "'shapes-extra/tree-shape-kids' and "
- "'shapes-extra/empty-shape-arrays'.");
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/chunk-admin"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.gcHeapChunkAdmin,
+ "The same as 'explicit/js/gc-heap/chunk-admin'.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-scripts"),
- nsIMemoryReporter::KIND_OTHER, rtStats.totalScripts,
- "Memory used for all script-related data in the main "
- "JSRuntime. This is the sum of all compartments' "
- "'gc-heap/scripts' and 'script-data' numbers.");
-
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-strings"),
- nsIMemoryReporter::KIND_OTHER, rtStats.totalStrings,
- "Memory used for all string-related data in the main "
- "JSRuntime. This is the sum of all compartments' "
- "'gc-heap/strings' and 'string-chars' numbers.");
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/arena-admin"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.totals.gcHeapArenaAdmin,
+ "The same as 'js-main-runtime/compartments/gc-heap/arena-admin'.");
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-mjit"),
- nsIMemoryReporter::KIND_OTHER, rtStats.totalMjit,
- "Memory used by the method JIT in the main JSRuntime. "
- "This is the sum of all compartments' 'mjit/code', and "
- "'mjit/data' numbers.");
+ REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/gc-things"),
+ nsIMemoryReporter::KIND_OTHER,
+ rtStats.gcHeapGcThings,
+ "Memory on the garbage-collected JavaScript heap that holds GC things such "
+ "as objects, strings, scripts, etc.")
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-type-inference"),
- nsIMemoryReporter::KIND_OTHER, rtStats.totalTypeInference,
- "Non-transient memory used by type inference in the main "
- "JSRuntime. This is the sum of all compartments' "
- "'gc-heap/type-objects', 'type-inference/script-main', "
- "'type-inference/object-main' and "
- "'type-inference/tables' numbers.");
+ // Report xpconnect.
- REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime-analysis-temporary"),
- nsIMemoryReporter::KIND_OTHER, rtStats.totalAnalysisTemp,
- "Memory used transiently during type inference and "
- "compilation in the main JSRuntime. This is the sum of "
- "all compartments' 'analysis-temporary' numbers.");
+ REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect"),
+ nsIMemoryReporter::KIND_HEAP, xpconnect,
+ "Memory used by XPConnect.");
return NS_OK;
}
NS_IMETHOD
GetExplicitNonHeap(PRInt64 *n)
{
JSRuntime *rt = nsXPConnect::GetRuntimeInstance()->GetJSRuntime();