Bug 1240984 - Remove dummy ArrayBufferContents backstop, r=Waldo

--HG--
extra : rebase_source : ac3a7e8d21f47f056956c5339c8cc4f9dc3fcd36
extra : intermediate-source : 11de53329deb91bd355f6b3d62b6be32a0f40bd7
extra : source : 694c87cbc37ae55cd49123324f842669baee7760
This commit is contained in:
Steve Fink 2016-07-28 22:03:03 -07:00
Родитель c2cbbe5f56
Коммит 352c38a321
5 изменённых файлов: 34 добавлений и 62 удалений

Просмотреть файл

@ -23,10 +23,7 @@ var buffer = new ArrayBuffer(BUF_MIN);
var {get, set} = asmLink(m, this, null, buffer);
set(4, 42);
assertEq(get(4), 42);
assertThrowsInstanceOf(() => detachArrayBuffer(buffer, "change-data"),
InternalError);
assertThrowsInstanceOf(() => detachArrayBuffer(buffer, "same-data"),
InternalError);
assertThrowsInstanceOf(() => detachArrayBuffer(buffer), Error);
var m = asmCompile('stdlib', 'foreign', 'buffer',
`"use asm";
@ -42,8 +39,7 @@ var m = asmCompile('stdlib', 'foreign', 'buffer',
var buffer = new ArrayBuffer(BUF_MIN);
function ffi1()
{
assertThrowsInstanceOf(() => detachArrayBuffer(buffer, "change-data"),
InternalError);
assertThrowsInstanceOf(() => detachArrayBuffer(buffer), Error);
}
var inner = asmLink(m, this, {ffi: ffi1}, buffer);

Просмотреть файл

@ -2106,12 +2106,7 @@ enum DetachDataDisposition {
* Detach an ArrayBuffer, causing all associated views to no longer refer to
* the ArrayBuffer's original attached memory.
*
* The |changeData| argument is a hint to inform internal behavior with respect
* to the ArrayBuffer's internal pointer to associated data. |ChangeData|
* attempts to set the internal pointer to fresh memory of the same size as the
* original memory; |KeepData| attempts to preserve the original pointer, even
* while the ArrayBuffer appears observably detached. There is no guarantee
* this parameter is respected -- it's only a hint.
* The |changeData| argument is obsolete and ignored.
*/
extern JS_FRIEND_API(bool)
JS_DetachArrayBuffer(JSContext* cx, JS::HandleObject obj,

Просмотреть файл

@ -260,16 +260,13 @@ NoteViewBufferWasDetached(ArrayBufferViewObject* view,
MarkObjectStateChange(cx, view);
}
/* static */ bool
/* static */ void
ArrayBufferObject::detach(JSContext* cx, Handle<ArrayBufferObject*> buffer,
BufferContents newContents)
{
assertSameCompartment(cx, buffer);
if (buffer->isWasm()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_OUT_OF_MEMORY);
return false;
}
MOZ_ASSERT(!buffer->isWasm());
// When detaching buffers where we don't know all views, the new data must
// match the old data. All missing views are typed objects, which do not
@ -316,7 +313,6 @@ ArrayBufferObject::detach(JSContext* cx, Handle<ArrayBufferObject*> buffer,
buffer->setByteLength(0);
buffer->setIsDetached();
return true;
}
void
@ -737,30 +733,27 @@ ArrayBufferObject::stealContents(JSContext* cx, Handle<ArrayBufferObject*> buffe
assertSameCompartment(cx, buffer);
BufferContents oldContents(buffer->dataPointer(), buffer->bufferKind());
BufferContents newContents = AllocateArrayBufferContents(cx, buffer->byteLength());
if (!newContents)
return BufferContents::createPlain(nullptr);
if (hasStealableContents) {
// Return the old contents and give the detached buffer a pointer to
// freshly allocated memory that we will never write to and should
// never get committed.
buffer->setOwnsData(DoesntOwnData);
if (!ArrayBufferObject::detach(cx, buffer, newContents)) {
js_free(newContents.data());
return BufferContents::createPlain(nullptr);
}
// Return the old contents and reset the detached buffer's data
// pointer. This pointer should never be accessed.
auto newContents = BufferContents::createPlain(nullptr);
buffer->setOwnsData(DoesntOwnData); // Do not free the stolen data.
ArrayBufferObject::detach(cx, buffer, newContents);
buffer->setOwnsData(DoesntOwnData); // Do not free the nullptr.
return oldContents;
}
// Create a new chunk of memory to return since we cannot steal the
// existing contents away from the buffer.
memcpy(newContents.data(), oldContents.data(), buffer->byteLength());
if (!ArrayBufferObject::detach(cx, buffer, oldContents)) {
js_free(newContents.data());
BufferContents contentsCopy = AllocateArrayBufferContents(cx, buffer->byteLength());
if (!contentsCopy)
return BufferContents::createPlain(nullptr);
}
return newContents;
if (buffer->byteLength() > 0)
memcpy(contentsCopy.data(), oldContents.data(), buffer->byteLength());
ArrayBufferObject::detach(cx, buffer, oldContents);
return contentsCopy;
}
/* static */ void
@ -1035,10 +1028,11 @@ ArrayBufferViewObject::trace(JSTracer* trc, JSObject* objArg)
if (IsArrayBuffer(&bufSlot.toObject())) {
ArrayBufferObject& buf = AsArrayBuffer(MaybeForwarded(&bufSlot.toObject()));
uint32_t offset = uint32_t(obj->getFixedSlot(TypedArrayObject::BYTEOFFSET_SLOT).toInt32());
MOZ_ASSERT(buf.dataPointer() != nullptr);
MOZ_ASSERT(offset <= INT32_MAX);
if (buf.forInlineTypedObject()) {
MOZ_ASSERT(buf.dataPointer() != nullptr);
// The data is inline with an InlineTypedObject associated with the
// buffer. Get a new address for the typed object if it moved.
JSObject* view = buf.firstView();
@ -1058,6 +1052,8 @@ ArrayBufferViewObject::trace(JSTracer* trc, JSObject* objArg)
trc->runtime()->gc.nursery.maybeSetForwardingPointer(trc, srcData, dstData,
/* direct = */ false);
} else {
MOZ_ASSERT_IF(buf.dataPointer() == nullptr, offset == 0);
// The data may or may not be inline with the buffer. The buffer
// can only move during a compacting GC, in which case its
// objectMoved hook has already updated the buffer's data pointer.
@ -1084,7 +1080,6 @@ JSObject::is<js::ArrayBufferObjectMaybeShared>() const
void
ArrayBufferViewObject::notifyBufferDetached(JSContext* cx, void* newData)
{
MOZ_ASSERT(newData != nullptr);
if (is<DataViewObject>()) {
as<DataViewObject>().notifyBufferDetached(newData);
} else if (is<TypedArrayObject>()) {
@ -1193,20 +1188,17 @@ JS_DetachArrayBuffer(JSContext* cx, HandleObject obj,
Rooted<ArrayBufferObject*> buffer(cx, &obj->as<ArrayBufferObject>());
if (changeData == ChangeData && buffer->hasStealableContents()) {
ArrayBufferObject::BufferContents newContents =
AllocateArrayBufferContents(cx, buffer->byteLength());
if (!newContents)
return false;
if (!ArrayBufferObject::detach(cx, buffer, newContents)) {
js_free(newContents.data());
return false;
}
} else {
if (!ArrayBufferObject::detach(cx, buffer, buffer->contents()))
return false;
if (buffer->isWasm()) {
JS_ReportError(cx, "Cannot detach WASM ArrayBuffer");
return false;
}
ArrayBufferObject::BufferContents newContents =
buffer->hasStealableContents() ? ArrayBufferObject::BufferContents::createPlain(nullptr)
: buffer->contents();
ArrayBufferObject::detach(cx, buffer, newContents);
return true;
}

Просмотреть файл

@ -213,9 +213,6 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
static bool fun_slice(JSContext* cx, unsigned argc, Value* vp);
static bool fun_isView(JSContext* cx, unsigned argc, Value* vp);
#ifdef NIGHTLY_BUILD
static bool fun_transfer(JSContext* cx, unsigned argc, Value* vp);
#endif
static bool fun_species(JSContext* cx, unsigned argc, Value* vp);
@ -252,15 +249,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
bool hasStealableContents() const {
// Inline elements strictly adhere to the corresponding buffer.
if (!ownsData())
return false;
// Detached contents aren't transferrable because we want a detached
// buffer's contents to be backed by zeroed memory equal in length to
// the original buffer contents. Transferring these contents would
// allocate new ones based on the current byteLength, which is 0 for a
// detached buffer -- not the original byteLength.
return !isDetached();
return ownsData();
}
// Return whether the buffer is allocated by js_malloc and should be freed
@ -286,7 +275,7 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
// Detach this buffer from its original memory. (This necessarily makes
// views of this buffer unusable for modifying that original memory.)
static MOZ_MUST_USE bool
static void
detach(JSContext* cx, Handle<ArrayBufferObject*> buffer, BufferContents newContents);
private:

Просмотреть файл

@ -1378,7 +1378,7 @@ JSStructuredCloneWriter::transferOwnership()
ArrayBufferObject::BufferContents bufContents =
ArrayBufferObject::stealContents(context(), arrayBuffer, hasStealableContents);
if (!bufContents)
return false; // Destructor will clean up the already-transferred data.
return false; // already transferred data
content = bufContents.data();
tag = SCTAG_TRANSFER_MAP_ARRAY_BUFFER;