diff --git a/src/wasm/module-compiler.cc b/src/wasm/module-compiler.cc index c8c647a5c9..47eb8bf870 100644 --- a/src/wasm/module-compiler.cc +++ b/src/wasm/module-compiler.cc @@ -1651,19 +1651,9 @@ MaybeHandle InstanceBuilder::Build() { WasmContext* wasm_context = instance->wasm_context()->get(); uint32_t globals_size = module_->globals_size; if (globals_size > 0) { - void* backing_store = - isolate_->array_buffer_allocator()->Allocate(globals_size); - if (backing_store == nullptr) { - thrower_->RangeError("Out of memory: wasm globals"); - return {}; - } - globals_ = - isolate_->factory()->NewJSArrayBuffer(SharedFlag::kNotShared, TENURED); - constexpr bool is_external = false; - constexpr bool is_wasm_memory = false; - JSArrayBuffer::Setup(globals_, isolate_, is_external, backing_store, - globals_size, SharedFlag::kNotShared, is_wasm_memory); - if (globals_.is_null()) { + constexpr bool enable_guard_regions = false; + if (!NewArrayBuffer(isolate_, globals_size, enable_guard_regions) + .ToHandle(&globals_)) { thrower_->RangeError("Out of memory: wasm globals"); return {}; } @@ -2358,12 +2348,14 @@ Handle InstanceBuilder::AllocateMemory(uint32_t num_pages) { thrower_->RangeError("Out of memory: wasm memory too large"); return Handle::null(); } + const bool enable_guard_regions = use_trap_handler(); const bool is_shared_memory = module_->has_shared_memory && i::FLAG_experimental_wasm_threads; i::SharedFlag shared_flag = is_shared_memory ? i::SharedFlag::kShared : i::SharedFlag::kNotShared; Handle mem_buffer; - if (!NewArrayBuffer(isolate_, num_pages * kWasmPageSize, shared_flag) + if (!NewArrayBuffer(isolate_, num_pages * kWasmPageSize, enable_guard_regions, + shared_flag) .ToHandle(&mem_buffer)) { thrower_->RangeError("Out of memory: wasm memory"); } diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc index e34de08d83..cb5bb9e229 100644 --- a/src/wasm/wasm-js.cc +++ b/src/wasm/wasm-js.cc @@ -651,12 +651,15 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo& args) { } } + size_t size = static_cast(i::wasm::kWasmPageSize) * + static_cast(initial); + const bool enable_guard_regions = + internal::trap_handler::IsTrapHandlerEnabled(); i::SharedFlag shared_flag = is_shared_memory ? i::SharedFlag::kShared : i::SharedFlag::kNotShared; i::Handle buffer; - size_t size = static_cast(i::wasm::kWasmPageSize) * - static_cast(initial); - if (!i::wasm::NewArrayBuffer(i_isolate, size, shared_flag) + if (!i::wasm::NewArrayBuffer(i_isolate, size, enable_guard_regions, + shared_flag) .ToHandle(&buffer)) { thrower.RangeError("could not allocate memory"); return; diff --git a/src/wasm/wasm-memory.cc b/src/wasm/wasm-memory.cc index 6572935e53..a76e1acdbe 100644 --- a/src/wasm/wasm-memory.cc +++ b/src/wasm/wasm-memory.cc @@ -14,18 +14,20 @@ namespace wasm { namespace { void* TryAllocateBackingStore(WasmMemoryTracker* memory_tracker, Heap* heap, - size_t size, void** allocation_base, + size_t size, bool require_guard_regions, + void** allocation_base, size_t* allocation_length) { -// We always allocate the largest possible offset into the heap, so the -// addressable memory after the guard page can be made inaccessible. -#if V8_TARGET_ARCH_64_BIT - *allocation_length = RoundUp(kWasmMaxHeapOffset, CommitPageSize()); -#else - *allocation_length = - RoundUp(base::bits::RoundUpToPowerOfTwo32(static_cast(size)), - kWasmPageSize); +#if V8_TARGET_ARCH_32_BIT + DCHECK(!require_guard_regions); #endif - + // We always allocate the largest possible offset into the heap, so the + // addressable memory after the guard page can be made inaccessible. + *allocation_length = + require_guard_regions + ? RoundUp(kWasmMaxHeapOffset, CommitPageSize()) + : RoundUp( + base::bits::RoundUpToPowerOfTwo32(static_cast(size)), + kWasmPageSize); DCHECK_GE(*allocation_length, size); DCHECK_GE(*allocation_length, kWasmPageSize); @@ -179,11 +181,12 @@ void* WasmMemoryTracker::GetEmptyBackingStore(void** allocation_base, Heap* heap) { if (empty_backing_store_.allocation_base == nullptr) { constexpr size_t buffer_length = 0; + const bool require_guard_regions = trap_handler::IsTrapHandlerEnabled(); void* local_allocation_base; size_t local_allocation_length; - void* buffer_start = TryAllocateBackingStore(this, heap, buffer_length, - &local_allocation_base, - &local_allocation_length); + void* buffer_start = TryAllocateBackingStore( + this, heap, buffer_length, require_guard_regions, + &local_allocation_base, &local_allocation_length); empty_backing_store_ = AllocationData(local_allocation_base, local_allocation_length, @@ -229,6 +232,7 @@ Handle SetupArrayBuffer(Isolate* isolate, void* backing_store, } MaybeHandle NewArrayBuffer(Isolate* isolate, size_t size, + bool require_guard_regions, SharedFlag shared) { // Check against kMaxInt, since the byte length is stored as int in the // JSArrayBuffer. Note that wasm_max_mem_pages can be raised from the command @@ -249,10 +253,10 @@ MaybeHandle NewArrayBuffer(Isolate* isolate, size_t size, ? memory_tracker->GetEmptyBackingStore( &allocation_base, &allocation_length, isolate->heap()) : TryAllocateBackingStore(memory_tracker, isolate->heap(), size, - &allocation_base, &allocation_length); - if (memory == nullptr) { - return {}; - } + require_guard_regions, &allocation_base, + &allocation_length); + + if (size > 0 && memory == nullptr) return {}; #if DEBUG // Double check the API allocator actually zero-initialized the memory. diff --git a/src/wasm/wasm-memory.h b/src/wasm/wasm-memory.h index 77d50dfb6d..1652868bf1 100644 --- a/src/wasm/wasm-memory.h +++ b/src/wasm/wasm-memory.h @@ -114,7 +114,8 @@ class WasmMemoryTracker { }; MaybeHandle NewArrayBuffer( - Isolate*, size_t size, SharedFlag shared = SharedFlag::kNotShared); + Isolate*, size_t size, bool require_guard_regions, + SharedFlag shared = SharedFlag::kNotShared); Handle SetupArrayBuffer( Isolate*, void* backing_store, size_t size, bool is_external, diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index 86b622b950..d27d9d6301 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -345,7 +345,8 @@ namespace { MaybeHandle GrowMemoryBuffer(Isolate* isolate, Handle old_buffer, uint32_t pages, - uint32_t maximum_pages) { + uint32_t maximum_pages, + bool use_trap_handler) { if (!old_buffer->is_growable()) return {}; Address old_mem_start = nullptr; uint32_t old_size = 0; @@ -396,7 +397,8 @@ MaybeHandle GrowMemoryBuffer(Isolate* isolate, // We couldn't reuse the old backing store, so create a new one and copy the // old contents in. Handle new_buffer; - if (!wasm::NewArrayBuffer(isolate, new_size).ToHandle(&new_buffer)) { + if (!wasm::NewArrayBuffer(isolate, new_size, use_trap_handler) + .ToHandle(&new_buffer)) { return {}; } if (old_size == 0) return new_buffer; @@ -500,7 +502,10 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, maximum_pages = Min(FLAG_wasm_max_mem_pages, static_cast(memory_object->maximum_pages())); } - if (!GrowMemoryBuffer(isolate, old_buffer, pages, maximum_pages) + // TODO(kschimpf): We need to fix this by adding a field to WasmMemoryObject + // that defines the style of memory being used. + if (!GrowMemoryBuffer(isolate, old_buffer, pages, maximum_pages, + trap_handler::IsTrapHandlerEnabled()) .ToHandle(&new_buffer)) { return -1; } diff --git a/test/cctest/wasm/test-run-wasm-module.cc b/test/cctest/wasm/test-run-wasm-module.cc index 1073c08f26..95084ff2c3 100644 --- a/test/cctest/wasm/test-run-wasm-module.cc +++ b/test/cctest/wasm/test-run-wasm-module.cc @@ -1079,8 +1079,15 @@ TEST(Run_WasmModule_Buffer_Externalized_GrowMemMemSize) { { Isolate* isolate = CcTest::InitIsolateOnce(); HandleScope scope(isolate); +#if V8_TARGET_ARCH_64_BIT + constexpr bool require_guard_regions = true; +#else + constexpr bool require_guard_regions = false; +#endif Handle buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); + CHECK( + wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize, require_guard_regions) + .ToHandle(&buffer)); Handle mem_obj = WasmMemoryObject::New(isolate, buffer, 100); auto const contents = v8::Utils::ToLocal(buffer)->Externalize(); @@ -1101,8 +1108,15 @@ TEST(Run_WasmModule_Buffer_Externalized_Detach) { // https://bugs.chromium.org/p/chromium/issues/detail?id=731046 Isolate* isolate = CcTest::InitIsolateOnce(); HandleScope scope(isolate); +#if V8_TARGET_ARCH_64_BIT + constexpr bool require_guard_regions = true; +#else + constexpr bool require_guard_regions = false; +#endif Handle buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); + CHECK( + wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize, require_guard_regions) + .ToHandle(&buffer)); auto const contents = v8::Utils::ToLocal(buffer)->Externalize(); wasm::DetachMemoryBuffer(isolate, buffer, true); constexpr bool is_wasm_memory = true; @@ -1118,8 +1132,14 @@ TEST(Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree) { // Regresion test for https://crbug.com/813876 Isolate* isolate = CcTest::InitIsolateOnce(); HandleScope scope(isolate); +#if V8_TARGET_ARCH_64_BIT + const bool require_guard_regions = trap_handler::IsTrapHandlerEnabled(); +#else + constexpr bool require_guard_regions = false; +#endif Handle buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); + CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize, require_guard_regions) + .ToHandle(&buffer)); Handle mem = WasmMemoryObject::New(isolate, buffer, 128); auto contents = v8::Utils::ToLocal(buffer)->Externalize(); WasmMemoryObject::Grow(isolate, mem, 0); @@ -1141,7 +1161,9 @@ TEST(Run_WasmModule_Reclaim_Memory) { Handle buffer; for (int i = 0; i < 256; ++i) { HandleScope scope(isolate); - CHECK(NewArrayBuffer(isolate, kWasmPageSize, SharedFlag::kNotShared) + constexpr bool require_guard_regions = true; + CHECK(NewArrayBuffer(isolate, kWasmPageSize, require_guard_regions, + SharedFlag::kNotShared) .ToHandle(&buffer)); } } diff --git a/test/cctest/wasm/wasm-run-utils.cc b/test/cctest/wasm/wasm-run-utils.cc index 881354e9d5..fd5662499d 100644 --- a/test/cctest/wasm/wasm-run-utils.cc +++ b/test/cctest/wasm/wasm-run-utils.cc @@ -40,9 +40,13 @@ byte* TestingModuleBuilder::AddMemory(uint32_t size) { CHECK_EQ(0, mem_size_); DCHECK(!instance_object_->has_memory_object()); test_module_.has_memory = true; - uint32_t alloc_size = RoundUp(size, kWasmPageSize); + const bool enable_guard_regions = + trap_handler::IsTrapHandlerEnabled() && test_module_.is_wasm(); + uint32_t alloc_size = + enable_guard_regions ? RoundUp(size, CommitPageSize()) : size; Handle new_buffer; - CHECK(wasm::NewArrayBuffer(isolate_, alloc_size).ToHandle(&new_buffer)); + CHECK(wasm::NewArrayBuffer(isolate_, alloc_size, enable_guard_regions) + .ToHandle(&new_buffer)); CHECK(!new_buffer.is_null()); mem_start_ = reinterpret_cast(new_buffer->backing_store()); mem_size_ = size;