Bug 1244841 - Don't measure SharedArrayBuffer objects multiple times. r=lth.

Redoes object element measurement and reporting:

- Adds "non-heap/elements/shared", which reports a (size / refcount)
  measurement. Previously these measurements went into
  "non-heap/elements/mapped" and the full size would be erroneously reported
  for every thread sharing the buffer.

- Renames "non-heap/elements/mapped" as "non-heap/elements/normal".

- Renames "malloc-heap/elements/non-asm.js" as "malloc-heap/elements/normal".

- Leaves "{malloc,non}-heap/elements/asm.js" unchanged.
This commit is contained in:
Nicholas Nethercote 2016-02-12 09:18:46 +11:00
parent 3e27bbe7d6
commit c59e7c0dae
6 changed files with 38 additions and 19 deletions

View File

@ -166,10 +166,11 @@ struct ClassInfo
#define FOR_EACH_SIZE(macro) \
macro(Objects, GCHeapUsed, objectsGCHeap) \
macro(Objects, MallocHeap, objectsMallocHeapSlots) \
macro(Objects, MallocHeap, objectsMallocHeapElementsNonAsmJS) \
macro(Objects, MallocHeap, objectsMallocHeapElementsNormal) \
macro(Objects, MallocHeap, objectsMallocHeapElementsAsmJS) \
macro(Objects, NonHeap, objectsNonHeapElementsNormal) \
macro(Objects, NonHeap, objectsNonHeapElementsAsmJS) \
macro(Objects, NonHeap, objectsNonHeapElementsMapped) \
macro(Objects, NonHeap, objectsNonHeapElementsShared) \
macro(Objects, NonHeap, objectsNonHeapCodeAsmJS) \
macro(Objects, MallocHeap, objectsMallocHeapMisc) \
\

View File

@ -3704,7 +3704,7 @@ JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassIn
if (is<NativeObject>() && as<NativeObject>().hasDynamicElements()) {
js::ObjectElements* elements = as<NativeObject>().getElementsHeader();
if (!elements->isCopyOnWrite() || elements->ownerObject() == this)
info->objectsMallocHeapElementsNonAsmJS += mallocSizeOf(elements);
info->objectsMallocHeapElementsNormal += mallocSizeOf(elements);
}
// Other things may be measured in the future if DMD indicates it is worthwhile.

View File

@ -754,10 +754,10 @@ ArrayBufferObject::addSizeOfExcludingThis(JSObject* obj, mozilla::MallocSizeOf m
switch (buffer.bufferKind()) {
case PLAIN:
info->objectsMallocHeapElementsNonAsmJS += mallocSizeOf(buffer.dataPointer());
info->objectsMallocHeapElementsNormal += mallocSizeOf(buffer.dataPointer());
break;
case MAPPED:
info->objectsNonHeapElementsMapped += buffer.byteLength();
info->objectsNonHeapElementsNormal += buffer.byteLength();
break;
case WASM_MALLOCED:
info->objectsMallocHeapElementsAsmJS += mallocSizeOf(buffer.dataPointer());

View File

@ -164,15 +164,15 @@ SharedArrayRawBuffer::New(JSContext* cx, uint32_t length)
void
SharedArrayRawBuffer::addReference()
{
MOZ_ASSERT(this->refcount > 0);
++this->refcount; // Atomic.
MOZ_ASSERT(this->refcount_ > 0);
++this->refcount_; // Atomic.
}
void
SharedArrayRawBuffer::dropReference()
{
// Drop the reference to the buffer.
uint32_t refcount = --this->refcount; // Atomic.
uint32_t refcount = --this->refcount_; // Atomic.
// If this was the final reference, release the buffer.
if (refcount == 0) {
@ -330,7 +330,15 @@ SharedArrayBufferObject::Finalize(FreeOp* fop, JSObject* obj)
SharedArrayBufferObject::addSizeOfExcludingThis(JSObject* obj, mozilla::MallocSizeOf mallocSizeOf,
JS::ClassInfo* info)
{
info->objectsNonHeapElementsMapped += obj->as<SharedArrayBufferObject>().byteLength();
// Divide the buffer size by the refcount to get the fraction of the buffer
// owned by this thread. It's conceivable that the refcount might change in
// the middle of memory reporting, in which case the amount reported for
// some threads might be to high (if the refcount goes up) or too low (if
// the refcount goes down). But that's unlikely and hard to avoid, so we
// just live with the risk.
const SharedArrayBufferObject& buf = obj->as<SharedArrayBufferObject>();
info->objectsNonHeapElementsShared +=
buf.byteLength() / buf.rawBufferObject()->refcount();
}
const Class SharedArrayBufferObject::protoClass = {

View File

@ -44,7 +44,7 @@ class FutexWaiter;
class SharedArrayRawBuffer
{
private:
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> refcount;
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> refcount_;
uint32_t length;
// A list of structures representing tasks waiting on some
@ -53,7 +53,7 @@ class SharedArrayRawBuffer
protected:
SharedArrayRawBuffer(uint8_t* buffer, uint32_t length)
: refcount(1),
: refcount_(1),
length(length),
waiters_(nullptr)
{
@ -84,6 +84,8 @@ class SharedArrayRawBuffer
return length;
}
uint32_t refcount() const { return refcount_; }
void addReference();
void dropReference();
};

View File

@ -2160,10 +2160,10 @@ ReportClassStats(const ClassInfo& classInfo, const nsACString& path,
"Non-fixed object slots.");
}
if (classInfo.objectsMallocHeapElementsNonAsmJS > 0) {
REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/malloc-heap/elements/non-asm.js"),
KIND_HEAP, classInfo.objectsMallocHeapElementsNonAsmJS,
"Non-asm.js indexed elements.");
if (classInfo.objectsMallocHeapElementsNormal > 0) {
REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/malloc-heap/elements/normal"),
KIND_HEAP, classInfo.objectsMallocHeapElementsNormal,
"Normal (non-asm.js) indexed elements.");
}
// asm.js arrays are heap-allocated on some platforms and
@ -2186,10 +2186,18 @@ ReportClassStats(const ClassInfo& classInfo, const nsACString& path,
"the GC heap.");
}
if (classInfo.objectsNonHeapElementsMapped > 0) {
REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/non-heap/elements/mapped"),
KIND_NONHEAP, classInfo.objectsNonHeapElementsMapped,
"Memory-mapped array buffer elements.");
if (classInfo.objectsNonHeapElementsNormal > 0) {
REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/non-heap/elements/normal"),
KIND_NONHEAP, classInfo.objectsNonHeapElementsNormal,
"Memory-mapped non-shared array buffer elements.");
}
if (classInfo.objectsNonHeapElementsShared > 0) {
REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/non-heap/elements/shared"),
KIND_NONHEAP, classInfo.objectsNonHeapElementsShared,
"Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.");
}
if (classInfo.objectsNonHeapCodeAsmJS > 0) {