From f101e6b927580b0814e65a77092588ee2cc7520f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Wed, 27 Nov 2019 13:56:16 +0000 Subject: [PATCH] Bug 1599416 - Part 8: Remove view tracking for TypedObjects. r=mgaudet `ArrayBufferObject::detach` expects all views are `ArrayBufferViewObject`, which means detaching an ArrayBuffer used for TypedObjects already crashes anyway. Instead let's change `ArrayBufferObject::addView` and `ABO::setFirstView` to only accept `ArrayBufferViewObject` and then remove the `addView` call in `OutlineTypedObject::attach`. Additionally introduce `ABO::createForTypedObject` as the single function which can call `ABO::setHasTypedObjectViews` to mark an ArrayBufferObject as being used for TypedObjects. Differential Revision: https://phabricator.services.mozilla.com/D54712 --HG-- extra : moz-landing-system : lando --- js/src/builtin/TypedObject.cpp | 12 ++---------- js/src/vm/ArrayBufferObject.cpp | 17 +++++++++++------ js/src/vm/ArrayBufferObject.h | 13 ++++++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index fa4c50396f00..42fef538e7ef 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -1607,15 +1607,7 @@ void OutlineTypedObject::attach(JSContext* cx, ArrayBufferObject& buffer, MOZ_ASSERT(!isAttached()); MOZ_ASSERT(offset <= buffer.byteLength()); MOZ_ASSERT(size() <= buffer.byteLength() - offset); - - buffer.setHasTypedObjectViews(); - - { - AutoEnterOOMUnsafeRegion oomUnsafe; - if (!buffer.addView(cx, this)) { - oomUnsafe.crash("TypedObject::attach"); - } - } + MOZ_ASSERT(buffer.hasTypedObjectViews()); setOwnerAndData(&buffer, buffer.dataPointer() + offset); } @@ -1688,7 +1680,7 @@ TypedObject* TypedObject::createZeroed(JSContext* cx, HandleTypeDescr descr, // Allocate and initialize the memory for this instance. size_t totalSize = descr->size(); Rooted buffer(cx); - buffer = ArrayBufferObject::createZeroed(cx, totalSize); + buffer = ArrayBufferObject::createForTypedObject(cx, totalSize); if (!buffer) { return nullptr; } diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 744d499414d6..8bba156b79be 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -1261,6 +1261,15 @@ ArrayBufferObject* ArrayBufferObject::createZeroed( return buffer; } +ArrayBufferObject* ArrayBufferObject::createForTypedObject(JSContext* cx, + uint32_t nbytes) { + ArrayBufferObject* buffer = createZeroed(cx, nbytes); + if (buffer) { + buffer->setHasTypedObjectViews(); + } + return buffer; +} + ArrayBufferObject* ArrayBufferObject::createEmpty(JSContext* cx) { AutoSetNewObjectMetadata metadata(cx); ArrayBufferObject* obj = NewBuiltinClassInstance(cx); @@ -1483,15 +1492,11 @@ JSObject* ArrayBufferObject::firstView() { : nullptr; } -void ArrayBufferObject::setFirstView(JSObject* view) { - MOZ_ASSERT_IF(view, - view->is() || view->is()); +void ArrayBufferObject::setFirstView(ArrayBufferViewObject* view) { setFixedSlot(FIRST_VIEW_SLOT, ObjectOrNullValue(view)); } -bool ArrayBufferObject::addView(JSContext* cx, JSObject* view) { - MOZ_ASSERT(view->is() || view->is()); - +bool ArrayBufferObject::addView(JSContext* cx, ArrayBufferViewObject* view) { if (!firstView()) { setFirstView(view); return true; diff --git a/js/src/vm/ArrayBufferObject.h b/js/src/vm/ArrayBufferObject.h index bff18b6b23ce..2aefa25bc1e7 100644 --- a/js/src/vm/ArrayBufferObject.h +++ b/js/src/vm/ArrayBufferObject.h @@ -217,7 +217,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared { DETACHED = 0b1000, - // Views of this buffer might include typed objects. + // Views of this buffer include only typed objects. TYPED_OBJECT_VIEWS = 0b1'0000, // This MALLOCED, MAPPED, or EXTERNAL buffer has been prepared for asm.js @@ -322,6 +322,9 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared { static ArrayBufferObject* createZeroed(JSContext* cx, uint32_t nbytes, HandleObject proto = nullptr); + static ArrayBufferObject* createForTypedObject(JSContext* cx, + uint32_t nbytes); + // Create an ArrayBufferObject that is safely finalizable and can later be // initialize()d to become a real, content-visible ArrayBufferObject. static ArrayBufferObject* createEmpty(JSContext* cx); @@ -356,14 +359,14 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared { // non-incrementalized sweep time. JSObject* firstView(); - bool addView(JSContext* cx, JSObject* view); + bool addView(JSContext* cx, ArrayBufferViewObject* view); // Detach this buffer from its original memory. (This necessarily makes // views of this buffer unusable for modifying that original memory.) static void detach(JSContext* cx, Handle buffer); private: - void setFirstView(JSObject* view); + void setFirstView(ArrayBufferViewObject* view); uint8_t* inlineDataPointer() const; @@ -427,7 +430,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared { static BufferContents createMappedContents(int fd, size_t offset, size_t length); - void setHasTypedObjectViews() { setFlags(flags() | TYPED_OBJECT_VIEWS); } + bool hasTypedObjectViews() const { return flags() & TYPED_OBJECT_VIEWS; } protected: void setDataPointer(BufferContents contents); @@ -438,7 +441,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared { uint32_t flags() const; void setFlags(uint32_t flags); - bool hasTypedObjectViews() const { return flags() & TYPED_OBJECT_VIEWS; } + void setHasTypedObjectViews() { setFlags(flags() | TYPED_OBJECT_VIEWS); } void setIsDetached() { setFlags(flags() | DETACHED); } void setIsPreparedForAsmJS() {