Chromium Code Reviews| 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 "src/wasm/wasm-objects.h" | 5 #include "src/wasm/wasm-objects.h" |
| 6 #include "src/utils.h" | 6 #include "src/utils.h" |
| 7 | 7 |
| 8 #include "src/assembler-inl.h" | 8 #include "src/assembler-inl.h" |
| 9 #include "src/base/iterator.h" | 9 #include "src/base/iterator.h" |
| 10 #include "src/compiler/wasm-compiler.h" | 10 #include "src/compiler/wasm-compiler.h" |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 isolate->factory()->NewJSObject(memory_ctor, TENURED)); | 322 isolate->factory()->NewJSObject(memory_ctor, TENURED)); |
| 323 if (buffer.is_null()) { | 323 if (buffer.is_null()) { |
| 324 const bool enable_guard_regions = EnableGuardRegions(); | 324 const bool enable_guard_regions = EnableGuardRegions(); |
| 325 buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false, | 325 buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false, |
| 326 enable_guard_regions); | 326 enable_guard_regions); |
| 327 } | 327 } |
| 328 memory_obj->set_array_buffer(*buffer); | 328 memory_obj->set_array_buffer(*buffer); |
| 329 memory_obj->set_maximum_pages(maximum); | 329 memory_obj->set_maximum_pages(maximum); |
| 330 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); | 330 Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym()); |
| 331 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); | 331 Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check(); |
| 332 return Handle<WasmMemoryObject>::cast(memory_obj); | 332 |
| 333 return memory_obj; | |
| 333 } | 334 } |
| 334 | 335 |
| 335 uint32_t WasmMemoryObject::current_pages() { | 336 uint32_t WasmMemoryObject::current_pages() { |
| 336 uint32_t byte_length; | 337 uint32_t byte_length; |
| 337 CHECK(array_buffer()->byte_length()->ToUint32(&byte_length)); | 338 CHECK(array_buffer()->byte_length()->ToUint32(&byte_length)); |
| 338 return byte_length / wasm::WasmModule::kPageSize; | 339 return byte_length / wasm::WasmModule::kPageSize; |
| 339 } | 340 } |
| 340 | 341 |
| 341 void WasmMemoryObject::AddInstance(Isolate* isolate, | 342 void WasmMemoryObject::AddInstance(Isolate* isolate, |
| 343 Handle<WasmMemoryObject> memory, | |
| 342 Handle<WasmInstanceObject> instance) { | 344 Handle<WasmInstanceObject> instance) { |
| 343 Handle<WasmInstanceWrapper> instance_wrapper = | 345 Handle<WeakFixedArray> old_instances = |
| 344 handle(instance->instance_wrapper()); | 346 memory->has_instances() |
| 345 if (has_instances_link()) { | 347 ? Handle<WeakFixedArray>(memory->instances(), isolate) |
| 346 Handle<WasmInstanceWrapper> current_wrapper(instances_link()); | 348 : Handle<WeakFixedArray>::null(); |
| 347 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*current_wrapper)); | 349 Handle<WeakFixedArray> new_instances = |
| 348 DCHECK(!current_wrapper->has_previous()); | 350 WeakFixedArray::Add(old_instances, instance); |
| 349 instance_wrapper->set_next_wrapper(*current_wrapper); | 351 memory->set_instances(*new_instances); |
| 350 current_wrapper->set_previous_wrapper(*instance_wrapper); | 352 } |
| 353 | |
| 354 void WasmMemoryObject::RemoveInstance(Isolate* isolate, | |
| 355 Handle<WasmMemoryObject> memory, | |
| 356 Handle<WasmInstanceObject> instance) { | |
| 357 if (memory->has_instances()) { | |
| 358 memory->instances()->Remove(instance); | |
|
Clemens Hammacher
2017/07/07 11:56:21
This is now linear in the number of instances, ins
titzer
2017/07/07 12:07:41
Add a comment to the declaration.
| |
| 351 } | 359 } |
| 352 set_instances_link(*instance_wrapper); | |
| 353 } | 360 } |
| 354 | 361 |
| 355 // static | 362 // static |
| 356 int32_t WasmMemoryObject::Grow(Isolate* isolate, | 363 int32_t WasmMemoryObject::Grow(Isolate* isolate, |
| 357 Handle<WasmMemoryObject> memory_object, | 364 Handle<WasmMemoryObject> memory_object, |
| 358 uint32_t pages) { | 365 uint32_t pages) { |
| 359 Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer()); | 366 Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer()); |
| 360 uint32_t old_size = 0; | 367 uint32_t old_size = 0; |
| 361 CHECK(old_buffer->byte_length()->ToUint32(&old_size)); | 368 CHECK(old_buffer->byte_length()->ToUint32(&old_size)); |
| 362 Handle<JSArrayBuffer> new_buffer; | 369 Handle<JSArrayBuffer> new_buffer; |
| 363 // Return current size if grow by 0. | 370 // Return current size if grow by 0. |
| 364 if (pages == 0) { | 371 if (pages == 0) { |
| 365 // Even for pages == 0, we need to attach a new JSArrayBuffer with the same | 372 // Even for pages == 0, we need to attach a new JSArrayBuffer with the same |
| 366 // backing store and neuter the old one to be spec compliant. | 373 // backing store and neuter the old one to be spec compliant. |
| 367 if (old_size != 0) { | 374 if (old_size != 0) { |
| 368 new_buffer = SetupArrayBuffer( | 375 new_buffer = SetupArrayBuffer( |
| 369 isolate, old_buffer->allocation_base(), | 376 isolate, old_buffer->allocation_base(), |
| 370 old_buffer->allocation_length(), old_buffer->backing_store(), | 377 old_buffer->allocation_length(), old_buffer->backing_store(), |
| 371 old_size, old_buffer->is_external(), old_buffer->has_guard_region()); | 378 old_size, old_buffer->is_external(), old_buffer->has_guard_region()); |
| 372 memory_object->set_array_buffer(*new_buffer); | 379 memory_object->set_array_buffer(*new_buffer); |
| 373 } | 380 } |
| 374 DCHECK_EQ(0, old_size % WasmModule::kPageSize); | 381 DCHECK_EQ(0, old_size % WasmModule::kPageSize); |
| 375 return old_size / WasmModule::kPageSize; | 382 return old_size / WasmModule::kPageSize; |
| 376 } | 383 } |
| 377 if (!memory_object->has_instances_link()) { | 384 |
| 378 // Memory object does not have an instance associated with it, just grow | 385 uint32_t max_pages; |
|
Clemens Hammacher
2017/07/07 11:56:21
This code is much clearer now 👍
Hard to see if it'
titzer
2017/07/07 12:07:41
Acknowledged.
| |
| 379 uint32_t max_pages; | 386 if (memory_object->has_maximum_pages()) { |
| 380 if (memory_object->has_maximum_pages()) { | 387 max_pages = static_cast<uint32_t>(memory_object->maximum_pages()); |
| 381 max_pages = static_cast<uint32_t>(memory_object->maximum_pages()); | 388 if (FLAG_wasm_max_mem_pages < max_pages) return -1; |
| 382 if (FLAG_wasm_max_mem_pages < max_pages) return -1; | |
| 383 } else { | |
| 384 max_pages = FLAG_wasm_max_mem_pages; | |
| 385 } | |
| 386 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); | |
| 387 if (new_buffer.is_null()) return -1; | |
| 388 } else { | 389 } else { |
| 389 Handle<WasmInstanceWrapper> instance_wrapper( | 390 max_pages = FLAG_wasm_max_mem_pages; |
| 390 memory_object->instances_link()); | 391 } |
| 391 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 392 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); |
| 392 DCHECK(instance_wrapper->has_instance()); | 393 if (new_buffer.is_null()) return -1; |
| 393 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); | |
| 394 DCHECK(instance->IsWasmInstanceObject()); | |
| 395 uint32_t max_pages = instance->GetMaxMemoryPages(); | |
| 396 | 394 |
| 397 // Grow memory object buffer and update instances associated with it. | 395 if (memory_object->has_instances()) { |
| 398 new_buffer = GrowMemoryBuffer(isolate, old_buffer, pages, max_pages); | |
| 399 if (new_buffer.is_null()) return -1; | |
| 400 DCHECK(!instance_wrapper->has_previous()); | |
| 401 SetInstanceMemory(isolate, instance, new_buffer); | |
| 402 Address old_mem_start = static_cast<Address>(old_buffer->backing_store()); | 396 Address old_mem_start = static_cast<Address>(old_buffer->backing_store()); |
| 403 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); | 397 Handle<WeakFixedArray> instances(memory_object->instances(), isolate); |
| 404 while (instance_wrapper->has_next()) { | 398 for (int i = 0; i < instances->Length(); i++) { |
| 405 instance_wrapper = instance_wrapper->next_wrapper(); | 399 Object* elem = instances->Get(i); |
| 406 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 400 if (!elem->IsWasmInstanceObject()) continue; |
| 407 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); | 401 Handle<WasmInstanceObject> instance(WasmInstanceObject::cast(elem), |
| 408 DCHECK(instance->IsWasmInstanceObject()); | 402 isolate); |
| 409 SetInstanceMemory(isolate, instance, new_buffer); | 403 SetInstanceMemory(isolate, instance, new_buffer); |
| 410 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); | 404 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); |
| 411 } | 405 } |
| 412 } | 406 } |
| 407 | |
| 413 memory_object->set_array_buffer(*new_buffer); | 408 memory_object->set_array_buffer(*new_buffer); |
| 414 DCHECK_EQ(0, old_size % WasmModule::kPageSize); | 409 DCHECK_EQ(0, old_size % WasmModule::kPageSize); |
| 415 return old_size / WasmModule::kPageSize; | 410 return old_size / WasmModule::kPageSize; |
| 416 } | 411 } |
| 417 | 412 |
| 418 WasmModuleObject* WasmInstanceObject::module_object() { | 413 WasmModuleObject* WasmInstanceObject::module_object() { |
| 419 return *compiled_module()->wasm_module(); | 414 return *compiled_module()->wasm_module(); |
| 420 } | 415 } |
| 421 | 416 |
| 422 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); } | 417 WasmModule* WasmInstanceObject::module() { return compiled_module()->module(); } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 436 Handle<JSObject> instance_object = | 431 Handle<JSObject> instance_object = |
| 437 isolate->factory()->NewJSObject(instance_cons, TENURED); | 432 isolate->factory()->NewJSObject(instance_cons, TENURED); |
| 438 | 433 |
| 439 Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym()); | 434 Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym()); |
| 440 Object::SetProperty(instance_object, instance_sym, instance_object, STRICT) | 435 Object::SetProperty(instance_object, instance_sym, instance_object, STRICT) |
| 441 .Check(); | 436 .Check(); |
| 442 Handle<WasmInstanceObject> instance( | 437 Handle<WasmInstanceObject> instance( |
| 443 reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate); | 438 reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate); |
| 444 | 439 |
| 445 instance->set_compiled_module(*compiled_module); | 440 instance->set_compiled_module(*compiled_module); |
| 446 Handle<WasmInstanceWrapper> instance_wrapper = | |
| 447 WasmInstanceWrapper::New(isolate, instance); | |
| 448 instance->set_instance_wrapper(*instance_wrapper); | |
| 449 return instance; | 441 return instance; |
| 450 } | 442 } |
| 451 | 443 |
| 452 int32_t WasmInstanceObject::GetMemorySize() { | 444 int32_t WasmInstanceObject::GetMemorySize() { |
| 453 if (!has_memory_buffer()) return 0; | 445 if (!has_memory_buffer()) return 0; |
| 454 uint32_t bytes = memory_buffer()->byte_length()->Number(); | 446 uint32_t bytes = memory_buffer()->byte_length()->Number(); |
| 455 DCHECK_EQ(0, bytes % WasmModule::kPageSize); | 447 DCHECK_EQ(0, bytes % WasmModule::kPageSize); |
| 456 return bytes / WasmModule::kPageSize; | 448 return bytes / WasmModule::kPageSize; |
| 457 } | 449 } |
| 458 | 450 |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1394 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, | 1386 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, |
| 1395 int offset, int func_index, bool patch_caller) { | 1387 int offset, int func_index, bool patch_caller) { |
| 1396 isolate->set_context(*instance->compiled_module()->native_context()); | 1388 isolate->set_context(*instance->compiled_module()->native_context()); |
| 1397 Object* orch_obj = | 1389 Object* orch_obj = |
| 1398 instance->compiled_module()->shared()->lazy_compilation_orchestrator(); | 1390 instance->compiled_module()->shared()->lazy_compilation_orchestrator(); |
| 1399 LazyCompilationOrchestrator* orch = | 1391 LazyCompilationOrchestrator* orch = |
| 1400 Managed<LazyCompilationOrchestrator>::cast(orch_obj)->get(); | 1392 Managed<LazyCompilationOrchestrator>::cast(orch_obj)->get(); |
| 1401 return orch->CompileLazy(isolate, instance, caller, offset, func_index, | 1393 return orch->CompileLazy(isolate, instance, caller, offset, func_index, |
| 1402 patch_caller); | 1394 patch_caller); |
| 1403 } | 1395 } |
| 1404 | |
| 1405 Handle<WasmInstanceWrapper> WasmInstanceWrapper::New( | |
| 1406 Isolate* isolate, Handle<WasmInstanceObject> instance) { | |
| 1407 Handle<FixedArray> array = | |
| 1408 isolate->factory()->NewFixedArray(kFieldCount, TENURED); | |
| 1409 Handle<WasmInstanceWrapper> instance_wrapper( | |
| 1410 reinterpret_cast<WasmInstanceWrapper*>(*array), isolate); | |
| 1411 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance); | |
| 1412 instance_wrapper->set(kWrapperInstanceObjectIndex, *cell); | |
| 1413 return instance_wrapper; | |
| 1414 } | |
| 1415 | |
| 1416 bool WasmInstanceWrapper::IsWasmInstanceWrapper(Object* obj) { | |
| 1417 if (!obj->IsFixedArray()) return false; | |
| 1418 Handle<FixedArray> array = handle(FixedArray::cast(obj)); | |
| 1419 if (array->length() != kFieldCount) return false; | |
| 1420 if (!array->get(kWrapperInstanceObjectIndex)->IsWeakCell()) return false; | |
| 1421 Isolate* isolate = array->GetIsolate(); | |
| 1422 if (!array->get(kNextInstanceWrapperIndex)->IsUndefined(isolate) && | |
| 1423 !array->get(kNextInstanceWrapperIndex)->IsFixedArray()) | |
| 1424 return false; | |
| 1425 if (!array->get(kPreviousInstanceWrapperIndex)->IsUndefined(isolate) && | |
| 1426 !array->get(kPreviousInstanceWrapperIndex)->IsFixedArray()) | |
| 1427 return false; | |
| 1428 return true; | |
| 1429 } | |
| OLD | NEW |