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

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

Issue 2490663002: [wasm] Move all heap-allocated WASM structures into wasm-objects.h. (Closed)
Patch Set: [wasm] Move all heap-allocated WASM structures into wasm-objects.h. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "src/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
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
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
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
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
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
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 module_name, import_name); 859 module_name, import_name);
931 } 860 }
932 } 861 }
933 862
934 static void UpdateDispatchTablesInternal(Isolate* isolate, 863 static void UpdateDispatchTablesInternal(Isolate* isolate,
935 Handle<FixedArray> dispatch_tables, 864 Handle<FixedArray> dispatch_tables,
936 int index, WasmFunction* function, 865 int index, WasmFunction* function,
937 Handle<Code> code) { 866 Handle<Code> code) {
938 DCHECK_EQ(0, dispatch_tables->length() % 3); 867 DCHECK_EQ(0, dispatch_tables->length() % 3);
939 for (int i = 0; i < dispatch_tables->length(); i += 3) { 868 for (int i = 0; i < dispatch_tables->length(); i += 3) {
940 Handle<Object> instance(dispatch_tables->get(i), isolate);
941 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance));
942 int table_index = Smi::cast(dispatch_tables->get(i + 1))->value(); 869 int table_index = Smi::cast(dispatch_tables->get(i + 1))->value();
943 Handle<FixedArray> dispatch_table( 870 Handle<FixedArray> dispatch_table(
944 FixedArray::cast(dispatch_tables->get(i + 2)), isolate); 871 FixedArray::cast(dispatch_tables->get(i + 2)), isolate);
945 if (function) { 872 if (function) {
946 // TODO(titzer): the signature might need to be copied to avoid 873 // TODO(titzer): the signature might need to be copied to avoid
947 // a dangling pointer in the signature map. 874 // a dangling pointer in the signature map.
875 Handle<WasmInstanceObject> instance(
876 WasmInstanceObject::cast(dispatch_tables->get(i)), isolate);
948 int sig_index = static_cast<int>( 877 int sig_index = static_cast<int>(
949 module->function_tables[table_index].map.FindOrInsert(function->sig)); 878 instance->module()->function_tables[table_index].map.FindOrInsert(
879 function->sig));
950 dispatch_table->set(index, Smi::FromInt(sig_index)); 880 dispatch_table->set(index, Smi::FromInt(sig_index));
951 dispatch_table->set(index + (dispatch_table->length() / 2), *code); 881 dispatch_table->set(index + (dispatch_table->length() / 2), *code);
952 } else { 882 } else {
953 Code* code = nullptr; 883 Code* code = nullptr;
954 dispatch_table->set(index, Smi::FromInt(-1)); 884 dispatch_table->set(index, Smi::FromInt(-1));
955 dispatch_table->set(index + (dispatch_table->length() / 2), code); 885 dispatch_table->set(index + (dispatch_table->length() / 2), code);
956 } 886 }
957 } 887 }
958 } 888 }
959 889
(...skipping 30 matching lines...) Expand all
990 MaybeHandle<JSObject> nothing; 920 MaybeHandle<JSObject> nothing;
991 HistogramTimerScope wasm_instantiate_module_time_scope( 921 HistogramTimerScope wasm_instantiate_module_time_scope(
992 isolate_->counters()->wasm_instantiate_module_time()); 922 isolate_->counters()->wasm_instantiate_module_time());
993 Factory* factory = isolate_->factory(); 923 Factory* factory = isolate_->factory();
994 924
995 //-------------------------------------------------------------------------- 925 //--------------------------------------------------------------------------
996 // Reuse the compiled module (if no owner), otherwise clone. 926 // Reuse the compiled module (if no owner), otherwise clone.
997 //-------------------------------------------------------------------------- 927 //--------------------------------------------------------------------------
998 Handle<FixedArray> code_table; 928 Handle<FixedArray> code_table;
999 Handle<FixedArray> old_code_table; 929 Handle<FixedArray> old_code_table;
1000 MaybeHandle<JSObject> owner; 930 MaybeHandle<WasmInstanceObject> owner;
1001 931
1002 TRACE("Starting new module instantiation\n"); 932 TRACE("Starting new module instantiation\n");
1003 { 933 {
1004 // Root the owner, if any, before doing any allocations, which 934 // Root the owner, if any, before doing any allocations, which
1005 // may trigger GC. 935 // may trigger GC.
1006 // Both owner and original template need to be in sync. Even 936 // Both owner and original template need to be in sync. Even
1007 // after we lose the original template handle, the code 937 // after we lose the original template handle, the code
1008 // objects we copied from it have data relative to the 938 // objects we copied from it have data relative to the
1009 // instance - such as globals addresses. 939 // instance - such as globals addresses.
1010 Handle<WasmCompiledModule> original; 940 Handle<WasmCompiledModule> original;
1011 { 941 {
1012 DisallowHeapAllocation no_gc; 942 DisallowHeapAllocation no_gc;
1013 original = handle( 943 original = handle(
1014 WasmCompiledModule::cast(module_object_->GetInternalField(0))); 944 WasmCompiledModule::cast(module_object_->GetInternalField(0)));
1015 if (original->has_weak_owning_instance()) { 945 if (original->has_weak_owning_instance()) {
1016 owner = 946 owner = handle(WasmInstanceObject::cast(
1017 handle(JSObject::cast(original->weak_owning_instance()->value())); 947 original->weak_owning_instance()->value()));
1018 } 948 }
1019 } 949 }
1020 DCHECK(!original.is_null()); 950 DCHECK(!original.is_null());
1021 // Always make a new copy of the code_table, since the old_code_table 951 // Always make a new copy of the code_table, since the old_code_table
1022 // may still have placeholders for imports. 952 // may still have placeholders for imports.
1023 old_code_table = original->code_table(); 953 old_code_table = original->code_table();
1024 code_table = factory->CopyFixedArray(old_code_table); 954 code_table = factory->CopyFixedArray(old_code_table);
1025 955
1026 if (original->has_weak_owning_instance()) { 956 if (original->has_weak_owning_instance()) {
1027 // Clone, but don't insert yet the clone in the instances chain. 957 // Clone, but don't insert yet the clone in the instances chain.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 } 991 }
1062 compiled_module_->set_code_table(code_table); 992 compiled_module_->set_code_table(code_table);
1063 } 993 }
1064 module_ = reinterpret_cast<WasmModuleWrapper*>( 994 module_ = reinterpret_cast<WasmModuleWrapper*>(
1065 *compiled_module_->module_wrapper()) 995 *compiled_module_->module_wrapper())
1066 ->get(); 996 ->get();
1067 997
1068 //-------------------------------------------------------------------------- 998 //--------------------------------------------------------------------------
1069 // Allocate the instance object. 999 // Allocate the instance object.
1070 //-------------------------------------------------------------------------- 1000 //--------------------------------------------------------------------------
1071 Handle<Map> map = factory->NewMap( 1001 Handle<WasmInstanceObject> instance =
1072 JS_OBJECT_TYPE, 1002 WasmInstanceObject::New(isolate_, compiled_module_);
1073 JSObject::kHeaderSize + kWasmInstanceInternalFieldCount * kPointerSize);
1074 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED);
1075 instance->SetInternalField(kWasmMemObject,
1076 isolate_->heap()->undefined_value());
1077 1003
1078 //-------------------------------------------------------------------------- 1004 //--------------------------------------------------------------------------
1079 // Set up the globals for the new instance. 1005 // Set up the globals for the new instance.
1080 //-------------------------------------------------------------------------- 1006 //--------------------------------------------------------------------------
1081 MaybeHandle<JSArrayBuffer> old_globals; 1007 MaybeHandle<JSArrayBuffer> old_globals;
1082 uint32_t globals_size = module_->globals_size; 1008 uint32_t globals_size = module_->globals_size;
1083 if (globals_size > 0) { 1009 if (globals_size > 0) {
1084 Handle<JSArrayBuffer> global_buffer = 1010 Handle<JSArrayBuffer> global_buffer =
1085 NewArrayBuffer(isolate_, globals_size); 1011 NewArrayBuffer(isolate_, globals_size);
1086 globals_ = global_buffer; 1012 globals_ = global_buffer;
1087 if (globals_.is_null()) { 1013 if (globals_.is_null()) {
1088 thrower_->RangeError("Out of memory: wasm globals"); 1014 thrower_->RangeError("Out of memory: wasm globals");
1089 return nothing; 1015 return nothing;
1090 } 1016 }
1091 Address old_address = owner.is_null() 1017 Address old_address =
1092 ? nullptr 1018 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate(
1093 : GetGlobalStartAddressFromCodeTemplate( 1019 isolate_->heap()->undefined_value(),
1094 isolate_->heap()->undefined_value(), 1020 *owner.ToHandleChecked());
1095 JSObject::cast(*owner.ToHandleChecked()));
1096 RelocateGlobals(code_table, old_address, 1021 RelocateGlobals(code_table, old_address,
1097 static_cast<Address>(global_buffer->backing_store())); 1022 static_cast<Address>(global_buffer->backing_store()));
1098 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); 1023 instance->set_globals_buffer(*global_buffer);
1099 } 1024 }
1100 1025
1101 //-------------------------------------------------------------------------- 1026 //--------------------------------------------------------------------------
1102 // Prepare for initialization of function tables. 1027 // Prepare for initialization of function tables.
1103 //-------------------------------------------------------------------------- 1028 //--------------------------------------------------------------------------
1104 int function_table_count = 1029 int function_table_count =
1105 static_cast<int>(module_->function_tables.size()); 1030 static_cast<int>(module_->function_tables.size());
1106 table_instances_.reserve(module_->function_tables.size()); 1031 table_instances_.reserve(module_->function_tables.size());
1107 for (int index = 0; index < function_table_count; ++index) { 1032 for (int index = 0; index < function_table_count; ++index) {
1108 table_instances_.push_back({Handle<JSObject>::null(), 1033 table_instances_.push_back({Handle<WasmTableObject>::null(),
1109 Handle<FixedArray>::null(), 1034 Handle<FixedArray>::null(),
1110 Handle<FixedArray>::null()}); 1035 Handle<FixedArray>::null()});
1111 } 1036 }
1112 1037
1113 //-------------------------------------------------------------------------- 1038 //--------------------------------------------------------------------------
1114 // Process the imports for the module. 1039 // Process the imports for the module.
1115 //-------------------------------------------------------------------------- 1040 //--------------------------------------------------------------------------
1116 int num_imported_functions = ProcessImports(code_table, instance); 1041 int num_imported_functions = ProcessImports(code_table, instance);
1117 if (num_imported_functions < 0) return nothing; 1042 if (num_imported_functions < 0) return nothing;
1118 1043
(...skipping 12 matching lines...) Expand all
1131 1056
1132 if (!memory_.is_null()) { 1057 if (!memory_.is_null()) {
1133 // Set externally passed ArrayBuffer non neuterable. 1058 // Set externally passed ArrayBuffer non neuterable.
1134 memory_->set_is_neuterable(false); 1059 memory_->set_is_neuterable(false);
1135 } else if (min_mem_pages > 0) { 1060 } else if (min_mem_pages > 0) {
1136 memory_ = AllocateMemory(min_mem_pages); 1061 memory_ = AllocateMemory(min_mem_pages);
1137 if (memory_.is_null()) return nothing; // failed to allocate memory 1062 if (memory_.is_null()) return nothing; // failed to allocate memory
1138 } 1063 }
1139 1064
1140 if (!memory_.is_null()) { 1065 if (!memory_.is_null()) {
1141 instance->SetInternalField(kWasmMemArrayBuffer, *memory_); 1066 instance->set_memory_buffer(*memory_);
1142 Address mem_start = static_cast<Address>(memory_->backing_store()); 1067 Address mem_start = static_cast<Address>(memory_->backing_store());
1143 uint32_t mem_size = 1068 uint32_t mem_size =
1144 static_cast<uint32_t>(memory_->byte_length()->Number()); 1069 static_cast<uint32_t>(memory_->byte_length()->Number());
1145 LoadDataSegments(mem_start, mem_size); 1070 LoadDataSegments(mem_start, mem_size);
1146 1071
1147 uint32_t old_mem_size = compiled_module_->mem_size(); 1072 uint32_t old_mem_size = compiled_module_->mem_size();
1148 Address old_mem_start = 1073 Address old_mem_start =
1149 compiled_module_->has_memory() 1074 compiled_module_->has_memory()
1150 ? static_cast<Address>( 1075 ? static_cast<Address>(
1151 compiled_module_->memory()->backing_store()) 1076 compiled_module_->memory()->backing_store())
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_); 1123 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_);
1199 Handle<WeakCell> link_to_owning_instance = factory->NewWeakCell(instance); 1124 Handle<WeakCell> link_to_owning_instance = factory->NewWeakCell(instance);
1200 MaybeHandle<WeakCell> link_to_original; 1125 MaybeHandle<WeakCell> link_to_original;
1201 MaybeHandle<WasmCompiledModule> original; 1126 MaybeHandle<WasmCompiledModule> original;
1202 if (!owner.is_null()) { 1127 if (!owner.is_null()) {
1203 // prepare the data needed for publishing in a chain, but don't link 1128 // prepare the data needed for publishing in a chain, but don't link
1204 // just yet, because 1129 // just yet, because
1205 // we want all the publishing to happen free from GC interruptions, and 1130 // we want all the publishing to happen free from GC interruptions, and
1206 // so we do it in 1131 // so we do it in
1207 // one GC-free scope afterwards. 1132 // one GC-free scope afterwards.
1208 original = handle(GetCompiledModule(*owner.ToHandleChecked())); 1133 original = handle(owner.ToHandleChecked()->get_compiled_module());
1209 link_to_original = factory->NewWeakCell(original.ToHandleChecked()); 1134 link_to_original = factory->NewWeakCell(original.ToHandleChecked());
1210 } 1135 }
1211 // Publish the new instance to the instances chain. 1136 // Publish the new instance to the instances chain.
1212 { 1137 {
1213 DisallowHeapAllocation no_gc; 1138 DisallowHeapAllocation no_gc;
1214 if (!link_to_original.is_null()) { 1139 if (!link_to_original.is_null()) {
1215 compiled_module_->set_weak_next_instance( 1140 compiled_module_->set_weak_next_instance(
1216 link_to_original.ToHandleChecked()); 1141 link_to_original.ToHandleChecked());
1217 original.ToHandleChecked()->set_weak_prev_instance(link_to_clone); 1142 original.ToHandleChecked()->set_weak_prev_instance(link_to_clone);
1218 compiled_module_->set_weak_wasm_module( 1143 compiled_module_->set_weak_wasm_module(
1219 original.ToHandleChecked()->weak_wasm_module()); 1144 original.ToHandleChecked()->weak_wasm_module());
1220 } 1145 }
1221 module_object_->SetInternalField(0, *compiled_module_); 1146 module_object_->SetInternalField(0, *compiled_module_);
1222 instance->SetInternalField(kWasmCompiledModule, *compiled_module_);
1223 compiled_module_->set_weak_owning_instance(link_to_owning_instance); 1147 compiled_module_->set_weak_owning_instance(link_to_owning_instance);
1224 GlobalHandles::MakeWeak(global_handle.location(), 1148 GlobalHandles::MakeWeak(global_handle.location(),
1225 global_handle.location(), &InstanceFinalizer, 1149 global_handle.location(), &InstanceFinalizer,
1226 v8::WeakCallbackType::kFinalizer); 1150 v8::WeakCallbackType::kFinalizer);
1227 } 1151 }
1228 } 1152 }
1229 1153
1230 DCHECK(wasm::IsWasmInstance(*instance)); 1154 DCHECK(wasm::IsWasmInstance(*instance));
1231 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), 1155 if (instance->has_memory_object()) {
1232 isolate_); 1156 instance->get_memory_object()->AddInstance(*instance);
1233 WasmJs::SetWasmMemoryInstance(isolate_, memory_object, instance); 1157 }
1234 1158
1235 //-------------------------------------------------------------------------- 1159 //--------------------------------------------------------------------------
1236 // Run the start function if one was specified. 1160 // Run the start function if one was specified.
1237 //-------------------------------------------------------------------------- 1161 //--------------------------------------------------------------------------
1238 if (module_->start_function_index >= 0) { 1162 if (module_->start_function_index >= 0) {
1239 HandleScope scope(isolate_); 1163 HandleScope scope(isolate_);
1240 ModuleEnv module_env; 1164 ModuleEnv module_env;
1241 module_env.module = module_; 1165 module_env.module = module_;
1242 module_env.instance = nullptr; 1166 module_env.instance = nullptr;
1243 module_env.origin = module_->origin; 1167 module_env.origin = module_->origin;
1244 int start_index = module_->start_function_index; 1168 int start_index = module_->start_function_index;
1245 Handle<Code> startup_code = 1169 Handle<Code> startup_code =
1246 code_table->GetValueChecked<Code>(isolate_, start_index); 1170 code_table->GetValueChecked<Code>(isolate_, start_index);
1247 FunctionSig* sig = module_->functions[start_index].sig; 1171 FunctionSig* sig = module_->functions[start_index].sig;
1248 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( 1172 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper(
1249 isolate_, &module_env, startup_code, start_index); 1173 isolate_, &module_env, startup_code, start_index);
1250 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( 1174 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New(
1251 isolate_, wrapper_code, factory->InternalizeUtf8String("start"), sig, 1175 isolate_, instance, factory->InternalizeUtf8String("start"),
1252 start_index, instance); 1176 wrapper_code, static_cast<int>(sig->parameter_count()), start_index);
1253 RecordStats(isolate_, *startup_code); 1177 RecordStats(isolate_, *startup_code);
1254 // Call the JS function. 1178 // Call the JS function.
1255 Handle<Object> undefined = factory->undefined_value(); 1179 Handle<Object> undefined = factory->undefined_value();
1256 MaybeHandle<Object> retval = 1180 MaybeHandle<Object> retval =
1257 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); 1181 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr);
1258 1182
1259 if (retval.is_null()) { 1183 if (retval.is_null()) {
1260 DCHECK(isolate_->has_pending_exception()); 1184 DCHECK(isolate_->has_pending_exception());
1261 isolate_->OptionalRescheduleException(false); 1185 isolate_->OptionalRescheduleException(false);
1262 // It's unfortunate that the new instance is already linked in the 1186 // It's unfortunate that the new instance is already linked in the
1263 // chain. However, we need to set up everything before executing the 1187 // chain. However, we need to set up everything before executing the
1264 // start function, such that stack trace information can be generated 1188 // start function, such that stack trace information can be generated
1265 // correctly already in the start function. 1189 // correctly already in the start function.
1266 return nothing; 1190 return nothing;
1267 } 1191 }
1268 } 1192 }
1269 1193
1270 DCHECK(!isolate_->has_pending_exception()); 1194 DCHECK(!isolate_->has_pending_exception());
1271 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); 1195 TRACE("Finishing instance %d\n", compiled_module_->instance_id());
1272 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); 1196 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0)));
1273 return instance; 1197 return instance;
1274 } 1198 }
1275 1199
1276 private: 1200 private:
1277 // Represents the initialized state of a table. 1201 // Represents the initialized state of a table.
1278 struct TableInstance { 1202 struct TableInstance {
1279 Handle<JSObject> table_object; // WebAssembly.Table instance 1203 Handle<WasmTableObject> table_object; // WebAssembly.Table instance
1280 Handle<FixedArray> js_wrappers; // JSFunctions exported 1204 Handle<FixedArray> js_wrappers; // JSFunctions exported
1281 Handle<FixedArray> dispatch_table; // internal (code, sig) pairs 1205 Handle<FixedArray> dispatch_table; // internal (code, sig) pairs
1282 }; 1206 };
1283 1207
1284 Isolate* isolate_; 1208 Isolate* isolate_;
1285 WasmModule* module_; 1209 WasmModule* module_;
1286 ErrorThrower* thrower_; 1210 ErrorThrower* thrower_;
1287 Handle<JSObject> module_object_; 1211 Handle<JSObject> module_object_;
1288 Handle<JSReceiver> ffi_; 1212 Handle<JSReceiver> ffi_;
1289 Handle<JSArrayBuffer> memory_; 1213 Handle<JSArrayBuffer> memory_;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 *GetRawGlobalPtr<double>(global) = static_cast<double>(num); 1334 *GetRawGlobalPtr<double>(global) = static_cast<double>(num);
1411 break; 1335 break;
1412 default: 1336 default:
1413 UNREACHABLE(); 1337 UNREACHABLE();
1414 } 1338 }
1415 } 1339 }
1416 1340
1417 // Process the imports, including functions, tables, globals, and memory, in 1341 // Process the imports, including functions, tables, globals, and memory, in
1418 // order, loading them from the {ffi_} object. Returns the number of imported 1342 // order, loading them from the {ffi_} object. Returns the number of imported
1419 // functions. 1343 // functions.
1420 int ProcessImports(Handle<FixedArray> code_table, Handle<JSObject> instance) { 1344 int ProcessImports(Handle<FixedArray> code_table,
1345 Handle<WasmInstanceObject> instance) {
1421 int num_imported_functions = 0; 1346 int num_imported_functions = 0;
1422 int num_imported_tables = 0; 1347 int num_imported_tables = 0;
1423 for (int index = 0; index < static_cast<int>(module_->import_table.size()); 1348 for (int index = 0; index < static_cast<int>(module_->import_table.size());
1424 ++index) { 1349 ++index) {
1425 WasmImport& import = module_->import_table[index]; 1350 WasmImport& import = module_->import_table[index];
1426 Handle<String> module_name = 1351 Handle<String> module_name =
1427 ExtractStringFromModuleBytes(isolate_, compiled_module_, 1352 ExtractStringFromModuleBytes(isolate_, compiled_module_,
1428 import.module_name_offset, 1353 import.module_name_offset,
1429 import.module_name_length) 1354 import.module_name_length)
1430 .ToHandleChecked(); 1355 .ToHandleChecked();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 case kExternalTable: { 1391 case kExternalTable: {
1467 Handle<Object> value = result.ToHandleChecked(); 1392 Handle<Object> value = result.ToHandleChecked();
1468 if (!WasmJs::IsWasmTableObject(isolate_, value)) { 1393 if (!WasmJs::IsWasmTableObject(isolate_, value)) {
1469 ReportFFIError("table import requires a WebAssembly.Table", index, 1394 ReportFFIError("table import requires a WebAssembly.Table", index,
1470 module_name, function_name); 1395 module_name, function_name);
1471 return -1; 1396 return -1;
1472 } 1397 }
1473 WasmIndirectFunctionTable& table = 1398 WasmIndirectFunctionTable& table =
1474 module_->function_tables[num_imported_tables]; 1399 module_->function_tables[num_imported_tables];
1475 TableInstance& table_instance = table_instances_[num_imported_tables]; 1400 TableInstance& table_instance = table_instances_[num_imported_tables];
1476 table_instance.table_object = Handle<JSObject>::cast(value); 1401 table_instance.table_object = Handle<WasmTableObject>::cast(value);
1477 table_instance.js_wrappers = WasmJs::GetWasmTableFunctions( 1402 table_instance.js_wrappers = Handle<FixedArray>(
1478 isolate_, table_instance.table_object); 1403 table_instance.table_object->get_functions(), isolate_);
1479 1404
1480 // TODO(titzer): import table size must match exactly for now. 1405 // TODO(titzer): import table size must match exactly for now.
1481 int table_size = table_instance.js_wrappers->length(); 1406 int table_size = table_instance.js_wrappers->length();
1482 if (table_size != static_cast<int>(table.min_size)) { 1407 if (table_size != static_cast<int>(table.min_size)) {
1483 thrower_->TypeError( 1408 thrower_->TypeError(
1484 "table import %d is wrong size (%d), expected %u", index, 1409 "table import %d is wrong size (%d), expected %u", index,
1485 table_size, table.min_size); 1410 table_size, table.min_size);
1486 return -1; 1411 return -1;
1487 } 1412 }
1488 1413
(...skipping 25 matching lines...) Expand all
1514 num_imported_tables++; 1439 num_imported_tables++;
1515 break; 1440 break;
1516 } 1441 }
1517 case kExternalMemory: { 1442 case kExternalMemory: {
1518 Handle<Object> object = result.ToHandleChecked(); 1443 Handle<Object> object = result.ToHandleChecked();
1519 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { 1444 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) {
1520 ReportFFIError("memory import must be a WebAssembly.Memory object", 1445 ReportFFIError("memory import must be a WebAssembly.Memory object",
1521 index, module_name, function_name); 1446 index, module_name, function_name);
1522 return -1; 1447 return -1;
1523 } 1448 }
1524 instance->SetInternalField(kWasmMemObject, *object); 1449 auto memory = Handle<WasmMemoryObject>::cast(object);
1525 memory_ = WasmJs::GetWasmMemoryArrayBuffer(isolate_, object); 1450 instance->set_memory_object(*memory);
1451 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_);
1526 break; 1452 break;
1527 } 1453 }
1528 case kExternalGlobal: { 1454 case kExternalGlobal: {
1529 // Global imports are converted to numbers and written into the 1455 // Global imports are converted to numbers and written into the
1530 // {globals_} array buffer. 1456 // {globals_} array buffer.
1531 Handle<Object> object = result.ToHandleChecked(); 1457 Handle<Object> object = result.ToHandleChecked();
1532 MaybeHandle<Object> number = Object::ToNumber(object); 1458 MaybeHandle<Object> number = Object::ToNumber(object);
1533 if (number.is_null()) { 1459 if (number.is_null()) {
1534 ReportFFIError("global import could not be converted to number", 1460 ReportFFIError("global import could not be converted to number",
1535 index, module_name, function_name); 1461 index, module_name, function_name);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 1529
1604 if (mem_buffer.is_null()) { 1530 if (mem_buffer.is_null()) {
1605 thrower_->RangeError("Out of memory: wasm memory"); 1531 thrower_->RangeError("Out of memory: wasm memory");
1606 } 1532 }
1607 return mem_buffer; 1533 return mem_buffer;
1608 } 1534 }
1609 1535
1610 // Process the exports, creating wrappers for functions, tables, memories, 1536 // Process the exports, creating wrappers for functions, tables, memories,
1611 // and globals. 1537 // and globals.
1612 void ProcessExports(Handle<FixedArray> code_table, 1538 void ProcessExports(Handle<FixedArray> code_table,
1613 Handle<JSObject> instance) { 1539 Handle<WasmInstanceObject> instance) {
1614 bool needs_wrappers = module_->num_exported_functions > 0; 1540 bool needs_wrappers = module_->num_exported_functions > 0;
1615 for (auto table_instance : table_instances_) { 1541 for (auto table_instance : table_instances_) {
1616 if (!table_instance.js_wrappers.is_null()) { 1542 if (!table_instance.js_wrappers.is_null()) {
1617 needs_wrappers = true; 1543 needs_wrappers = true;
1618 break; 1544 break;
1619 } 1545 }
1620 } 1546 }
1621 for (auto table : module_->function_tables) { 1547 for (auto table : module_->function_tables) {
1622 if (table.exported) { 1548 if (table.exported) {
1623 needs_wrappers = true; 1549 needs_wrappers = true;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 case kExternalFunction: { 1582 case kExternalFunction: {
1657 // Wrap and export the code as a JSFunction. 1583 // Wrap and export the code as a JSFunction.
1658 WasmFunction& function = module_->functions[exp.index]; 1584 WasmFunction& function = module_->functions[exp.index];
1659 int func_index = 1585 int func_index =
1660 static_cast<int>(module_->functions.size() + export_index); 1586 static_cast<int>(module_->functions.size() + export_index);
1661 Handle<JSFunction> js_function = js_wrappers_[exp.index]; 1587 Handle<JSFunction> js_function = js_wrappers_[exp.index];
1662 if (js_function.is_null()) { 1588 if (js_function.is_null()) {
1663 // Wrap the exported code as a JSFunction. 1589 // Wrap the exported code as a JSFunction.
1664 Handle<Code> export_code = 1590 Handle<Code> export_code =
1665 code_table->GetValueChecked<Code>(isolate_, func_index); 1591 code_table->GetValueChecked<Code>(isolate_, func_index);
1666 js_function = WrapExportCodeAsJSFunction( 1592 js_function = WasmExportedFunction::New(
1667 isolate_, export_code, name, function.sig, function.func_index, 1593 isolate_, instance, name, export_code,
1668 instance); 1594 static_cast<int>(function.sig->parameter_count()),
1595 function.func_index);
1669 js_wrappers_[exp.index] = js_function; 1596 js_wrappers_[exp.index] = js_function;
1670 } 1597 }
1671 desc.set_value(js_function); 1598 desc.set_value(js_function);
1672 export_index++; 1599 export_index++;
1673 break; 1600 break;
1674 } 1601 }
1675 case kExternalTable: { 1602 case kExternalTable: {
1676 // Export a table as a WebAssembly.Table object. 1603 // Export a table as a WebAssembly.Table object.
1677 TableInstance& table_instance = table_instances_[exp.index]; 1604 TableInstance& table_instance = table_instances_[exp.index];
1678 WasmIndirectFunctionTable& table = 1605 WasmIndirectFunctionTable& table =
1679 module_->function_tables[exp.index]; 1606 module_->function_tables[exp.index];
1680 if (table_instance.table_object.is_null()) { 1607 if (table_instance.table_object.is_null()) {
1681 table_instance.table_object = WasmJs::CreateWasmTableObject( 1608 uint32_t maximum =
1682 isolate_, table.min_size, table.has_max, table.max_size, 1609 table.has_max ? table.max_size : WasmModule::kV8MaxTableSize;
1683 &table_instance.js_wrappers); 1610 table_instance.table_object = WasmTableObject::New(
1611 isolate_, table.min_size, maximum, &table_instance.js_wrappers);
1684 } 1612 }
1685 desc.set_value(table_instance.table_object); 1613 desc.set_value(table_instance.table_object);
1686 break; 1614 break;
1687 } 1615 }
1688 case kExternalMemory: { 1616 case kExternalMemory: {
1689 // Export the memory as a WebAssembly.Memory object. 1617 // Export the memory as a WebAssembly.Memory object.
1690 Handle<Object> memory_object( 1618 Handle<WasmMemoryObject> memory_object;
1691 instance->GetInternalField(kWasmMemObject), isolate_); 1619 if (!instance->has_memory_object()) {
1692 if (memory_object->IsUndefined(isolate_)) {
1693 // If there was no imported WebAssembly.Memory object, create one. 1620 // If there was no imported WebAssembly.Memory object, create one.
1694 Handle<JSArrayBuffer> buffer( 1621 Handle<JSArrayBuffer> buffer(instance->get_memory_buffer(),
1695 JSArrayBuffer::cast( 1622 isolate_);
1696 instance->GetInternalField(kWasmMemArrayBuffer)), 1623 memory_object = WasmMemoryObject::New(
1697 isolate_); 1624 isolate_, buffer,
1698 memory_object = WasmJs::CreateWasmMemoryObject( 1625 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1);
1699 isolate_, buffer, (module_->max_mem_pages != 0), 1626 instance->set_memory_object(*memory_object);
1700 module_->max_mem_pages); 1627 } else {
1701 instance->SetInternalField(kWasmMemObject, *memory_object); 1628 memory_object = Handle<WasmMemoryObject>(
1629 instance->get_memory_object(), isolate_);
1702 } 1630 }
1703 1631
1704 desc.set_value(memory_object); 1632 desc.set_value(memory_object);
1705 break; 1633 break;
1706 } 1634 }
1707 case kExternalGlobal: { 1635 case kExternalGlobal: {
1708 // Export the value of the global variable as a number. 1636 // Export the value of the global variable as a number.
1709 WasmGlobal& global = module_->globals[exp.index]; 1637 WasmGlobal& global = module_->globals[exp.index];
1710 double num = 0; 1638 double num = 0;
1711 switch (global.type) { 1639 switch (global.type) {
(...skipping 21 matching lines...) Expand all
1733 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); 1661 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR);
1734 if (!status.IsJust()) { 1662 if (!status.IsJust()) {
1735 thrower_->TypeError("export of %.*s failed.", name->length(), 1663 thrower_->TypeError("export of %.*s failed.", name->length(),
1736 name->ToCString().get()); 1664 name->ToCString().get());
1737 return; 1665 return;
1738 } 1666 }
1739 } 1667 }
1740 } 1668 }
1741 1669
1742 void InitializeTables(Handle<FixedArray> code_table, 1670 void InitializeTables(Handle<FixedArray> code_table,
1743 Handle<JSObject> instance) { 1671 Handle<WasmInstanceObject> instance) {
1744 Handle<FixedArray> old_function_tables = 1672 Handle<FixedArray> old_function_tables =
1745 compiled_module_->function_tables(); 1673 compiled_module_->function_tables();
1746 int function_table_count = 1674 int function_table_count =
1747 static_cast<int>(module_->function_tables.size()); 1675 static_cast<int>(module_->function_tables.size());
1748 Handle<FixedArray> new_function_tables = 1676 Handle<FixedArray> new_function_tables =
1749 isolate_->factory()->NewFixedArray(function_table_count); 1677 isolate_->factory()->NewFixedArray(function_table_count);
1750 for (int index = 0; index < function_table_count; ++index) { 1678 for (int index = 0; index < function_table_count; ++index) {
1751 WasmIndirectFunctionTable& table = module_->function_tables[index]; 1679 WasmIndirectFunctionTable& table = module_->function_tables[index];
1752 TableInstance& table_instance = table_instances_[index]; 1680 TableInstance& table_instance = table_instances_[index];
1753 int table_size = static_cast<int>(table.min_size); 1681 int table_size = static_cast<int>(table.min_size);
1754 1682
1755 if (table_instance.dispatch_table.is_null()) { 1683 if (table_instance.dispatch_table.is_null()) {
1756 // Create a new dispatch table if necessary. 1684 // Create a new dispatch table if necessary.
1757 table_instance.dispatch_table = 1685 table_instance.dispatch_table =
1758 isolate_->factory()->NewFixedArray(table_size * 2); 1686 isolate_->factory()->NewFixedArray(table_size * 2);
1759 for (int i = 0; i < table_size; ++i) { 1687 for (int i = 0; i < table_size; ++i) {
1760 // Fill the table with invalid signature indexes so that 1688 // Fill the table with invalid signature indexes so that
1761 // uninitialized entries will always fail the signature check. 1689 // uninitialized entries will always fail the signature check.
1762 table_instance.dispatch_table->set(i, Smi::FromInt(kInvalidSigIndex)); 1690 table_instance.dispatch_table->set(i, Smi::FromInt(kInvalidSigIndex));
1763 } 1691 }
1764 } 1692 }
1765 1693
1766 new_function_tables->set(static_cast<int>(index), 1694 new_function_tables->set(static_cast<int>(index),
1767 *table_instance.dispatch_table); 1695 *table_instance.dispatch_table);
1768 1696
1769 Handle<FixedArray> all_dispatch_tables; 1697 Handle<FixedArray> all_dispatch_tables;
1770 if (!table_instance.table_object.is_null()) { 1698 if (!table_instance.table_object.is_null()) {
1771 // Get the existing dispatch table(s) with the WebAssembly.Table object. 1699 // Get the existing dispatch table(s) with the WebAssembly.Table object.
1772 all_dispatch_tables = WasmJs::AddWasmTableDispatchTable( 1700 all_dispatch_tables = WasmTableObject::AddDispatchTable(
1773 isolate_, table_instance.table_object, Handle<JSObject>::null(), 1701 isolate_, table_instance.table_object,
1774 index, Handle<FixedArray>::null()); 1702 Handle<WasmInstanceObject>::null(), index,
1703 Handle<FixedArray>::null());
1775 } 1704 }
1776 1705
1777 // TODO(titzer): this does redundant work if there are multiple tables, 1706 // TODO(titzer): this does redundant work if there are multiple tables,
1778 // since initializations are not sorted by table index. 1707 // since initializations are not sorted by table index.
1779 for (auto table_init : module_->table_inits) { 1708 for (auto table_init : module_->table_inits) {
1780 uint32_t base = EvalUint32InitExpr(table_init.offset); 1709 uint32_t base = EvalUint32InitExpr(table_init.offset);
1781 if (base > static_cast<uint32_t>(table_size) || 1710 if (base > static_cast<uint32_t>(table_size) ||
1782 (base + table_init.entries.size() > 1711 (base + table_init.entries.size() >
1783 static_cast<uint32_t>(table_size))) { 1712 static_cast<uint32_t>(table_size))) {
1784 thrower_->CompileError("table initializer is out of bounds"); 1713 thrower_->CompileError("table initializer is out of bounds");
(...skipping 24 matching lines...) Expand all
1809 temp_instance.mem_start = nullptr; 1738 temp_instance.mem_start = nullptr;
1810 temp_instance.globals_start = nullptr; 1739 temp_instance.globals_start = nullptr;
1811 1740
1812 ModuleEnv module_env; 1741 ModuleEnv module_env;
1813 module_env.module = module_; 1742 module_env.module = module_;
1814 module_env.instance = &temp_instance; 1743 module_env.instance = &temp_instance;
1815 module_env.origin = module_->origin; 1744 module_env.origin = module_->origin;
1816 1745
1817 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( 1746 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper(
1818 isolate_, &module_env, wasm_code, func_index); 1747 isolate_, &module_env, wasm_code, func_index);
1819 Handle<JSFunction> js_function = WrapExportCodeAsJSFunction( 1748 Handle<WasmExportedFunction> js_function =
1820 isolate_, wrapper_code, isolate_->factory()->empty_string(), 1749 WasmExportedFunction::New(
1821 function->sig, func_index, instance); 1750 isolate_, instance, isolate_->factory()->empty_string(),
1751 wrapper_code,
1752 static_cast<int>(function->sig->parameter_count()),
1753 func_index);
1822 js_wrappers_[func_index] = js_function; 1754 js_wrappers_[func_index] = js_function;
1823 } 1755 }
1824 table_instance.js_wrappers->set(table_index, 1756 table_instance.js_wrappers->set(table_index,
1825 *js_wrappers_[func_index]); 1757 *js_wrappers_[func_index]);
1826 1758
1827 UpdateDispatchTablesInternal(isolate_, all_dispatch_tables, 1759 UpdateDispatchTablesInternal(isolate_, all_dispatch_tables,
1828 table_index, function, wasm_code); 1760 table_index, function, wasm_code);
1829 } 1761 }
1830 } 1762 }
1831 } 1763 }
1832 1764
1833 // TODO(titzer): we add the new dispatch table at the end to avoid 1765 // TODO(titzer): we add the new dispatch table at the end to avoid
1834 // redundant work and also because the new instance is not yet fully 1766 // redundant work and also because the new instance is not yet fully
1835 // initialized. 1767 // initialized.
1836 if (!table_instance.table_object.is_null()) { 1768 if (!table_instance.table_object.is_null()) {
1837 // Add the new dispatch table to the WebAssembly.Table object. 1769 // Add the new dispatch table to the WebAssembly.Table object.
1838 all_dispatch_tables = WasmJs::AddWasmTableDispatchTable( 1770 all_dispatch_tables = WasmTableObject::AddDispatchTable(
1839 isolate_, table_instance.table_object, instance, index, 1771 isolate_, table_instance.table_object, instance, index,
1840 table_instance.dispatch_table); 1772 table_instance.dispatch_table);
1841 } 1773 }
1842 } 1774 }
1843 // Patch all code that has references to the old indirect tables. 1775 // Patch all code that has references to the old indirect tables.
1844 for (int i = 0; i < code_table->length(); ++i) { 1776 for (int i = 0; i < code_table->length(); ++i) {
1845 if (!code_table->get(i)->IsCode()) continue; 1777 if (!code_table->get(i)->IsCode()) continue;
1846 Handle<Code> code(Code::cast(code_table->get(i)), isolate_); 1778 Handle<Code> code(Code::cast(code_table->get(i)), isolate_);
1847 for (int j = 0; j < function_table_count; ++j) { 1779 for (int j = 0; j < function_table_count; ++j) {
1848 ReplaceReferenceInCode( 1780 ReplaceReferenceInCode(
1849 code, Handle<Object>(old_function_tables->get(j), isolate_), 1781 code, Handle<Object>(old_function_tables->get(j), isolate_),
1850 Handle<Object>(new_function_tables->get(j), isolate_)); 1782 Handle<Object>(new_function_tables->get(j), isolate_));
1851 } 1783 }
1852 } 1784 }
1853 compiled_module_->set_function_tables(new_function_tables); 1785 compiled_module_->set_function_tables(new_function_tables);
1854 } 1786 }
1855 }; 1787 };
1856 1788
1857 // Instantiates a WASM module, creating a WebAssembly.Instance from a 1789 // Instantiates a WASM module, creating a WebAssembly.Instance from a
1858 // WebAssembly.Module. 1790 // WebAssembly.Module.
1859 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, 1791 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
1860 ErrorThrower* thrower, 1792 ErrorThrower* thrower,
1861 Handle<JSObject> wasm_module, 1793 Handle<JSObject> wasm_module,
1862 Handle<JSReceiver> ffi, 1794 Handle<JSReceiver> ffi,
1863 Handle<JSArrayBuffer> memory) { 1795 Handle<JSArrayBuffer> memory) {
1864 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); 1796 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
1865 return builder.Build(); 1797 return builder.Build();
1866 } 1798 }
1867 1799
1868 Handle<WasmCompiledModule> WasmCompiledModule::New(
1869 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper) {
1870 Handle<FixedArray> ret =
1871 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED);
1872 // WasmCompiledModule::cast would fail since module bytes are not set yet.
1873 Handle<WasmCompiledModule> compiled_module(
1874 reinterpret_cast<WasmCompiledModule*>(*ret), isolate);
1875 compiled_module->InitId();
1876 compiled_module->set_module_wrapper(module_wrapper);
1877 return compiled_module;
1878 }
1879
1880 void WasmCompiledModule::InitId() {
1881 #if DEBUG
1882 static uint32_t instance_id_counter = 0;
1883 set(kID_instance_id, Smi::FromInt(instance_id_counter++));
1884 TRACE("New compiled module id: %d\n", instance_id());
1885 #endif
1886 }
1887
1888 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) {
1889 if (!obj->IsFixedArray()) return false;
1890 FixedArray* arr = FixedArray::cast(obj);
1891 if (arr->length() != PropertyIndices::Count) return false;
1892 Isolate* isolate = arr->GetIsolate();
1893 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \
1894 if (!arr->get(kID_##NAME)->IsSmi()) return false;
1895 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \
1896 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \
1897 !arr->get(kID_##NAME)->Is##TYPE()) \
1898 return false;
1899 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME)
1900 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME)
1901 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME)
1902 WCM_PROPERTY_TABLE(WCM_CHECK)
1903 #undef WCM_CHECK
1904
1905 // All checks passed.
1906 return true;
1907 }
1908
1909 void WasmCompiledModule::PrintInstancesChain() {
1910 #if DEBUG
1911 if (!FLAG_trace_wasm_instances) return;
1912 for (WasmCompiledModule* current = this; current != nullptr;) {
1913 PrintF("->%d", current->instance_id());
1914 if (current->ptr_to_weak_next_instance() == nullptr) break;
1915 CHECK(!current->ptr_to_weak_next_instance()->cleared());
1916 current =
1917 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value());
1918 }
1919 PrintF("\n");
1920 #endif
1921 }
1922
1923 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, 1800 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate,
1924 Handle<Object> instance, 1801 Handle<Object> object,
1925 uint32_t func_index) { 1802 uint32_t func_index) {
1926 if (!instance->IsUndefined(isolate)) { 1803 if (!object->IsUndefined(isolate)) {
1927 DCHECK(IsWasmInstance(*instance)); 1804 auto instance = Handle<WasmInstanceObject>::cast(object);
1928 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); 1805 WasmModule* module = instance->module();
1929 WasmFunction& function = module->functions[func_index]; 1806 WasmFunction& function = module->functions[func_index];
1930 Handle<WasmCompiledModule> compiled_module(GetCompiledModule(*instance), 1807 Handle<WasmCompiledModule> compiled_module(instance->get_compiled_module(),
1931 isolate); 1808 isolate);
1932 MaybeHandle<String> string = ExtractStringFromModuleBytes( 1809 MaybeHandle<String> string = ExtractStringFromModuleBytes(
1933 isolate, compiled_module, function.name_offset, function.name_length); 1810 isolate, compiled_module, function.name_offset, function.name_length);
1934 if (!string.is_null()) return string.ToHandleChecked(); 1811 if (!string.is_null()) return string.ToHandleChecked();
1935 } 1812 }
1936 return isolate->factory()->null_value(); 1813 return isolate->factory()->null_value();
1937 } 1814 }
1938 1815
1939 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate, 1816 Handle<String> wasm::GetWasmFunctionName(Isolate* isolate,
1940 Handle<Object> instance, 1817 Handle<Object> instance,
1941 uint32_t func_index) { 1818 uint32_t func_index) {
1942 Handle<Object> name_or_null = 1819 Handle<Object> name_or_null =
1943 GetWasmFunctionNameOrNull(isolate, instance, func_index); 1820 GetWasmFunctionNameOrNull(isolate, instance, func_index);
1944 if (!name_or_null->IsNull(isolate)) { 1821 if (!name_or_null->IsNull(isolate)) {
1945 return Handle<String>::cast(name_or_null); 1822 return Handle<String>::cast(name_or_null);
1946 } 1823 }
1947 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>"); 1824 return isolate->factory()->NewStringFromStaticChars("<WASM UNNAMED>");
1948 } 1825 }
1949 1826
1950 bool wasm::IsWasmInstance(Object* object) { 1827 bool wasm::IsWasmInstance(Object* object) {
1951 if (!object->IsJSObject()) return false; 1828 return WasmInstanceObject::IsWasmInstanceObject(object);
1952
1953 JSObject* obj = JSObject::cast(object);
1954 Isolate* isolate = obj->GetIsolate();
1955 if (obj->GetInternalFieldCount() != kWasmInstanceInternalFieldCount) {
1956 return false;
1957 }
1958
1959 Object* mem = obj->GetInternalField(kWasmMemArrayBuffer);
1960 if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) ||
1961 !WasmCompiledModule::IsWasmCompiledModule(
1962 obj->GetInternalField(kWasmCompiledModule))) {
1963 return false;
1964 }
1965
1966 // All checks passed.
1967 return true;
1968 } 1829 }
1969 1830
1970 WasmCompiledModule* wasm::GetCompiledModule(Object* instance) { 1831 WasmCompiledModule* wasm::GetCompiledModule(Object* object) {
1971 DCHECK(IsWasmInstance(instance)); 1832 return WasmInstanceObject::cast(object)->get_compiled_module();
1972 return WasmCompiledModule::cast(
1973 JSObject::cast(instance)->GetInternalField(kWasmCompiledModule));
1974 } 1833 }
1975 1834
1976 bool wasm::WasmIsAsmJs(Object* instance, Isolate* isolate) { 1835 bool wasm::WasmIsAsmJs(Object* object, Isolate* isolate) {
1977 return IsWasmInstance(instance) && 1836 return IsWasmInstance(object) &&
1978 GetCompiledModule(JSObject::cast(instance))->has_asm_js_script(); 1837 WasmInstanceObject::cast(object)
1838 ->get_compiled_module()
1839 ->has_asm_js_script();
1979 } 1840 }
1980 1841
1981 Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> instance) { 1842 Handle<Script> wasm::GetAsmWasmScript(Handle<JSObject> object) {
1982 DCHECK(IsWasmInstance(*instance)); 1843 return Handle<WasmInstanceObject>::cast(object)
1983 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); 1844 ->get_compiled_module()
1984 return compiled_module->asm_js_script(); 1845 ->asm_js_script();
1985 } 1846 }
1986 1847
1987 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, 1848 int wasm::GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index,
1988 int byte_offset) { 1849 int byte_offset) {
1989 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance), 1850 return WasmDebugInfo::GetAsmJsSourcePosition(GetDebugInfo(instance),
1990 func_index, byte_offset); 1851 func_index, byte_offset);
1991 } 1852 }
1992 1853
1993 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> instance) { 1854 Handle<SeqOneByteString> wasm::GetWasmBytes(Handle<JSObject> object) {
1994 DCHECK(IsWasmInstance(*instance)); 1855 return Handle<WasmInstanceObject>::cast(object)
1995 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); 1856 ->get_compiled_module()
1996 return compiled_module->module_bytes(); 1857 ->module_bytes();
1997 } 1858 }
1998 1859
1999 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> instance) { 1860 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) {
2000 Handle<Object> info(instance->GetInternalField(kWasmDebugInfo), 1861 auto instance = Handle<WasmInstanceObject>::cast(object);
2001 instance->GetIsolate()); 1862 if (instance->has_debug_info()) {
2002 if (!info->IsUndefined(instance->GetIsolate())) 1863 Handle<WasmDebugInfo> info(instance->get_debug_info(),
2003 return Handle<WasmDebugInfo>::cast(info); 1864 instance->GetIsolate());
1865 return info;
1866 }
2004 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance); 1867 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance);
2005 instance->SetInternalField(kWasmDebugInfo, *new_info); 1868 instance->set_debug_info(*new_info);
2006 return new_info; 1869 return new_info;
2007 } 1870 }
2008 1871
2009 int wasm::GetNumberOfFunctions(Handle<JSObject> instance) { 1872 int wasm::GetNumberOfFunctions(Handle<JSObject> object) {
2010 return static_cast<int>(GetCppModule(instance)->functions.size()); 1873 return static_cast<int>(
2011 } 1874 Handle<WasmInstanceObject>::cast(object)->module()->functions.size());
2012
2013 Handle<JSObject> wasm::CreateWasmModuleObject(
2014 Isolate* isolate, Handle<WasmCompiledModule> compiled_module,
2015 ModuleOrigin origin) {
2016 Handle<JSObject> wasm_module;
2017 if (origin == ModuleOrigin::kWasmOrigin) {
2018 Handle<JSFunction> module_cons(
2019 isolate->native_context()->wasm_module_constructor());
2020 wasm_module = isolate->factory()->NewJSObject(module_cons);
2021 } else {
2022 DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
2023 Handle<Map> map = isolate->factory()->NewMap(
2024 JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
2025 wasm_module = isolate->factory()->NewJSObjectFromMap(map, TENURED);
2026 }
2027 wasm_module->SetInternalField(0, *compiled_module);
2028 if (origin == ModuleOrigin::kWasmOrigin) {
2029 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
2030 Object::SetProperty(wasm_module, module_sym, wasm_module, STRICT).Check();
2031 }
2032 Handle<WeakCell> link_to_module =
2033 isolate->factory()->NewWeakCell(wasm_module);
2034 compiled_module->set_weak_wasm_module(link_to_module);
2035 return wasm_module;
2036 } 1875 }
2037 1876
2038 // TODO(clemensh): origin can be inferred from asm_js_script; remove it. 1877 // TODO(clemensh): origin can be inferred from asm_js_script; remove it.
2039 MaybeHandle<JSObject> wasm::CreateModuleObjectFromBytes( 1878 MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
2040 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, 1879 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
2041 ModuleOrigin origin, Handle<Script> asm_js_script, 1880 ModuleOrigin origin, Handle<Script> asm_js_script,
2042 const byte* asm_js_offset_tables_start, 1881 const byte* asm_js_offset_tables_start,
2043 const byte* asm_js_offset_tables_end) { 1882 const byte* asm_js_offset_tables_end) {
2044 MaybeHandle<JSObject> nothing; 1883 MaybeHandle<WasmModuleObject> nothing;
2045 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); 1884 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
2046 if (result.failed()) { 1885 if (result.failed()) {
2047 if (result.val) delete result.val; 1886 if (result.val) delete result.val;
2048 thrower->CompileFailed("Wasm decoding failed", result); 1887 thrower->CompileFailed("Wasm decoding failed", result);
2049 return nothing; 1888 return nothing;
2050 } 1889 }
2051 // The {module_wrapper} will take ownership of the {WasmModule} object, 1890 // The {module_wrapper} will take ownership of the {WasmModule} object,
2052 // and it will be destroyed when the GC reclaims the wrapper object. 1891 // and it will be destroyed when the GC reclaims the wrapper object.
2053 Handle<WasmModuleWrapper> module_wrapper = 1892 Handle<WasmModuleWrapper> module_wrapper =
2054 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); 1893 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val));
(...skipping 15 matching lines...) Expand all
2070 size_t offset_tables_len = 1909 size_t offset_tables_len =
2071 asm_js_offset_tables_end - asm_js_offset_tables_start; 1910 asm_js_offset_tables_end - asm_js_offset_tables_start;
2072 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); 1911 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len);
2073 Handle<ByteArray> offset_tables = 1912 Handle<ByteArray> offset_tables =
2074 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); 1913 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len));
2075 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, 1914 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start,
2076 offset_tables_len); 1915 offset_tables_len);
2077 compiled_module->set_asm_js_offset_tables(offset_tables); 1916 compiled_module->set_asm_js_offset_tables(offset_tables);
2078 } 1917 }
2079 1918
2080 return CreateWasmModuleObject(isolate, compiled_module, origin); 1919 return WasmModuleObject::New(isolate, compiled_module);
2081 } 1920 }
2082 1921
2083 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, 1922 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
2084 const byte* end, ErrorThrower* thrower, 1923 const byte* end, ErrorThrower* thrower,
2085 ModuleOrigin origin) { 1924 ModuleOrigin origin) {
2086 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); 1925 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
2087 if (result.val) { 1926 if (result.val) {
2088 delete result.val; 1927 delete result.val;
2089 } else { 1928 } else {
2090 DCHECK(!result.ok()); 1929 DCHECK(!result.ok());
2091 } 1930 }
2092 return result.ok(); 1931 return result.ok();
2093 } 1932 }
2094 1933
2095 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(Isolate* isolate, 1934 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(Isolate* isolate,
2096 Handle<JSObject> instance) { 1935 Handle<JSObject> object) {
2097 Object* mem = instance->GetInternalField(kWasmMemArrayBuffer); 1936 auto instance = Handle<WasmInstanceObject>::cast(object);
2098 DCHECK(IsWasmInstance(*instance)); 1937 if (instance->has_memory_buffer()) {
2099 if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>(); 1938 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate);
2100 return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem)); 1939 }
1940 return MaybeHandle<JSArrayBuffer>();
2101 } 1941 }
2102 1942
2103 void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) { 1943 void SetInstanceMemory(Handle<JSObject> object, JSArrayBuffer* buffer) {
2104 DisallowHeapAllocation no_gc; 1944 DisallowHeapAllocation no_gc;
2105 DCHECK(IsWasmInstance(*instance)); 1945 auto instance = Handle<WasmInstanceObject>::cast(object);
2106 instance->SetInternalField(kWasmMemArrayBuffer, buffer); 1946 instance->set_memory_buffer(buffer);
2107 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); 1947 instance->get_compiled_module()->set_ptr_to_memory(buffer);
2108 compiled_module->set_ptr_to_memory(buffer);
2109 } 1948 }
2110 1949
2111 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, 1950 int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
2112 Handle<JSObject> instance) { 1951 Handle<JSObject> instance) {
2113 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = 1952 MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
2114 GetInstanceMemory(isolate, instance); 1953 GetInstanceMemory(isolate, instance);
2115 Handle<JSArrayBuffer> buffer; 1954 Handle<JSArrayBuffer> buffer;
2116 if (!maybe_mem_buffer.ToHandle(&buffer)) { 1955 if (!maybe_mem_buffer.ToHandle(&buffer)) {
2117 return 0; 1956 return 0;
2118 } else { 1957 } else {
2119 return buffer->byte_length()->Number() / WasmModule::kPageSize; 1958 return buffer->byte_length()->Number() / WasmModule::kPageSize;
2120 } 1959 }
2121 } 1960 }
2122 1961
2123 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { 1962 uint32_t GetMaxInstanceMemorySize(Isolate* isolate,
2124 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), 1963 Handle<WasmInstanceObject> instance) {
2125 isolate); 1964 if (instance->has_memory_object()) {
2126 if (!memory_object->IsUndefined(isolate)) { 1965 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(),
2127 uint32_t mem_obj_max = 1966 isolate);
2128 WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object); 1967
2129 if (mem_obj_max != 0) return mem_obj_max; 1968 int maximum = memory_object->maximum_pages();
1969 if (maximum > 0) return static_cast<uint32_t>(maximum);
2130 } 1970 }
2131 uint32_t compiled_max_pages = GetCompiledModule(*instance)->max_mem_pages(); 1971 uint32_t compiled_max_pages =
1972 instance->get_compiled_module()->max_mem_pages();
2132 isolate->counters()->wasm_max_mem_pages_count()->AddSample( 1973 isolate->counters()->wasm_max_mem_pages_count()->AddSample(
2133 compiled_max_pages); 1974 compiled_max_pages);
2134 if (compiled_max_pages != 0) return compiled_max_pages; 1975 if (compiled_max_pages != 0) return compiled_max_pages;
2135 return WasmModule::kV8MaxPages; 1976 return WasmModule::kV8MaxPages;
2136 } 1977 }
2137 1978
2138 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, 1979 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> object,
2139 uint32_t pages) { 1980 uint32_t pages) {
2140 if (!IsWasmInstance(*instance)) return -1; 1981 if (!IsWasmInstance(*object)) return -1;
1982 auto instance = Handle<WasmInstanceObject>::cast(object);
2141 if (pages == 0) return GetInstanceMemorySize(isolate, instance); 1983 if (pages == 0) return GetInstanceMemorySize(isolate, instance);
2142 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); 1984 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
2143 1985
2144 Address old_mem_start = nullptr; 1986 Address old_mem_start = nullptr;
2145 uint32_t old_size = 0, new_size = 0; 1987 uint32_t old_size = 0, new_size = 0;
2146 1988
2147 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = 1989 MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
2148 GetInstanceMemory(isolate, instance); 1990 GetInstanceMemory(isolate, instance);
2149 Handle<JSArrayBuffer> old_buffer; 1991 Handle<JSArrayBuffer> old_buffer;
2150 if (!maybe_mem_buffer.ToHandle(&old_buffer) || 1992 if (!maybe_mem_buffer.ToHandle(&old_buffer) ||
(...skipping 17 matching lines...) Expand all
2168 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) { 2010 WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) {
2169 return -1; 2011 return -1;
2170 } 2012 }
2171 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); 2013 Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size);
2172 if (buffer.is_null()) return -1; 2014 if (buffer.is_null()) return -1;
2173 Address new_mem_start = static_cast<Address>(buffer->backing_store()); 2015 Address new_mem_start = static_cast<Address>(buffer->backing_store());
2174 if (old_size != 0) { 2016 if (old_size != 0) {
2175 memcpy(new_mem_start, old_mem_start, old_size); 2017 memcpy(new_mem_start, old_mem_start, old_size);
2176 } 2018 }
2177 SetInstanceMemory(instance, *buffer); 2019 SetInstanceMemory(instance, *buffer);
2178 Handle<FixedArray> code_table = GetCompiledModule(*instance)->code_table(); 2020 Handle<FixedArray> code_table = instance->get_compiled_module()->code_table();
2179 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start, 2021 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start,
2180 old_size, new_size); 2022 old_size, new_size);
2181 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), 2023 if (instance->has_memory_object()) {
2182 isolate); 2024 instance->get_memory_object()->set_buffer(*buffer);
2183 if (!memory_object->IsUndefined(isolate)) {
2184 WasmJs::SetWasmMemoryArrayBuffer(isolate, memory_object, buffer);
2185 } 2025 }
2186 2026
2187 DCHECK(old_size % WasmModule::kPageSize == 0); 2027 DCHECK(old_size % WasmModule::kPageSize == 0);
2188 return (old_size / WasmModule::kPageSize); 2028 return (old_size / WasmModule::kPageSize);
2189 } 2029 }
2190 2030
2191 void testing::ValidateInstancesChain(Isolate* isolate, 2031 void testing::ValidateInstancesChain(Isolate* isolate,
2192 Handle<JSObject> wasm_module, 2032 Handle<JSObject> wasm_module,
2193 int instance_count) { 2033 int instance_count) {
2194 CHECK_GE(instance_count, 0); 2034 CHECK_GE(instance_count, 0);
(...skipping 27 matching lines...) Expand all
2222 WasmCompiledModule* compiled_module = 2062 WasmCompiledModule* compiled_module =
2223 WasmCompiledModule::cast(wasm_module->GetInternalField(0)); 2063 WasmCompiledModule::cast(wasm_module->GetInternalField(0));
2224 CHECK(compiled_module->has_weak_wasm_module()); 2064 CHECK(compiled_module->has_weak_wasm_module());
2225 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *wasm_module); 2065 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *wasm_module);
2226 CHECK(!compiled_module->has_weak_prev_instance()); 2066 CHECK(!compiled_module->has_weak_prev_instance());
2227 CHECK(!compiled_module->has_weak_next_instance()); 2067 CHECK(!compiled_module->has_weak_next_instance());
2228 CHECK(!compiled_module->has_weak_owning_instance()); 2068 CHECK(!compiled_module->has_weak_owning_instance());
2229 } 2069 }
2230 2070
2231 void testing::ValidateOrphanedInstance(Isolate* isolate, 2071 void testing::ValidateOrphanedInstance(Isolate* isolate,
2232 Handle<JSObject> wasm_module) { 2072 Handle<JSObject> object) {
2233 DisallowHeapAllocation no_gc; 2073 DisallowHeapAllocation no_gc;
2234 CHECK(IsWasmInstance(*wasm_module)); 2074 WasmInstanceObject* instance = WasmInstanceObject::cast(*object);
2235 WasmCompiledModule* compiled_module = GetCompiledModule(*wasm_module); 2075 WasmCompiledModule* compiled_module = instance->get_compiled_module();
2236 CHECK(compiled_module->has_weak_wasm_module()); 2076 CHECK(compiled_module->has_weak_wasm_module());
2237 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); 2077 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
2238 } 2078 }
2239 2079
2240 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate, 2080 void WasmCompiledModule::RecreateModuleWrapper(Isolate* isolate,
2241 Handle<FixedArray> array) { 2081 Handle<FixedArray> array) {
2242 Handle<WasmCompiledModule> compiled_module( 2082 Handle<WasmCompiledModule> compiled_module(
2243 reinterpret_cast<WasmCompiledModule*>(*array), isolate); 2083 reinterpret_cast<WasmCompiledModule*>(*array), isolate);
2244 2084
2245 WasmModule* module = nullptr; 2085 WasmModule* module = nullptr;
(...skipping 13 matching lines...) Expand all
2259 CHECK_NOT_NULL(result.val); 2099 CHECK_NOT_NULL(result.val);
2260 module = const_cast<WasmModule*>(result.val); 2100 module = const_cast<WasmModule*>(result.val);
2261 } 2101 }
2262 2102
2263 Handle<WasmModuleWrapper> module_wrapper = 2103 Handle<WasmModuleWrapper> module_wrapper =
2264 WasmModuleWrapper::New(isolate, module); 2104 WasmModuleWrapper::New(isolate, module);
2265 2105
2266 compiled_module->set_module_wrapper(module_wrapper); 2106 compiled_module->set_module_wrapper(module_wrapper);
2267 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); 2107 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
2268 } 2108 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | src/wasm/wasm-objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698