author | Jeff Walden <jwalden@mit.edu> |
Wed, 20 Feb 2019 13:33:16 -0800 | |
changeset 461605 | a9638eeea75714425a28e5bcd9edb9ae55dd13b9 |
parent 461604 | 715e9b139ebbd407ac64b5ee8737d0f042f74b4c |
child 461606 | 5f4cc2c4551793656ade258587b3d83caae29b3e |
push id | 35626 |
push user | csabou@mozilla.com |
push date | Thu, 28 Feb 2019 11:31:08 +0000 |
treeherder | mozilla-central@2ea0c1db7e60 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sfink |
bugs | 1529298 |
milestone | 67.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -1106,44 +1106,66 @@ Maybe<uint32_t> ArrayBufferObject::wasmM Maybe<uint32_t> js::WasmArrayBufferMaxSize( const ArrayBufferObjectMaybeShared* buf) { if (buf->is<ArrayBufferObject>()) { return buf->as<ArrayBufferObject>().wasmMaxSize(); } return buf->as<SharedArrayBufferObject>().wasmMaxSize(); } +static void CheckStealPreconditions(Handle<ArrayBufferObject*> buffer, + JSContext* cx) { + cx->check(buffer); + + MOZ_ASSERT(!buffer->isDetached(), "can't steal from a detached buffer"); + MOZ_ASSERT(!buffer->isPreparedForAsmJS(), + "asm.js-prepared buffers don't have detachable/stealable data"); +} + /* static */ bool ArrayBufferObject::wasmGrowToSizeInPlace( uint32_t newSize, HandleArrayBufferObject oldBuf, MutableHandleArrayBufferObject newBuf, JSContext* cx) { + CheckStealPreconditions(oldBuf, cx); + + MOZ_ASSERT(oldBuf->isWasm()); + // On failure, do not throw and ensure that the original buffer is // unmodified and valid. After WasmArrayRawBuffer::growToSizeInPlace(), the // wasm-visible length of the buffer has been increased so it must be the // last fallible operation. if (newSize > ArrayBufferObject::MaxBufferByteLength) { return false; } newBuf.set(ArrayBufferObject::createEmpty(cx)); if (!newBuf) { cx->clearPendingException(); return false; } + MOZ_ASSERT(newBuf->isNoData()); + if (!oldBuf->contents().wasmBuffer()->growToSizeInPlace(oldBuf->byteLength(), newSize)) { return false; } - bool hasStealableContents = true; - BufferContents contents = - ArrayBufferObject::stealContents(cx, oldBuf, hasStealableContents); - MOZ_ASSERT(contents); - newBuf->initialize(newSize, contents, OwnsData); + // Extract the grown contents from |oldBuf|. + BufferContents oldContents = oldBuf->contents(); + + // Overwrite |oldBuf|'s data pointer *without* releasing old data. + BufferContents detachedContents = BufferContents::createNoData(); + oldBuf->setDataPointer(detachedContents, OwnsData); + + // Detach |oldBuf| now that doing so won't release |oldContents|. + ArrayBufferObject::detach(cx, oldBuf, detachedContents); + + // Set |newBuf|'s contents to |oldBuf|'s original contents. + newBuf->initialize(newSize, oldContents, OwnsData); return true; } #ifndef WASM_HUGE_MEMORY /* static */ bool ArrayBufferObject::wasmMovingGrowToSize( uint32_t newSize, HandleArrayBufferObject oldBuf, MutableHandleArrayBufferObject newBuf, JSContext* cx) { // On failure, do not throw and ensure that the original buffer is @@ -1368,25 +1390,16 @@ ArrayBufferObject* ArrayBufferObject::cr auto contents = BufferContents::createWasm(rawBuffer->dataPointer()); buffer->setDataPointer(contents, OwnsData); cx->updateMallocCounter(initialSize); return buffer; } -static void CheckStealPreconditions(Handle<ArrayBufferObject*> buffer, - JSContext* cx) { - cx->check(buffer); - - MOZ_ASSERT(!buffer->isDetached(), "can't steal from a detached buffer"); - MOZ_ASSERT(!buffer->isPreparedForAsmJS(), - "asm.js-prepared buffers don't have detachable/stealable data"); -} - /* static */ uint8_t* ArrayBufferObject::stealMallocedContents( JSContext* cx, Handle<ArrayBufferObject*> buffer) { CheckStealPreconditions(buffer, cx); switch (buffer->bufferKind()) { case MALLOCED: if (buffer->ownsData()) { uint8_t* stolenData = buffer->dataPointer();