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

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: More dead code 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 29 matching lines...) Expand all
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
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