tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit f77375ba41acc4f5ea4ec581b1060a6dac5d888b
parent f49212e6d50613b3ce7f7aedac5c364a33d542ae
Author: Andy Wingo <wingo@igalia.com>
Date:   Mon,  8 Dec 2025 16:02:52 +0000

Bug 1977854 - Add PageSize to array buffers.  r=rhunt,bvisness

Also add an assert to bounds-check elimination for the time being.

Differential Revision: https://phabricator.services.mozilla.com/D257726

Diffstat:
Mjs/src/vm/ArrayBufferObject.cpp | 29+++++++++++++++++++++--------
Mjs/src/vm/ArrayBufferObject.h | 5++++-
Mjs/src/vm/SharedArrayObject.cpp | 4++--
Mjs/src/vm/SharedArrayObject.h | 12++++++++++--
Mjs/src/wasm/WasmBCMemory.cpp | 3+++
5 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp @@ -818,7 +818,7 @@ bool ArrayBufferObject::resizeImpl(JSContext* cx, const CallArgs& args) { } Pages newPages = - Pages::fromByteLengthExact(newByteLength, wasm::PageSize::Standard); + Pages::fromByteLengthExact(newByteLength, obj->wasmPageSize()); MOZ_RELEASE_ASSERT(WasmArrayBufferSourceMaxPages(obj).isSome()); Rooted<ArrayBufferObject*> res( cx, @@ -1979,12 +1979,20 @@ AddressType ArrayBufferObject::wasmAddressType() const { return wasm::AddressType::I32; } +wasm::PageSize ArrayBufferObject::wasmPageSize() const { + if (isWasm()) { + return contents().wasmBuffer()->pageSize(); + } + MOZ_ASSERT(isPreparedForAsmJS()); + return wasm::PageSize::Standard; +} + Pages ArrayBufferObject::wasmPages() const { if (isWasm()) { return contents().wasmBuffer()->pages(); } MOZ_ASSERT(isPreparedForAsmJS()); - return Pages::fromByteLengthExact(byteLength(), wasm::PageSize::Standard); + return Pages::fromByteLengthExact(byteLength(), wasmPageSize()); } Pages ArrayBufferObject::wasmClampedMaxPages() const { @@ -1992,7 +2000,7 @@ Pages ArrayBufferObject::wasmClampedMaxPages() const { return contents().wasmBuffer()->clampedMaxPages(); } MOZ_ASSERT(isPreparedForAsmJS()); - return Pages::fromByteLengthExact(byteLength(), wasm::PageSize::Standard); + return Pages::fromByteLengthExact(byteLength(), wasmPageSize()); } Maybe<Pages> ArrayBufferObject::wasmSourceMaxPages() const { @@ -2000,8 +2008,7 @@ Maybe<Pages> ArrayBufferObject::wasmSourceMaxPages() const { return contents().wasmBuffer()->sourceMaxPages(); } MOZ_ASSERT(isPreparedForAsmJS()); - return Some<Pages>( - Pages::fromByteLengthExact(byteLength(), wasm::PageSize::Standard)); + return Some<Pages>(Pages::fromByteLengthExact(byteLength(), wasmPageSize())); } size_t js::WasmArrayBufferMappedSize(const ArrayBufferObjectMaybeShared* buf) { @@ -2018,6 +2025,13 @@ AddressType js::WasmArrayBufferAddressType( } return buf->as<SharedArrayBufferObject>().wasmAddressType(); } +wasm::PageSize js::WasmArrayBufferPageSize( + const ArrayBufferObjectMaybeShared* buf) { + if (buf->is<ArrayBufferObject>()) { + return buf->as<ArrayBufferObject>().wasmPageSize(); + } + return buf->as<SharedArrayBufferObject>().wasmPageSize(); +} Pages js::WasmArrayBufferPages(const ArrayBufferObjectMaybeShared* buf) { if (buf->is<ArrayBufferObject>()) { return buf->as<ArrayBufferObject>().wasmPages(); @@ -2165,10 +2179,9 @@ ArrayBufferObject* ArrayBufferObject::wasmMovingGrowToPages( Pages clampedMaxPages = wasm::ClampedMaxPages(t, newPages, Nothing(), /* hugeMemory */ false); - wasm::PageSize pageSize = wasm::PageSize::Standard; WasmArrayRawBuffer* newRawBuf = WasmArrayRawBuffer::AllocateWasm( - oldBuf->wasmAddressType(), pageSize, newPages, clampedMaxPages, Nothing(), - Nothing()); + oldBuf->wasmAddressType(), oldBuf->wasmPageSize(), newPages, + clampedMaxPages, Nothing(), Nothing()); if (!newRawBuf) { return nullptr; } diff --git a/js/src/vm/ArrayBufferObject.h b/js/src/vm/ArrayBufferObject.h @@ -135,6 +135,7 @@ class ArrayBufferObjectMaybeShared; wasm::AddressType WasmArrayBufferAddressType( const ArrayBufferObjectMaybeShared* buf); +wasm::PageSize WasmArrayBufferPageSize(const ArrayBufferObjectMaybeShared* buf); wasm::Pages WasmArrayBufferPages(const ArrayBufferObjectMaybeShared* buf); wasm::Pages WasmArrayBufferClampedMaxPages( const ArrayBufferObjectMaybeShared* buf); @@ -159,6 +160,7 @@ class ArrayBufferObjectMaybeShared : public NativeObject { wasm::AddressType wasmAddressType() const { return WasmArrayBufferAddressType(this); } + wasm::PageSize wasmPageSize() const { return WasmArrayBufferPageSize(this); } wasm::Pages wasmPages() const { return WasmArrayBufferPages(this); } wasm::Pages wasmClampedMaxPages() const { return WasmArrayBufferClampedMaxPages(this); @@ -634,6 +636,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared { size_t wasmMappedSize() const; wasm::AddressType wasmAddressType() const; + wasm::PageSize wasmPageSize() const; wasm::Pages wasmPages() const; wasm::Pages wasmClampedMaxPages() const; mozilla::Maybe<wasm::Pages> wasmSourceMaxPages() const; @@ -1061,7 +1064,7 @@ class WasmArrayRawBuffer { size_t byteLength() const { return length_; } wasm::Pages pages() const { - return wasm::Pages::fromByteLengthExact(length_, wasm::PageSize::Standard); + return wasm::Pages::fromByteLengthExact(length_, pageSize()); } /* diff --git a/js/src/vm/SharedArrayObject.cpp b/js/src/vm/SharedArrayObject.cpp @@ -133,7 +133,7 @@ WasmSharedArrayRawBuffer* WasmSharedArrayRawBuffer::AllocateWasm( uint8_t* buffer = reinterpret_cast<uint8_t*>(p) + gc::SystemPageSize(); uint8_t* base = buffer - sizeof(WasmSharedArrayRawBuffer); return new (base) WasmSharedArrayRawBuffer( - buffer, length, addressType, clampedMaxPages, + buffer, length, addressType, pageSize, clampedMaxPages, sourceMaxPages.valueOr(Pages::fromPageCount(0, pageSize)), computedMappedSize); } @@ -432,7 +432,7 @@ bool SharedArrayBufferObject::growImpl(JSContext* cx, const CallArgs& args) { } Pages newPages = - Pages::fromByteLengthExact(newByteLength, wasm::PageSize::Standard); + Pages::fromByteLengthExact(newByteLength, buffer->wasmPageSize()); return buffer->rawWasmBufferObject()->wasmGrowToPagesInPlace( *lock, buffer->wasmAddressType(), newPages); } diff --git a/js/src/vm/SharedArrayObject.h b/js/src/vm/SharedArrayObject.h @@ -127,6 +127,8 @@ class WasmSharedArrayRawBuffer : public SharedArrayRawBuffer { Mutex growLock_ MOZ_UNANNOTATED; // The address type of this buffer. wasm::AddressType addressType_; + // The size of each wasm page in this buffer. + wasm::PageSize pageSize_; // The maximum size of this buffer in wasm pages. wasm::Pages clampedMaxPages_; wasm::Pages sourceMaxPages_; @@ -141,11 +143,12 @@ class WasmSharedArrayRawBuffer : public SharedArrayRawBuffer { protected: WasmSharedArrayRawBuffer(uint8_t* buffer, size_t length, wasm::AddressType addressType, - wasm::Pages clampedMaxPages, + wasm::PageSize pageSize, wasm::Pages clampedMaxPages, wasm::Pages sourceMaxPages, size_t mappedSize) : SharedArrayRawBuffer(WasmBuffer{}, buffer, length), growLock_(mutexid::SharedArrayGrow), addressType_(addressType), + pageSize_(pageSize), clampedMaxPages_(clampedMaxPages), sourceMaxPages_(sourceMaxPages), mappedSize_(mappedSize) {} @@ -183,9 +186,10 @@ class WasmSharedArrayRawBuffer : public SharedArrayRawBuffer { } wasm::AddressType wasmAddressType() const { return addressType_; } + wasm::PageSize wasmPageSize() const { return pageSize_; } wasm::Pages volatileWasmPages() const { - return wasm::Pages::fromByteLengthExact(length_, wasm::PageSize::Standard); + return wasm::Pages::fromByteLengthExact(length_, wasmPageSize()); } wasm::Pages wasmClampedMaxPages() const { return clampedMaxPages_; } @@ -371,6 +375,10 @@ class SharedArrayBufferObject : public ArrayBufferObjectMaybeShared { return rawWasmBufferObject()->wasmAddressType(); } + wasm::PageSize wasmPageSize() const { + return rawWasmBufferObject()->wasmPageSize(); + } + bool isWasm() const { return rawBufferObject()->isWasm(); } bool isGrowable() const { return is<GrowableSharedArrayBufferObject>(); } diff --git a/js/src/wasm/WasmBCMemory.cpp b/js/src/wasm/WasmBCMemory.cpp @@ -371,6 +371,9 @@ template <typename RegAddressType> void BaseCompiler::prepareMemoryAccess(MemoryAccessDesc* access, AccessCheck* check, RegPtr instance, RegAddressType ptr) { + MOZ_ASSERT(codeMeta_.memories[access->memoryIndex()].pageSize() == + PageSize::Standard); + uint64_t offsetGuardLimit = GetMaxOffsetGuardLimit( codeMeta_.hugeMemoryEnabled(access->memoryIndex()));