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 <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 | 9 |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| 11 #include "src/objects.h" | 11 #include "src/objects.h" |
| 12 #include "src/property-descriptor.h" | 12 #include "src/property-descriptor.h" |
| 13 #include "src/simulator.h" | 13 #include "src/simulator.h" |
| 14 #include "src/snapshot/snapshot.h" | 14 #include "src/snapshot/snapshot.h" |
| 15 #include "src/v8.h" | 15 #include "src/v8.h" |
| 16 | 16 |
| 17 #include "src/wasm/ast-decoder.h" | 17 #include "src/wasm/ast-decoder.h" |
| 18 #include "src/wasm/module-decoder.h" | 18 #include "src/wasm/module-decoder.h" |
| 19 #include "src/wasm/wasm-debug.h" | |
| 20 #include "src/wasm/wasm-js.h" | 19 #include "src/wasm/wasm-js.h" |
| 21 #include "src/wasm/wasm-module.h" | 20 #include "src/wasm/wasm-module.h" |
| 21 #include "src/wasm/wasm-objects.h" | |
| 22 #include "src/wasm/wasm-result.h" | 22 #include "src/wasm/wasm-result.h" |
| 23 | 23 |
| 24 #include "src/compiler/wasm-compiler.h" | 24 #include "src/compiler/wasm-compiler.h" |
| 25 | 25 |
| 26 using namespace v8::internal; | 26 using namespace v8::internal; |
| 27 using namespace v8::internal::wasm; | 27 using namespace v8::internal::wasm; |
| 28 namespace base = v8::base; | 28 namespace base = v8::base; |
| 29 | 29 |
| 30 #define TRACE(...) \ | 30 #define TRACE(...) \ |
| 31 do { \ | 31 do { \ |
| 32 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ | 32 if (FLAG_trace_wasm_instances) PrintF(__VA_ARGS__); \ |
| 33 } while (false) | 33 } while (false) |
| 34 | 34 |
| 35 #define TRACE_CHAIN(instance) \ | 35 #define TRACE_CHAIN(instance) \ |
| 36 do { \ | 36 do { \ |
| 37 instance->PrintInstancesChain(); \ | 37 instance->PrintInstancesChain(); \ |
| 38 } while (false) | 38 } while (false) |
| 39 | 39 |
| 40 static const int kInvalidSigIndex = -1; | |
| 41 | |
| 42 // Collects all the data values to which a given WASM code object may be | |
| 43 // specialized. | |
| 44 struct Specialization { | |
| 45 // The native context, which is used in JS->WASM and WASM->JS wrappers | |
| 46 // and calls to the runtime. | |
| 47 Handle<Context> context; | |
| 48 | |
| 49 // Specialization to the memory. | |
| 50 byte* memory_base; | |
| 51 uint32_t memory_size; | |
| 52 | |
| 53 // Specialization to the globals. | |
| 54 byte* globals_base; | |
| 55 | |
| 56 // Specialization to the function table. | |
| 57 uint32_t function_table_size; | |
| 58 Handle<FixedArray> function_table_sigs; | |
| 59 Handle<FixedArray> function_table_code; | |
| 60 | |
| 61 Specialization() | |
| 62 : memory_base(nullptr), | |
| 63 memory_size(0), | |
| 64 globals_base(nullptr), | |
| 65 function_table_size(0) {} | |
| 66 }; | |
| 67 | |
| 68 namespace { | 40 namespace { |
| 69 | 41 |
| 42 static const int kInvalidSigIndex = -1; | |
| 70 static const int kPlaceholderMarker = 1000000000; | 43 static const int kPlaceholderMarker = 1000000000; |
| 71 | 44 |
| 72 enum JSFunctionExportInternalField { | |
| 73 kInternalModuleInstance, | |
| 74 kInternalFunctionIndex | |
| 75 }; | |
| 76 | |
| 77 // Internal constants for the layout of the module object. | |
| 78 enum WasmInstanceObjectFields { | |
| 79 kWasmCompiledModule = 0, | |
| 80 kWasmMemObject, | |
| 81 kWasmMemArrayBuffer, | |
| 82 kWasmGlobalsArrayBuffer, | |
| 83 kWasmDebugInfo, | |
| 84 kWasmInstanceInternalFieldCount | |
| 85 }; | |
| 86 | |
| 87 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { | 45 byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { |
| 88 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; | 46 return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; |
| 89 } | 47 } |
| 90 | 48 |
| 91 uint32_t GetMinModuleMemSize(const WasmModule* module) { | |
| 92 return WasmModule::kPageSize * module->min_mem_pages; | |
| 93 } | |
| 94 | |
| 95 MaybeHandle<String> ExtractStringFromModuleBytes( | 49 MaybeHandle<String> ExtractStringFromModuleBytes( |
| 96 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, | 50 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, |
| 97 uint32_t offset, uint32_t size) { | 51 uint32_t offset, uint32_t size) { |
| 98 // TODO(wasm): cache strings from modules if it's a performance win. | 52 // TODO(wasm): cache strings from modules if it's a performance win. |
| 99 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes(); | 53 Handle<SeqOneByteString> module_bytes = compiled_module->module_bytes(); |
| 100 Address raw = module_bytes->GetCharsAddress() + offset; | 54 Address raw = module_bytes->GetCharsAddress() + offset; |
| 101 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) | 55 if (!unibrow::Utf8::Validate(reinterpret_cast<const byte*>(raw), size)) |
| 102 return {}; // UTF8 decoding error for name. | 56 return {}; // UTF8 decoding error for name. |
| 103 return isolate->factory()->NewStringFromUtf8SubString( | 57 return isolate->factory()->NewStringFromUtf8SubString( |
| 104 module_bytes, static_cast<int>(offset), static_cast<int>(size)); | 58 module_bytes, static_cast<int>(offset), static_cast<int>(size)); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 for (RelocIterator it(*code, mask); !it.done(); it.next()) { | 118 for (RelocIterator it(*code, mask); !it.done(); it.next()) { |
| 165 it.rinfo()->update_wasm_global_reference(old_start, globals_start); | 119 it.rinfo()->update_wasm_global_reference(old_start, globals_start); |
| 166 } | 120 } |
| 167 } | 121 } |
| 168 } | 122 } |
| 169 | 123 |
| 170 Handle<Code> CreatePlaceholder(Factory* factory, uint32_t index, | 124 Handle<Code> CreatePlaceholder(Factory* factory, uint32_t index, |
| 171 Code::Kind kind) { | 125 Code::Kind kind) { |
| 172 // Create a placeholder code object and encode the corresponding index in | 126 // Create a placeholder code object and encode the corresponding index in |
| 173 // the {constant_pool_offset} field of the code object. | 127 // the {constant_pool_offset} field of the code object. |
| 174 // TODO(titzer): placeholder code objects are somewhat dangerous. | 128 // TODO(titzer): instead of placeholders, use a reloc_info mode. |
| 175 static byte buffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; // fake instructions. | 129 static byte buffer[] = {0, 0, 0, 0}; // fake instructions. |
| 176 static CodeDesc desc = { | 130 static CodeDesc desc = { |
| 177 buffer, arraysize(buffer), arraysize(buffer), 0, 0, nullptr, 0, nullptr}; | 131 buffer, arraysize(buffer), arraysize(buffer), 0, 0, nullptr, 0, nullptr}; |
| 178 Handle<Code> code = factory->NewCode(desc, Code::KindField::encode(kind), | 132 Handle<Code> code = factory->NewCode(desc, Code::KindField::encode(kind), |
| 179 Handle<Object>::null()); | 133 Handle<Object>::null()); |
| 180 code->set_constant_pool_offset(static_cast<int>(index) + kPlaceholderMarker); | 134 code->set_constant_pool_offset(static_cast<int>(index) + kPlaceholderMarker); |
| 181 return code; | 135 return code; |
| 182 } | 136 } |
| 183 | 137 |
| 184 bool LinkFunction(Handle<Code> unlinked, | 138 bool LinkFunction(Handle<Code> unlinked, |
| 185 std::vector<Handle<Code>>& code_table) { | 139 std::vector<Handle<Code>>& code_table) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 } | 243 } |
| 290 | 244 |
| 291 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) { | 245 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) { |
| 292 DisallowHeapAllocation no_gc; | 246 DisallowHeapAllocation no_gc; |
| 293 for (int i = 0; i < functions->length(); ++i) { | 247 for (int i = 0; i < functions->length(); ++i) { |
| 294 RecordStats(isolate, Code::cast(functions->get(i))); | 248 RecordStats(isolate, Code::cast(functions->get(i))); |
| 295 } | 249 } |
| 296 } | 250 } |
| 297 | 251 |
| 298 Address GetGlobalStartAddressFromCodeTemplate(Object* undefined, | 252 Address GetGlobalStartAddressFromCodeTemplate(Object* undefined, |
| 299 JSObject* owner) { | 253 JSObject* object) { |
| 254 auto instance = WasmInstanceObject::cast(object); | |
| 300 Address old_address = nullptr; | 255 Address old_address = nullptr; |
| 301 Object* stored_value = owner->GetInternalField(kWasmGlobalsArrayBuffer); | 256 if (instance->has_globals_buffer()) { |
| 302 if (stored_value != undefined) { | 257 old_address = |
| 303 old_address = static_cast<Address>( | 258 static_cast<Address>(instance->get_globals_buffer()->backing_store()); |
| 304 JSArrayBuffer::cast(stored_value)->backing_store()); | |
| 305 } | 259 } |
| 306 return old_address; | 260 return old_address; |
| 307 } | 261 } |
| 308 | 262 |
| 309 void InitializeParallelCompilation( | 263 void InitializeParallelCompilation( |
| 310 Isolate* isolate, const std::vector<WasmFunction>& functions, | 264 Isolate* isolate, const std::vector<WasmFunction>& functions, |
| 311 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 265 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
| 312 ModuleEnv& module_env, ErrorThrower* thrower) { | 266 ModuleEnv& module_env, ErrorThrower* thrower) { |
| 313 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { | 267 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { |
| 314 const WasmFunction* func = &functions[i]; | 268 const WasmFunction* func = &functions[i]; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 if (new_code != old_code) { | 441 if (new_code != old_code) { |
| 488 it.rinfo()->set_target_address(new_code->instruction_start(), | 442 it.rinfo()->set_target_address(new_code->instruction_start(), |
| 489 UPDATE_WRITE_BARRIER, | 443 UPDATE_WRITE_BARRIER, |
| 490 SKIP_ICACHE_FLUSH); | 444 SKIP_ICACHE_FLUSH); |
| 491 } | 445 } |
| 492 } | 446 } |
| 493 } | 447 } |
| 494 } | 448 } |
| 495 } | 449 } |
| 496 | 450 |
| 497 static void ResetCompiledModule(Isolate* isolate, JSObject* owner, | 451 static void ResetCompiledModule(Isolate* isolate, WasmInstanceObject* owner, |
| 498 WasmCompiledModule* compiled_module) { | 452 WasmCompiledModule* compiled_module) { |
| 499 TRACE("Resetting %d\n", compiled_module->instance_id()); | 453 TRACE("Resetting %d\n", compiled_module->instance_id()); |
| 500 Object* undefined = *isolate->factory()->undefined_value(); | 454 Object* undefined = *isolate->factory()->undefined_value(); |
| 501 uint32_t old_mem_size = compiled_module->mem_size(); | 455 uint32_t old_mem_size = compiled_module->mem_size(); |
| 502 uint32_t default_mem_size = compiled_module->default_mem_size(); | 456 uint32_t default_mem_size = compiled_module->default_mem_size(); |
| 503 Object* mem_start = compiled_module->ptr_to_memory(); | 457 Object* mem_start = compiled_module->ptr_to_memory(); |
| 504 Address old_mem_address = nullptr; | 458 Address old_mem_address = nullptr; |
| 505 Address globals_start = | 459 Address globals_start = |
| 506 GetGlobalStartAddressFromCodeTemplate(undefined, owner); | 460 GetGlobalStartAddressFromCodeTemplate(undefined, owner); |
| 507 | 461 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 Assembler::FlushICache(isolate, code->instruction_start(), | 511 Assembler::FlushICache(isolate, code->instruction_start(), |
| 558 code->instruction_size()); | 512 code->instruction_size()); |
| 559 } | 513 } |
| 560 } | 514 } |
| 561 } | 515 } |
| 562 compiled_module->reset_memory(); | 516 compiled_module->reset_memory(); |
| 563 } | 517 } |
| 564 | 518 |
| 565 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { | 519 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { |
| 566 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); | 520 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); |
| 567 JSObject* owner = *p; | 521 WasmInstanceObject* owner = reinterpret_cast<WasmInstanceObject*>(*p); |
| 568 WasmCompiledModule* compiled_module = GetCompiledModule(owner); | 522 WasmCompiledModule* compiled_module = owner->get_compiled_module(); |
| 569 TRACE("Finalizing %d {\n", compiled_module->instance_id()); | 523 TRACE("Finalizing %d {\n", compiled_module->instance_id()); |
| 570 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); | 524 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); |
| 571 DCHECK(compiled_module->has_weak_wasm_module()); | 525 DCHECK(compiled_module->has_weak_wasm_module()); |
| 572 WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module(); | 526 WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module(); |
| 573 | 527 |
| 574 // weak_wasm_module may have been cleared, meaning the module object | 528 // weak_wasm_module may have been cleared, meaning the module object |
| 575 // was GC-ed. In that case, there won't be any new instances created, | 529 // was GC-ed. In that case, there won't be any new instances created, |
| 576 // and we don't need to maintain the links between instances. | 530 // and we don't need to maintain the links between instances. |
| 577 if (!weak_wasm_module->cleared()) { | 531 if (!weak_wasm_module->cleared()) { |
| 578 JSObject* wasm_module = JSObject::cast(weak_wasm_module->value()); | 532 JSObject* wasm_module = JSObject::cast(weak_wasm_module->value()); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 os.write(name.start(), name.length()); | 645 os.write(name.start(), name.length()); |
| 692 } else { | 646 } else { |
| 693 os << "+" << pair.function_->func_index; | 647 os << "+" << pair.function_->func_index; |
| 694 } | 648 } |
| 695 } else { | 649 } else { |
| 696 os << "?"; | 650 os << "?"; |
| 697 } | 651 } |
| 698 return os; | 652 return os; |
| 699 } | 653 } |
| 700 | 654 |
| 701 Handle<JSFunction> wasm::WrapExportCodeAsJSFunction( | |
| 702 Isolate* isolate, Handle<Code> export_code, Handle<String> name, | |
| 703 FunctionSig* sig, int func_index, Handle<JSObject> instance) { | |
| 704 Handle<SharedFunctionInfo> shared = | |
| 705 isolate->factory()->NewSharedFunctionInfo(name, export_code, false); | |
| 706 int arity = static_cast<int>(sig->parameter_count()); | |
| 707 shared->set_length(arity); | |
| 708 shared->set_internal_formal_parameter_count(arity); | |
| 709 Handle<JSFunction> function = isolate->factory()->NewFunction( | |
| 710 isolate->wasm_function_map(), name, export_code); | |
| 711 function->set_shared(*shared); | |
| 712 | |
| 713 function->SetInternalField(kInternalModuleInstance, *instance); | |
| 714 function->SetInternalField(kInternalFunctionIndex, Smi::FromInt(func_index)); | |
| 715 return function; | |
| 716 } | |
| 717 | |
| 718 Object* wasm::GetOwningWasmInstance(Code* code) { | 655 Object* wasm::GetOwningWasmInstance(Code* code) { |
| 719 DCHECK(code->kind() == Code::WASM_FUNCTION); | 656 DCHECK(code->kind() == Code::WASM_FUNCTION); |
| 720 DisallowHeapAllocation no_gc; | 657 DisallowHeapAllocation no_gc; |
| 721 FixedArray* deopt_data = code->deoptimization_data(); | 658 FixedArray* deopt_data = code->deoptimization_data(); |
| 722 DCHECK_NOT_NULL(deopt_data); | 659 DCHECK_NOT_NULL(deopt_data); |
| 723 DCHECK(deopt_data->length() == 2); | 660 DCHECK(deopt_data->length() == 2); |
| 724 Object* weak_link = deopt_data->get(0); | 661 Object* weak_link = deopt_data->get(0); |
| 725 if (!weak_link->IsWeakCell()) return nullptr; | 662 if (!weak_link->IsWeakCell()) return nullptr; |
| 726 WeakCell* cell = WeakCell::cast(weak_link); | 663 WeakCell* cell = WeakCell::cast(weak_link); |
| 727 return cell->value(); | 664 return cell->value(); |
| 728 } | 665 } |
| 729 | 666 |
| 730 WasmModule* GetCppModule(Handle<JSObject> instance) { | 667 int wasm::GetNumImportedFunctions(Handle<JSObject> object) { |
| 731 DCHECK(IsWasmInstance(*instance)); | 668 return static_cast<int>(Handle<WasmInstanceObject>::cast(object) |
| 732 return reinterpret_cast<WasmModuleWrapper*>( | 669 ->module() |
| 733 *GetCompiledModule(*instance)->module_wrapper()) | 670 ->num_imported_functions); |
| 734 ->get(); | |
| 735 } | |
| 736 | |
| 737 int wasm::GetNumImportedFunctions(Handle<JSObject> instance) { | |
| 738 return static_cast<int>(GetCppModule(instance)->num_imported_functions); | |
| 739 } | 671 } |
| 740 | 672 |
| 741 WasmModule::WasmModule(Zone* owned, const byte* module_start) | 673 WasmModule::WasmModule(Zone* owned, const byte* module_start) |
| 742 : owned_zone(owned), | 674 : owned_zone(owned), |
| 743 module_start(module_start), | 675 module_start(module_start), |
| 744 pending_tasks(new base::Semaphore(0)) {} | 676 pending_tasks(new base::Semaphore(0)) {} |
| 745 | 677 |
| 746 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( | 678 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( |
| 747 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, | 679 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, |
| 748 ErrorThrower* thrower) const { | 680 ErrorThrower* thrower) const { |
| 749 Factory* factory = isolate->factory(); | 681 Factory* factory = isolate->factory(); |
| 750 | 682 |
| 751 MaybeHandle<WasmCompiledModule> nothing; | 683 MaybeHandle<WasmCompiledModule> nothing; |
| 752 | 684 |
| 753 WasmInstance temp_instance(this); | 685 WasmInstance temp_instance(this); |
| 754 temp_instance.context = isolate->native_context(); | 686 temp_instance.context = isolate->native_context(); |
| 755 temp_instance.mem_size = GetMinModuleMemSize(this); | 687 temp_instance.mem_size = WasmModule::kPageSize * this->min_mem_pages; |
| 756 temp_instance.mem_start = nullptr; | 688 temp_instance.mem_start = nullptr; |
| 757 temp_instance.globals_start = nullptr; | 689 temp_instance.globals_start = nullptr; |
| 758 | 690 |
| 759 // Initialize the indirect tables with placeholders. | 691 // Initialize the indirect tables with placeholders. |
| 760 int function_table_count = static_cast<int>(this->function_tables.size()); | 692 int function_table_count = static_cast<int>(this->function_tables.size()); |
| 761 Handle<FixedArray> function_tables = | 693 Handle<FixedArray> function_tables = |
| 762 factory->NewFixedArray(function_table_count); | 694 factory->NewFixedArray(function_table_count); |
| 763 for (int i = 0; i < function_table_count; ++i) { | 695 for (int i = 0; i < function_table_count; ++i) { |
| 764 temp_instance.function_tables[i] = factory->NewFixedArray(0); | 696 temp_instance.function_tables[i] = factory->NewFixedArray(0); |
| 765 function_tables->set(i, *temp_instance.function_tables[i]); | 697 function_tables->set(i, *temp_instance.function_tables[i]); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 869 ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string)); | 801 ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string)); |
| 870 } | 802 } |
| 871 | 803 |
| 872 return ret; | 804 return ret; |
| 873 } | 805 } |
| 874 | 806 |
| 875 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, | 807 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, |
| 876 Handle<Object> target) { | 808 Handle<Object> target) { |
| 877 if (target->IsJSFunction()) { | 809 if (target->IsJSFunction()) { |
| 878 Handle<JSFunction> func = Handle<JSFunction>::cast(target); | 810 Handle<JSFunction> func = Handle<JSFunction>::cast(target); |
| 879 Handle<Code> export_wrapper_code = handle(func->code()); | 811 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) { |
| 880 if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) { | 812 auto exported = Handle<WasmExportedFunction>::cast(func); |
| 881 Handle<JSObject> other_instance( | 813 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate); |
| 882 JSObject::cast(func->GetInternalField(kInternalModuleInstance)), | 814 int func_index = exported->function_index(); |
| 883 isolate); | 815 return &other_instance->module()->functions[func_index]; |
| 884 int func_index = | |
| 885 Smi::cast(func->GetInternalField(kInternalFunctionIndex))->value(); | |
| 886 return &GetCppModule(other_instance)->functions[func_index]; | |
| 887 } | 816 } |
| 888 } | 817 } |
| 889 return nullptr; | 818 return nullptr; |
| 890 } | 819 } |
| 891 | 820 |
| 892 static Handle<Code> UnwrapImportWrapper(Handle<Object> target) { | 821 static Handle<Code> UnwrapImportWrapper(Handle<Object> target) { |
| 893 Handle<JSFunction> func = Handle<JSFunction>::cast(target); | 822 Handle<JSFunction> func = Handle<JSFunction>::cast(target); |
| 894 Handle<Code> export_wrapper_code = handle(func->code()); | 823 Handle<Code> export_wrapper_code = handle(func->code()); |
| 895 int found = 0; | 824 int found = 0; |
| 896 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 825 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 926 module_name, import_name); | 855 module_name, import_name); |
| 927 } | 856 } |
| 928 } | 857 } |
| 929 | 858 |
| 930 static void UpdateDispatchTablesInternal(Isolate* isolate, | 859 static void UpdateDispatchTablesInternal(Isolate* isolate, |
| 931 Handle<FixedArray> dispatch_tables, | 860 Handle<FixedArray> dispatch_tables, |
| 932 int index, WasmFunction* function, | 861 int index, WasmFunction* function, |
| 933 Handle<Code> code) { | 862 Handle<Code> code) { |
| 934 DCHECK_EQ(0, dispatch_tables->length() % 3); | 863 DCHECK_EQ(0, dispatch_tables->length() % 3); |
| 935 for (int i = 0; i < dispatch_tables->length(); i += 3) { | 864 for (int i = 0; i < dispatch_tables->length(); i += 3) { |
| 936 Handle<Object> instance(dispatch_tables->get(i), isolate); | |
| 937 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); | |
| 938 int table_index = Smi::cast(dispatch_tables->get(i + 1))->value(); | 865 int table_index = Smi::cast(dispatch_tables->get(i + 1))->value(); |
| 939 Handle<FixedArray> dispatch_table( | 866 Handle<FixedArray> dispatch_table( |
| 940 FixedArray::cast(dispatch_tables->get(i + 2)), isolate); | 867 FixedArray::cast(dispatch_tables->get(i + 2)), isolate); |
| 941 if (function) { | 868 if (function) { |
| 942 // TODO(titzer): the signature might need to be copied to avoid | 869 // TODO(titzer): the signature might need to be copied to avoid |
| 943 // a dangling pointer in the signature map. | 870 // a dangling pointer in the signature map. |
| 871 Handle<WasmInstanceObject> instance( | |
| 872 WasmInstanceObject::cast(dispatch_tables->get(i)), isolate); | |
| 944 int sig_index = static_cast<int>( | 873 int sig_index = static_cast<int>( |
| 945 module->function_tables[table_index].map.FindOrInsert(function->sig)); | 874 instance->module()->function_tables[table_index].map.FindOrInsert( |
| 875 function->sig)); | |
| 946 dispatch_table->set(index, Smi::FromInt(sig_index)); | 876 dispatch_table->set(index, Smi::FromInt(sig_index)); |
| 947 dispatch_table->set(index + (dispatch_table->length() / 2), *code); | 877 dispatch_table->set(index + (dispatch_table->length() / 2), *code); |
| 948 } else { | 878 } else { |
| 949 Code* code = nullptr; | 879 Code* code = nullptr; |
| 950 dispatch_table->set(index, Smi::FromInt(-1)); | 880 dispatch_table->set(index, Smi::FromInt(-1)); |
| 951 dispatch_table->set(index + (dispatch_table->length() / 2), code); | 881 dispatch_table->set(index + (dispatch_table->length() / 2), code); |
| 952 } | 882 } |
| 953 } | 883 } |
| 954 } | 884 } |
| 955 | 885 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 986 MaybeHandle<JSObject> nothing; | 916 MaybeHandle<JSObject> nothing; |
| 987 HistogramTimerScope wasm_instantiate_module_time_scope( | 917 HistogramTimerScope wasm_instantiate_module_time_scope( |
| 988 isolate_->counters()->wasm_instantiate_module_time()); | 918 isolate_->counters()->wasm_instantiate_module_time()); |
| 989 Factory* factory = isolate_->factory(); | 919 Factory* factory = isolate_->factory(); |
| 990 | 920 |
| 991 //-------------------------------------------------------------------------- | 921 //-------------------------------------------------------------------------- |
| 992 // Reuse the compiled module (if no owner), otherwise clone. | 922 // Reuse the compiled module (if no owner), otherwise clone. |
| 993 //-------------------------------------------------------------------------- | 923 //-------------------------------------------------------------------------- |
| 994 Handle<FixedArray> code_table; | 924 Handle<FixedArray> code_table; |
| 995 Handle<FixedArray> old_code_table; | 925 Handle<FixedArray> old_code_table; |
| 996 MaybeHandle<JSObject> owner; | 926 MaybeHandle<WasmInstanceObject> owner; |
| 997 | 927 |
| 998 TRACE("Starting new module instantiation\n"); | 928 TRACE("Starting new module instantiation\n"); |
| 999 { | 929 { |
| 1000 // Root the owner, if any, before doing any allocations, which | 930 // Root the owner, if any, before doing any allocations, which |
| 1001 // may trigger GC. | 931 // may trigger GC. |
| 1002 // Both owner and original template need to be in sync. Even | 932 // Both owner and original template need to be in sync. Even |
| 1003 // after we lose the original template handle, the code | 933 // after we lose the original template handle, the code |
| 1004 // objects we copied from it have data relative to the | 934 // objects we copied from it have data relative to the |
| 1005 // instance - such as globals addresses. | 935 // instance - such as globals addresses. |
| 1006 Handle<WasmCompiledModule> original; | 936 Handle<WasmCompiledModule> original; |
| 1007 { | 937 { |
| 1008 DisallowHeapAllocation no_gc; | 938 DisallowHeapAllocation no_gc; |
| 1009 original = handle( | 939 original = handle( |
| 1010 WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 940 WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
| 1011 if (original->has_weak_owning_instance()) { | 941 if (original->has_weak_owning_instance()) { |
| 1012 owner = | 942 owner = handle(WasmInstanceObject::cast( |
| 1013 handle(JSObject::cast(original->weak_owning_instance()->value())); | 943 original->weak_owning_instance()->value())); |
| 1014 } | 944 } |
| 1015 } | 945 } |
| 1016 DCHECK(!original.is_null()); | 946 DCHECK(!original.is_null()); |
| 1017 // Always make a new copy of the code_table, since the old_code_table | 947 // Always make a new copy of the code_table, since the old_code_table |
| 1018 // may still have placeholders for imports. | 948 // may still have placeholders for imports. |
| 1019 old_code_table = original->code_table(); | 949 old_code_table = original->code_table(); |
| 1020 code_table = factory->CopyFixedArray(old_code_table); | 950 code_table = factory->CopyFixedArray(old_code_table); |
| 1021 | 951 |
| 1022 if (original->has_weak_owning_instance()) { | 952 if (original->has_weak_owning_instance()) { |
| 1023 // Clone, but don't insert yet the clone in the instances chain. | 953 // Clone, but don't insert yet the clone in the instances chain. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1057 } | 987 } |
| 1058 compiled_module_->set_code_table(code_table); | 988 compiled_module_->set_code_table(code_table); |
| 1059 } | 989 } |
| 1060 module_ = reinterpret_cast<WasmModuleWrapper*>( | 990 module_ = reinterpret_cast<WasmModuleWrapper*>( |
| 1061 *compiled_module_->module_wrapper()) | 991 *compiled_module_->module_wrapper()) |
| 1062 ->get(); | 992 ->get(); |
| 1063 | 993 |
| 1064 //-------------------------------------------------------------------------- | 994 //-------------------------------------------------------------------------- |
| 1065 // Allocate the instance object. | 995 // Allocate the instance object. |
| 1066 //-------------------------------------------------------------------------- | 996 //-------------------------------------------------------------------------- |
| 1067 Handle<Map> map = factory->NewMap( | 997 Handle<WasmInstanceObject> instance = |
| 1068 JS_OBJECT_TYPE, | 998 WasmInstanceObject::New(isolate_, compiled_module_); |
| 1069 JSObject::kHeaderSize + kWasmInstanceInternalFieldCount * kPointerSize); | |
| 1070 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED); | |
| 1071 instance->SetInternalField(kWasmMemObject, | |
| 1072 isolate_->heap()->undefined_value()); | |
| 1073 | 999 |
| 1074 //-------------------------------------------------------------------------- | 1000 //-------------------------------------------------------------------------- |
| 1075 // Set up the globals for the new instance. | 1001 // Set up the globals for the new instance. |
| 1076 //-------------------------------------------------------------------------- | 1002 //-------------------------------------------------------------------------- |
| 1077 MaybeHandle<JSArrayBuffer> old_globals; | 1003 MaybeHandle<JSArrayBuffer> old_globals; |
| 1078 uint32_t globals_size = module_->globals_size; | 1004 uint32_t globals_size = module_->globals_size; |
| 1079 if (globals_size > 0) { | 1005 if (globals_size > 0) { |
| 1080 Handle<JSArrayBuffer> global_buffer = | 1006 Handle<JSArrayBuffer> global_buffer = |
| 1081 NewArrayBuffer(isolate_, globals_size); | 1007 NewArrayBuffer(isolate_, globals_size); |
| 1082 globals_ = global_buffer; | 1008 globals_ = global_buffer; |
| 1083 if (globals_.is_null()) { | 1009 if (globals_.is_null()) { |
| 1084 thrower_->RangeError("Out of memory: wasm globals"); | 1010 thrower_->RangeError("Out of memory: wasm globals"); |
| 1085 return nothing; | 1011 return nothing; |
| 1086 } | 1012 } |
| 1087 Address old_address = owner.is_null() | 1013 Address old_address = |
| 1088 ? nullptr | 1014 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate( |
| 1089 : GetGlobalStartAddressFromCodeTemplate( | 1015 isolate_->heap()->undefined_value(), |
| 1090 isolate_->heap()->undefined_value(), | 1016 *owner.ToHandleChecked()); |
| 1091 JSObject::cast(*owner.ToHandleChecked())); | |
| 1092 RelocateGlobals(code_table, old_address, | 1017 RelocateGlobals(code_table, old_address, |
| 1093 static_cast<Address>(global_buffer->backing_store())); | 1018 static_cast<Address>(global_buffer->backing_store())); |
| 1094 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); | 1019 instance->set_globals_buffer(*global_buffer); |
| 1095 } | 1020 } |
| 1096 | 1021 |
| 1097 //-------------------------------------------------------------------------- | 1022 //-------------------------------------------------------------------------- |
| 1098 // Prepare for initialization of function tables. | 1023 // Prepare for initialization of function tables. |
| 1099 //-------------------------------------------------------------------------- | 1024 //-------------------------------------------------------------------------- |
| 1100 int function_table_count = | 1025 int function_table_count = |
| 1101 static_cast<int>(module_->function_tables.size()); | 1026 static_cast<int>(module_->function_tables.size()); |
| 1102 table_instances_.reserve(module_->function_tables.size()); | 1027 table_instances_.reserve(module_->function_tables.size()); |
| 1103 for (int index = 0; index < function_table_count; ++index) { | 1028 for (int index = 0; index < function_table_count; ++index) { |
| 1104 table_instances_.push_back({Handle<JSObject>::null(), | 1029 table_instances_.push_back({Handle<WasmTableObject>::null(), |
| 1105 Handle<FixedArray>::null(), | 1030 Handle<FixedArray>::null(), |
| 1106 Handle<FixedArray>::null()}); | 1031 Handle<FixedArray>::null()}); |
| 1107 } | 1032 } |
| 1108 | 1033 |
| 1109 //-------------------------------------------------------------------------- | 1034 //-------------------------------------------------------------------------- |
| 1110 // Process the imports for the module. | 1035 // Process the imports for the module. |
| 1111 //-------------------------------------------------------------------------- | 1036 //-------------------------------------------------------------------------- |
| 1112 int num_imported_functions = ProcessImports(code_table, instance); | 1037 int num_imported_functions = ProcessImports(code_table, instance); |
| 1113 if (num_imported_functions < 0) return nothing; | 1038 if (num_imported_functions < 0) return nothing; |
| 1114 | 1039 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1127 | 1052 |
| 1128 if (!memory_.is_null()) { | 1053 if (!memory_.is_null()) { |
| 1129 // Set externally passed ArrayBuffer non neuterable. | 1054 // Set externally passed ArrayBuffer non neuterable. |
| 1130 memory_->set_is_neuterable(false); | 1055 memory_->set_is_neuterable(false); |
| 1131 } else if (min_mem_pages > 0) { | 1056 } else if (min_mem_pages > 0) { |
| 1132 memory_ = AllocateMemory(min_mem_pages); | 1057 memory_ = AllocateMemory(min_mem_pages); |
| 1133 if (memory_.is_null()) return nothing; // failed to allocate memory | 1058 if (memory_.is_null()) return nothing; // failed to allocate memory |
| 1134 } | 1059 } |
| 1135 | 1060 |
| 1136 if (!memory_.is_null()) { | 1061 if (!memory_.is_null()) { |
| 1137 instance->SetInternalField(kWasmMemArrayBuffer, *memory_); | 1062 instance->set_memory_buffer(*memory_); |
| 1138 Address mem_start = static_cast<Address>(memory_->backing_store()); | 1063 Address mem_start = static_cast<Address>(memory_->backing_store()); |
| 1139 uint32_t mem_size = | 1064 uint32_t mem_size = |
| 1140 static_cast<uint32_t>(memory_->byte_length()->Number()); | 1065 static_cast<uint32_t>(memory_->byte_length()->Number()); |
| 1141 LoadDataSegments(mem_start, mem_size); | 1066 LoadDataSegments(mem_start, mem_size); |
| 1142 | 1067 |
| 1143 uint32_t old_mem_size = compiled_module_->mem_size(); | 1068 uint32_t old_mem_size = compiled_module_->mem_size(); |
| 1144 Address old_mem_start = | 1069 Address old_mem_start = |
| 1145 compiled_module_->has_memory() | 1070 compiled_module_->has_memory() |
| 1146 ? static_cast<Address>( | 1071 ? static_cast<Address>( |
| 1147 compiled_module_->memory()->backing_store()) | 1072 compiled_module_->memory()->backing_store()) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1194 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_); | 1119 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_); |
| 1195 Handle<WeakCell> link_to_owning_instance = factory->NewWeakCell(instance); | 1120 Handle<WeakCell> link_to_owning_instance = factory->NewWeakCell(instance); |
| 1196 MaybeHandle<WeakCell> link_to_original; | 1121 MaybeHandle<WeakCell> link_to_original; |
| 1197 MaybeHandle<WasmCompiledModule> original; | 1122 MaybeHandle<WasmCompiledModule> original; |
| 1198 if (!owner.is_null()) { | 1123 if (!owner.is_null()) { |
| 1199 // prepare the data needed for publishing in a chain, but don't link | 1124 // prepare the data needed for publishing in a chain, but don't link |
| 1200 // just yet, because | 1125 // just yet, because |
| 1201 // we want all the publishing to happen free from GC interruptions, and | 1126 // we want all the publishing to happen free from GC interruptions, and |
| 1202 // so we do it in | 1127 // so we do it in |
| 1203 // one GC-free scope afterwards. | 1128 // one GC-free scope afterwards. |
| 1204 original = handle(GetCompiledModule(*owner.ToHandleChecked())); | 1129 original = handle(owner.ToHandleChecked()->get_compiled_module()); |
| 1205 link_to_original = factory->NewWeakCell(original.ToHandleChecked()); | 1130 link_to_original = factory->NewWeakCell(original.ToHandleChecked()); |
| 1206 } | 1131 } |
| 1207 // Publish the new instance to the instances chain. | 1132 // Publish the new instance to the instances chain. |
| 1208 { | 1133 { |
| 1209 DisallowHeapAllocation no_gc; | 1134 DisallowHeapAllocation no_gc; |
| 1210 if (!link_to_original.is_null()) { | 1135 if (!link_to_original.is_null()) { |
| 1211 compiled_module_->set_weak_next_instance( | 1136 compiled_module_->set_weak_next_instance( |
| 1212 link_to_original.ToHandleChecked()); | 1137 link_to_original.ToHandleChecked()); |
| 1213 original.ToHandleChecked()->set_weak_prev_instance(link_to_clone); | 1138 original.ToHandleChecked()->set_weak_prev_instance(link_to_clone); |
| 1214 compiled_module_->set_weak_wasm_module( | 1139 compiled_module_->set_weak_wasm_module( |
| 1215 original.ToHandleChecked()->weak_wasm_module()); | 1140 original.ToHandleChecked()->weak_wasm_module()); |
| 1216 } | 1141 } |
| 1217 module_object_->SetInternalField(0, *compiled_module_); | 1142 module_object_->SetInternalField(0, *compiled_module_); |
| 1218 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); | |
| 1219 compiled_module_->set_weak_owning_instance(link_to_owning_instance); | 1143 compiled_module_->set_weak_owning_instance(link_to_owning_instance); |
| 1220 GlobalHandles::MakeWeak(global_handle.location(), | 1144 GlobalHandles::MakeWeak(global_handle.location(), |
| 1221 global_handle.location(), &InstanceFinalizer, | 1145 global_handle.location(), &InstanceFinalizer, |
| 1222 v8::WeakCallbackType::kFinalizer); | 1146 v8::WeakCallbackType::kFinalizer); |
| 1223 } | 1147 } |
| 1224 } | 1148 } |
| 1225 | 1149 |
| 1226 DCHECK(wasm::IsWasmInstance(*instance)); | 1150 DCHECK(wasm::IsWasmInstance(*instance)); |
| 1227 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | 1151 if (instance->has_memory_object()) { |
| 1228 isolate_); | 1152 instance->get_memory_object()->AddInstance(*instance); |
| 1229 WasmJs::SetWasmMemoryInstance(isolate_, memory_object, instance); | 1153 } |
| 1230 | 1154 |
| 1231 //-------------------------------------------------------------------------- | 1155 //-------------------------------------------------------------------------- |
| 1232 // Run the start function if one was specified. | 1156 // Run the start function if one was specified. |
| 1233 //-------------------------------------------------------------------------- | 1157 //-------------------------------------------------------------------------- |
| 1234 if (module_->start_function_index >= 0) { | 1158 if (module_->start_function_index >= 0) { |
| 1235 HandleScope scope(isolate_); | 1159 HandleScope scope(isolate_); |
| 1236 ModuleEnv module_env; | 1160 ModuleEnv module_env; |
| 1237 module_env.module = module_; | 1161 module_env.module = module_; |
| 1238 module_env.instance = nullptr; | 1162 module_env.instance = nullptr; |
| 1239 module_env.origin = module_->origin; | 1163 module_env.origin = module_->origin; |
| 1240 int start_index = module_->start_function_index; | 1164 int start_index = module_->start_function_index; |
| 1241 Handle<Code> startup_code = | 1165 Handle<Code> startup_code = |
| 1242 code_table->GetValueChecked<Code>(isolate_, start_index); | 1166 code_table->GetValueChecked<Code>(isolate_, start_index); |
| 1243 FunctionSig* sig = module_->functions[start_index].sig; | 1167 FunctionSig* sig = module_->functions[start_index].sig; |
| 1244 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( | 1168 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( |
| 1245 isolate_, &module_env, startup_code, start_index); | 1169 isolate_, &module_env, startup_code, start_index); |
| 1246 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( | 1170 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( |
| 1247 isolate_, wrapper_code, factory->InternalizeUtf8String("start"), sig, | 1171 isolate_, instance, factory->InternalizeUtf8String("start"), |
| 1248 start_index, instance); | 1172 wrapper_code, static_cast<int>(sig->parameter_count()), start_index); |
| 1249 RecordStats(isolate_, *startup_code); | 1173 RecordStats(isolate_, *startup_code); |
| 1250 // Call the JS function. | 1174 // Call the JS function. |
| 1251 Handle<Object> undefined = factory->undefined_value(); | 1175 Handle<Object> undefined = factory->undefined_value(); |
| 1252 MaybeHandle<Object> retval = | 1176 MaybeHandle<Object> retval = |
| 1253 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1177 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
| 1254 | 1178 |
| 1255 if (retval.is_null()) { | 1179 if (retval.is_null()) { |
| 1256 DCHECK(isolate_->has_pending_exception()); | 1180 DCHECK(isolate_->has_pending_exception()); |
| 1257 isolate_->OptionalRescheduleException(false); | 1181 isolate_->OptionalRescheduleException(false); |
| 1258 // It's unfortunate that the new instance is already linked in the | 1182 // It's unfortunate that the new instance is already linked in the |
| 1259 // chain. However, we need to set up everything before executing the | 1183 // chain. However, we need to set up everything before executing the |
| 1260 // start function, such that stack trace information can be generated | 1184 // start function, such that stack trace information can be generated |
| 1261 // correctly already in the start function. | 1185 // correctly already in the start function. |
| 1262 return nothing; | 1186 return nothing; |
| 1263 } | 1187 } |
| 1264 } | 1188 } |
| 1265 | 1189 |
| 1266 DCHECK(!isolate_->has_pending_exception()); | 1190 DCHECK(!isolate_->has_pending_exception()); |
| 1267 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1191 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
| 1268 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1192 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
| 1269 return instance; | 1193 return instance; |
| 1270 } | 1194 } |
| 1271 | 1195 |
| 1272 private: | 1196 private: |
| 1273 // Represents the initialized state of a table. | 1197 // Represents the initialized state of a table. |
| 1274 struct TableInstance { | 1198 struct TableInstance { |
| 1275 Handle<JSObject> table_object; // WebAssembly.Table instance | 1199 Handle<WasmTableObject> table_object; // WebAssembly.Table instance |
| 1276 Handle<FixedArray> js_wrappers; // JSFunctions exported | 1200 Handle<FixedArray> js_wrappers; // JSFunctions exported |
| 1277 Handle<FixedArray> dispatch_table; // internal (code, sig) pairs | 1201 Handle<FixedArray> dispatch_table; // internal (code, sig) pairs |
| 1278 }; | 1202 }; |
| 1279 | 1203 |
| 1280 Isolate* isolate_; | 1204 Isolate* isolate_; |
| 1281 WasmModule* module_; | 1205 WasmModule* module_; |
| 1282 ErrorThrower* thrower_; | 1206 ErrorThrower* thrower_; |
| 1283 Handle<JSObject> module_object_; | 1207 Handle<JSObject> module_object_; |
| 1284 Handle<JSReceiver> ffi_; | 1208 Handle<JSReceiver> ffi_; |
| 1285 Handle<JSArrayBuffer> memory_; | 1209 Handle<JSArrayBuffer> memory_; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1406 *GetRawGlobalPtr<double>(global) = static_cast<double>(num); | 1330 *GetRawGlobalPtr<double>(global) = static_cast<double>(num); |
| 1407 break; | 1331 break; |
| 1408 default: | 1332 default: |
| 1409 UNREACHABLE(); | 1333 UNREACHABLE(); |
| 1410 } | 1334 } |
| 1411 } | 1335 } |
| 1412 | 1336 |
| 1413 // Process the imports, including functions, tables, globals, and memory, in | 1337 // Process the imports, including functions, tables, globals, and memory, in |
| 1414 // order, loading them from the {ffi_} object. Returns the number of imported | 1338 // order, loading them from the {ffi_} object. Returns the number of imported |
| 1415 // functions. | 1339 // functions. |
| 1416 int ProcessImports(Handle<FixedArray> code_table, Handle<JSObject> instance) { | 1340 int ProcessImports(Handle<FixedArray> code_table, |
| 1341 Handle<WasmInstanceObject> instance) { | |
| 1417 int num_imported_functions = 0; | 1342 int num_imported_functions = 0; |
| 1418 int num_imported_tables = 0; | 1343 int num_imported_tables = 0; |
| 1419 for (int index = 0; index < static_cast<int>(module_->import_table.size()); | 1344 for (int index = 0; index < static_cast<int>(module_->import_table.size()); |
| 1420 ++index) { | 1345 ++index) { |
| 1421 WasmImport& import = module_->import_table[index]; | 1346 WasmImport& import = module_->import_table[index]; |
| 1422 Handle<String> module_name = | 1347 Handle<String> module_name = |
| 1423 ExtractStringFromModuleBytes(isolate_, compiled_module_, | 1348 ExtractStringFromModuleBytes(isolate_, compiled_module_, |
| 1424 import.module_name_offset, | 1349 import.module_name_offset, |
| 1425 import.module_name_length) | 1350 import.module_name_length) |
| 1426 .ToHandleChecked(); | 1351 .ToHandleChecked(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1457 case kExternalTable: { | 1382 case kExternalTable: { |
| 1458 Handle<Object> value = result.ToHandleChecked(); | 1383 Handle<Object> value = result.ToHandleChecked(); |
| 1459 if (!WasmJs::IsWasmTableObject(isolate_, value)) { | 1384 if (!WasmJs::IsWasmTableObject(isolate_, value)) { |
| 1460 ReportFFIError("table import requires a WebAssembly.Table", index, | 1385 ReportFFIError("table import requires a WebAssembly.Table", index, |
| 1461 module_name, function_name); | 1386 module_name, function_name); |
| 1462 return -1; | 1387 return -1; |
| 1463 } | 1388 } |
| 1464 WasmIndirectFunctionTable& table = | 1389 WasmIndirectFunctionTable& table = |
| 1465 module_->function_tables[num_imported_tables]; | 1390 module_->function_tables[num_imported_tables]; |
| 1466 TableInstance& table_instance = table_instances_[num_imported_tables]; | 1391 TableInstance& table_instance = table_instances_[num_imported_tables]; |
| 1467 table_instance.table_object = Handle<JSObject>::cast(value); | 1392 table_instance.table_object = Handle<WasmTableObject>::cast(value); |
| 1468 table_instance.js_wrappers = WasmJs::GetWasmTableFunctions( | 1393 table_instance.js_wrappers = Handle<FixedArray>( |
| 1469 isolate_, table_instance.table_object); | 1394 table_instance.table_object->get_functions(), isolate_); |
| 1470 | 1395 |
| 1471 // TODO(titzer): import table size must match exactly for now. | 1396 // TODO(titzer): import table size must match exactly for now. |
| 1472 int table_size = table_instance.js_wrappers->length(); | 1397 int table_size = table_instance.js_wrappers->length(); |
| 1473 if (table_size != table.min_size) { | 1398 if (table_size != table.min_size) { |
| 1474 thrower_->TypeError( | 1399 thrower_->TypeError( |
| 1475 "table import %d is wrong size (%d), expected %u", index, | 1400 "table import %d is wrong size (%d), expected %u", index, |
| 1476 table_size, table.min_size); | 1401 table_size, table.min_size); |
| 1477 return -1; | 1402 return -1; |
| 1478 } | 1403 } |
| 1479 | 1404 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1505 num_imported_tables++; | 1430 num_imported_tables++; |
| 1506 break; | 1431 break; |
| 1507 } | 1432 } |
| 1508 case kExternalMemory: { | 1433 case kExternalMemory: { |
| 1509 Handle<Object> object = result.ToHandleChecked(); | 1434 Handle<Object> object = result.ToHandleChecked(); |
| 1510 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { | 1435 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { |
| 1511 ReportFFIError("memory import must be a WebAssembly.Memory object", | 1436 ReportFFIError("memory import must be a WebAssembly.Memory object", |
| 1512 index, module_name, function_name); | 1437 index, module_name, function_name); |
| 1513 return -1; | 1438 return -1; |
| 1514 } | 1439 } |
| 1515 instance->SetInternalField(kWasmMemObject, *object); | 1440 auto memory = Handle<WasmMemoryObject>::cast(object); |
| 1516 memory_ = WasmJs::GetWasmMemoryArrayBuffer(isolate_, object); | 1441 instance->set_memory_object(*memory); |
| 1442 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_); | |
| 1517 break; | 1443 break; |
| 1518 } | 1444 } |
| 1519 case kExternalGlobal: { | 1445 case kExternalGlobal: { |
| 1520 // Global imports are converted to numbers and written into the | 1446 // Global imports are converted to numbers and written into the |
| 1521 // {globals_} array buffer. | 1447 // {globals_} array buffer. |
| 1522 Handle<Object> object = result.ToHandleChecked(); | 1448 Handle<Object> object = result.ToHandleChecked(); |
| 1523 MaybeHandle<Object> number = Object::ToNumber(object); | 1449 MaybeHandle<Object> number = Object::ToNumber(object); |
| 1524 if (number.is_null()) { | 1450 if (number.is_null()) { |
| 1525 ReportFFIError("global import could not be converted to number", | 1451 ReportFFIError("global import could not be converted to number", |
| 1526 index, module_name, function_name); | 1452 index, module_name, function_name); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1594 | 1520 |
| 1595 if (mem_buffer.is_null()) { | 1521 if (mem_buffer.is_null()) { |
| 1596 thrower_->RangeError("Out of memory: wasm memory"); | 1522 thrower_->RangeError("Out of memory: wasm memory"); |
| 1597 } | 1523 } |
| 1598 return mem_buffer; | 1524 return mem_buffer; |
| 1599 } | 1525 } |
| 1600 | 1526 |
| 1601 // Process the exports, creating wrappers for functions, tables, memories, | 1527 // Process the exports, creating wrappers for functions, tables, memories, |
| 1602 // and globals. | 1528 // and globals. |
| 1603 void ProcessExports(Handle<FixedArray> code_table, | 1529 void ProcessExports(Handle<FixedArray> code_table, |
| 1604 Handle<JSObject> instance) { | 1530 Handle<WasmInstanceObject> instance) { |
| 1605 bool needs_wrappers = module_->num_exported_functions > 0; | 1531 bool needs_wrappers = module_->num_exported_functions > 0; |
| 1606 for (auto table_instance : table_instances_) { | 1532 for (auto table_instance : table_instances_) { |
| 1607 if (!table_instance.js_wrappers.is_null()) { | 1533 if (!table_instance.js_wrappers.is_null()) { |
| 1608 needs_wrappers = true; | 1534 needs_wrappers = true; |
| 1609 break; | 1535 break; |
| 1610 } | 1536 } |
| 1611 } | 1537 } |
| 1612 for (auto table : module_->function_tables) { | 1538 for (auto table : module_->function_tables) { |
| 1613 if (table.exported) { | 1539 if (table.exported) { |
| 1614 needs_wrappers = true; | 1540 needs_wrappers = true; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1647 case kExternalFunction: { | 1573 case kExternalFunction: { |
| 1648 // Wrap and export the code as a JSFunction. | 1574 // Wrap and export the code as a JSFunction. |
| 1649 WasmFunction& function = module_->functions[exp.index]; | 1575 WasmFunction& function = module_->functions[exp.index]; |
| 1650 int func_index = | 1576 int func_index = |
| 1651 static_cast<int>(module_->functions.size() + export_index); | 1577 static_cast<int>(module_->functions.size() + export_index); |
| 1652 Handle<JSFunction> js_function = js_wrappers_[exp.index]; | 1578 Handle<JSFunction> js_function = js_wrappers_[exp.index]; |
| 1653 if (js_function.is_null()) { | 1579 if (js_function.is_null()) { |
| 1654 // Wrap the exported code as a JSFunction. | 1580 // Wrap the exported code as a JSFunction. |
| 1655 Handle<Code> export_code = | 1581 Handle<Code> export_code = |
| 1656 code_table->GetValueChecked<Code>(isolate_, func_index); | 1582 code_table->GetValueChecked<Code>(isolate_, func_index); |
| 1657 js_function = WrapExportCodeAsJSFunction( | 1583 js_function = WasmExportedFunction::New( |
| 1658 isolate_, export_code, name, function.sig, function.func_index, | 1584 isolate_, instance, name, export_code, |
| 1659 instance); | 1585 static_cast<int>(function.sig->parameter_count()), |
|
rossberg
2016/11/10 15:12:16
Having to perform this cast seems stupid.
| |
| 1586 function.func_index); | |
| 1660 js_wrappers_[exp.index] = js_function; | 1587 js_wrappers_[exp.index] = js_function; |
| 1661 } | 1588 } |
| 1662 desc.set_value(js_function); | 1589 desc.set_value(js_function); |
| 1663 export_index++; | 1590 export_index++; |
| 1664 break; | 1591 break; |
| 1665 } | 1592 } |
| 1666 case kExternalTable: { | 1593 case kExternalTable: { |
| 1667 // Export a table as a WebAssembly.Table object. | 1594 // Export a table as a WebAssembly.Table object. |
| 1668 TableInstance& table_instance = table_instances_[exp.index]; | 1595 TableInstance& table_instance = table_instances_[exp.index]; |
| 1669 WasmIndirectFunctionTable& table = | 1596 WasmIndirectFunctionTable& table = |
| 1670 module_->function_tables[exp.index]; | 1597 module_->function_tables[exp.index]; |
| 1671 if (table_instance.table_object.is_null()) { | 1598 if (table_instance.table_object.is_null()) { |
| 1672 table_instance.table_object = WasmJs::CreateWasmTableObject( | 1599 uint32_t maximum = |
| 1673 isolate_, table.min_size, table.has_max, table.max_size, | 1600 table.has_max ? table.max_size : WasmModule::kV8MaxTableSize; |
| 1674 &table_instance.js_wrappers); | 1601 table_instance.table_object = WasmTableObject::New( |
| 1602 isolate_, table.min_size, maximum, &table_instance.js_wrappers); | |
| 1675 } | 1603 } |
| 1676 desc.set_value(table_instance.table_object); | 1604 desc.set_value(table_instance.table_object); |
| 1677 break; | 1605 break; |
| 1678 } | 1606 } |
| 1679 case kExternalMemory: { | 1607 case kExternalMemory: { |
| 1680 // Export the memory as a WebAssembly.Memory object. | 1608 // Export the memory as a WebAssembly.Memory object. |
| 1681 Handle<Object> memory_object( | 1609 Handle<WasmMemoryObject> memory_object; |
| 1682 instance->GetInternalField(kWasmMemObject), isolate_); | 1610 if (!instance->has_memory_object()) { |
| 1683 if (memory_object->IsUndefined(isolate_)) { | |
| 1684 // If there was no imported WebAssembly.Memory object, create one. | 1611 // If there was no imported WebAssembly.Memory object, create one. |
| 1685 Handle<JSArrayBuffer> buffer( | 1612 Handle<JSArrayBuffer> buffer(instance->get_memory_buffer(), |
| 1686 JSArrayBuffer::cast( | 1613 isolate_); |
| 1687 instance->GetInternalField(kWasmMemArrayBuffer)), | 1614 memory_object = WasmMemoryObject::New( |
| 1688 isolate_); | 1615 isolate_, buffer, |
| 1689 memory_object = WasmJs::CreateWasmMemoryObject( | 1616 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1); |
| 1690 isolate_, buffer, (module_->max_mem_pages != 0), | 1617 instance->set_memory_object(*memory_object); |
| 1691 module_->max_mem_pages); | 1618 } else { |
| 1692 instance->SetInternalField(kWasmMemObject, *memory_object); | 1619 memory_object = Handle<WasmMemoryObject>( |
| 1620 instance->get_memory_object(), isolate_); | |
| 1693 } | 1621 } |
| 1694 | 1622 |
| 1695 desc.set_value(memory_object); | 1623 desc.set_value(memory_object); |
| 1696 break; | 1624 break; |
| 1697 } | 1625 } |
| 1698 case kExternalGlobal: { | 1626 case kExternalGlobal: { |
| 1699 // Export the value of the global variable as a number. | 1627 // Export the value of the global variable as a number. |
| 1700 WasmGlobal& global = module_->globals[exp.index]; | 1628 WasmGlobal& global = module_->globals[exp.index]; |
| 1701 double num = 0; | 1629 double num = 0; |
| 1702 switch (global.type) { | 1630 switch (global.type) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1724 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); | 1652 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); |
| 1725 if (!status.IsJust()) { | 1653 if (!status.IsJust()) { |
| 1726 thrower_->TypeError("export of %.*s failed.", name->length(), | 1654 thrower_->TypeError("export of %.*s failed.", name->length(), |
| 1727 name->ToCString().get()); | 1655 name->ToCString().get()); |
| 1728 return; | 1656 return; |
| 1729 } | 1657 } |
| 1730 } | 1658 } |
| 1731 } | 1659 } |
| 1732 | 1660 |
| 1733 void InitializeTables(Handle<FixedArray> code_table, | 1661 void InitializeTables(Handle<FixedArray> code_table, |
| 1734 Handle<JSObject> instance) { | 1662 Handle<WasmInstanceObject> instance) { |
| 1735 Handle<FixedArray> old_function_tables = | 1663 Handle<FixedArray> old_function_tables = |
| 1736 compiled_module_->function_tables(); | 1664 compiled_module_->function_tables(); |
| 1737 int function_table_count = | 1665 int function_table_count = |
| 1738 static_cast<int>(module_->function_tables.size()); | 1666 static_cast<int>(module_->function_tables.size()); |
| 1739 Handle<FixedArray> new_function_tables = | 1667 Handle<FixedArray> new_function_tables = |
| 1740 isolate_->factory()->NewFixedArray(function_table_count); | 1668 isolate_->factory()->NewFixedArray(function_table_count); |
| 1741 for (int index = 0; index < function_table_count; ++index) { | 1669 for (int index = 0; index < function_table_count; ++index) { |
| 1742 WasmIndirectFunctionTable& table = module_->function_tables[index]; | 1670 WasmIndirectFunctionTable& table = module_->function_tables[index]; |
| 1743 TableInstance& table_instance = table_instances_[index]; | 1671 TableInstance& table_instance = table_instances_[index]; |
| 1744 int table_size = static_cast<int>(table.min_size); | 1672 int table_size = static_cast<int>(table.min_size); |
| 1745 | 1673 |
| 1746 if (table_instance.dispatch_table.is_null()) { | 1674 if (table_instance.dispatch_table.is_null()) { |
| 1747 // Create a new dispatch table if necessary. | 1675 // Create a new dispatch table if necessary. |
| 1748 table_instance.dispatch_table = | 1676 table_instance.dispatch_table = |
| 1749 isolate_->factory()->NewFixedArray(table_size * 2); | 1677 isolate_->factory()->NewFixedArray(table_size * 2); |
| 1750 for (int i = 0; i < table_size; ++i) { | 1678 for (int i = 0; i < table_size; ++i) { |
| 1751 // Fill the table with invalid signature indexes so that | 1679 // Fill the table with invalid signature indexes so that |
| 1752 // uninitialized entries will always fail the signature check. | 1680 // uninitialized entries will always fail the signature check. |
| 1753 table_instance.dispatch_table->set(i, Smi::FromInt(kInvalidSigIndex)); | 1681 table_instance.dispatch_table->set(i, Smi::FromInt(kInvalidSigIndex)); |
| 1754 } | 1682 } |
| 1755 } | 1683 } |
| 1756 | 1684 |
| 1757 new_function_tables->set(static_cast<int>(index), | 1685 new_function_tables->set(static_cast<int>(index), |
| 1758 *table_instance.dispatch_table); | 1686 *table_instance.dispatch_table); |
| 1759 | 1687 |
| 1760 Handle<FixedArray> all_dispatch_tables; | 1688 Handle<FixedArray> all_dispatch_tables; |
| 1761 if (!table_instance.table_object.is_null()) { | 1689 if (!table_instance.table_object.is_null()) { |
| 1762 // Get the existing dispatch table(s) with the WebAssembly.Table object. | 1690 // Get the existing dispatch table(s) with the WebAssembly.Table object. |
| 1763 all_dispatch_tables = WasmJs::AddWasmTableDispatchTable( | 1691 all_dispatch_tables = WasmTableObject::AddDispatchTable( |
| 1764 isolate_, table_instance.table_object, Handle<JSObject>::null(), | 1692 isolate_, table_instance.table_object, |
| 1765 index, Handle<FixedArray>::null()); | 1693 Handle<WasmInstanceObject>::null(), index, |
| 1694 Handle<FixedArray>::null()); | |
| 1766 } | 1695 } |
| 1767 | 1696 |
| 1768 // TODO(titzer): this does redundant work if there are multiple tables, | 1697 // TODO(titzer): this does redundant work if there are multiple tables, |
| 1769 // since initializations are not sorted by table index. | 1698 // since initializations are not sorted by table index. |
| 1770 for (auto table_init : module_->table_inits) { | 1699 for (auto table_init : module_->table_inits) { |
| 1771 uint32_t base = EvalUint32InitExpr(table_init.offset); | 1700 uint32_t base = EvalUint32InitExpr(table_init.offset); |
| 1772 if (base > static_cast<uint32_t>(table_size) || | 1701 if (base > static_cast<uint32_t>(table_size) || |
| 1773 (base + table_init.entries.size() > | 1702 (base + table_init.entries.size() > |
| 1774 static_cast<uint32_t>(table_size))) { | 1703 static_cast<uint32_t>(table_size))) { |
| 1775 thrower_->CompileError("table initializer is out of bounds"); | 1704 thrower_->CompileError("table initializer is out of bounds"); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1800 temp_instance.mem_start = nullptr; | 1729 temp_instance.mem_start = nullptr; |
| 1801 temp_instance.globals_start = nullptr; | 1730 temp_instance.globals_start = nullptr; |
| 1802 | 1731 |
| 1803 ModuleEnv module_env; | 1732 ModuleEnv module_env; |
| 1804 module_env.module = module_; | 1733 module_env.module = module_; |
| 1805 module_env.instance = &temp_instance; | 1734 module_env.instance = &temp_instance; |
| 1806 module_env.origin = module_->origin; | 1735 module_env.origin = module_->origin; |
| 1807 | 1736 |
| 1808 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( | 1737 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( |
| 1809 isolate_, &module_env, wasm_code, func_index); | 1738 isolate_, &module_env, wasm_code, func_index); |
| 1810 Handle<JSFunction> js_function = WrapExportCodeAsJSFunction( | 1739 Handle<WasmExportedFunction> js_function = |
| 1811 isolate_, wrapper_code, isolate_->factory()->empty_string(), | 1740 WasmExportedFunction::New( |
| 1812 function->sig, func_index, instance); | 1741 isolate_, instance, isolate_->factory()->empty_string(), |
| 1742 wrapper_code, | |
| 1743 static_cast<int>(function->sig->parameter_count()), | |
| 1744 func_index); | |
| 1813 js_wrappers_[func_index] = js_function; | 1745 js_wrappers_[func_index] = js_function; |
| 1814 } | 1746 } |
| 1815 table_instance.js_wrappers->set(table_index, | 1747 table_instance.js_wrappers->set(table_index, |
| 1816 *js_wrappers_[func_index]); | 1748 *js_wrappers_[func_index]); |
| 1817 | 1749 |
| 1818 UpdateDispatchTablesInternal(isolate_, all_dispatch_tables, | 1750 UpdateDispatchTablesInternal(isolate_, all_dispatch_tables, |
| 1819 table_index, function, wasm_code); | 1751 table_index, function, wasm_code); |
| 1820 } | 1752 } |
| 1821 } | 1753 } |
| 1822 } | 1754 } |
| 1823 | 1755 |
| 1824 // TODO(titzer): we add the new dispatch table at the end to avoid | 1756 // TODO(titzer): we add the new dispatch table at the end to avoid |
| 1825 // redundant work and also because the new instance is not yet fully | 1757 // redundant work and also because the new instance is not yet fully |
| 1826 // initialized. | 1758 // initialized. |
| 1827 if (!table_instance.table_object.is_null()) { | 1759 if (!table_instance.table_object.is_null()) { |
| 1828 // Add the new dispatch table to the WebAssembly.Table object. | 1760 // Add the new dispatch table to the WebAssembly.Table object. |
| 1829 all_dispatch_tables = WasmJs::AddWasmTableDispatchTable( | 1761 all_dispatch_tables = WasmTableObject::AddDispatchTable( |
| 1830 isolate_, table_instance.table_object, instance, index, | 1762 isolate_, table_instance.table_object, instance, index, |
| 1831 table_instance.dispatch_table); | 1763 table_instance.dispatch_table); |
| 1832 } | 1764 } |
| 1833 } | 1765 } |
| 1834 // Patch all code that has references to the old indirect tables. | 1766 // Patch all code that has references to the old indirect tables. |
| 1835 for (int i = 0; i < code_table->length(); ++i) { | 1767 for (int i = 0; i < code_table->length(); ++i) { |
| 1836 if (!code_table->get(i)->IsCode()) continue; | 1768 if (!code_table->get(i)->IsCode()) continue; |
| 1837 Handle<Code> code(Code::cast(code_table->get(i)), isolate_); | 1769 Handle<Code> code(Code::cast(code_table->get(i)), isolate_); |
| 1838 for (int j = 0; j < function_table_count; ++j) { | 1770 for (int j = 0; j < function_table_count; ++j) { |
| 1839 ReplaceReferenceInCode( | 1771 ReplaceReferenceInCode( |
| 1840 code, Handle<Object>(old_function_tables->get(j), isolate_), | 1772 code, Handle<Object>(old_function_tables->get(j), isolate_), |
| 1841 Handle<Object>(new_function_tables->get(j), isolate_)); | 1773 Handle<Object>(new_function_tables->get(j), isolate_)); |
| 1842 } | 1774 } |
| 1843 } | 1775 } |
| 1844 compiled_module_->set_function_tables(new_function_tables); | 1776 compiled_module_->set_function_tables(new_function_tables); |
| 1845 } | 1777 } |
| 1846 }; | 1778 }; |
| 1847 | 1779 |
| 1848 // Instantiates a WASM module, creating a WebAssembly.Instance from a | 1780 // Instantiates a WASM module, creating a WebAssembly.Instance from a |
| 1849 // WebAssembly.Module. | 1781 // WebAssembly.Module. |
| 1850 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 1782 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
| 1851 ErrorThrower* thrower, | 1783 ErrorThrower* thrower, |
| 1852 Handle<JSObject> wasm_module, | 1784 Handle<JSObject> wasm_module, |
| 1853 Handle<JSReceiver> ffi, | 1785 Handle<JSReceiver> ffi, |
| 1854 Handle<JSArrayBuffer> memory) { | 1786 Handle<JSArrayBuffer> memory) { |
| 1855 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); | 1787 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); |
| 1856 return builder.Build(); | 1788 return builder.Build(); |
| 1857 } | 1789 } |
| 1858 | 1790 |
| 1859 Handle<WasmCompiledModule> WasmCompiledModule::New( | |
| 1860 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper) { | |
| 1861 Handle<FixedArray> ret = | |
| 1862 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); | |
| 1863 // WasmCompiledModule::cast would fail since module bytes are not set yet. | |
| 1864 Handle<WasmCompiledModule> compiled_module( | |
| 1865 reinterpret_cast<WasmCompiledModule*>(*ret), isolate); | |
| 1866 compiled_module->InitId(); | |
| 1867 compiled_module->set_module_wrapper(module_wrapper); | |
| 1868 return compiled_module; | |
| 1869 } | |
| 1870 | |
| 1871 void WasmCompiledModule::InitId() { | |
| 1872 #if DEBUG | |
| 1873 static uint32_t instance_id_counter = 0; | |
| 1874 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); | |
| 1875 TRACE("New compiled module id: %d\n", instance_id()); | |
| 1876 #endif | |
| 1877 } | |
| 1878 | |
| 1879 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) { | |
| 1880 if (!obj->IsFixedArray()) return false; | |
| 1881 FixedArray* arr = FixedArray::cast(obj); | |
| 1882 if (arr->length() != PropertyIndices::Count) return false; | |
| 1883 Isolate* isolate = arr->GetIsolate(); | |
| 1884 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \ | |
| 1885 if (!arr->get(kID_##NAME)->IsSmi()) return false; | |
| 1886 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \ | |
| 1887 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \ | |
| 1888 !arr->get(kID_##NAME)->Is##TYPE()) \ | |
| 1889 return false; | |
| 1890 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) | |
| 1891 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME) | |
| 1892 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME) | |
| 1893 WCM_PROPERTY_TABLE(WCM_CHECK) | |
| 1894 #undef WCM_CHECK | |
| 1895 | |
| 1896 // All checks passed. | |
| 1897 return true; | |
| 1898 } | |
| 1899 | |
| 1900 void WasmCompiledModule::PrintInstancesChain() { | |
| 1901 #if DEBUG | |
| 1902 if (!FLAG_trace_wasm_instances) return; | |
| 1903 for (WasmCompiledModule* current = this; current != nullptr;) { | |
| 1904 PrintF("->%d", current->instance_id()); | |
| 1905 if (current->ptr_to_weak_next_instance() == nullptr) break; | |
| 1906 CHECK(!current->ptr_to_weak_next_instance()->cleared()); | |
| 1907 current = | |
| 1908 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); | |
| 1909 } | |
| 1910 PrintF("\n"); | |
| 1911 #endif | |
| 1912 } | |
| 1913 | |
| 1914 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, | 1791 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, |
| 1915 Handle<Object> instance, | 1792 Handle<Object> object, |
| 1916 uint32_t func_index) { | 1793 uint32_t func_index) { |
| 1917 if (!instance->IsUndefined(isolate)) { | 1794 if (!object->IsUndefined(isolate)) { |
| 1918 DCHECK(IsWasmInstance(*instance)); | 1795 auto instance = Handle<WasmInstanceObject>::cast(object); |
| 1919 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); | 1796 WasmModule* module = instance->module(); |
| 1920 WasmFunction& function = module->functions[func_index]; | 1797 WasmFunction& function = module->functions[func_index]; |
| 1921 Handle<WasmCompiledModule> compiled_module(GetCompiledModule(*instance), | 1798 Handle<WasmCompiledModule> compiled_module(instance->get_compiled_module(), |
| 1922 isolate); | 1799 isolate); |
| 1923 MaybeHandle<String> string = ExtractStringFromModuleBytes( | 1800 MaybeHandle<String> string = ExtractStringFromModuleBytes( |
| 1924 isolate, compiled_module, function.name_offset, function.name_length); | 1801 isolate, compiled_module, function.name_offset, function.name_length); |
| 1925 if (!string.is_null()) return string.ToHandleChecked(); | 1802 if (!string.is_null()) return string.ToHandleChecked(); |
| 1926 } | 1803 } |
| 1927 return isolate->factory()->null_value(); | 1804 return isolate->factory()->null_value(); |
| 1928 } | 1805 } |
| 1929 | 1806 |
| 1930 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, | 1807 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, |
| 1931 Handle<Object> instance, | 1808 Handle<Object> instance, |
| 1932 uint32_t func_index) { | 1809 uint32_t func_index) { |
| 1933 Handle<Object> name_or_null = | 1810 Handle<Object> name_or_null = |
| 1934 GetWasmFunctionNameOrNull(isolate, instance, func_index); | 1811 GetWasmFunctionNameOrNull(isolate, instance, func_index); |
| 1935 if (!name_or_null->IsNull(isolate)) { | 1812 if (!name_or_null->IsNull(isolate)) { |
| 1936 return Handle<String>::cast(name_or_null); | 1813 return Handle<String>::cast(name_or_null); |
| 1937 } | 1814 } |
| 1938 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); | 1815 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); |
| 1939 } | 1816 } |
| 1940 | 1817 |
| 1941 bool wasm::IsWasmInstance(Object* object) { | 1818 bool wasm::IsWasmInstance(Object* object) { |
| 1942 if (!object->IsJSObject()) return false; | 1819 return WasmInstanceObject::IsWasmInstanceObject(object); |
| 1943 | |
| 1944 JSObject* obj = JSObject::cast(object); | |
| 1945 Isolate* isolate = obj->GetIsolate(); | |
| 1946 if (obj->GetInternalFieldCount() != kWasmInstanceInternalFieldCount) { | |
| 1947 return false; | |
| 1948 } | |
| 1949 | |
| 1950 Object* mem = obj->GetInternalField(kWasmMemArrayBuffer); | |
| 1951 if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) || | |
| 1952 !WasmCompiledModule::IsWasmCompiledModule( | |
| 1953 obj->GetInternalField(kWasmCompiledModule))) { | |
| 1954 return false; | |
| 1955 } | |
| 1956 | |
| 1957 // All checks passed. | |
| 1958 return true; | |
| 1959 } | 1820 } |
| 1960 | 1821 |
| 1961 WasmCompiledModule* wasm::GetCompiledModule(Object* instance) { | 1822 WasmCompiledModule* wasm::GetCompiledModule(Object* object) { |
| 1962 DCHECK(IsWasmInstance(instance)); | 1823 return WasmInstanceObject::cast(object)->get_compiled_module(); |
| 1963 return WasmCompiledModule::cast( | |
| 1964 JSObject::cast(instance)->GetInternalField(kWasmCompiledModule)); | |
| 1965 } | 1824 } |
| 1966 | 1825 |
| 1967 bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) { | 1826 bool wasm::WasmIsAsmJs(Object* object, Isolate* isolate) { |
| 1968 return IsWasmInstance(instance) && | 1827 return IsWasmInstance(object) && |
| 1969 GetCompiledModule(JSObject::cast(instance))->has_asm_js_script(); | 1828 WasmInstanceObject::cast(object) |
| 1829 ->get_compiled_module() | |
| 1830 ->has_asm_js_script(); | |
| 1970 } | 1831 } |
| 1971 | 1832 |
| 1972 Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> instance) { | 1833 Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> object) { |
| 1973 DCHECK(IsWasmInstance(*instance)); | 1834 return Handle<WasmInstanceObject>::cast(object) |
| 1974 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); | 1835 ->get_compiled_module() |
| 1975 return compiled_module->asm_js_script(); | 1836 ->asm_js_script(); |
| 1976 } | 1837 } |
| 1977 | 1838 |
| 1978 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, | 1839 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, |
| 1979 int byte_offset) { | 1840 int byte_offset) { |
| 1980 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance), | 1841 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance), |
| 1981 func_index, byte_offset); | 1842 func_index, byte_offset); |
| 1982 } | 1843 } |
| 1983 | 1844 |
| 1984 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> instance) { | 1845 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> object) { |
| 1985 DCHECK(IsWasmInstance(*instance)); | 1846 return Handle<WasmInstanceObject>::cast(object) |
| 1986 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); | 1847 ->get_compiled_module() |
| 1987 return compiled_module->module_bytes(); | 1848 ->module_bytes(); |
| 1988 } | 1849 } |
| 1989 | 1850 |
| 1990 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> instance) { | 1851 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) { |
| 1991 Handle<Object> info(instance->GetInternalField(kWasmDebugInfo), | 1852 auto instance = Handle<WasmInstanceObject>::cast(object); |
| 1992 instance->GetIsolate()); | 1853 if (instance->has_debug_info()) { |
| 1993 if (!info->IsUndefined(instance->GetIsolate())) | 1854 Handle<WasmDebugInfo> info(instance->get_debug_info(), |
| 1994 return Handle<WasmDebugInfo>::cast(info); | 1855 instance->GetIsolate()); |
| 1856 return info; | |
| 1857 } | |
| 1995 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance); | 1858 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance); |
| 1996 instance->SetInternalField(kWasmDebugInfo, *new_info); | 1859 instance->set_debug_info(*new_info); |
| 1997 return new_info; | 1860 return new_info; |
| 1998 } | 1861 } |
| 1999 | 1862 |
| 2000 int wasm::GetNumberOfFunctions(Handle<JSObject> instance) { | 1863 int wasm::GetNumberOfFunctions(Handle<JSObject> object) { |
| 2001 return static_cast<int>(GetCppModule(instance)->functions.size()); | 1864 return static_cast<int>( |
| 2002 } | 1865 Handle<WasmInstanceObject>::cast(object)->module()->functions.size()); |
| 2003 | |
| 2004 Handle<JSObject> wasm::CreateWasmModuleObject( | |
| 2005 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, | |
| 2006 ModuleOrigin origin) { | |
| 2007 Handle<JSObject> wasm_module; | |
| 2008 if (origin == ModuleOrigin::kWasmOrigin) { | |
| 2009 Handle<JSFunction> module_cons( | |
| 2010 isolate->native_context()->wasm_module_constructor()); | |
| 2011 wasm_module = isolate->factory()->NewJSObject(module_cons); | |
| 2012 } else { | |
| 2013 DCHECK(origin == ModuleOrigin::kAsmJsOrigin); | |
| 2014 Handle<Map> map = isolate->factory()->NewMap( | |
| 2015 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize); | |
| 2016 wasm_module = isolate->factory()->NewJSObjectFromMap(map, TENURED); | |
| 2017 } | |
| 2018 wasm_module->SetInternalField(0, *compiled_module); | |
| 2019 if (origin == ModuleOrigin::kWasmOrigin) { | |
| 2020 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); | |
| 2021 Object::SetProperty(wasm_module, module_sym, wasm_module, STRICT).Check(); | |
| 2022 } | |
| 2023 Handle<WeakCell> link_to_module = | |
| 2024 isolate->factory()->NewWeakCell(wasm_module); | |
| 2025 compiled_module->set_weak_wasm_module(link_to_module); | |
| 2026 return wasm_module; | |
| 2027 } | 1866 } |
| 2028 | 1867 |
| 2029 // TODO(clemensh): origin can be inferred from asm_js_script; remove it. | 1868 // TODO(clemensh): origin can be inferred from asm_js_script; remove it. |
| 2030 MaybeHandle<JSObject> wasm::CreateModuleObjectFromBytes( | 1869 MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes( |
| 2031 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, | 1870 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, |
| 2032 ModuleOrigin origin, Handle<Script> asm_js_script, | 1871 ModuleOrigin origin, Handle<Script> asm_js_script, |
| 2033 const byte* asm_js_offset_tables_start, | 1872 const byte* asm_js_offset_tables_start, |
| 2034 const byte* asm_js_offset_tables_end) { | 1873 const byte* asm_js_offset_tables_end) { |
| 2035 MaybeHandle<JSObject> nothing; | 1874 MaybeHandle<WasmModuleObject> nothing; |
| 2036 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); | 1875 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); |
| 2037 if (result.failed()) { | 1876 if (result.failed()) { |
| 2038 if (result.val) delete result.val; | 1877 if (result.val) delete result.val; |
| 2039 thrower->CompileFailed("Wasm decoding failed", result); | 1878 thrower->CompileFailed("Wasm decoding failed", result); |
| 2040 return nothing; | 1879 return nothing; |
| 2041 } | 1880 } |
| 2042 // The {module_wrapper} will take ownership of the {WasmModule} object, | 1881 // The {module_wrapper} will take ownership of the {WasmModule} object, |
| 2043 // and it will be destroyed when the GC reclaims the wrapper object. | 1882 // and it will be destroyed when the GC reclaims the wrapper object. |
| 2044 Handle<WasmModuleWrapper> module_wrapper = | 1883 Handle<WasmModuleWrapper> module_wrapper = |
| 2045 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); | 1884 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2061 size_t offset_tables_len = | 1900 size_t offset_tables_len = |
| 2062 asm_js_offset_tables_end - asm_js_offset_tables_start; | 1901 asm_js_offset_tables_end - asm_js_offset_tables_start; |
| 2063 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); | 1902 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); |
| 2064 Handle<ByteArray> offset_tables = | 1903 Handle<ByteArray> offset_tables = |
| 2065 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); | 1904 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); |
| 2066 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, | 1905 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, |
| 2067 offset_tables_len); | 1906 offset_tables_len); |
| 2068 compiled_module->set_asm_js_offset_tables(offset_tables); | 1907 compiled_module->set_asm_js_offset_tables(offset_tables); |
| 2069 } | 1908 } |
| 2070 | 1909 |
| 2071 return CreateWasmModuleObject(isolate, compiled_module, origin); | 1910 return WasmModuleObject::New(isolate, compiled_module); |
| 2072 } | 1911 } |
| 2073 | 1912 |
| 2074 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, | 1913 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, |
| 2075 const byte* end, ErrorThrower* thrower, | 1914 const byte* end, ErrorThrower* thrower, |
| 2076 ModuleOrigin origin) { | 1915 ModuleOrigin origin) { |
| 2077 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); | 1916 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); |
| 2078 if (result.val) { | 1917 if (result.val) { |
| 2079 delete result.val; | 1918 delete result.val; |
| 2080 } else { | 1919 } else { |
| 2081 DCHECK(!result.ok()); | 1920 DCHECK(!result.ok()); |
| 2082 } | 1921 } |
| 2083 return result.ok(); | 1922 return result.ok(); |
| 2084 } | 1923 } |
| 2085 | 1924 |
| 2086 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(Isolate* isolate, | 1925 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(Isolate* isolate, |
| 2087 Handle<JSObject> instance) { | 1926 Handle<JSObject> object) { |
| 2088 Object* mem = instance->GetInternalField(kWasmMemArrayBuffer); | 1927 auto instance = Handle<WasmInstanceObject>::cast(object); |
| 2089 DCHECK(IsWasmInstance(*instance)); | 1928 if (instance->has_memory_buffer()) { |
| 2090 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>(); | 1929 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate); |
| 2091 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem)); | 1930 } |
| 1931 return MaybeHandle<JSArrayBuffer>(); | |
| 2092 } | 1932 } |
| 2093 | 1933 |
| 2094 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) { | 1934 void SetInstanceMemory(Handle<JSObject> object, JSArrayBuffer* buffer) { |
| 2095 DisallowHeapAllocation no_gc; | 1935 DisallowHeapAllocation no_gc; |
| 2096 DCHECK(IsWasmInstance(*instance)); | 1936 auto instance = Handle<WasmInstanceObject>::cast(object); |
| 2097 instance->SetInternalField(kWasmMemArrayBuffer, buffer); | 1937 instance->set_memory_buffer(buffer); |
| 2098 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); | 1938 instance->get_compiled_module()->set_ptr_to_memory(buffer); |
| 2099 compiled_module->set_ptr_to_memory(buffer); | |
| 2100 } | 1939 } |
| 2101 | 1940 |
| 2102 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, | 1941 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, |
| 2103 Handle<JSObject> instance) { | 1942 Handle<JSObject> instance) { |
| 2104 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 1943 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2105 GetInstanceMemory(isolate, instance); | 1944 GetInstanceMemory(isolate, instance); |
| 2106 Handle<JSArrayBuffer> buffer; | 1945 Handle<JSArrayBuffer> buffer; |
| 2107 if (!maybe_mem_buffer.ToHandle(&buffer)) { | 1946 if (!maybe_mem_buffer.ToHandle(&buffer)) { |
| 2108 return 0; | 1947 return 0; |
| 2109 } else { | 1948 } else { |
| 2110 return buffer->byte_length()->Number() / WasmModule::kPageSize; | 1949 return buffer->byte_length()->Number() / WasmModule::kPageSize; |
| 2111 } | 1950 } |
| 2112 } | 1951 } |
| 2113 | 1952 |
| 2114 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { | 1953 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, |
| 2115 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | 1954 Handle<WasmInstanceObject> instance) { |
| 2116 isolate); | 1955 if (instance->has_memory_object()) { |
| 2117 if (!memory_object->IsUndefined(isolate)) { | 1956 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(), |
| 2118 uint32_t mem_obj_max = | 1957 isolate); |
| 2119 WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object); | 1958 |
| 2120 if (mem_obj_max != 0) return mem_obj_max; | 1959 int maximum = memory_object->maximum_pages(); |
| 1960 if (maximum > 0) return static_cast<uint32_t>(maximum); | |
| 2121 } | 1961 } |
| 2122 uint32_t compiled_max_pages = GetCompiledModule(*instance)->max_mem_pages(); | 1962 uint32_t compiled_max_pages = |
| 1963 instance->get_compiled_module()->max_mem_pages(); | |
| 2123 isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 1964 isolate->counters()->wasm_max_mem_pages_count()->AddSample( |
| 2124 compiled_max_pages); | 1965 compiled_max_pages); |
| 2125 if (compiled_max_pages != 0) return compiled_max_pages; | 1966 if (compiled_max_pages != 0) return compiled_max_pages; |
| 2126 return WasmModule::kV8MaxPages; | 1967 return WasmModule::kV8MaxPages; |
| 2127 } | 1968 } |
| 2128 | 1969 |
| 2129 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, | 1970 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> object, |
| 2130 uint32_t pages) { | 1971 uint32_t pages) { |
| 2131 if (!IsWasmInstance(*instance)) return -1; | 1972 if (!IsWasmInstance(*object)) return -1; |
| 1973 auto instance = Handle<WasmInstanceObject>::cast(object); | |
| 2132 if (pages == 0) return GetInstanceMemorySize(isolate, instance); | 1974 if (pages == 0) return GetInstanceMemorySize(isolate, instance); |
| 2133 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); | 1975 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); |
| 2134 | 1976 |
| 2135 Address old_mem_start = nullptr; | 1977 Address old_mem_start = nullptr; |
| 2136 uint32_t old_size = 0, new_size = 0; | 1978 uint32_t old_size = 0, new_size = 0; |
| 2137 | 1979 |
| 2138 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = | 1980 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = |
| 2139 GetInstanceMemory(isolate, instance); | 1981 GetInstanceMemory(isolate, instance); |
| 2140 Handle<JSArrayBuffer> old_buffer; | 1982 Handle<JSArrayBuffer> old_buffer; |
| 2141 if (!maybe_mem_buffer.ToHandle(&old_buffer) || | 1983 if (!maybe_mem_buffer.ToHandle(&old_buffer) || |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2159 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) { | 2001 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) { |
| 2160 return -1; | 2002 return -1; |
| 2161 } | 2003 } |
| 2162 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); | 2004 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); |
| 2163 if (buffer.is_null()) return -1; | 2005 if (buffer.is_null()) return -1; |
| 2164 Address new_mem_start = static_cast<Address>(buffer->backing_store()); | 2006 Address new_mem_start = static_cast<Address>(buffer->backing_store()); |
| 2165 if (old_size != 0) { | 2007 if (old_size != 0) { |
| 2166 memcpy(new_mem_start, old_mem_start, old_size); | 2008 memcpy(new_mem_start, old_mem_start, old_size); |
| 2167 } | 2009 } |
| 2168 SetInstanceMemory(instance, *buffer); | 2010 SetInstanceMemory(instance, *buffer); |
| 2169 Handle<FixedArray> code_table = GetCompiledModule(*instance)->code_table(); | 2011 Handle<FixedArray> code_table = instance->get_compiled_module()->code_table(); |
| 2170 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start, | 2012 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start, |
| 2171 old_size, new_size); | 2013 old_size, new_size); |
| 2172 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | 2014 if (instance->has_memory_object()) { |
| 2173 isolate); | 2015 instance->get_memory_object()->set_buffer(*buffer); |
| 2174 if (!memory_object->IsUndefined(isolate)) { | |
| 2175 WasmJs::SetWasmMemoryArrayBuffer(isolate, memory_object, buffer); | |
| 2176 } | 2016 } |
| 2177 | 2017 |
| 2178 DCHECK(old_size % WasmModule::kPageSize == 0); | 2018 DCHECK(old_size % WasmModule::kPageSize == 0); |
| 2179 return (old_size / WasmModule::kPageSize); | 2019 return (old_size / WasmModule::kPageSize); |
| 2180 } | 2020 } |
| 2181 | 2021 |
| 2182 void testing::ValidateInstancesChain(Isolate* isolate, | 2022 void testing::ValidateInstancesChain(Isolate* isolate, |
| 2183 Handle<JSObject> wasm_module, | 2023 Handle<JSObject> wasm_module, |
| 2184 int instance_count) { | 2024 int instance_count) { |
| 2185 CHECK_GE(instance_count, 0); | 2025 CHECK_GE(instance_count, 0); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2213 WasmCompiledModule* compiled_module = | 2053 WasmCompiledModule* compiled_module = |
| 2214 WasmCompiledModule::cast(wasm_module->GetInternalField(0)); | 2054 WasmCompiledModule::cast(wasm_module->GetInternalField(0)); |
| 2215 CHECK(compiled_module->has_weak_wasm_module()); | 2055 CHECK(compiled_module->has_weak_wasm_module()); |
| 2216 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *wasm_module); | 2056 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *wasm_module); |
| 2217 CHECK(!compiled_module->has_weak_prev_instance()); | 2057 CHECK(!compiled_module->has_weak_prev_instance()); |
| 2218 CHECK(!compiled_module->has_weak_next_instance()); | 2058 CHECK(!compiled_module->has_weak_next_instance()); |
| 2219 CHECK(!compiled_module->has_weak_owning_instance()); | 2059 CHECK(!compiled_module->has_weak_owning_instance()); |
| 2220 } | 2060 } |
| 2221 | 2061 |
| 2222 void testing::ValidateOrphanedInstance(Isolate* isolate, | 2062 void testing::ValidateOrphanedInstance(Isolate* isolate, |
| 2223 Handle<JSObject> wasm_module) { | 2063 Handle<JSObject> object) { |
| 2224 DisallowHeapAllocation no_gc; | 2064 DisallowHeapAllocation no_gc; |
| 2225 CHECK(IsWasmInstance(*wasm_module)); | 2065 WasmInstanceObject* instance = WasmInstanceObject::cast(*object); |
| 2226 WasmCompiledModule* compiled_module = GetCompiledModule(*wasm_module); | 2066 WasmCompiledModule* compiled_module = instance->get_compiled_module(); |
| 2227 CHECK(compiled_module->has_weak_wasm_module()); | 2067 CHECK(compiled_module->has_weak_wasm_module()); |
| 2228 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); | 2068 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); |
| 2229 } | 2069 } |
| 2230 | 2070 |
| 2231 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, | 2071 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, |
| 2232 Handle<FixedArray> array) { | 2072 Handle<FixedArray> array) { |
| 2233 Handle<WasmCompiledModule> compiled_module( | 2073 Handle<WasmCompiledModule> compiled_module( |
| 2234 reinterpret_cast<WasmCompiledModule*>(*array), isolate); | 2074 reinterpret_cast<WasmCompiledModule*>(*array), isolate); |
| 2235 | 2075 |
| 2236 WasmModule* module = nullptr; | 2076 WasmModule* module = nullptr; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2250 CHECK_NOT_NULL(result.val); | 2090 CHECK_NOT_NULL(result.val); |
| 2251 module = const_cast<WasmModule*>(result.val); | 2091 module = const_cast<WasmModule*>(result.val); |
| 2252 } | 2092 } |
| 2253 | 2093 |
| 2254 Handle<WasmModuleWrapper> module_wrapper = | 2094 Handle<WasmModuleWrapper> module_wrapper = |
| 2255 WasmModuleWrapper::New(isolate, module); | 2095 WasmModuleWrapper::New(isolate, module); |
| 2256 | 2096 |
| 2257 compiled_module->set_module_wrapper(module_wrapper); | 2097 compiled_module->set_module_wrapper(module_wrapper); |
| 2258 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); | 2098 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); |
| 2259 } | 2099 } |
| OLD | NEW |