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
This commit is contained in:
Jon Coppeard 2019-06-12 16:22:03 +01:00
parent 2f2b9fb759
commit 0c97e981f1
3 changed files with 18 additions and 12 deletions

View File

@ -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(_) \

View File

@ -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.

View File

@ -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;
}