OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |