mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 676732 - Measure and/or avoid slop in important JS memory reporters. r=dmandelin.
This commit is contained in:
parent
59e8ad1ced
commit
5164fb3ecf
@ -2717,6 +2717,15 @@ obj_preventExtensions(JSContext *cx, uintN argc, Value *vp)
|
||||
return obj->preventExtensions(cx, &props);
|
||||
}
|
||||
|
||||
size_t
|
||||
JSObject::sizeOfSlotsArray(size_t(*mus)(void *))
|
||||
{
|
||||
if (!hasSlotsArray())
|
||||
return 0;
|
||||
size_t usable = mus((void *)slots);
|
||||
return usable ? usable : numSlots() * sizeof(js::Value);
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::sealOrFreeze(JSContext *cx, ImmutabilityType it)
|
||||
{
|
||||
|
@ -478,6 +478,8 @@ struct JSObject : js::gc::Cell {
|
||||
jsuword initializedLength;
|
||||
};
|
||||
|
||||
size_t sizeOfSlotsArray(size_t(*mus)(void *));
|
||||
|
||||
JSObject *parent; /* object's parent */
|
||||
void *privateData; /* private data */
|
||||
jsuword capacity; /* total number of available slots */
|
||||
|
@ -251,7 +251,12 @@ struct PropertyTable {
|
||||
/* Computes the size of the entries array for a given capacity. */
|
||||
static size_t sizeOfEntries(size_t cap) { return cap * sizeof(Shape *); }
|
||||
|
||||
size_t sizeOf() const {
|
||||
size_t sizeOf(size_t(*mus)(void *)) const {
|
||||
if (mus) {
|
||||
size_t usable = mus((void*)this) + mus(entries);
|
||||
if (usable)
|
||||
return usable;
|
||||
}
|
||||
return sizeOfEntries(capacity()) + sizeof(PropertyTable);
|
||||
}
|
||||
|
||||
|
@ -674,8 +674,9 @@ struct JSScript : public js::gc::Cell {
|
||||
return JITScript_Valid;
|
||||
}
|
||||
|
||||
// This method is implemented in MethodJIT.h.
|
||||
JS_FRIEND_API(size_t) jitDataSize();/* Size of the JITScript and all sections */
|
||||
/* Size of the JITScript and all sections. (This method is implemented in MethodJIT.h.) */
|
||||
JS_FRIEND_API(size_t) jitDataSize(size_t(*mus)(void *));
|
||||
|
||||
#endif
|
||||
|
||||
jsbytecode *main() {
|
||||
|
@ -183,9 +183,9 @@ using namespace js::tjit;
|
||||
*
|
||||
* FIXME: Bug 624590 is open to get rid of all this.
|
||||
*/
|
||||
static const size_t DataReserveSize = 12500 * sizeof(uintptr_t);
|
||||
static const size_t TraceReserveSize = 5000 * sizeof(uintptr_t);
|
||||
static const size_t TempReserveSize = 1000 * sizeof(uintptr_t);
|
||||
static const size_t DataReserveSize = 8192 * sizeof(uintptr_t);
|
||||
static const size_t TraceReserveSize = 512 * sizeof(uintptr_t);
|
||||
static const size_t TempReserveSize = 4096 * sizeof(uintptr_t);
|
||||
|
||||
void*
|
||||
nanojit::Allocator::allocChunk(size_t nbytes, bool fallible)
|
||||
|
@ -1328,7 +1328,8 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
|
||||
#endif
|
||||
|
||||
JS_ASSERT(size_t(cursor - (uint8*)jit) == dataSize);
|
||||
JS_ASSERT(jit->scriptDataSize() == dataSize);
|
||||
/* Pass in NULL here -- we don't want slop bytes to be counted. */
|
||||
JS_ASSERT(jit->scriptDataSize(NULL) == dataSize);
|
||||
|
||||
/* Link fast and slow paths together. */
|
||||
stubcc.fixCrossJumps(result, masm.size(), masm.size() + stubcc.size());
|
||||
|
@ -1137,21 +1137,23 @@ mjit::JITScript::~JITScript()
|
||||
}
|
||||
|
||||
size_t
|
||||
JSScript::jitDataSize()
|
||||
JSScript::jitDataSize(size_t(*mus)(void *))
|
||||
{
|
||||
size_t n = 0;
|
||||
if (jitNormal)
|
||||
n += jitNormal->scriptDataSize();
|
||||
n += jitNormal->scriptDataSize(mus);
|
||||
if (jitCtor)
|
||||
n += jitCtor->scriptDataSize();
|
||||
n += jitCtor->scriptDataSize(mus);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Please keep in sync with Compiler::finishThisUp! */
|
||||
size_t
|
||||
mjit::JITScript::scriptDataSize()
|
||||
mjit::JITScript::scriptDataSize(size_t(*mus)(void *))
|
||||
{
|
||||
return sizeof(JITScript) +
|
||||
size_t usable = mus ? mus(this) : 0;
|
||||
return usable ? usable :
|
||||
sizeof(JITScript) +
|
||||
sizeof(NativeMapEntry) * nNmapPairs +
|
||||
sizeof(InlineFrame) * nInlineFrames +
|
||||
sizeof(CallSite) * nCallSites +
|
||||
|
@ -640,7 +640,7 @@ struct JITScript {
|
||||
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
size_t scriptDataSize();
|
||||
size_t scriptDataSize(size_t(*mus)(void *));
|
||||
|
||||
jsbytecode *nativeToPC(void *returnAddress, CallSite **pinline) const;
|
||||
|
||||
|
@ -4070,13 +4070,13 @@ MJitCodeStats(JSContext *cx, uintN argc, jsval *vp)
|
||||
#ifdef JS_METHODJIT
|
||||
|
||||
static void
|
||||
SumJitDataSizeCallabck(JSContext *cx, void *data, void *thing,
|
||||
SumJitDataSizeCallback(JSContext *cx, void *data, void *thing,
|
||||
JSGCTraceKind traceKind, size_t thingSize)
|
||||
{
|
||||
size_t *sump = static_cast<size_t *>(data);
|
||||
JS_ASSERT(traceKind == JSTRACE_SCRIPT);
|
||||
JSScript *script = static_cast<JSScript *>(thing);
|
||||
*sump += script->jitDataSize();
|
||||
*sump += script->jitDataSize(NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -4086,7 +4086,7 @@ MJitDataStats(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
size_t n = 0;
|
||||
IterateCells(cx, NULL, gc::FINALIZE_TYPE_OBJECT, &n, SumJitDataSizeCallabck);
|
||||
IterateCells(cx, NULL, gc::FINALIZE_TYPE_OBJECT, &n, SumJitDataSizeCallback);
|
||||
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(n));
|
||||
#else
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
|
@ -1346,7 +1346,7 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
||||
case JSTRACE_OBJECT:
|
||||
{
|
||||
JSObject *obj = static_cast<JSObject *>(thing);
|
||||
curr->objectSlots += JS_ObjectCountDynamicSlots(obj) * sizeof(js::Value);
|
||||
curr->objectSlots += obj->sizeOfSlotsArray(moz_malloc_usable_size);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_STRING:
|
||||
@ -1359,15 +1359,19 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
||||
{
|
||||
js::Shape *shape = static_cast<js::Shape *>(thing);
|
||||
if(shape->hasTable())
|
||||
curr->propertyTables += shape->getTable()->sizeOf();
|
||||
curr->propertyTables +=
|
||||
shape->getTable()->sizeOf(moz_malloc_usable_size);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_SCRIPT:
|
||||
{
|
||||
JSScript *script = static_cast<JSScript *>(thing);
|
||||
curr->scriptData += script->dataSize();
|
||||
if (script->data != script->inlineData) {
|
||||
size_t usable = moz_malloc_usable_size(script->data);
|
||||
curr->scriptData += usable ? usable : script->dataSize();
|
||||
}
|
||||
#ifdef JS_METHODJIT
|
||||
curr->mjitData += script->jitDataSize();
|
||||
curr->mjitData += script->jitDataSize(moz_malloc_usable_size);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -1628,6 +1632,8 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
||||
for(js::ThreadDataIter i(rt); !i.empty(); i.popFront())
|
||||
data->stackSize += i.threadData()->stackSpace.committedSize();
|
||||
|
||||
size_t usable = moz_malloc_usable_size(rt);
|
||||
data->runtimeObjectSize += usable ? usable : sizeof(JSRuntime);
|
||||
data->atomsTableSize += rt->atomState.atoms.tableSize();
|
||||
}
|
||||
|
||||
@ -1674,6 +1680,9 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define SLOP_BYTES_STRING \
|
||||
" The measurement includes slop bytes caused by the heap allocator rounding up request sizes."
|
||||
|
||||
static void
|
||||
ReportCompartmentStats(const CompartmentStats &stats,
|
||||
const nsACString &pathPrefix,
|
||||
@ -1736,7 +1745,7 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"gc-heap/shapes"),
|
||||
"gc-heap/type-objects"),
|
||||
JS_GC_HEAP_KIND, stats.gcHeapKinds[JSTRACE_TYPE_OBJECT],
|
||||
"Memory on the compartment's garbage-collected JavaScript heap that holds "
|
||||
"type inference information.",
|
||||
@ -1756,7 +1765,7 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
"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 are not counted here, but in "
|
||||
"'gc-heap/objects' instead.",
|
||||
"'gc-heap/objects' instead." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
@ -1774,7 +1783,7 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
nsIMemoryReporter::KIND_HEAP, stats.propertyTables,
|
||||
"Memory allocated for the compartment's property tables. A property "
|
||||
"table is an internal data structure that makes JavaScript property "
|
||||
"accesses fast.",
|
||||
"accesses fast." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
@ -1784,20 +1793,11 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
"Arrays attached to prototype JS objects managing shape information.",
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"scripts"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.gcHeapKinds[JSTRACE_SCRIPT],
|
||||
"Memory allocated for the compartment's JSScripts. 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,
|
||||
"script-data"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.scriptData,
|
||||
"Memory allocated for JSScript bytecode and various variable-length "
|
||||
"tables.",
|
||||
"tables." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
@ -1824,7 +1824,7 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
"mjit-data"),
|
||||
nsIMemoryReporter::KIND_HEAP, stats.mjitData,
|
||||
"Memory used by the method JIT for the compartment's compilation data: "
|
||||
"JITScripts, native maps, and inline cache structs.",
|
||||
"JITScripts, native maps, and inline cache structs." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
#endif
|
||||
#ifdef JS_TRACER
|
||||
@ -1884,11 +1884,11 @@ ReportCompartmentStats(const CompartmentStats &stats,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes0(MakeMemoryReporterPath(pathPrefix, stats.name,
|
||||
"type-inference-temporary"),
|
||||
"analysis-temporary"),
|
||||
nsIMemoryReporter::KIND_HEAP,
|
||||
stats.typeInferenceMemory.temporary,
|
||||
"Memory used during type inference to hold transient analysis "
|
||||
"information. Cleared on GC.",
|
||||
"Memory used during type inference and compilation to hold transient "
|
||||
"analysis information. Cleared on GC.",
|
||||
callback, closure);
|
||||
}
|
||||
|
||||
@ -1906,8 +1906,8 @@ ReportJSRuntimeStats(const IterateData &data, const nsACString &pathPrefix,
|
||||
}
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/runtime-object"),
|
||||
nsIMemoryReporter::KIND_NONHEAP, sizeof(JSRuntime),
|
||||
"Memory used by the JSRuntime object.",
|
||||
nsIMemoryReporter::KIND_NONHEAP, data.runtimeObjectSize,
|
||||
"Memory used by the JSRuntime object." SLOP_BYTES_STRING,
|
||||
callback, closure);
|
||||
|
||||
ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("runtime/atoms-table"),
|
||||
|
@ -227,7 +227,8 @@ struct CompartmentStats
|
||||
struct IterateData
|
||||
{
|
||||
IterateData()
|
||||
: atomsTableSize(0),
|
||||
: runtimeObjectSize(0),
|
||||
atomsTableSize(0),
|
||||
stackSize(0),
|
||||
gcHeapChunkTotal(0),
|
||||
gcHeapChunkCleanUnused(0),
|
||||
@ -238,6 +239,7 @@ struct IterateData
|
||||
compartmentStatsVector(),
|
||||
currCompartmentStats(NULL) { }
|
||||
|
||||
PRInt64 runtimeObjectSize;
|
||||
PRInt64 atomsTableSize;
|
||||
PRInt64 stackSize;
|
||||
PRInt64 gcHeapChunkTotal;
|
||||
|
Loading…
Reference in New Issue
Block a user