[rab/gsab] Fix gsab maxByteLength after transferring to worker

Bug: v8:11111
Change-Id: I41a318d3858e48035ae67e937420e2963a13d871
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3035091
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75878}
This commit is contained in:
Marja Hölttä 2021-07-23 10:51:56 +02:00 committed by V8 LUCI CQ
parent 66856bacdc
commit 1e7effd113
5 changed files with 46 additions and 24 deletions

View File

@ -108,8 +108,8 @@ Object ConstructBuffer(Isolate* isolate, Handle<JSFunction> target,
}
constexpr bool kIsWasmMemory = false;
backing_store = BackingStore::TryAllocateAndPartiallyCommitMemory(
isolate, byte_length, page_size, initial_pages, max_pages,
kIsWasmMemory, shared);
isolate, byte_length, max_byte_length, page_size, initial_pages,
max_pages, kIsWasmMemory, shared);
}
if (!backing_store) {
// Allocation of backing store failed.
@ -475,6 +475,9 @@ BUILTIN(SharedArrayBufferPrototypeGetByteLength) {
// 3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
CHECK_SHARED(true, array_buffer, kMethodName);
DCHECK_EQ(array_buffer->max_byte_length(),
array_buffer->GetBackingStore()->max_byte_length());
// 4. Let length be ArrayBufferByteLength(O, SeqCst).
size_t byte_length;
if (array_buffer->is_resizable()) {

View File

@ -267,6 +267,7 @@ std::unique_ptr<BackingStore> BackingStore::Allocate(
auto result = new BackingStore(buffer_start, // start
byte_length, // length
byte_length, // max length
byte_length, // capacity
shared, // shared
ResizableFlag::kNotResizable, // resizable
@ -305,8 +306,9 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory(
maximum_pages = std::min(engine_max_pages, maximum_pages);
auto result = TryAllocateAndPartiallyCommitMemory(
isolate, initial_pages * wasm::kWasmPageSize, wasm::kWasmPageSize,
initial_pages, maximum_pages, true, shared);
isolate, initial_pages * wasm::kWasmPageSize,
maximum_pages * wasm::kWasmPageSize, wasm::kWasmPageSize, initial_pages,
maximum_pages, true, shared);
// Shared Wasm memories need an anchor for the memory object list.
if (result && shared == SharedFlag::kShared) {
result->type_specific_data_.shared_wasm_memory_data =
@ -336,9 +338,9 @@ void BackingStore::ReleaseReservation(uint64_t num_bytes) {
}
std::unique_ptr<BackingStore> BackingStore::TryAllocateAndPartiallyCommitMemory(
Isolate* isolate, size_t byte_length, size_t page_size,
size_t initial_pages, size_t maximum_pages, bool is_wasm_memory,
SharedFlag shared) {
Isolate* isolate, size_t byte_length, size_t max_byte_length,
size_t page_size, size_t initial_pages, size_t maximum_pages,
bool is_wasm_memory, SharedFlag shared) {
// Enforce engine limitation on the maximum number of pages.
if (maximum_pages > std::numeric_limits<size_t>::max() / page_size) {
return nullptr;
@ -445,16 +447,17 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateAndPartiallyCommitMemory(
ResizableFlag resizable =
is_wasm_memory ? ResizableFlag::kNotResizable : ResizableFlag::kResizable;
auto result = new BackingStore(buffer_start, // start
byte_length, // length
byte_capacity, // capacity
shared, // shared
resizable, // resizable
is_wasm_memory, // is_wasm_memory
true, // free_on_destruct
guards, // has_guard_regions
false, // custom_deleter
false); // empty_deleter
auto result = new BackingStore(buffer_start, // start
byte_length, // length
max_byte_length, // max_byte_length
byte_capacity, // capacity
shared, // shared
resizable, // resizable
is_wasm_memory, // is_wasm_memory
true, // free_on_destruct
guards, // has_guard_regions
false, // custom_deleter
false); // empty_deleter
TRACE_BS(
"BSw:alloc bs=%p mem=%p (length=%zu, capacity=%zu, reservation=%zu)\n",
@ -707,6 +710,7 @@ std::unique_ptr<BackingStore> BackingStore::WrapAllocation(
SharedFlag shared, bool free_on_destruct) {
auto result = new BackingStore(allocation_base, // start
allocation_length, // length
allocation_length, // max length
allocation_length, // capacity
shared, // shared
ResizableFlag::kNotResizable, // resizable
@ -728,6 +732,7 @@ std::unique_ptr<BackingStore> BackingStore::WrapAllocation(
bool is_empty_deleter = (deleter == v8::BackingStore::EmptyDeleter);
auto result = new BackingStore(allocation_base, // start
allocation_length, // length
allocation_length, // max length
allocation_length, // capacity
shared, // shared
ResizableFlag::kNotResizable, // resizable
@ -746,6 +751,7 @@ std::unique_ptr<BackingStore> BackingStore::EmptyBackingStore(
SharedFlag shared) {
auto result = new BackingStore(nullptr, // start
0, // length
0, // max length
0, // capacity
shared, // shared
ResizableFlag::kNotResizable, // resizable

View File

@ -61,9 +61,9 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
// Tries to allocate `maximum_pages` of memory and commit `initial_pages`.
static std::unique_ptr<BackingStore> TryAllocateAndPartiallyCommitMemory(
Isolate* isolate, size_t byte_length, size_t page_size,
size_t initial_pages, size_t maximum_pages, bool is_wasm_memory,
SharedFlag shared);
Isolate* isolate, size_t byte_length, size_t max_byte_length,
size_t page_size, size_t initial_pages, size_t maximum_pages,
bool is_wasm_memory, SharedFlag shared);
// Create a backing store that wraps existing allocated memory.
// If {free_on_destruct} is {true}, the memory will be freed using the
@ -90,6 +90,7 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
std::memory_order memory_order = std::memory_order_relaxed) const {
return byte_length_.load(memory_order);
}
size_t max_byte_length() const { return max_byte_length_; }
size_t byte_capacity() const { return byte_capacity_; }
bool is_shared() const { return is_shared_; }
bool is_resizable() const { return is_resizable_; }
@ -165,12 +166,13 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
private:
friend class GlobalBackingStoreRegistry;
BackingStore(void* buffer_start, size_t byte_length, size_t byte_capacity,
SharedFlag shared, ResizableFlag resizable, bool is_wasm_memory,
bool free_on_destruct, bool has_guard_regions,
bool custom_deleter, bool empty_deleter)
BackingStore(void* buffer_start, size_t byte_length, size_t max_byte_length,
size_t byte_capacity, SharedFlag shared, ResizableFlag resizable,
bool is_wasm_memory, bool free_on_destruct,
bool has_guard_regions, bool custom_deleter, bool empty_deleter)
: buffer_start_(buffer_start),
byte_length_(byte_length),
max_byte_length_(max_byte_length),
byte_capacity_(byte_capacity),
is_shared_(shared == SharedFlag::kShared),
is_resizable_(resizable == ResizableFlag::kResizable),
@ -185,6 +187,8 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
DCHECK_IMPLIES(is_wasm_memory_, !is_resizable_);
DCHECK_IMPLIES(is_resizable_, !custom_deleter_);
DCHECK_IMPLIES(is_resizable_, free_on_destruct_);
DCHECK_IMPLIES(!is_wasm_memory && !is_resizable_,
byte_length_ == max_byte_length_);
}
BackingStore(const BackingStore&) = delete;
BackingStore& operator=(const BackingStore&) = delete;
@ -192,6 +196,9 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
void* buffer_start_ = nullptr;
std::atomic<size_t> byte_length_{0};
// Max byte length of the corresponding JSArrayBuffer(s).
size_t max_byte_length_ = 0;
// Amount of the memory allocated
size_t byte_capacity_ = 0;
struct DeleterInfo {

View File

@ -59,6 +59,7 @@ void JSArrayBuffer::Setup(SharedFlag shared, ResizableFlag resizable,
if (!backing_store) {
set_backing_store(GetIsolate(), nullptr);
set_byte_length(0);
set_max_byte_length(0);
} else {
Attach(std::move(backing_store));
}
@ -72,6 +73,9 @@ void JSArrayBuffer::Attach(std::shared_ptr<BackingStore> backing_store) {
DCHECK_NOT_NULL(backing_store);
DCHECK_EQ(is_shared(), backing_store->is_shared());
DCHECK_EQ(is_resizable(), backing_store->is_resizable());
DCHECK_IMPLIES(
!backing_store->is_wasm_memory() && !backing_store->is_resizable(),
backing_store->byte_length() == backing_store->max_byte_length());
DCHECK(!was_detached());
Isolate* isolate = GetIsolate();
set_backing_store(isolate, backing_store->buffer_start());
@ -82,6 +86,7 @@ void JSArrayBuffer::Attach(std::shared_ptr<BackingStore> backing_store) {
} else {
set_byte_length(backing_store->byte_length());
}
set_max_byte_length(backing_store->max_byte_length());
if (backing_store->is_wasm_memory()) set_is_detachable(false);
if (!backing_store->free_on_destruct()) set_is_external(true);
Heap* heap = isolate->heap();

View File

@ -534,6 +534,7 @@ const ctors = [[ArrayBuffer, (b) => b.resizable],
assert(!(gsab instanceof ArrayBuffer));
assert(gsab instanceof SharedArrayBuffer);
assert(10 == gsab.byteLength);
assert(20 == gsab.maxByteLength);
gsab.grow(15);
postMessage('ok');
}