From 0c97e981f15956c69a0b60f9a80a6655e5371c81 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 12 Jun 2019 16:22:03 +0100 Subject: [PATCH] Bug 1395509 - Track malloc memory used by non-inline TypedArray elements r=sfink Note that we only track the for typed arrays that are not backed by an ArrayBuffer as the memory is tracked there from then on. Differential Revision: https://phabricator.services.mozilla.com/D34729 --- js/src/gc/GCEnum.h | 3 ++- js/src/jit/MacroAssembler.cpp | 9 +++++---- js/src/vm/TypedArrayObject.cpp | 18 +++++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index 3b88a5a4b4d7..4fdbe1980aba 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -110,7 +110,8 @@ enum class ZealMode { _(ArgumentsData) \ _(RareArgumentsData) \ _(RegExpStatics) \ - _(RegExpSharedBytecode) + _(RegExpSharedBytecode) \ + _(TypedArrayElements) #define JS_FOR_EACH_MEMORY_USE(_) \ JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 5ba710a1a996..13b92db3d972 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -871,8 +871,9 @@ static void FindStartOfUninitializedAndUndefinedSlots( } } -static void AllocateObjectBufferWithInit(JSContext* cx, TypedArrayObject* obj, - int32_t count) { +static void AllocateAndInitTypedArrayBuffer(JSContext* cx, + TypedArrayObject* obj, + int32_t count) { AutoUnsafeCallWithABI unsafe; obj->initPrivate(nullptr); @@ -895,7 +896,7 @@ static void AllocateObjectBufferWithInit(JSContext* cx, TypedArrayObject* obj, void* buf = cx->nursery().allocateZeroedBuffer(obj, nbytes, js::ArrayBufferContentsArena); if (buf) { - obj->initPrivate(buf); + InitObjectPrivate(obj, buf, nbytes, MemoryUse::TypedArrayElements); } } @@ -964,7 +965,7 @@ void MacroAssembler::initTypedArraySlots(Register obj, Register temp, passABIArg(temp); passABIArg(obj); passABIArg(lengthReg); - callWithABI(JS_FUNC_TO_DATA_PTR(void*, AllocateObjectBufferWithInit)); + callWithABI(JS_FUNC_TO_DATA_PTR(void*, AllocateAndInitTypedArrayBuffer)); PopRegsInMask(liveRegs); // Fail when data elements is set to NULL. diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 879d6175df28..8521fc399e39 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -122,10 +122,12 @@ bool TypedArrayObject::ensureHasBuffer(JSContext* cx, // If the object is in the nursery, the buffer will be freed by the next // nursery GC. Free the data slot pointer if the object has no inline data. + size_t nbytes = JS_ROUNDUP(tarray->byteLength(), sizeof(Value)); Nursery& nursery = cx->nursery(); if (tarray->isTenured() && !tarray->hasInlineElements() && !nursery.isInside(tarray->elements())) { js_free(tarray->elements()); + RemoveCellMemory(tarray, nbytes, MemoryUse::TypedArrayElements); } tarray->setPrivate(buffer->dataPointer()); @@ -166,7 +168,8 @@ void TypedArrayObject::finalize(FreeOp* fop, JSObject* obj) { // Free the data slot pointer if it does not point into the old JSObject. if (!curObj->hasInlineElements()) { - fop->free_(curObj->elements()); + size_t nbytes = JS_ROUNDUP(curObj->byteLength(), sizeof(Value)); + fop->free_(obj, curObj->elements(), nbytes, MemoryUse::TypedArrayElements); } } @@ -202,6 +205,8 @@ size_t TypedArrayObject::objectMoved(JSObject* obj, JSObject* old) { Nursery& nursery = obj->runtimeFromMainThread()->gc.nursery(); if (!nursery.isInside(buf)) { nursery.removeMallocedBuffer(buf); + size_t nbytes = JS_ROUNDUP(newObj->byteLength(), sizeof(Value)); + AddCellMemory(newObj, nbytes, MemoryUse::TypedArrayElements); return 0; } @@ -240,7 +245,7 @@ size_t TypedArrayObject::objectMoved(JSObject* obj, JSObject* old) { "Failed to allocate typed array elements while tenuring."); } MOZ_ASSERT(!nursery.isInside(data)); - newObj->initPrivate(data); + InitObjectPrivate(newObj, data, nbytes, MemoryUse::TypedArrayElements); } mozilla::PodCopy(newObj->elements(), oldObj->elements(), nbytes); @@ -512,12 +517,11 @@ class TypedArrayObjectTemplate : public TypedArrayObject { #endif } - static void initTypedArrayData(TypedArrayObject* tarray, int32_t len, - void* buf, gc::AllocKind allocKind) { + static void initTypedArrayData(TypedArrayObject* tarray, void* buf, + size_t nbytes, gc::AllocKind allocKind) { if (buf) { - tarray->initPrivate(buf); + InitObjectPrivate(tarray, buf, nbytes, MemoryUse::TypedArrayElements); } else { - size_t nbytes = len * BYTES_PER_ELEMENT; #ifdef DEBUG constexpr size_t dataOffset = TypedArrayObject::dataOffset(); constexpr size_t offset = dataOffset + sizeof(HeapSlot); @@ -571,7 +575,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject { } } - initTypedArrayData(obj, len, buf, allocKind); + initTypedArrayData(obj, buf, nbytes, allocKind); return obj; }