Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2772973002: [wasm] Detach memory buffer only when GrowMemory is called from the JS API (Closed)
Patch Set: Add comment Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/mjsunit/regress/wasm/regression-699485.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "src/assembler-inl.h" 7 #include "src/assembler-inl.h"
8 #include "src/base/adapters.h" 8 #include "src/base/adapters.h"
9 #include "src/base/atomic-utils.h" 9 #include "src/base/atomic-utils.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 2331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 if (compiled_max_pages != 0) return compiled_max_pages; 2342 if (compiled_max_pages != 0) return compiled_max_pages;
2343 return FLAG_wasm_max_mem_pages; 2343 return FLAG_wasm_max_mem_pages;
2344 } 2344 }
2345 2345
2346 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate, 2346 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate,
2347 MaybeHandle<JSArrayBuffer> buffer, 2347 MaybeHandle<JSArrayBuffer> buffer,
2348 uint32_t pages, uint32_t max_pages) { 2348 uint32_t pages, uint32_t max_pages) {
2349 Handle<JSArrayBuffer> old_buffer; 2349 Handle<JSArrayBuffer> old_buffer;
2350 Address old_mem_start = nullptr; 2350 Address old_mem_start = nullptr;
2351 uint32_t old_size = 0; 2351 uint32_t old_size = 0;
2352 if (buffer.ToHandle(&old_buffer) && old_buffer->backing_store() != nullptr) { 2352 if (buffer.ToHandle(&old_buffer) && old_buffer->backing_store() != nullptr &&
2353 old_buffer->byte_length()->IsNumber()) {
2353 old_mem_start = static_cast<Address>(old_buffer->backing_store()); 2354 old_mem_start = static_cast<Address>(old_buffer->backing_store());
2354 DCHECK_NOT_NULL(old_mem_start); 2355 DCHECK_NOT_NULL(old_mem_start);
2355 old_size = old_buffer->byte_length()->Number(); 2356 old_size = old_buffer->byte_length()->Number();
2356 } 2357 }
2357 DCHECK(old_size + pages * WasmModule::kPageSize <= 2358 DCHECK(old_size + pages * WasmModule::kPageSize <=
2358 std::numeric_limits<uint32_t>::max()); 2359 std::numeric_limits<uint32_t>::max());
2359 uint32_t new_size = old_size + pages * WasmModule::kPageSize; 2360 uint32_t new_size = old_size + pages * WasmModule::kPageSize;
2360 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size || 2361 if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size ||
2361 FLAG_wasm_max_mem_pages * WasmModule::kPageSize < new_size) { 2362 FLAG_wasm_max_mem_pages * WasmModule::kPageSize < new_size) {
2362 return Handle<JSArrayBuffer>::null(); 2363 return Handle<JSArrayBuffer>::null();
(...skipping 22 matching lines...) Expand all
2385 uint32_t new_size = mem_buffer->byte_length()->Number(); 2386 uint32_t new_size = mem_buffer->byte_length()->Number();
2386 Address new_mem_start = static_cast<Address>(mem_buffer->backing_store()); 2387 Address new_mem_start = static_cast<Address>(mem_buffer->backing_store());
2387 DCHECK_NOT_NULL(new_mem_start); 2388 DCHECK_NOT_NULL(new_mem_start);
2388 Zone specialization_zone(isolate->allocator(), ZONE_NAME); 2389 Zone specialization_zone(isolate->allocator(), ZONE_NAME);
2389 CodeSpecialization code_specialization(isolate, &specialization_zone); 2390 CodeSpecialization code_specialization(isolate, &specialization_zone);
2390 code_specialization.RelocateMemoryReferences(old_mem_start, old_size, 2391 code_specialization.RelocateMemoryReferences(old_mem_start, old_size,
2391 new_mem_start, new_size); 2392 new_mem_start, new_size);
2392 code_specialization.ApplyToWholeInstance(*instance); 2393 code_specialization.ApplyToWholeInstance(*instance);
2393 } 2394 }
2394 2395
2395 void DetachArrayBuffer(Isolate* isolate, Handle<JSArrayBuffer> buffer) { 2396 void wasm::DetachWebAssemblyMemoryBuffer(Isolate* isolate,
2396 const bool has_guard_regions = 2397 Handle<JSArrayBuffer> buffer) {
2397 (!buffer.is_null() && buffer->has_guard_region()); 2398 int64_t byte_length =
2399 buffer->byte_length()->IsNumber()
2400 ? static_cast<uint32_t>(buffer->byte_length()->Number())
2401 : 0;
2402 if (buffer.is_null() || byte_length == 0) return;
2403 const bool has_guard_regions = buffer->has_guard_region();
2398 const bool is_external = buffer->is_external(); 2404 const bool is_external = buffer->is_external();
2399 void* backing_store = buffer->backing_store(); 2405 void* backing_store = buffer->backing_store();
2400 if (backing_store != nullptr) { 2406 DCHECK(!buffer->is_neuterable());
2401 DCHECK(!buffer->is_neuterable()); 2407 if (!has_guard_regions && !is_external) {
2402 int64_t byte_length = NumberToSize(buffer->byte_length()); 2408 buffer->set_is_external(true);
2403 buffer->set_is_neuterable(true); 2409 isolate->heap()->UnregisterArrayBuffer(*buffer);
2404 if (!has_guard_regions && !is_external) { 2410 }
2405 buffer->set_is_external(true); 2411 buffer->set_is_neuterable(true);
2406 isolate->heap()->UnregisterArrayBuffer(*buffer); 2412 buffer->Neuter();
2407 } 2413 if (has_guard_regions) {
2408 buffer->Neuter(); 2414 base::OS::Free(backing_store, RoundUp(i::wasm::kWasmMaxHeapOffset,
2409 if (has_guard_regions) { 2415 base::OS::CommitPageSize()));
2410 base::OS::Free(backing_store, RoundUp(i::wasm::kWasmMaxHeapOffset, 2416 reinterpret_cast<v8::Isolate*>(isolate)
2411 base::OS::CommitPageSize())); 2417 ->AdjustAmountOfExternalAllocatedMemory(-byte_length);
2412 reinterpret_cast<v8::Isolate*>(isolate) 2418 } else if (!has_guard_regions && !is_external) {
2413 ->AdjustAmountOfExternalAllocatedMemory(-byte_length); 2419 isolate->array_buffer_allocator()->Free(backing_store, byte_length);
2414 } else if (!has_guard_regions && !is_external) {
2415 isolate->array_buffer_allocator()->Free(backing_store, byte_length);
2416 }
2417 } 2420 }
2418 } 2421 }
2419 2422
2420 int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, 2423 int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate,
2421 Handle<WasmMemoryObject> receiver, 2424 Handle<WasmMemoryObject> receiver,
2422 uint32_t pages) { 2425 uint32_t pages) {
2423 DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver)); 2426 DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver));
2424 Handle<WasmMemoryObject> memory_object = 2427 Handle<WasmMemoryObject> memory_object =
2425 handle(WasmMemoryObject::cast(*receiver)); 2428 handle(WasmMemoryObject::cast(*receiver));
2426 MaybeHandle<JSArrayBuffer> memory_buffer = handle(memory_object->buffer()); 2429 MaybeHandle<JSArrayBuffer> memory_buffer = handle(memory_object->buffer());
2427 Handle<JSArrayBuffer> old_buffer; 2430 Handle<JSArrayBuffer> old_buffer;
2428 uint32_t old_size = 0; 2431 uint32_t old_size = 0;
2429 Address old_mem_start = nullptr; 2432 Address old_mem_start = nullptr;
2433 // Force byte_length to 0, if byte_length fails IsNumber() check.
2430 if (memory_buffer.ToHandle(&old_buffer) && 2434 if (memory_buffer.ToHandle(&old_buffer) &&
2431 old_buffer->backing_store() != nullptr) { 2435 old_buffer->backing_store() != nullptr &&
2436 old_buffer->byte_length()->IsNumber()) {
2432 old_size = old_buffer->byte_length()->Number(); 2437 old_size = old_buffer->byte_length()->Number();
2433 old_mem_start = static_cast<Address>(old_buffer->backing_store()); 2438 old_mem_start = static_cast<Address>(old_buffer->backing_store());
2434 } 2439 }
2435 Handle<JSArrayBuffer> new_buffer; 2440 Handle<JSArrayBuffer> new_buffer;
2436 // Return current size if grow by 0 2441 // Return current size if grow by 0
2437 if (pages == 0) { 2442 if (pages == 0) {
2438 if (!old_buffer.is_null() && old_buffer->backing_store() != nullptr) { 2443 if (!old_buffer.is_null() && old_buffer->backing_store() != nullptr) {
2439 new_buffer = SetupArrayBuffer(isolate, old_buffer->backing_store(), 2444 new_buffer = SetupArrayBuffer(isolate, old_buffer->backing_store(),
2440 old_size, old_buffer->is_external(), 2445 old_size, old_buffer->is_external(),
2441 old_buffer->has_guard_region()); 2446 old_buffer->has_guard_region());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 while (instance_wrapper->has_next()) { 2486 while (instance_wrapper->has_next()) {
2482 instance_wrapper = instance_wrapper->next_wrapper(); 2487 instance_wrapper = instance_wrapper->next_wrapper();
2483 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); 2488 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
2484 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); 2489 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
2485 DCHECK(IsWasmInstance(*instance)); 2490 DCHECK(IsWasmInstance(*instance));
2486 SetInstanceMemory(instance, *new_buffer); 2491 SetInstanceMemory(instance, *new_buffer);
2487 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); 2492 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
2488 } 2493 }
2489 } 2494 }
2490 memory_object->set_buffer(*new_buffer); 2495 memory_object->set_buffer(*new_buffer);
2491 DetachArrayBuffer(isolate, old_buffer);
2492 DCHECK(old_size % WasmModule::kPageSize == 0); 2496 DCHECK(old_size % WasmModule::kPageSize == 0);
2493 return (old_size / WasmModule::kPageSize); 2497 return (old_size / WasmModule::kPageSize);
2494 } 2498 }
2495 2499
2496 int32_t wasm::GrowMemory(Isolate* isolate, Handle<WasmInstanceObject> instance, 2500 int32_t wasm::GrowMemory(Isolate* isolate, Handle<WasmInstanceObject> instance,
2497 uint32_t pages) { 2501 uint32_t pages) {
2498 if (!IsWasmInstance(*instance)) return -1; 2502 if (!IsWasmInstance(*instance)) return -1;
2499 if (pages == 0) return GetInstanceMemorySize(isolate, instance); 2503 if (pages == 0) return GetInstanceMemorySize(isolate, instance);
2500 Handle<WasmInstanceObject> instance_obj(WasmInstanceObject::cast(*instance)); 2504 Handle<WasmInstanceObject> instance_obj(WasmInstanceObject::cast(*instance));
2501 if (!instance_obj->has_memory_object()) { 2505 if (!instance_obj->has_memory_object()) {
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
3202 callee_compiled->instruction_start()); 3206 callee_compiled->instruction_start());
3203 } 3207 }
3204 DCHECK_EQ(non_compiled_functions.size(), idx); 3208 DCHECK_EQ(non_compiled_functions.size(), idx);
3205 } 3209 }
3206 3210
3207 Code* ret = 3211 Code* ret =
3208 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); 3212 Code::cast(compiled_module->code_table()->get(func_to_return_idx));
3209 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); 3213 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind());
3210 return handle(ret, isolate); 3214 return handle(ret, isolate);
3211 } 3215 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/mjsunit/regress/wasm/regression-699485.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698