[api] Remove deprecated [Shared]ArrayBuffer API

Bug: v8:9380
Change-Id: I47d23dda133c3838c7f0e8e5ccfdbe3b9520684f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2720306
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73375}
This commit is contained in:
Ulan Degenbaev 2021-02-25 19:09:49 +01:00 committed by Commit Bot
parent 5e08891f69
commit 578f6be77f
4 changed files with 8 additions and 747 deletions

View File

@ -5409,57 +5409,6 @@ class V8_EXPORT ArrayBuffer : public Object {
static Allocator* NewDefaultAllocator();
};
/**
* The contents of an |ArrayBuffer|. Externalization of |ArrayBuffer|
* returns an instance of this class, populated, with a pointer to data
* and byte length.
*
* The Data pointer of ArrayBuffer::Contents must be freed using the provided
* deleter, which will call ArrayBuffer::Allocator::Free if the buffer
* was allocated with ArraryBuffer::Allocator::Allocate.
*/
class V8_EXPORT Contents { // NOLINT
public:
using DeleterCallback = void (*)(void* buffer, size_t length, void* info);
Contents()
: data_(nullptr),
byte_length_(0),
allocation_base_(nullptr),
allocation_length_(0),
allocation_mode_(Allocator::AllocationMode::kNormal),
deleter_(nullptr),
deleter_data_(nullptr) {}
void* AllocationBase() const { return allocation_base_; }
size_t AllocationLength() const { return allocation_length_; }
Allocator::AllocationMode AllocationMode() const {
return allocation_mode_;
}
void* Data() const { return data_; }
size_t ByteLength() const { return byte_length_; }
DeleterCallback Deleter() const { return deleter_; }
void* DeleterData() const { return deleter_data_; }
private:
Contents(void* data, size_t byte_length, void* allocation_base,
size_t allocation_length,
Allocator::AllocationMode allocation_mode, DeleterCallback deleter,
void* deleter_data);
void* data_;
size_t byte_length_;
void* allocation_base_;
size_t allocation_length_;
Allocator::AllocationMode allocation_mode_;
DeleterCallback deleter_;
void* deleter_data_;
friend class ArrayBuffer;
};
/**
* Data length in bytes.
*/
@ -5473,22 +5422,6 @@ class V8_EXPORT ArrayBuffer : public Object {
*/
static Local<ArrayBuffer> New(Isolate* isolate, size_t byte_length);
/**
* Create a new ArrayBuffer over an existing memory block.
* The created array buffer is by default immediately in externalized state.
* In externalized state, the memory block will not be reclaimed when a
* created ArrayBuffer is garbage-collected.
* In internalized state, the memory block will be released using
* |Allocator::Free| once all ArrayBuffers referencing it are collected by
* the garbage collector.
*/
V8_DEPRECATED(
"Use the version that takes a BackingStore. "
"See http://crbug.com/v8/9908.")
static Local<ArrayBuffer> New(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
/**
* Create a new ArrayBuffer with an existing backing store.
* The created array keeps a reference to the backing store until the array
@ -5527,15 +5460,6 @@ class V8_EXPORT ArrayBuffer : public Object {
void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
void* deleter_data);
/**
* Returns true if ArrayBuffer is externalized, that is, does not
* own its memory block.
*/
V8_DEPRECATED(
"With v8::BackingStore externalized ArrayBuffers are "
"the same as ordinary ArrayBuffers. See http://crbug.com/v8/9908.")
bool IsExternal() const;
/**
* Returns true if this ArrayBuffer may be detached.
*/
@ -5549,47 +5473,11 @@ class V8_EXPORT ArrayBuffer : public Object {
*/
void Detach();
/**
* Make this ArrayBuffer external. The pointer to underlying memory block
* and byte length are returned as |Contents| structure. After ArrayBuffer
* had been externalized, it does no longer own the memory block. The caller
* should take steps to free memory when it is no longer needed.
*
* The Data pointer of ArrayBuffer::Contents must be freed using the provided
* deleter, which will call ArrayBuffer::Allocator::Free if the buffer
* was allocated with ArrayBuffer::Allocator::Allocate.
*/
V8_DEPRECATED("Use GetBackingStore or Detach. See http://crbug.com/v8/9908.")
Contents Externalize();
/**
* Marks this ArrayBuffer external given a witness that the embedder
* has fetched the backing store using the new GetBackingStore() function.
*
* With the new lifetime management of backing stores there is no need for
* externalizing, so this function exists only to make the transition easier.
*/
V8_DEPRECATED("This will be removed together with IsExternal.")
void Externalize(const std::shared_ptr<BackingStore>& backing_store);
/**
* Get a pointer to the ArrayBuffer's underlying memory block without
* externalizing it. If the ArrayBuffer is not externalized, this pointer
* will become invalid as soon as the ArrayBuffer gets garbage collected.
*
* The embedder should make sure to hold a strong reference to the
* ArrayBuffer while accessing this pointer.
*/
V8_DEPRECATED("Use GetBackingStore. See http://crbug.com/v8/9908.")
Contents GetContents();
/**
* Get a shared pointer to the backing store of this array buffer. This
* pointer coordinates the lifetime management of the internal storage
* with any live ArrayBuffers on the heap, even across isolates. The embedder
* should not attempt to manage lifetime of the storage through other means.
*
* This function replaces both Externalize() and GetContents().
*/
std::shared_ptr<BackingStore> GetBackingStore();
@ -5601,7 +5489,6 @@ class V8_EXPORT ArrayBuffer : public Object {
private:
ArrayBuffer();
static void CheckCast(Value* obj);
Contents GetContents(bool externalize);
};
@ -5894,57 +5781,6 @@ class V8_EXPORT DataView : public ArrayBufferView {
*/
class V8_EXPORT SharedArrayBuffer : public Object {
public:
/**
* The contents of an |SharedArrayBuffer|. Externalization of
* |SharedArrayBuffer| returns an instance of this class, populated, with a
* pointer to data and byte length.
*
* The Data pointer of ArrayBuffer::Contents must be freed using the provided
* deleter, which will call ArrayBuffer::Allocator::Free if the buffer
* was allocated with ArraryBuffer::Allocator::Allocate.
*/
class V8_EXPORT Contents { // NOLINT
public:
using Allocator = v8::ArrayBuffer::Allocator;
using DeleterCallback = void (*)(void* buffer, size_t length, void* info);
Contents()
: data_(nullptr),
byte_length_(0),
allocation_base_(nullptr),
allocation_length_(0),
allocation_mode_(Allocator::AllocationMode::kNormal),
deleter_(nullptr),
deleter_data_(nullptr) {}
void* AllocationBase() const { return allocation_base_; }
size_t AllocationLength() const { return allocation_length_; }
Allocator::AllocationMode AllocationMode() const {
return allocation_mode_;
}
void* Data() const { return data_; }
size_t ByteLength() const { return byte_length_; }
DeleterCallback Deleter() const { return deleter_; }
void* DeleterData() const { return deleter_data_; }
private:
Contents(void* data, size_t byte_length, void* allocation_base,
size_t allocation_length,
Allocator::AllocationMode allocation_mode, DeleterCallback deleter,
void* deleter_data);
void* data_;
size_t byte_length_;
void* allocation_base_;
size_t allocation_length_;
Allocator::AllocationMode allocation_mode_;
DeleterCallback deleter_;
void* deleter_data_;
friend class SharedArrayBuffer;
};
/**
* Data length in bytes.
*/
@ -5958,19 +5794,6 @@ class V8_EXPORT SharedArrayBuffer : public Object {
*/
static Local<SharedArrayBuffer> New(Isolate* isolate, size_t byte_length);
/**
* Create a new SharedArrayBuffer over an existing memory block. The created
* array buffer is immediately in externalized state unless otherwise
* specified. The memory block will not be reclaimed when a created
* SharedArrayBuffer is garbage-collected.
*/
V8_DEPRECATED(
"Use the version that takes a BackingStore. "
"See http://crbug.com/v8/9908.")
static Local<SharedArrayBuffer> New(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
/**
* Create a new SharedArrayBuffer with an existing backing store.
* The created array keeps a reference to the backing store until the array
@ -6009,73 +5832,11 @@ class V8_EXPORT SharedArrayBuffer : public Object {
void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
void* deleter_data);
/**
* Create a new SharedArrayBuffer over an existing memory block. Propagate
* flags to indicate whether the underlying buffer can be grown.
*/
V8_DEPRECATED(
"Use the version that takes a BackingStore. "
"See http://crbug.com/v8/9908.")
static Local<SharedArrayBuffer> New(
Isolate* isolate, const SharedArrayBuffer::Contents&,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
/**
* Returns true if SharedArrayBuffer is externalized, that is, does not
* own its memory block.
*/
V8_DEPRECATED(
"With v8::BackingStore externalized SharedArrayBuffers are the same "
"as ordinary SharedArrayBuffers. See http://crbug.com/v8/9908.")
bool IsExternal() const;
/**
* Make this SharedArrayBuffer external. The pointer to underlying memory
* block and byte length are returned as |Contents| structure. After
* SharedArrayBuffer had been externalized, it does no longer own the memory
* block. The caller should take steps to free memory when it is no longer
* needed.
*
* The memory block is guaranteed to be allocated with |Allocator::Allocate|
* by the allocator specified in
* v8::Isolate::CreateParams::array_buffer_allocator.
*
*/
V8_DEPRECATED("Use GetBackingStore or Detach. See http://crbug.com/v8/9908.")
Contents Externalize();
/**
* Marks this SharedArrayBuffer external given a witness that the embedder
* has fetched the backing store using the new GetBackingStore() function.
*
* With the new lifetime management of backing stores there is no need for
* externalizing, so this function exists only to make the transition easier.
*/
V8_DEPRECATED("This will be removed together with IsExternal.")
void Externalize(const std::shared_ptr<BackingStore>& backing_store);
/**
* Get a pointer to the ArrayBuffer's underlying memory block without
* externalizing it. If the ArrayBuffer is not externalized, this pointer
* will become invalid as soon as the ArrayBuffer became garbage collected.
*
* The embedder should make sure to hold a strong reference to the
* ArrayBuffer while accessing this pointer.
*
* The memory block is guaranteed to be allocated with |Allocator::Allocate|
* by the allocator specified in
* v8::Isolate::CreateParams::array_buffer_allocator.
*/
V8_DEPRECATED("Use GetBackingStore. See http://crbug.com/v8/9908.")
Contents GetContents();
/**
* Get a shared pointer to the backing store of this array buffer. This
* pointer coordinates the lifetime management of the internal storage
* with any live ArrayBuffers on the heap, even across isolates. The embedder
* should not attempt to manage lifetime of the storage through other means.
*
* This function replaces both Externalize() and GetContents().
*/
std::shared_ptr<BackingStore> GetBackingStore();
@ -6086,7 +5847,6 @@ class V8_EXPORT SharedArrayBuffer : public Object {
private:
SharedArrayBuffer();
static void CheckCast(Value* obj);
Contents GetContents(bool externalize);
};

View File

@ -7460,169 +7460,17 @@ v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
return new ArrayBufferAllocator();
}
bool v8::ArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
bool v8::ArrayBuffer::IsDetachable() const {
return Utils::OpenHandle(this)->is_detachable();
}
namespace {
// The backing store deleter just deletes the indirection, which downrefs
// the shared pointer. It will get collected normally.
void BackingStoreDeleter(void* buffer, size_t length, void* info) {
std::shared_ptr<i::BackingStore>* bs_indirection =
reinterpret_cast<std::shared_ptr<i::BackingStore>*>(info);
if (bs_indirection) {
i::BackingStore* backing_store = bs_indirection->get();
TRACE_BS("API:delete bs=%p mem=%p (length=%zu)\n", backing_store,
backing_store->buffer_start(), backing_store->byte_length());
USE(backing_store);
}
delete bs_indirection;
}
void* MakeDeleterData(std::shared_ptr<i::BackingStore> backing_store) {
if (!backing_store) return nullptr;
TRACE_BS("API:extern bs=%p mem=%p (length=%zu)\n", backing_store.get(),
backing_store->buffer_start(), backing_store->byte_length());
return new std::shared_ptr<i::BackingStore>(backing_store);
}
std::shared_ptr<i::BackingStore> LookupOrCreateBackingStore(
i::Isolate* i_isolate, void* data, size_t byte_length, i::SharedFlag shared,
ArrayBufferCreationMode mode) {
// "internalized" means that the storage was allocated by the
// ArrayBufferAllocator and thus should be freed upon destruction.
bool free_on_destruct = mode == ArrayBufferCreationMode::kInternalized;
// Try to lookup a previously-registered backing store in the global
// registry. If found, use that instead of wrapping an embedder allocation.
std::shared_ptr<i::BackingStore> backing_store =
i::GlobalBackingStoreRegistry::Lookup(data, byte_length);
if (backing_store) {
// Check invariants for a previously-found backing store.
// 1. We cannot allow an embedder to first allocate a backing store that
// should not be freed upon destruct, and then allocate an alias that should
// destruct it. The other order is fine.
bool changing_destruct_mode =
free_on_destruct && !backing_store->free_on_destruct();
Utils::ApiCheck(
!changing_destruct_mode, "v8_[Shared]ArrayBuffer_New",
"previous backing store found that should not be freed on destruct");
// 2. We cannot allow embedders to use the same backing store for both
// SharedArrayBuffers and regular ArrayBuffers.
bool changing_shared_flag =
(shared == i::SharedFlag::kShared) != backing_store->is_shared();
Utils::ApiCheck(
!changing_shared_flag, "v8_[Shared]ArrayBuffer_New",
"previous backing store found that does not match shared flag");
} else {
// No previous backing store found.
backing_store = i::BackingStore::WrapAllocation(
i_isolate, data, byte_length, shared, free_on_destruct);
// The embedder already has a direct pointer to the buffer start, so
// globally register the backing store in case they come back with the
// same buffer start and the backing store is marked as free_on_destruct.
i::GlobalBackingStoreRegistry::Register(backing_store);
}
return backing_store;
}
std::shared_ptr<i::BackingStore> ToInternal(
std::shared_ptr<i::BackingStoreBase> backing_store) {
return std::static_pointer_cast<i::BackingStore>(backing_store);
}
} // namespace
v8::ArrayBuffer::Contents::Contents(void* data, size_t byte_length,
void* allocation_base,
size_t allocation_length,
Allocator::AllocationMode allocation_mode,
DeleterCallback deleter, void* deleter_data)
: data_(data),
byte_length_(byte_length),
allocation_base_(allocation_base),
allocation_length_(allocation_length),
allocation_mode_(allocation_mode),
deleter_(deleter),
deleter_data_(deleter_data) {
DCHECK_LE(allocation_base_, data_);
DCHECK_LE(byte_length_, allocation_length_);
}
v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
return GetContents(true);
}
void v8::ArrayBuffer::Externalize(
const std::shared_ptr<BackingStore>& backing_store) {
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
"ArrayBuffer already externalized");
self->set_is_external(true);
DCHECK_EQ(self->backing_store(), backing_store->Data());
}
v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
return GetContents(false);
}
v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents(bool externalize) {
// TODO(titzer): reduce duplication between shared/unshared GetContents()
using BufferType = v8::ArrayBuffer;
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
void* deleter_data = nullptr;
if (externalize) {
Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
"ArrayBuffer already externalized");
self->set_is_external(true);
// When externalizing, upref the shared pointer to the backing store
// and store that as the deleter data. When the embedder calls the deleter
// callback, we will delete the additional (on-heap) shared_ptr.
deleter_data = MakeDeleterData(backing_store);
}
if (!backing_store) {
// If the array buffer has zero length or was detached, return empty
// contents.
DCHECK_EQ(0, self->byte_length());
BufferType::Contents contents(
nullptr, 0, nullptr, 0,
v8::ArrayBuffer::Allocator::AllocationMode::kNormal,
BackingStoreDeleter, deleter_data);
return contents;
}
// Backing stores that given to the embedder might be passed back through
// the API using only the start of the buffer. We need to find such
// backing stores using global registration until the API is changed.
i::GlobalBackingStoreRegistry::Register(backing_store);
auto allocation_mode =
backing_store->is_wasm_memory()
? v8::ArrayBuffer::Allocator::AllocationMode::kReservation
: v8::ArrayBuffer::Allocator::AllocationMode::kNormal;
BufferType::Contents contents(backing_store->buffer_start(), // --
backing_store->byte_length(), // --
backing_store->buffer_start(), // --
backing_store->byte_length(), // --
allocation_mode, // --
BackingStoreDeleter, // --
deleter_data);
return contents;
}
void v8::ArrayBuffer::Detach() {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
@ -7656,27 +7504,6 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
return Utils::ToLocal(array_buffer);
}
Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
size_t byte_length,
ArrayBufferCreationMode mode) {
// Embedders must guarantee that the external backing store is valid.
CHECK_IMPLIES(byte_length != 0, data != nullptr);
CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, ArrayBuffer, New);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
std::shared_ptr<i::BackingStore> backing_store = LookupOrCreateBackingStore(
i_isolate, data, byte_length, i::SharedFlag::kNotShared, mode);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer(std::move(backing_store));
if (mode == ArrayBufferCreationMode::kExternalized) {
obj->set_is_external(true);
}
return Utils::ToLocal(obj);
}
Local<ArrayBuffer> v8::ArrayBuffer::New(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
CHECK_IMPLIES(backing_store->ByteLength() != 0,
@ -7850,119 +7677,6 @@ Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
return Utils::ToLocal(obj);
}
namespace {
i::Handle<i::JSArrayBuffer> SetupSharedArrayBuffer(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode) {
CHECK(i::FLAG_harmony_sharedarraybuffer);
// Embedders must guarantee that the external backing store is valid.
CHECK(byte_length == 0 || data != nullptr);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, SharedArrayBuffer, New);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
std::shared_ptr<i::BackingStore> backing_store = LookupOrCreateBackingStore(
i_isolate, data, byte_length, i::SharedFlag::kShared, mode);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
if (mode == ArrayBufferCreationMode::kExternalized) {
obj->set_is_external(true);
}
return obj;
}
} // namespace
bool v8::SharedArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
v8::SharedArrayBuffer::Contents::Contents(
void* data, size_t byte_length, void* allocation_base,
size_t allocation_length, Allocator::AllocationMode allocation_mode,
DeleterCallback deleter, void* deleter_data)
: data_(data),
byte_length_(byte_length),
allocation_base_(allocation_base),
allocation_length_(allocation_length),
allocation_mode_(allocation_mode),
deleter_(deleter),
deleter_data_(deleter_data) {
DCHECK_LE(allocation_base_, data_);
DCHECK_LE(byte_length_, allocation_length_);
}
v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
return GetContents(true);
}
void v8::SharedArrayBuffer::Externalize(
const std::shared_ptr<BackingStore>& backing_store) {
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
"SharedArrayBuffer already externalized");
self->set_is_external(true);
DCHECK_EQ(self->backing_store(), backing_store->Data());
}
v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
return GetContents(false);
}
v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents(
bool externalize) {
// TODO(titzer): reduce duplication between shared/unshared GetContents()
using BufferType = v8::SharedArrayBuffer;
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
void* deleter_data = nullptr;
if (externalize) {
Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
"SharedArrayBuffer already externalized");
self->set_is_external(true);
// When externalizing, upref the shared pointer to the backing store
// and store that as the deleter data. When the embedder calls the deleter
// callback, we will delete the additional (on-heap) shared_ptr.
deleter_data = MakeDeleterData(backing_store);
}
if (!backing_store) {
// If the array buffer has zero length or was detached, return empty
// contents.
DCHECK_EQ(0, self->byte_length());
BufferType::Contents contents(
nullptr, 0, nullptr, 0,
v8::ArrayBuffer::Allocator::AllocationMode::kNormal,
BackingStoreDeleter, deleter_data);
return contents;
}
// Backing stores that given to the embedder might be passed back through
// the API using only the start of the buffer. We need to find such
// backing stores using global registration until the API is changed.
i::GlobalBackingStoreRegistry::Register(backing_store);
auto allocation_mode =
backing_store->is_wasm_memory()
? v8::ArrayBuffer::Allocator::AllocationMode::kReservation
: v8::ArrayBuffer::Allocator::AllocationMode::kNormal;
BufferType::Contents contents(backing_store->buffer_start(), // --
backing_store->byte_length(), // --
backing_store->buffer_start(), // --
backing_store->byte_length(), // --
allocation_mode, // --
BackingStoreDeleter, // --
deleter_data);
return contents;
}
size_t v8::SharedArrayBuffer::ByteLength() const {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
return obj->byte_length();
@ -7990,14 +7704,6 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
return Utils::ToLocalShared(obj);
}
Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode) {
i::Handle<i::JSArrayBuffer> buffer =
SetupSharedArrayBuffer(isolate, data, byte_length, mode);
return Utils::ToLocalShared(buffer);
}
Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
CHECK(i::FLAG_harmony_sharedarraybuffer);
@ -8015,14 +7721,6 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
return Utils::ToLocalShared(obj);
}
Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
Isolate* isolate, const SharedArrayBuffer::Contents& contents,
ArrayBufferCreationMode mode) {
i::Handle<i::JSArrayBuffer> buffer = SetupSharedArrayBuffer(
isolate, contents.Data(), contents.ByteLength(), mode);
return Utils::ToLocalShared(buffer);
}
std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
Isolate* isolate, size_t byte_length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);

View File

@ -47,31 +47,11 @@ Local<TypedArray> CreateAndCheck(Local<v8::ArrayBuffer> ab, int byteOffset,
std::shared_ptr<v8::BackingStore> Externalize(Local<v8::ArrayBuffer> ab) {
std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore();
// Keep the tests until the deprecated functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
ab->Externalize(backing_store);
CHECK(ab->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
return backing_store;
}
std::shared_ptr<v8::BackingStore> Externalize(Local<v8::SharedArrayBuffer> ab) {
std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore();
// Keep the tests until the deprecated functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
ab->Externalize(backing_store);
CHECK(ab->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
return backing_store;
}
@ -150,46 +130,6 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) {
CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust());
}
THREADED_TEST(ArrayBuffer_External) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<uint8_t> my_data(100);
memset(my_data.begin(), 0, 100);
// Keep the tests until the deprecated functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
Local<v8::ArrayBuffer> ab3 =
v8::ArrayBuffer::New(isolate, my_data.begin(), 100);
CheckInternalFieldsAreZero(ab3);
CHECK_EQ(100, ab3->ByteLength());
CHECK(ab3->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust());
v8::Local<v8::Value> result = CompileRun("ab3.byteLength");
CHECK_EQ(100, result->Int32Value(env.local()).FromJust());
result = CompileRun(
"var u8_b = new Uint8Array(ab3);"
"u8_b[0] = 0xBB;"
"u8_b[1] = 0xCC;"
"u8_b.length");
CHECK_EQ(100, result->Int32Value(env.local()).FromJust());
CHECK_EQ(0xBB, my_data[0]);
CHECK_EQ(0xCC, my_data[1]);
my_data[0] = 0xCC;
my_data[1] = 0x11;
result = CompileRun("u8_b[0] + u8_b[1]");
CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust());
}
THREADED_TEST(ArrayBuffer_DisableDetach) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@ -293,37 +233,6 @@ THREADED_TEST(ArrayBuffer_DetachingScript) {
CheckDataViewIsDetached(dv);
}
// TODO(v8:9380) the Contents data structure should be deprecated.
THREADED_TEST(ArrayBuffer_AllocationInformation) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
const size_t ab_size = 1024;
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, ab_size);
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
v8::ArrayBuffer::Contents contents(ab->GetContents());
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
// Array buffers should have normal allocation mode.
CHECK_EQ(contents.AllocationMode(),
v8::ArrayBuffer::Allocator::AllocationMode::kNormal);
// The allocation must contain the buffer (normally they will be equal, but
// this is not required by the contract).
CHECK_NOT_NULL(contents.AllocationBase());
const uintptr_t alloc =
reinterpret_cast<uintptr_t>(contents.AllocationBase());
const uintptr_t data = reinterpret_cast<uintptr_t>(contents.Data());
CHECK_LE(alloc, data);
CHECK_LE(data + contents.ByteLength(), alloc + contents.AllocationLength());
}
THREADED_TEST(ArrayBuffer_ExternalizeEmpty) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@ -342,7 +251,6 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) {
// marked as is_external or not.
USE(u8a->Buffer());
CHECK(ab->IsExternal());
CHECK_EQ(2, backing_store->ByteLength());
}
@ -381,35 +289,6 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) {
CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust());
}
THREADED_TEST(ArrayBuffer_ExternalReused) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<uint8_t> data(100);
Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, data.begin(), 100);
std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore();
ab1->Detach();
Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, data.begin(), 100);
std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore();
CHECK_EQ(bs1->Data(), bs2->Data());
}
THREADED_TEST(SharedArrayBuffer_ExternalReused) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<uint8_t> data(100);
Local<v8::SharedArrayBuffer> ab1 =
v8::SharedArrayBuffer::New(isolate, data.begin(), 100);
std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore();
Local<v8::SharedArrayBuffer> ab2 =
v8::SharedArrayBuffer::New(isolate, data.begin(), 100);
std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore();
CHECK_EQ(bs1->Data(), bs2->Data());
}
THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) {
i::FLAG_harmony_sharedarraybuffer = true;
LocalContext env;
@ -451,64 +330,6 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) {
CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust());
}
THREADED_TEST(SharedArrayBuffer_External) {
i::FLAG_harmony_sharedarraybuffer = true;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<uint8_t> my_data(100);
memset(my_data.begin(), 0, 100);
Local<v8::SharedArrayBuffer> ab3 =
v8::SharedArrayBuffer::New(isolate, my_data.begin(), 100);
CheckInternalFieldsAreZero(ab3);
CHECK_EQ(100, static_cast<int>(ab3->ByteLength()));
CHECK(ab3->IsExternal());
CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust());
v8::Local<v8::Value> result = CompileRun("ab3.byteLength");
CHECK_EQ(100, result->Int32Value(env.local()).FromJust());
result = CompileRun(
"var u8_b = new Uint8Array(ab3);"
"u8_b[0] = 0xBB;"
"u8_b[1] = 0xCC;"
"u8_b.length");
CHECK_EQ(100, result->Int32Value(env.local()).FromJust());
CHECK_EQ(0xBB, my_data[0]);
CHECK_EQ(0xCC, my_data[1]);
my_data[0] = 0xCC;
my_data[1] = 0x11;
result = CompileRun("u8_b[0] + u8_b[1]");
CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust());
}
// TODO(v8:9380) the Contents data structure should be deprecated.
THREADED_TEST(SharedArrayBuffer_AllocationInformation) {
i::FLAG_harmony_sharedarraybuffer = true;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
const size_t ab_size = 1024;
Local<v8::SharedArrayBuffer> ab =
v8::SharedArrayBuffer::New(isolate, ab_size);
v8::SharedArrayBuffer::Contents contents(ab->GetContents());
// Array buffers should have normal allocation mode.
CHECK_EQ(contents.AllocationMode(),
v8::ArrayBuffer::Allocator::AllocationMode::kNormal);
// The allocation must contain the buffer (normally they will be equal, but
// this is not required by the contract).
CHECK_NOT_NULL(contents.AllocationBase());
const uintptr_t alloc =
reinterpret_cast<uintptr_t>(contents.AllocationBase());
const uintptr_t data = reinterpret_cast<uintptr_t>(contents.Data());
CHECK_LE(alloc, data);
CHECK_LE(data + contents.ByteLength(), alloc + contents.AllocationLength());
}
THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@ -516,9 +337,12 @@ THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) {
// Make sure the pointer looks like a heap object
uint8_t* store_ptr = reinterpret_cast<uint8_t*>(i::kHeapObjectTag);
auto backing_store = v8::ArrayBuffer::NewBackingStore(
store_ptr, 8, [](void*, size_t, void*) {}, nullptr);
// Create ArrayBuffer with pointer-that-cannot-be-visited in the backing store
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, store_ptr, 8);
Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, std::move(backing_store));
// Should not crash
CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
@ -539,12 +363,15 @@ THREADED_TEST(SkipArrayBufferDuringScavenge) {
Local<v8::Object> tmp = v8::Object::New(isolate);
uint8_t* store_ptr =
reinterpret_cast<uint8_t*>(*reinterpret_cast<uintptr_t*>(*tmp));
auto backing_store = v8::ArrayBuffer::NewBackingStore(
store_ptr, 8, [](void*, size_t, void*) {}, nullptr);
// Make `store_ptr` point to from space
CcTest::CollectGarbage(i::NEW_SPACE);
// Create ArrayBuffer with pointer-that-cannot-be-visited in the backing store
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, store_ptr, 8);
Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, std::move(backing_store));
// Should not crash,
// i.e. backing store pointer should not be treated as a heap object pointer

View File

@ -71,30 +71,6 @@ TEST(CopyContentsView) {
TestArrayBufferViewContents(&env, true);
}
TEST(AllocateNotExternal) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
void* memory = reinterpret_cast<Isolate*>(env->GetIsolate())
->array_buffer_allocator()
->Allocate(1024);
// Keep the test until the functions are removed.
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
v8::Local<v8::ArrayBuffer> buffer =
v8::ArrayBuffer::New(env->GetIsolate(), memory, 1024,
v8::ArrayBufferCreationMode::kInternalized);
CHECK(!buffer->IsExternal());
#if __clang__
#pragma clang diagnostic pop
#endif
CHECK_EQ(memory, buffer->GetBackingStore()->Data());
}
void TestSpeciesProtector(char* code,
bool invalidates_species_protector = true) {
v8::Isolate::CreateParams create_params;