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

--HG--
extra : rebase_source : 7710041552c96677344c85849cb6a7409a95edd2
This commit is contained in:
Nicholas Nethercote 2013-03-25 20:39:28 -07:00
parent ea912ef189
commit cc8b45cc14
5 changed files with 67 additions and 44 deletions

View File

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

View File

@ -5040,3 +5040,40 @@ js_DumpBacktrace(JSContext *cx)
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 void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes);
void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes);
bool hasIdempotentProtoChain() const;

View File

@ -1077,42 +1077,6 @@ JSObject::hasShapeTable() const
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
JSObject::lookupGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
js::MutableHandleObject objp, js::MutableHandleShape propp)

View File

@ -1763,11 +1763,29 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
"stored on the JavaScript heap; those slots "
"are not counted here, but in 'gc-heap/objects' instead.");
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements"),
cStats.objectsExtra.elements,
"Memory allocated for object element "
"arrays, which are used to represent indexed object "
"properties.");
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/non-asm.js"),
cStats.objectsExtra.elementsNonAsmJS,
"Memory allocated for non-asm.js object element arrays, "
"which are used to represent indexed object 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"),
cStats.objectsExtra.argumentsData,