зеркало из https://github.com/mozilla/pjs.git
Bug 721628 (part 4) - Use better names for various JS memory reporting things. r=Ms2ger.
--HG-- extra : rebase_source : 4edc916c571906329075b6be68c245267f9b61d0
This commit is contained in:
Родитель
6ee279d5ec
Коммит
881438bc8e
|
@ -232,16 +232,16 @@ public:
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
JS::IterateData data(xpc::JsMallocSizeOf, xpc::GetCompartmentName,
|
||||
xpc::DestroyCompartmentName);
|
||||
nsresult rv = CollectForRuntime(/* isQuick = */false, &data);
|
||||
JS::RuntimeStats rtStats(xpc::JsMallocSizeOf, xpc::GetCompartmentName,
|
||||
xpc::DestroyCompartmentName);
|
||||
nsresult rv = CollectForRuntime(/* isQuick = */false, &rtStats);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Always report, even if we're disabled, so that we at least get an entry
|
||||
// in about::memory.
|
||||
ReportJSRuntimeStats(data, mPathPrefix, aCallback, aClosure);
|
||||
ReportJSRuntimeStats(rtStats, mPathPrefix, aCallback, aClosure);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1524,7 +1524,7 @@ public:
|
|||
|
||||
*mSucceeded = mIsQuick
|
||||
? JS::GetExplicitNonHeapForRuntime(JS_GetRuntime(aCx), static_cast<int64_t*>(mData), xpc::JsMallocSizeOf)
|
||||
: JS::CollectCompartmentStatsForRuntime(JS_GetRuntime(aCx), static_cast<JS::IterateData*>(mData));
|
||||
: JS::CollectRuntimeStats(JS_GetRuntime(aCx), static_cast<JS::RuntimeStats*>(mData));
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
|
|
@ -116,10 +116,10 @@ struct CompartmentStats
|
|||
TypeInferenceSizes typeInferenceSizes;
|
||||
};
|
||||
|
||||
struct IterateData
|
||||
struct RuntimeStats
|
||||
{
|
||||
IterateData(JSMallocSizeOfFun mallocSizeOf, GetNameCallback getNameCb,
|
||||
DestroyNameCallback destroyNameCb)
|
||||
RuntimeStats(JSMallocSizeOfFun mallocSizeOf, GetNameCallback getNameCb,
|
||||
DestroyNameCallback destroyNameCb)
|
||||
: runtimeObject(0)
|
||||
, runtimeAtomsTable(0)
|
||||
, runtimeContexts(0)
|
||||
|
@ -187,7 +187,7 @@ struct IterateData
|
|||
#ifdef JS_THREADSAFE
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data);
|
||||
CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
GetExplicitNonHeapForRuntime(JSRuntime *rt, int64_t *amount,
|
||||
|
|
|
@ -55,23 +55,23 @@ namespace JS {
|
|||
using namespace js;
|
||||
|
||||
static void
|
||||
CompartmentMemoryCallback(JSContext *cx, void *vdata, JSCompartment *compartment)
|
||||
CompartmentStatsCallback(JSContext *cx, void *vdata, JSCompartment *compartment)
|
||||
{
|
||||
// Append a new CompartmentStats to the vector.
|
||||
IterateData *data = static_cast<IterateData *>(vdata);
|
||||
RuntimeStats *rtStats = static_cast<RuntimeStats *>(vdata);
|
||||
|
||||
// CollectCompartmentStatsForRuntime reserves enough space.
|
||||
MOZ_ALWAYS_TRUE(data->compartmentStatsVector.growBy(1));
|
||||
CompartmentStats &curr = data->compartmentStatsVector.back();
|
||||
curr.init(data->getNameCb(cx, compartment), data->destroyNameCb);
|
||||
data->currCompartmentStats = &curr;
|
||||
// CollectRuntimeStats reserves enough space.
|
||||
MOZ_ALWAYS_TRUE(rtStats->compartmentStatsVector.growBy(1));
|
||||
CompartmentStats &cStats = rtStats->compartmentStatsVector.back();
|
||||
cStats.init(rtStats->getNameCb(cx, compartment), rtStats->destroyNameCb);
|
||||
rtStats->currCompartmentStats = &cStats;
|
||||
|
||||
// Get the compartment-level numbers.
|
||||
#ifdef JS_METHODJIT
|
||||
curr.mjitCode = compartment->sizeOfMjitCode();
|
||||
cStats.mjitCode = compartment->sizeOfMjitCode();
|
||||
#endif
|
||||
compartment->sizeOfTypeInferenceData(cx, &curr.typeInferenceSizes, data->mallocSizeOf);
|
||||
curr.shapesCompartmentTables = compartment->sizeOfShapeTable(data->mallocSizeOf);
|
||||
compartment->sizeOfTypeInferenceData(cx, &cStats.typeInferenceSizes, rtStats->mallocSizeOf);
|
||||
cStats.shapesCompartmentTables = compartment->sizeOfShapeTable(rtStats->mallocSizeOf);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -88,108 +88,107 @@ ChunkCallback(JSContext *cx, void *vdata, gc::Chunk *chunk)
|
|||
{
|
||||
// Nb: This function is only called for dirty chunks, which is why we
|
||||
// increment gcHeapChunkDirtyDecommitted.
|
||||
IterateData *data = static_cast<IterateData *>(vdata);
|
||||
RuntimeStats *rtStats = static_cast<RuntimeStats *>(vdata);
|
||||
for (size_t i = 0; i < gc::ArenasPerChunk; i++)
|
||||
if (chunk->decommittedArenas.get(i))
|
||||
data->gcHeapChunkDirtyDecommitted += gc::ArenaSize;
|
||||
rtStats->gcHeapChunkDirtyDecommitted += gc::ArenaSize;
|
||||
}
|
||||
|
||||
static void
|
||||
ArenaCallback(JSContext *cx, void *vdata, gc::Arena *arena,
|
||||
JSGCTraceKind traceKind, size_t thingSize)
|
||||
{
|
||||
IterateData *data = static_cast<IterateData *>(vdata);
|
||||
RuntimeStats *rtStats = static_cast<RuntimeStats *>(vdata);
|
||||
|
||||
data->currCompartmentStats->gcHeapArenaHeaders +=
|
||||
sizeof(gc::ArenaHeader);
|
||||
rtStats->currCompartmentStats->gcHeapArenaHeaders += sizeof(gc::ArenaHeader);
|
||||
size_t allocationSpace = arena->thingsSpan(thingSize);
|
||||
data->currCompartmentStats->gcHeapArenaPadding +=
|
||||
rtStats->currCompartmentStats->gcHeapArenaPadding +=
|
||||
gc::ArenaSize - allocationSpace - sizeof(gc::ArenaHeader);
|
||||
// We don't call the callback on unused things. So we compute the
|
||||
// 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 CellCallback().
|
||||
data->currCompartmentStats->gcHeapArenaUnused += allocationSpace;
|
||||
rtStats->currCompartmentStats->gcHeapArenaUnused += allocationSpace;
|
||||
}
|
||||
|
||||
static void
|
||||
CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
||||
size_t thingSize)
|
||||
{
|
||||
IterateData *data = static_cast<IterateData *>(vdata);
|
||||
CompartmentStats *curr = data->currCompartmentStats;
|
||||
RuntimeStats *rtStats = static_cast<RuntimeStats *>(vdata);
|
||||
CompartmentStats *cStats = rtStats->currCompartmentStats;
|
||||
switch (traceKind) {
|
||||
case JSTRACE_OBJECT:
|
||||
{
|
||||
JSObject *obj = static_cast<JSObject *>(thing);
|
||||
if (obj->isFunction()) {
|
||||
curr->gcHeapObjectsFunction += thingSize;
|
||||
cStats->gcHeapObjectsFunction += thingSize;
|
||||
} else {
|
||||
curr->gcHeapObjectsNonFunction += thingSize;
|
||||
cStats->gcHeapObjectsNonFunction += thingSize;
|
||||
}
|
||||
size_t slotsSize, elementsSize;
|
||||
obj->sizeOfExcludingThis(data->mallocSizeOf, &slotsSize, &elementsSize);
|
||||
curr->objectSlots += slotsSize;
|
||||
curr->objectElements += elementsSize;
|
||||
obj->sizeOfExcludingThis(rtStats->mallocSizeOf, &slotsSize, &elementsSize);
|
||||
cStats->objectSlots += slotsSize;
|
||||
cStats->objectElements += elementsSize;
|
||||
break;
|
||||
}
|
||||
case JSTRACE_STRING:
|
||||
{
|
||||
JSString *str = static_cast<JSString *>(thing);
|
||||
curr->gcHeapStrings += thingSize;
|
||||
curr->stringChars += str->sizeOfExcludingThis(data->mallocSizeOf);
|
||||
cStats->gcHeapStrings += thingSize;
|
||||
cStats->stringChars += str->sizeOfExcludingThis(rtStats->mallocSizeOf);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_SHAPE:
|
||||
{
|
||||
Shape *shape = static_cast<Shape*>(thing);
|
||||
size_t propTableSize, kidsSize;
|
||||
shape->sizeOfExcludingThis(data->mallocSizeOf, &propTableSize, &kidsSize);
|
||||
shape->sizeOfExcludingThis(rtStats->mallocSizeOf, &propTableSize, &kidsSize);
|
||||
if (shape->inDictionary()) {
|
||||
curr->gcHeapShapesDict += thingSize;
|
||||
curr->shapesExtraDictTables += propTableSize;
|
||||
cStats->gcHeapShapesDict += thingSize;
|
||||
cStats->shapesExtraDictTables += propTableSize;
|
||||
JS_ASSERT(kidsSize == 0);
|
||||
} else {
|
||||
curr->gcHeapShapesTree += thingSize;
|
||||
curr->shapesExtraTreeTables += propTableSize;
|
||||
curr->shapesExtraTreeShapeKids += kidsSize;
|
||||
cStats->gcHeapShapesTree += thingSize;
|
||||
cStats->shapesExtraTreeTables += propTableSize;
|
||||
cStats->shapesExtraTreeShapeKids += kidsSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSTRACE_BASE_SHAPE:
|
||||
{
|
||||
curr->gcHeapShapesBase += thingSize;
|
||||
cStats->gcHeapShapesBase += thingSize;
|
||||
break;
|
||||
}
|
||||
case JSTRACE_SCRIPT:
|
||||
{
|
||||
JSScript *script = static_cast<JSScript *>(thing);
|
||||
curr->gcHeapScripts += thingSize;
|
||||
curr->scriptData += script->sizeOfData(data->mallocSizeOf);
|
||||
cStats->gcHeapScripts += thingSize;
|
||||
cStats->scriptData += script->sizeOfData(rtStats->mallocSizeOf);
|
||||
#ifdef JS_METHODJIT
|
||||
curr->mjitData += script->sizeOfJitScripts(data->mallocSizeOf);
|
||||
cStats->mjitData += script->sizeOfJitScripts(rtStats->mallocSizeOf);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case JSTRACE_TYPE_OBJECT:
|
||||
{
|
||||
types::TypeObject *obj = static_cast<types::TypeObject *>(thing);
|
||||
curr->gcHeapTypeObjects += thingSize;
|
||||
obj->sizeOfExcludingThis(&curr->typeInferenceSizes, data->mallocSizeOf);
|
||||
cStats->gcHeapTypeObjects += thingSize;
|
||||
obj->sizeOfExcludingThis(&cStats->typeInferenceSizes, rtStats->mallocSizeOf);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_XML:
|
||||
{
|
||||
curr->gcHeapXML += thingSize;
|
||||
cStats->gcHeapXML += thingSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Yes, this is a subtraction: see ArenaCallback() for details.
|
||||
curr->gcHeapArenaUnused -= thingSize;
|
||||
cStats->gcHeapArenaUnused -= thingSize;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
||||
CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats)
|
||||
{
|
||||
JSContext *cx = JS_NewContext(rt, 0);
|
||||
if (!cx)
|
||||
|
@ -198,119 +197,116 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
|||
{
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
if (!data->compartmentStatsVector.reserve(rt->compartments.length()))
|
||||
if (!rtStats->compartmentStatsVector.reserve(rt->compartments.length()))
|
||||
return false;
|
||||
|
||||
data->gcHeapChunkCleanDecommitted =
|
||||
rt->gcChunkPool.countCleanDecommittedArenas(rt) *
|
||||
gc::ArenaSize;
|
||||
data->gcHeapChunkCleanUnused =
|
||||
int64_t(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) *
|
||||
gc::ChunkSize -
|
||||
data->gcHeapChunkCleanDecommitted;
|
||||
data->gcHeapChunkTotal =
|
||||
int64_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) *
|
||||
gc::ChunkSize;
|
||||
rtStats->gcHeapChunkCleanDecommitted =
|
||||
rt->gcChunkPool.countCleanDecommittedArenas(rt) * gc::ArenaSize;
|
||||
rtStats->gcHeapChunkCleanUnused =
|
||||
int64_t(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) * gc::ChunkSize -
|
||||
rtStats->gcHeapChunkCleanDecommitted;
|
||||
rtStats->gcHeapChunkTotal =
|
||||
int64_t(JS_GetGCParameter(rt, JSGC_TOTAL_CHUNKS)) * gc::ChunkSize;
|
||||
|
||||
IterateCompartmentsArenasCells(cx, data, CompartmentMemoryCallback,
|
||||
IterateCompartmentsArenasCells(cx, rtStats, CompartmentStatsCallback,
|
||||
ArenaCallback, CellCallback);
|
||||
IterateChunks(cx, data, ChunkCallback);
|
||||
IterateChunks(cx, rtStats, ChunkCallback);
|
||||
|
||||
data->runtimeObject = data->mallocSizeOf(rt);
|
||||
rtStats->runtimeObject = rtStats->mallocSizeOf(rt);
|
||||
|
||||
size_t normal, temporary, regexpCode, stackCommitted;
|
||||
rt->sizeOfExcludingThis(data->mallocSizeOf,
|
||||
rt->sizeOfExcludingThis(rtStats->mallocSizeOf,
|
||||
&normal,
|
||||
&temporary,
|
||||
®expCode,
|
||||
&stackCommitted);
|
||||
|
||||
data->runtimeNormal = normal;
|
||||
data->runtimeTemporary = temporary;
|
||||
data->runtimeRegexpCode = regexpCode;
|
||||
data->runtimeStackCommitted = stackCommitted;
|
||||
rtStats->runtimeNormal = normal;
|
||||
rtStats->runtimeTemporary = temporary;
|
||||
rtStats->runtimeRegexpCode = regexpCode;
|
||||
rtStats->runtimeStackCommitted = stackCommitted;
|
||||
|
||||
// Nb: we use sizeOfExcludingThis() because atomState.atoms is within
|
||||
// JSRuntime, and so counted when JSRuntime is counted.
|
||||
data->runtimeAtomsTable =
|
||||
rt->atomState.atoms.sizeOfExcludingThis(data->mallocSizeOf);
|
||||
rtStats->runtimeAtomsTable =
|
||||
rt->atomState.atoms.sizeOfExcludingThis(rtStats->mallocSizeOf);
|
||||
|
||||
JSContext *acx, *iter = NULL;
|
||||
while ((acx = JS_ContextIteratorUnlocked(rt, &iter)) != NULL)
|
||||
data->runtimeContexts += acx->sizeOfIncludingThis(data->mallocSizeOf);
|
||||
rtStats->runtimeContexts += acx->sizeOfIncludingThis(rtStats->mallocSizeOf);
|
||||
}
|
||||
|
||||
JS_DestroyContextNoGC(cx);
|
||||
|
||||
// This is initialized to all bytes stored in used chunks, and then we
|
||||
// subtract used space from it each time around the loop.
|
||||
data->gcHeapChunkDirtyUnused = data->gcHeapChunkTotal -
|
||||
data->gcHeapChunkCleanUnused -
|
||||
data->gcHeapChunkCleanDecommitted -
|
||||
data->gcHeapChunkDirtyDecommitted;
|
||||
rtStats->gcHeapChunkDirtyUnused = rtStats->gcHeapChunkTotal -
|
||||
rtStats->gcHeapChunkCleanUnused -
|
||||
rtStats->gcHeapChunkCleanDecommitted -
|
||||
rtStats->gcHeapChunkDirtyDecommitted;
|
||||
|
||||
for (size_t index = 0;
|
||||
index < data->compartmentStatsVector.length();
|
||||
index < rtStats->compartmentStatsVector.length();
|
||||
index++) {
|
||||
CompartmentStats &stats = data->compartmentStatsVector[index];
|
||||
CompartmentStats &cStats = rtStats->compartmentStatsVector[index];
|
||||
|
||||
int64_t used = stats.gcHeapArenaHeaders +
|
||||
stats.gcHeapArenaPadding +
|
||||
stats.gcHeapArenaUnused +
|
||||
stats.gcHeapObjectsNonFunction +
|
||||
stats.gcHeapObjectsFunction +
|
||||
stats.gcHeapStrings +
|
||||
stats.gcHeapShapesTree +
|
||||
stats.gcHeapShapesDict +
|
||||
stats.gcHeapShapesBase +
|
||||
stats.gcHeapScripts +
|
||||
stats.gcHeapTypeObjects +
|
||||
stats.gcHeapXML;
|
||||
int64_t used = cStats.gcHeapArenaHeaders +
|
||||
cStats.gcHeapArenaPadding +
|
||||
cStats.gcHeapArenaUnused +
|
||||
cStats.gcHeapObjectsNonFunction +
|
||||
cStats.gcHeapObjectsFunction +
|
||||
cStats.gcHeapStrings +
|
||||
cStats.gcHeapShapesTree +
|
||||
cStats.gcHeapShapesDict +
|
||||
cStats.gcHeapShapesBase +
|
||||
cStats.gcHeapScripts +
|
||||
cStats.gcHeapTypeObjects +
|
||||
cStats.gcHeapXML;
|
||||
|
||||
data->gcHeapChunkDirtyUnused -= used;
|
||||
data->gcHeapArenaUnused += stats.gcHeapArenaUnused;
|
||||
data->totalObjects += stats.gcHeapObjectsNonFunction +
|
||||
stats.gcHeapObjectsFunction +
|
||||
stats.objectSlots +
|
||||
stats.objectElements;
|
||||
data->totalShapes += stats.gcHeapShapesTree +
|
||||
stats.gcHeapShapesDict +
|
||||
stats.gcHeapShapesBase +
|
||||
stats.shapesExtraTreeTables +
|
||||
stats.shapesExtraDictTables +
|
||||
stats.shapesCompartmentTables;
|
||||
data->totalScripts += stats.gcHeapScripts +
|
||||
stats.scriptData;
|
||||
data->totalStrings += stats.gcHeapStrings +
|
||||
stats.stringChars;
|
||||
rtStats->gcHeapChunkDirtyUnused -= used;
|
||||
rtStats->gcHeapArenaUnused += cStats.gcHeapArenaUnused;
|
||||
rtStats->totalObjects += cStats.gcHeapObjectsNonFunction +
|
||||
cStats.gcHeapObjectsFunction +
|
||||
cStats.objectSlots +
|
||||
cStats.objectElements;
|
||||
rtStats->totalShapes += cStats.gcHeapShapesTree +
|
||||
cStats.gcHeapShapesDict +
|
||||
cStats.gcHeapShapesBase +
|
||||
cStats.shapesExtraTreeTables +
|
||||
cStats.shapesExtraDictTables +
|
||||
cStats.shapesCompartmentTables;
|
||||
rtStats->totalScripts += cStats.gcHeapScripts +
|
||||
cStats.scriptData;
|
||||
rtStats->totalStrings += cStats.gcHeapStrings +
|
||||
cStats.stringChars;
|
||||
#ifdef JS_METHODJIT
|
||||
data->totalMjit += stats.mjitCode +
|
||||
stats.mjitData;
|
||||
rtStats->totalMjit += cStats.mjitCode +
|
||||
cStats.mjitData;
|
||||
#endif
|
||||
data->totalTypeInference += stats.gcHeapTypeObjects +
|
||||
stats.typeInferenceSizes.objects +
|
||||
stats.typeInferenceSizes.scripts +
|
||||
stats.typeInferenceSizes.tables;
|
||||
data->totalAnalysisTemp += stats.typeInferenceSizes.temporary;
|
||||
rtStats->totalTypeInference += cStats.gcHeapTypeObjects +
|
||||
cStats.typeInferenceSizes.objects +
|
||||
cStats.typeInferenceSizes.scripts +
|
||||
cStats.typeInferenceSizes.tables;
|
||||
rtStats->totalAnalysisTemp += cStats.typeInferenceSizes.temporary;
|
||||
}
|
||||
|
||||
size_t numDirtyChunks = (data->gcHeapChunkTotal -
|
||||
data->gcHeapChunkCleanUnused) /
|
||||
size_t numDirtyChunks = (rtStats->gcHeapChunkTotal -
|
||||
rtStats->gcHeapChunkCleanUnused) /
|
||||
gc::ChunkSize;
|
||||
int64_t perChunkAdmin =
|
||||
sizeof(gc::Chunk) - (sizeof(gc::Arena) * gc::ArenasPerChunk);
|
||||
data->gcHeapChunkAdmin = numDirtyChunks * perChunkAdmin;
|
||||
data->gcHeapChunkDirtyUnused -= data->gcHeapChunkAdmin;
|
||||
rtStats->gcHeapChunkAdmin = numDirtyChunks * perChunkAdmin;
|
||||
rtStats->gcHeapChunkDirtyUnused -= rtStats->gcHeapChunkAdmin;
|
||||
|
||||
// Why 10000x? 100x because it's a percentage, and another 100x
|
||||
// because nsIMemoryReporter requires that for percentage amounts so
|
||||
// they can be fractional.
|
||||
data->gcHeapUnusedPercentage = (data->gcHeapChunkCleanUnused +
|
||||
data->gcHeapChunkDirtyUnused +
|
||||
data->gcHeapChunkCleanDecommitted +
|
||||
data->gcHeapChunkDirtyDecommitted +
|
||||
data->gcHeapArenaUnused) * 10000 /
|
||||
data->gcHeapChunkTotal;
|
||||
rtStats->gcHeapUnusedPercentage = (rtStats->gcHeapChunkCleanUnused +
|
||||
rtStats->gcHeapChunkDirtyUnused +
|
||||
rtStats->gcHeapChunkCleanDecommitted +
|
||||
rtStats->gcHeapChunkDirtyDecommitted +
|
||||
rtStats->gcHeapArenaUnused) * 10000 /
|
||||
rtStats->gcHeapChunkTotal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1350,11 +1350,11 @@ ReportMemoryPercentage(const nsACString &path, PRInt32 kind, PRInt64 amount,
|
|||
template <int N>
|
||||
inline const nsCString
|
||||
MakeMemoryReporterPath(const nsACString &pathPrefix,
|
||||
const JS::CompartmentStats &compartmentStats,
|
||||
const JS::CompartmentStats &cStats,
|
||||
const char (&reporterName)[N])
|
||||
{
|
||||
return pathPrefix + NS_LITERAL_CSTRING("compartment(") +
|
||||
*static_cast<nsCString*>(compartmentStats.name) +
|
||||
*static_cast<nsCString*>(cStats.name) +
|
||||
NS_LITERAL_CSTRING(")/") + nsDependentCString(reporterName);
|
||||
}
|
||||
|
||||
|
@ -1422,52 +1422,52 @@ namespace xpconnect {
|
|||
namespace memory {
|
||||
|
||||
static PRInt64
|
||||
ReportCompartmentStats(const JS::CompartmentStats &stats,
|
||||
ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
||||
const nsACString &pathPrefix,
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
PRInt64 gcTotal = 0;
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/arena/headers"),
|
||||
&gcTotal, stats.gcHeapArenaHeaders,
|
||||
&gcTotal, cStats.gcHeapArenaHeaders,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap, within "
|
||||
"arenas, that is used to hold internal book-keeping information.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/arena/padding"),
|
||||
&gcTotal, stats.gcHeapArenaPadding,
|
||||
&gcTotal, 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.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/arena/unused"),
|
||||
&gcTotal, stats.gcHeapArenaUnused,
|
||||
&gcTotal, cStats.gcHeapArenaUnused,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap, within "
|
||||
"arenas, that could be holding useful data but currently isn't.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/objects/non-function"),
|
||||
&gcTotal, stats.gcHeapObjectsNonFunction,
|
||||
&gcTotal, cStats.gcHeapObjectsNonFunction,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"non-function objects.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/objects/function"),
|
||||
&gcTotal, stats.gcHeapObjectsFunction,
|
||||
&gcTotal, cStats.gcHeapObjectsFunction,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"function objects.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/strings"),
|
||||
&gcTotal, stats.gcHeapStrings,
|
||||
&gcTotal, cStats.gcHeapStrings,
|
||||
"Memory on the compartment's 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 "
|
||||
|
@ -1475,52 +1475,52 @@ ReportCompartmentStats(const JS::CompartmentStats &stats,
|
|||
"under 'gc-heap/string-chars' instead.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/scripts"),
|
||||
&gcTotal, stats.gcHeapScripts,
|
||||
&gcTotal, cStats.gcHeapScripts,
|
||||
"Memory on the compartment's 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.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/shapes/tree"),
|
||||
&gcTotal, stats.gcHeapShapesTree,
|
||||
&gcTotal, cStats.gcHeapShapesTree,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"shapes that are in a property tree.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/shapes/dict"),
|
||||
&gcTotal, stats.gcHeapShapesDict,
|
||||
&gcTotal, cStats.gcHeapShapesDict,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"shapes that are in dictionary mode.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/shapes/base"),
|
||||
&gcTotal, stats.gcHeapShapesBase,
|
||||
&gcTotal, cStats.gcHeapShapesBase,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that collates "
|
||||
"data common to many shapes.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/type-objects"),
|
||||
&gcTotal, stats.gcHeapTypeObjects,
|
||||
&gcTotal, cStats.gcHeapTypeObjects,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"type inference information.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"gc-heap/xml"),
|
||||
&gcTotal, stats.gcHeapXML,
|
||||
&gcTotal, cStats.gcHeapXML,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"E4X XML objects.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"object-slots"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.objectSlots,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.objectSlots,
|
||||
"Memory allocated for the compartment's 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 "
|
||||
|
@ -1528,16 +1528,16 @@ ReportCompartmentStats(const JS::CompartmentStats &stats,
|
|||
"'gc-heap/objects' instead.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"object-elements"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.objectElements,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.objectElements,
|
||||
"Memory allocated for the compartment's object element arrays, "
|
||||
"which are used to represent indexed object properties.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"string-chars"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.stringChars,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.stringChars,
|
||||
"Memory allocated to hold the compartment's string characters. Sometimes "
|
||||
"more memory is allocated than necessary, to simplify string "
|
||||
"concatenation. Each string also includes a header which is stored on the "
|
||||
|
@ -1545,83 +1545,83 @@ ReportCompartmentStats(const JS::CompartmentStats &stats,
|
|||
"'gc-heap/strings' instead.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"shapes-extra/tree-tables"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.shapesExtraTreeTables,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.shapesExtraTreeTables,
|
||||
"Memory allocated for the compartment's property tables that belong to "
|
||||
"shapes that are in a property tree.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"shapes-extra/dict-tables"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.shapesExtraDictTables,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.shapesExtraDictTables,
|
||||
"Memory allocated for the compartment's property tables that belong to "
|
||||
"shapes that are in dictionary mode.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"shapes-extra/tree-shape-kids"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.shapesExtraTreeShapeKids,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.shapesExtraTreeShapeKids,
|
||||
"Memory allocated for the compartment's kid hashes that belong to shapes "
|
||||
"that are in a property tree.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"shapes-extra/compartment-tables"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.shapesCompartmentTables,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.shapesCompartmentTables,
|
||||
"Memory used by compartment wide tables storing shape information "
|
||||
"for use during object construction.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"script-data"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.scriptData,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.scriptData,
|
||||
"Memory allocated for JSScript bytecode and various variable-length "
|
||||
"tables.",
|
||||
callback, closure);
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"mjit-code"),
|
||||
nsIMemoryReporter::KIND_NONHEAP, stats.mjitCode,
|
||||
nsIMemoryReporter::KIND_NONHEAP, cStats.mjitCode,
|
||||
"Memory used by the method JIT to hold the compartment's generated code.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"mjit-data"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.mjitData,
|
||||
nsIMemoryReporter::KIND_HEAP, cStats.mjitData,
|
||||
"Memory used by the method JIT for the compartment's compilation data: "
|
||||
"JITScripts, native maps, and inline cache structs.",
|
||||
callback, closure);
|
||||
#endif
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"type-inference/script-main"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.typeInferenceSizes.scripts,
|
||||
cStats.typeInferenceSizes.scripts,
|
||||
"Memory used during type inference to store type sets of variables "
|
||||
"and dynamically observed types.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"type-inference/object-main"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.typeInferenceSizes.objects,
|
||||
cStats.typeInferenceSizes.objects,
|
||||
"Memory used during type inference to store types and possible "
|
||||
"property types of JS objects.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"type-inference/tables"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.typeInferenceSizes.tables,
|
||||
cStats.typeInferenceSizes.tables,
|
||||
"Memory used during type inference for compartment-wide tables.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats,
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, cStats,
|
||||
"analysis-temporary"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.typeInferenceSizes.temporary,
|
||||
cStats.typeInferenceSizes.temporary,
|
||||
"Memory used during type inference and compilation to hold transient "
|
||||
"analysis information. Cleared on GC.",
|
||||
callback, closure);
|
||||
|
@ -1630,54 +1630,54 @@ ReportCompartmentStats(const JS::CompartmentStats &stats,
|
|||
}
|
||||
|
||||
void
|
||||
ReportJSRuntimeStats(const JS::IterateData &data, const nsACString &pathPrefix,
|
||||
ReportJSRuntimeStats(const JS::RuntimeStats &rtStats, const nsACString &pathPrefix,
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
PRInt64 gcTotal = 0;
|
||||
for (size_t index = 0;
|
||||
index < data.compartmentStatsVector.length();
|
||||
index < rtStats.compartmentStatsVector.length();
|
||||
index++) {
|
||||
gcTotal += ReportCompartmentStats(data.compartmentStatsVector[index], pathPrefix,
|
||||
gcTotal += ReportCompartmentStats(rtStats.compartmentStatsVector[index], pathPrefix,
|
||||
callback, closure);
|
||||
}
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/runtime-object"),
|
||||
nsIMemoryReporter::KIND_HEAP, data.runtimeObject,
|
||||
nsIMemoryReporter::KIND_HEAP, rtStats.runtimeObject,
|
||||
"Memory used by the JSRuntime object.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/atoms-table"),
|
||||
nsIMemoryReporter::KIND_HEAP, data.runtimeAtomsTable,
|
||||
nsIMemoryReporter::KIND_HEAP, rtStats.runtimeAtomsTable,
|
||||
"Memory used by the atoms table.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/contexts"),
|
||||
nsIMemoryReporter::KIND_HEAP, data.runtimeContexts,
|
||||
nsIMemoryReporter::KIND_HEAP, rtStats.runtimeContexts,
|
||||
"Memory used by JSContext objects and certain structures "
|
||||
"hanging off them." ,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/normal"),
|
||||
nsIMemoryReporter::KIND_HEAP, data.runtimeNormal,
|
||||
nsIMemoryReporter::KIND_HEAP, rtStats.runtimeNormal,
|
||||
"Memory used by a JSRuntime, "
|
||||
"excluding memory that is reported by "
|
||||
"other reporters under 'explicit/js/runtime/'.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/temporary"),
|
||||
nsIMemoryReporter::KIND_HEAP, data.runtimeTemporary,
|
||||
nsIMemoryReporter::KIND_HEAP, rtStats.runtimeTemporary,
|
||||
"Memory held transiently in JSRuntime and used during "
|
||||
"compilation. It mostly holds parse nodes.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(pathPrefix + NS_LITERAL_CSTRING("runtime/regexp-code"),
|
||||
nsIMemoryReporter::KIND_NONHEAP, data.runtimeRegexpCode,
|
||||
nsIMemoryReporter::KIND_NONHEAP, rtStats.runtimeRegexpCode,
|
||||
"Memory used by the regexp JIT to hold generated code.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/stack-committed"),
|
||||
nsIMemoryReporter::KIND_NONHEAP, data.runtimeStackCommitted,
|
||||
nsIMemoryReporter::KIND_NONHEAP, rtStats.runtimeStackCommitted,
|
||||
"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.",
|
||||
|
@ -1685,7 +1685,7 @@ ReportJSRuntimeStats(const JS::IterateData &data, const nsACString &pathPrefix,
|
|||
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-chunk-dirty-unused"),
|
||||
&gcTotal, data.gcHeapChunkDirtyUnused,
|
||||
&gcTotal, rtStats.gcHeapChunkDirtyUnused,
|
||||
"Memory on the garbage-collected JavaScript heap, within chunks with at "
|
||||
"least one allocated GC thing, that could be holding useful data but "
|
||||
"currently isn't. Memory here is mutually exclusive with memory reported"
|
||||
|
@ -1694,7 +1694,7 @@ ReportJSRuntimeStats(const JS::IterateData &data, const nsACString &pathPrefix,
|
|||
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-chunk-clean-unused"),
|
||||
&gcTotal, data.gcHeapChunkCleanUnused,
|
||||
&gcTotal, rtStats.gcHeapChunkCleanUnused,
|
||||
"Memory on the garbage-collected JavaScript heap taken by completely empty "
|
||||
"chunks, that soon will be released unless claimed for new allocations. "
|
||||
"Memory here is mutually exclusive with memory reported under "
|
||||
|
@ -1704,21 +1704,21 @@ ReportJSRuntimeStats(const JS::IterateData &data, const nsACString &pathPrefix,
|
|||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-decommitted"),
|
||||
&gcTotal,
|
||||
data.gcHeapChunkCleanDecommitted + data.gcHeapChunkDirtyDecommitted,
|
||||
rtStats.gcHeapChunkCleanDecommitted + rtStats.gcHeapChunkDirtyDecommitted,
|
||||
"Memory in the address space of the garbage-collected JavaScript heap that "
|
||||
"is currently returned to the OS.",
|
||||
callback, closure);
|
||||
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-chunk-admin"),
|
||||
&gcTotal, data.gcHeapChunkAdmin,
|
||||
&gcTotal, rtStats.gcHeapChunkAdmin,
|
||||
"Memory on the garbage-collected JavaScript heap, within chunks, that is "
|
||||
"used to hold internal book-keeping information.",
|
||||
callback, closure);
|
||||
|
||||
// gcTotal is the sum of everything we've reported for the GC heap. It
|
||||
// should equal data.gcHeapChunkTotal.
|
||||
JS_ASSERT(gcTotal == data.gcHeapChunkTotal);
|
||||
// should equal rtStats.gcHeapChunkTotal.
|
||||
JS_ASSERT(gcTotal == rtStats.gcHeapChunkTotal);
|
||||
}
|
||||
|
||||
} // namespace memory
|
||||
|
@ -1740,9 +1740,9 @@ public:
|
|||
// the callback. Separating these steps is important because the
|
||||
// callback may be a JS function, and executing JS while getting these
|
||||
// stats seems like a bad idea.
|
||||
JS::IterateData data(xpc::JsMallocSizeOf, xpc::GetCompartmentName,
|
||||
xpc::DestroyCompartmentName);
|
||||
if (!JS::CollectCompartmentStatsForRuntime(xpcrt->GetJSRuntime(), &data))
|
||||
JS::RuntimeStats rtStats(xpc::JsMallocSizeOf, xpc::GetCompartmentName,
|
||||
xpc::DestroyCompartmentName);
|
||||
if (!JS::CollectRuntimeStats(xpcrt->GetJSRuntime(), &rtStats))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
uint64_t xpconnect;
|
||||
|
@ -1755,7 +1755,7 @@ public:
|
|||
NS_NAMED_LITERAL_CSTRING(pathPrefix, "explicit/js/");
|
||||
|
||||
// This is the second step (see above).
|
||||
ReportJSRuntimeStats(data, pathPrefix, callback, closure);
|
||||
ReportJSRuntimeStats(rtStats, pathPrefix, callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("xpconnect"),
|
||||
nsIMemoryReporter::KIND_HEAP, xpconnect,
|
||||
|
@ -1764,28 +1764,28 @@ public:
|
|||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-gc-heap-chunk-dirty-unused"),
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
data.gcHeapChunkDirtyUnused,
|
||||
rtStats.gcHeapChunkDirtyUnused,
|
||||
"The same as 'explicit/js/gc-heap-chunk-dirty-unused'. Shown here for "
|
||||
"easy comparison with other 'js-gc' reporters.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-gc-heap-chunk-clean-unused"),
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
data.gcHeapChunkCleanUnused,
|
||||
rtStats.gcHeapChunkCleanUnused,
|
||||
"The same as 'explicit/js/gc-heap-chunk-clean-unused'. Shown here for "
|
||||
"easy comparison with other 'js-gc' reporters.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-gc-heap-decommitted"),
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
data.gcHeapChunkCleanDecommitted + data.gcHeapChunkDirtyDecommitted,
|
||||
rtStats.gcHeapChunkCleanDecommitted + rtStats.gcHeapChunkDirtyDecommitted,
|
||||
"The same as 'explicit/js/gc-heap-decommitted'. Shown here for "
|
||||
"easy comparison with other 'js-gc' reporters.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-gc-heap-arena-unused"),
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
data.gcHeapArenaUnused,
|
||||
rtStats.gcHeapArenaUnused,
|
||||
"Memory on the 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.",
|
||||
|
@ -1793,7 +1793,7 @@ public:
|
|||
|
||||
ReportMemoryPercentage(NS_LITERAL_CSTRING("js-gc-heap-unused-fraction"),
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
data.gcHeapUnusedPercentage,
|
||||
rtStats.gcHeapUnusedPercentage,
|
||||
"Fraction of the 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' + "
|
||||
|
@ -1801,14 +1801,14 @@ public:
|
|||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-objects"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalObjects,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalObjects,
|
||||
"Memory used for all object-related data. This is the sum of all "
|
||||
"compartments' 'gc-heap/objects-non-function', "
|
||||
"'gc-heap/objects-function' and 'object-slots' numbers.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-shapes"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalShapes,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalShapes,
|
||||
"Memory used for all shape-related data. This is the sum of all "
|
||||
"compartments' 'gc-heap/shapes/tree', 'gc-heap/shapes/dict', "
|
||||
"'gc-heap/shapes/base', "
|
||||
|
@ -1817,32 +1817,32 @@ public:
|
|||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-scripts"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalScripts,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalScripts,
|
||||
"Memory used for all script-related data. This is the sum of all "
|
||||
"compartments' 'gc-heap/scripts' and 'script-data' numbers.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-strings"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalStrings,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalStrings,
|
||||
"Memory used for all string-related data. This is the sum of all "
|
||||
"compartments' 'gc-heap/strings' and 'string-chars' numbers.",
|
||||
callback, closure);
|
||||
#ifdef JS_METHODJIT
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-mjit"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalMjit,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalMjit,
|
||||
"Memory used by the method JIT. This is the sum of all compartments' "
|
||||
"'mjit-code', and 'mjit-data' numbers.",
|
||||
callback, closure);
|
||||
#endif
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-type-inference"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalTypeInference,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalTypeInference,
|
||||
"Non-transient memory used by type inference. This is the sum of all "
|
||||
"compartments' 'gc-heap/type-objects', 'type-inference/script-main', "
|
||||
"'type-inference/object-main' and 'type-inference/tables' numbers.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-analysis-temporary"),
|
||||
nsIMemoryReporter::KIND_OTHER, data.totalAnalysisTemp,
|
||||
nsIMemoryReporter::KIND_OTHER, rtStats.totalAnalysisTemp,
|
||||
"Memory used transiently during type inference and compilation. "
|
||||
"This is the sum of all compartments' 'analysis-temporary' numbers.",
|
||||
callback, closure);
|
||||
|
|
|
@ -230,7 +230,7 @@ namespace xpconnect {
|
|||
namespace memory {
|
||||
|
||||
void
|
||||
ReportJSRuntimeStats(const JS::IterateData &data, const nsACString &pathPrefix,
|
||||
ReportJSRuntimeStats(const JS::RuntimeStats &rtStats, const nsACString &pathPrefix,
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче