Commit 337611a4 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[api] Add [Shared]ArrayBuffer::New that takes a BackingStore

This complements [Shared]ArrayBuffer::GetBackingStore and allows the
embedder to transfer (shared) array buffers using only BackingStores.

Bug: v8:9380
Change-Id: I4714a27e06d5be43aef06dc633f11f2d43e4ee75
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1811037
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63889}
parent 513c7511
......@@ -4874,6 +4874,21 @@ class V8_EXPORT ArrayBuffer : public Object {
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
* is garbage collected. Note that the IsExternal bit does not affect this
* reference from the array to the backing store.
*
* In future IsExternal bit will be removed. Until then the bit is set as
* follows. If the backing store does not own the underlying buffer, then
* the array is created in externalized state. Otherwise, the array is created
* in internalized state. In the latter case the array can be transitioned
* to the externalized state using Externalize(backing_store).
*/
static Local<ArrayBuffer> New(Isolate* isolate,
std::shared_ptr<BackingStore> backing_store);
/**
* Returns true if ArrayBuffer is externalized, that is, does not
* own its memory block.
......@@ -5309,6 +5324,21 @@ class V8_EXPORT SharedArrayBuffer : public Object {
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
* is garbage collected. Note that the IsExternal bit does not affect this
* reference from the array to the backing store.
*
* In future IsExternal bit will be removed. Until then the bit is set as
* follows. If the backing store does not own the underlying buffer, then
* the array is created in externalized state. Otherwise, the array is created
* in internalized state. In the latter case the array can be transitioned
* to the externalized state using Externalize(backing_store).
*/
static Local<SharedArrayBuffer> New(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store);
/**
* Create a new SharedArrayBuffer over an existing memory block. Propagate
* flags to indicate whether the underlying buffer can be grown.
......
......@@ -7303,6 +7303,11 @@ std::shared_ptr<i::BackingStore> LookupOrCreateBackingStore(
}
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,
......@@ -7427,7 +7432,7 @@ 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(byte_length == 0 || data != nullptr);
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);
......@@ -7444,6 +7449,24 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
return Utils::ToLocal(obj);
}
Local<ArrayBuffer> v8::ArrayBuffer::New(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
CHECK_IMPLIES(backing_store->ByteLength() != 0,
backing_store->Data() != nullptr);
CHECK_LE(backing_store->ByteLength(), 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> i_backing_store(
ToInternal(std::move(backing_store)));
Utils::ApiCheck(
!i_backing_store->is_shared(), "v8_ArrayBuffer_New",
"Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
i::Handle<i::JSArrayBuffer> obj = i_isolate->factory()->NewJSArrayBuffer();
obj->Attach(std::move(i_backing_store));
return Utils::ToLocal(obj);
}
Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
i::Handle<i::JSArrayBuffer> buffer;
......@@ -7721,6 +7744,25 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
return Utils::ToLocalShared(buffer);
}
Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
CHECK(i::FLAG_harmony_sharedarraybuffer);
CHECK_IMPLIES(backing_store->ByteLength() != 0,
backing_store->Data() != nullptr);
CHECK_LE(backing_store->ByteLength(), i::JSArrayBuffer::kMaxByteLength);
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> i_backing_store(ToInternal(backing_store));
Utils::ApiCheck(
i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
"Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSSharedArrayBuffer();
obj->Attach(std::move(i_backing_store));
return Utils::ToLocalShared(obj);
}
Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
Isolate* isolate, const SharedArrayBuffer::Contents& contents,
ArrayBufferCreationMode mode) {
......
......@@ -3308,8 +3308,8 @@ class Deserializer : public ValueDeserializer::Delegate {
uint32_t index = 0;
for (const auto& backing_store : data_->backing_stores()) {
Local<ArrayBuffer> array_buffer = ArrayBuffer::New(
isolate_, backing_store->Data(), backing_store->ByteLength());
Local<ArrayBuffer> array_buffer =
ArrayBuffer::New(isolate_, std::move(backing_store));
deserializer_.TransferArrayBuffer(index++, array_buffer);
}
......@@ -3320,9 +3320,8 @@ class Deserializer : public ValueDeserializer::Delegate {
Isolate* isolate, uint32_t clone_id) override {
DCHECK_NOT_NULL(data_);
if (clone_id < data_->sab_backing_stores().size()) {
auto backing_store = data_->sab_backing_stores().at(clone_id);
return SharedArrayBuffer::New(isolate_, backing_store->Data(),
backing_store->ByteLength());
return SharedArrayBuffer::New(
isolate_, std::move(data_->sab_backing_stores().at(clone_id)));
}
return MaybeLocal<SharedArrayBuffer>();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment