mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 709653 - Fix GC heap memory reporters. r=bhackett.
--HG-- extra : rebase_source : 6805671750bd6a9e9661e70832a3837d4064f6ea
This commit is contained in:
parent
5e5a2b9464
commit
41607c5826
@ -537,7 +537,7 @@ ChunkPool::expire(JSRuntime *rt, bool releaseAll)
|
||||
}
|
||||
|
||||
JS_FRIEND_API(int64_t)
|
||||
ChunkPool::countDecommittedArenas(JSRuntime *rt)
|
||||
ChunkPool::countCleanDecommittedArenas(JSRuntime *rt)
|
||||
{
|
||||
JS_ASSERT(this == &rt->gcChunkPool);
|
||||
|
||||
|
@ -786,7 +786,7 @@ class ChunkPool {
|
||||
void expire(JSRuntime *rt, bool releaseAll);
|
||||
|
||||
/* Must be called either during the GC or with the GC lock taken. */
|
||||
JS_FRIEND_API(int64_t) countDecommittedArenas(JSRuntime *rt);
|
||||
JS_FRIEND_API(int64_t) countCleanDecommittedArenas(JSRuntime *rt);
|
||||
};
|
||||
|
||||
inline uintptr_t
|
||||
|
@ -1265,6 +1265,8 @@ CompartmentCallback(JSContext *cx, void *vdata, JSCompartment *compartment)
|
||||
void
|
||||
ChunkCallback(JSContext *cx, void *vdata, js::gc::Chunk *chunk)
|
||||
{
|
||||
// Nb: This function is only called for dirty chunks, which is why we
|
||||
// increment gcHeapChunkDirtyDecommitted.
|
||||
IterateData *data = static_cast<IterateData *>(vdata);
|
||||
for (uint32 i = 0; i < js::gc::ArenasPerChunk; i++)
|
||||
if (chunk->decommittedArenas.get(i))
|
||||
@ -1395,6 +1397,29 @@ ReportMemoryBytes0(const nsCString &path, PRInt32 kind, PRInt64 amount,
|
||||
ReportMemoryBytes(path, kind, amount, desc, callback, closure);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
inline void
|
||||
ReportGCHeapBytes(const nsACString &path, PRInt64 *total, PRInt64 amount,
|
||||
const char (&desc)[N],
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
ReportMemory(path, nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount,
|
||||
desc, callback, closure);
|
||||
*total += amount;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
inline void
|
||||
ReportGCHeapBytes0(const nsCString &path, PRInt64 *total, PRInt64 amount,
|
||||
const char (&desc)[N],
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
if (amount)
|
||||
return ReportGCHeapBytes(path, total, amount, desc, callback, closure);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
inline void
|
||||
ReportMemoryPercentage(const nsACString &path, PRInt32 kind, PRInt64 amount,
|
||||
@ -1418,8 +1443,6 @@ MakeMemoryReporterPath(const nsACString &pathPrefix,
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
#define JS_GC_HEAP_KIND nsIMemoryReporter::KIND_NONHEAP
|
||||
|
||||
// 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.
|
||||
@ -1548,7 +1571,7 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
||||
data->compartmentStatsVector.SetCapacity(rt->compartments.length());
|
||||
|
||||
data->gcHeapChunkCleanDecommitted =
|
||||
rt->gcChunkPool.countDecommittedArenas(rt) *
|
||||
rt->gcChunkPool.countCleanDecommittedArenas(rt) *
|
||||
js::gc::ArenaSize;
|
||||
data->gcHeapChunkCleanUnused =
|
||||
PRInt64(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) *
|
||||
@ -1629,6 +1652,7 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
||||
stats.gcHeapStrings +
|
||||
stats.gcHeapShapesTree +
|
||||
stats.gcHeapShapesDict +
|
||||
stats.gcHeapShapesBase +
|
||||
stats.gcHeapScripts +
|
||||
stats.gcHeapTypeObjects +
|
||||
stats.gcHeapXML;
|
||||
@ -1683,51 +1707,53 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
||||
#define SLOP_BYTES_STRING \
|
||||
" The measurement includes slop bytes caused by the heap allocator rounding up request sizes."
|
||||
|
||||
static void
|
||||
static PRInt64
|
||||
ReportCompartmentStats(const CompartmentStats &stats,
|
||||
const nsACString &pathPrefix,
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
PRInt64 gcTotal = 0;
|
||||
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/arena/headers"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapArenaHeaders,
|
||||
&gcTotal, stats.gcHeapArenaHeaders,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap, within "
|
||||
"arenas, that is used to hold internal book-keeping information.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/arena/padding"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapArenaPadding,
|
||||
&gcTotal, stats.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);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/arena/unused"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapArenaUnused,
|
||||
&gcTotal, stats.gcHeapArenaUnused,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap, within "
|
||||
"arenas, that could be holding useful data but currently isn't.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/objects/non-function"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapObjectsNonFunction,
|
||||
&gcTotal, stats.gcHeapObjectsNonFunction,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"non-function objects.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/objects/function"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapObjectsFunction,
|
||||
&gcTotal, stats.gcHeapObjectsFunction,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"function objects.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/strings"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapStrings,
|
||||
&gcTotal, stats.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 "
|
||||
@ -1735,45 +1761,45 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
"under 'gc-heap/string-chars' instead.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/scripts"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapScripts,
|
||||
&gcTotal, stats.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);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/shapes/tree"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapShapesTree,
|
||||
&gcTotal, stats.gcHeapShapesTree,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"shapes that are in a property tree.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/shapes/dict"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapShapesDict,
|
||||
&gcTotal, stats.gcHeapShapesDict,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"shapes that are in dictionary mode.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/shapes/base"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapShapesBase,
|
||||
&gcTotal, stats.gcHeapShapesBase,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that collates "
|
||||
"data common to many shapes.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/type-objects"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapTypeObjects,
|
||||
&gcTotal, stats.gcHeapTypeObjects,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"type inference information.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
ReportGCHeapBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/xml"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapXML,
|
||||
&gcTotal, stats.gcHeapXML,
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"E4X XML objects.",
|
||||
callback, closure);
|
||||
@ -1858,7 +1884,7 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"type-inference/object-main"),
|
||||
JS_GC_HEAP_KIND,
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.typeInferenceMemory.objects,
|
||||
"Memory used during type inference to store types and possible "
|
||||
"property types of JS objects.",
|
||||
@ -1878,6 +1904,8 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
"Memory used during type inference and compilation to hold transient "
|
||||
"analysis information. Cleared on GC.",
|
||||
callback, closure);
|
||||
|
||||
return gcTotal;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1885,11 +1913,12 @@ ReportJSRuntimeStats(const IterateData &data, const nsACString &pathPrefix,
|
||||
nsIMemoryMultiReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
PRInt64 gcTotal = 0;
|
||||
for (PRUint32 index = 0;
|
||||
index < data.compartmentStatsVector.Length();
|
||||
index++) {
|
||||
ReportCompartmentStats(data.compartmentStatsVector[index], pathPrefix,
|
||||
callback, closure);
|
||||
gcTotal += ReportCompartmentStats(data.compartmentStatsVector[index], pathPrefix,
|
||||
callback, closure);
|
||||
}
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/runtime-object"),
|
||||
@ -1939,39 +1968,42 @@ ReportJSRuntimeStats(const IterateData &data, const nsACString &pathPrefix,
|
||||
"Memory used by XPConnect." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix +
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-chunk-dirty-unused"),
|
||||
JS_GC_HEAP_KIND, data.gcHeapChunkDirtyUnused,
|
||||
&gcTotal, data.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"
|
||||
"under gc-heap-decommitted.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix +
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-chunk-clean-unused"),
|
||||
JS_GC_HEAP_KIND, data.gcHeapChunkCleanUnused,
|
||||
&gcTotal, data.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 "
|
||||
"gc-heap-decommitted.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix +
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-decommitted"),
|
||||
JS_GC_HEAP_KIND,
|
||||
&gcTotal,
|
||||
data.gcHeapChunkCleanDecommitted + data.gcHeapChunkDirtyDecommitted,
|
||||
"Memory in the address space of the garbage-collected JavaScript heap that "
|
||||
"is currently returned to the OS.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix +
|
||||
ReportGCHeapBytes(pathPrefix +
|
||||
NS_LITERAL_CSTRING("gc-heap-chunk-admin"),
|
||||
JS_GC_HEAP_KIND, data.gcHeapChunkAdmin,
|
||||
&gcTotal, data.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);
|
||||
}
|
||||
|
||||
} // namespace memory
|
||||
|
Loading…
Reference in New Issue
Block a user