Bug 854763 - Add a memory reporter for asm.js array buffers. r=luke.

This commit is contained in:
Nicholas Nethercote
2013-03-25 20:39:28 -07:00
parent a2dde8111a
commit c39929eef5
5 changed files with 67 additions and 44 deletions

View File

@@ -40,7 +40,9 @@ namespace JS {
struct ObjectsExtraSizes struct ObjectsExtraSizes
{ {
size_t slots; size_t slots;
size_t elements; size_t elementsNonAsmJS;
size_t elementsAsmJSHeap;
size_t elementsAsmJSNonHeap;
size_t argumentsData; size_t argumentsData;
size_t regExpStatics; size_t regExpStatics;
size_t propertyIteratorData; size_t propertyIteratorData;
@@ -52,7 +54,9 @@ struct ObjectsExtraSizes
void add(ObjectsExtraSizes &sizes) { void add(ObjectsExtraSizes &sizes) {
this->slots += sizes.slots; this->slots += sizes.slots;
this->elements += sizes.elements; this->elementsNonAsmJS += sizes.elementsNonAsmJS;
this->elementsAsmJSHeap += sizes.elementsAsmJSHeap;
this->elementsAsmJSNonHeap += sizes.elementsAsmJSNonHeap;
this->argumentsData += sizes.argumentsData; this->argumentsData += sizes.argumentsData;
this->regExpStatics += sizes.regExpStatics; this->regExpStatics += sizes.regExpStatics;
this->propertyIteratorData += sizes.propertyIteratorData; this->propertyIteratorData += sizes.propertyIteratorData;

View File

@@ -5040,3 +5040,40 @@ js_DumpBacktrace(JSContext *cx)
fprintf(stdout, "%s", sprinter.string()); fprintf(stdout, "%s", sprinter.string());
} }
void
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes)
{
if (hasDynamicSlots())
sizes->slots = mallocSizeOf(slots);
if (hasDynamicElements()) {
js::ObjectElements *elements = getElementsHeader();
if (JS_UNLIKELY(elements->isAsmJSArrayBuffer())) {
#if defined (JS_CPU_X64)
// On x64, ArrayBufferObject::prepareForAsmJS switches the
// ArrayBufferObject to use mmap'd storage.
sizes->elementsAsmJSNonHeap = asArrayBuffer().byteLength();
#else
sizes->elementsAsmJSHeap = mallocSizeOf(elements);
#endif
} else {
sizes->elementsNonAsmJS = mallocSizeOf(elements);
}
}
// Other things may be measured in the future if DMD indicates it is worthwhile.
// Note that sizes->private_ is measured elsewhere.
if (isArguments()) {
sizes->argumentsData = asArguments().sizeOfMisc(mallocSizeOf);
} else if (isRegExpStatics()) {
sizes->regExpStatics = js::SizeOfRegExpStaticsData(this, mallocSizeOf);
} else if (isPropertyIterator()) {
sizes->propertyIteratorData = asPropertyIterator().sizeOfMisc(mallocSizeOf);
#ifdef JS_HAS_CTYPES
} else {
// This must be the last case.
sizes->ctypesData = js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
#endif
}
}

View File

@@ -370,7 +370,7 @@ class JSObject : public js::ObjectImpl
inline bool hasShapeTable() const; inline bool hasShapeTable() const;
inline void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes); void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes);
bool hasIdempotentProtoChain() const; bool hasIdempotentProtoChain() const;

View File

@@ -1077,42 +1077,6 @@ JSObject::hasShapeTable() const
return lastProperty()->hasTable(); return lastProperty()->hasTable();
} }
inline void
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes)
{
if (hasDynamicSlots())
sizes->slots = mallocSizeOf(slots);
if (hasDynamicElements()) {
js::ObjectElements *elements = getElementsHeader();
#if defined (JS_CPU_X64)
// On x64, ArrayBufferObject::prepareForAsmJS switches the
// ArrayBufferObject to use mmap'd storage. This is not included in the
// total 'explicit' figure and thus we must not include it here.
// TODO: include it somewhere else.
if (JS_LIKELY(!elements->isAsmJSArrayBuffer()))
sizes->elements = mallocSizeOf(elements);
#else
sizes->elements = mallocSizeOf(elements);
#endif
}
// Other things may be measured in the future if DMD indicates it is worthwhile.
// Note that sizes->private_ is measured elsewhere.
if (isArguments()) {
sizes->argumentsData = asArguments().sizeOfMisc(mallocSizeOf);
} else if (isRegExpStatics()) {
sizes->regExpStatics = js::SizeOfRegExpStaticsData(this, mallocSizeOf);
} else if (isPropertyIterator()) {
sizes->propertyIteratorData = asPropertyIterator().sizeOfMisc(mallocSizeOf);
#ifdef JS_HAS_CTYPES
} else {
// This must be the last case.
sizes->ctypesData = js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
#endif
}
}
/* static */ inline JSBool /* static */ inline JSBool
JSObject::lookupGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id, JSObject::lookupGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
js::MutableHandleObject objp, js::MutableHandleShape propp) js::MutableHandleObject objp, js::MutableHandleShape propp)

View File

@@ -1763,11 +1763,29 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
"stored on the JavaScript heap; those slots " "stored on the JavaScript heap; those slots "
"are not counted here, but in 'gc-heap/objects' instead."); "are not counted here, but in 'gc-heap/objects' instead.");
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements"), ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/non-asm.js"),
cStats.objectsExtra.elements, cStats.objectsExtra.elementsNonAsmJS,
"Memory allocated for object element " "Memory allocated for non-asm.js object element arrays, "
"arrays, which are used to represent indexed object " "which are used to represent indexed object properties.");
"properties.");
// asm.js arrays are heap-allocated on some platforms and
// non-heap-allocated on others. We never put them under sundries,
// because (a) in practice they're almost always larger than the sundries
// threshold, and (b) we'd need a third category of non-heap, non-GC
// sundries, which would be a pain.
#define ASM_JS_DESC "Memory allocated for object element " \
"arrays used as asm.js array buffers."
size_t asmJSHeap = cStats.objectsExtra.elementsAsmJSHeap;
size_t asmJSNonHeap = cStats.objectsExtra.elementsAsmJSNonHeap;
JS_ASSERT(asmJSHeap == 0 || asmJSNonHeap == 0);
if (asmJSHeap > 0) {
REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/asm.js"),
nsIMemoryReporter::KIND_HEAP, asmJSHeap, ASM_JS_DESC);
}
if (asmJSNonHeap > 0) {
REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/asm.js"),
nsIMemoryReporter::KIND_NONHEAP, asmJSNonHeap, ASM_JS_DESC);
}
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/arguments-data"), ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/arguments-data"),
cStats.objectsExtra.argumentsData, cStats.objectsExtra.argumentsData,