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

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

Issue 2591653002: [wasm] Introduce WasmSharedModuleData and refactor other objects (Closed)
Patch Set: Fix SLOW_DCHECK Created 3 years, 12 months 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/assembler-inl.h" 7 #include "src/assembler-inl.h"
8 #include "src/base/adapters.h" 8 #include "src/base/adapters.h"
9 #include "src/base/atomic-utils.h" 9 #include "src/base/atomic-utils.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 RecordStats(isolate, Code::cast(functions->get(i))); 275 RecordStats(isolate, Code::cast(functions->get(i)));
276 } 276 }
277 } 277 }
278 278
279 Address GetGlobalStartAddressFromCodeTemplate(Object* undefined, 279 Address GetGlobalStartAddressFromCodeTemplate(Object* undefined,
280 JSObject* object) { 280 JSObject* object) {
281 auto instance = WasmInstanceObject::cast(object); 281 auto instance = WasmInstanceObject::cast(object);
282 Address old_address = nullptr; 282 Address old_address = nullptr;
283 if (instance->has_globals_buffer()) { 283 if (instance->has_globals_buffer()) {
284 old_address = 284 old_address =
285 static_cast<Address>(instance->get_globals_buffer()->backing_store()); 285 static_cast<Address>(instance->globals_buffer()->backing_store());
286 } 286 }
287 return old_address; 287 return old_address;
288 } 288 }
289 289
290 void InitializeParallelCompilation( 290 void InitializeParallelCompilation(
291 Isolate* isolate, const std::vector<WasmFunction>& functions, 291 Isolate* isolate, const std::vector<WasmFunction>& functions,
292 std::vector<compiler::WasmCompilationUnit*>& compilation_units, 292 std::vector<compiler::WasmCompilationUnit*>& compilation_units,
293 ModuleBytesEnv& module_env, ErrorThrower* thrower) { 293 ModuleBytesEnv& module_env, ErrorThrower* thrower) {
294 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { 294 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) {
295 const WasmFunction* func = &functions[i]; 295 const WasmFunction* func = &functions[i];
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 } 544 }
545 compiled_module->reset_memory(); 545 compiled_module->reset_memory();
546 } 546 }
547 547
548 static void MemoryInstanceFinalizer(Isolate* isolate, 548 static void MemoryInstanceFinalizer(Isolate* isolate,
549 WasmInstanceObject* instance) { 549 WasmInstanceObject* instance) {
550 DisallowHeapAllocation no_gc; 550 DisallowHeapAllocation no_gc;
551 // If the memory object is destroyed, nothing needs to be done here. 551 // If the memory object is destroyed, nothing needs to be done here.
552 if (!instance->has_memory_object()) return; 552 if (!instance->has_memory_object()) return;
553 Handle<WasmInstanceWrapper> instance_wrapper = 553 Handle<WasmInstanceWrapper> instance_wrapper =
554 handle(instance->get_instance_wrapper()); 554 handle(instance->instance_wrapper());
555 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); 555 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
556 DCHECK(instance_wrapper->has_instance()); 556 DCHECK(instance_wrapper->has_instance());
557 bool has_prev = instance_wrapper->has_previous(); 557 bool has_prev = instance_wrapper->has_previous();
558 bool has_next = instance_wrapper->has_next(); 558 bool has_next = instance_wrapper->has_next();
559 Handle<WasmMemoryObject> memory_object(instance->get_memory_object()); 559 Handle<WasmMemoryObject> memory_object(instance->memory_object());
560 560
561 if (!has_prev && !has_next) { 561 if (!has_prev && !has_next) {
562 memory_object->ResetInstancesLink(isolate); 562 memory_object->ResetInstancesLink(isolate);
563 return; 563 return;
564 } else { 564 } else {
565 Handle<WasmInstanceWrapper> next_wrapper, prev_wrapper; 565 Handle<WasmInstanceWrapper> next_wrapper, prev_wrapper;
566 if (!has_prev) { 566 if (!has_prev) {
567 Handle<WasmInstanceWrapper> next_wrapper = 567 Handle<WasmInstanceWrapper> next_wrapper =
568 instance_wrapper->next_wrapper(); 568 instance_wrapper->next_wrapper();
569 next_wrapper->reset_previous_wrapper(); 569 next_wrapper->reset_previous_wrapper();
(...skipping 15 matching lines...) Expand all
585 // Reset to avoid dangling pointers 585 // Reset to avoid dangling pointers
586 instance_wrapper->reset(); 586 instance_wrapper->reset();
587 } 587 }
588 } 588 }
589 589
590 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { 590 static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
591 DisallowHeapAllocation no_gc; 591 DisallowHeapAllocation no_gc;
592 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter()); 592 JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
593 WasmInstanceObject* owner = reinterpret_cast<WasmInstanceObject*>(*p); 593 WasmInstanceObject* owner = reinterpret_cast<WasmInstanceObject*>(*p);
594 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate()); 594 Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
595 // Is a link to shared memory instances exists, update the list of memory 595 // If a link to shared memory instances exists, update the list of memory
596 // instances before the instance is destroyed. 596 // instances before the instance is destroyed.
597 if (owner->has_instance_wrapper()) MemoryInstanceFinalizer(isolate, owner); 597 if (owner->has_instance_wrapper()) MemoryInstanceFinalizer(isolate, owner);
598 WasmCompiledModule* compiled_module = owner->get_compiled_module(); 598 WasmCompiledModule* compiled_module = owner->compiled_module();
599 TRACE("Finalizing %d {\n", compiled_module->instance_id()); 599 TRACE("Finalizing %d {\n", compiled_module->instance_id());
600 DCHECK(compiled_module->has_weak_wasm_module()); 600 DCHECK(compiled_module->has_weak_wasm_module());
601 WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module(); 601 WeakCell* weak_wasm_module = compiled_module->ptr_to_weak_wasm_module();
602 602
603 // weak_wasm_module may have been cleared, meaning the module object 603 // weak_wasm_module may have been cleared, meaning the module object
604 // was GC-ed. In that case, there won't be any new instances created, 604 // was GC-ed. In that case, there won't be any new instances created,
605 // and we don't need to maintain the links between instances. 605 // and we don't need to maintain the links between instances.
606 if (!weak_wasm_module->cleared()) { 606 if (!weak_wasm_module->cleared()) {
607 JSObject* wasm_module = JSObject::cast(weak_wasm_module->value()); 607 JSObject* wasm_module = JSObject::cast(weak_wasm_module->value());
608 WasmCompiledModule* current_template = 608 WasmCompiledModule* current_template =
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 WasmModule* module = compiled_module->module(); 663 WasmModule* module = compiled_module->module();
664 if (func_index < 0 || 664 if (func_index < 0 ||
665 static_cast<size_t>(func_index) > module->functions.size()) { 665 static_cast<size_t>(func_index) > module->functions.size()) {
666 return {0, 0}; 666 return {0, 0};
667 } 667 }
668 WasmFunction& func = module->functions[func_index]; 668 WasmFunction& func = module->functions[func_index];
669 return {static_cast<int>(func.code_start_offset), 669 return {static_cast<int>(func.code_start_offset),
670 static_cast<int>(func.code_end_offset - func.code_start_offset)}; 670 static_cast<int>(func.code_end_offset - func.code_start_offset)};
671 } 671 }
672 672
673 Handle<Script> CreateWasmScript(Isolate* isolate,
674 const ModuleWireBytes& wire_bytes) {
675 Handle<Script> script =
676 isolate->factory()->NewScript(isolate->factory()->empty_string());
677 script->set_type(Script::TYPE_WASM);
678
679 int hash = StringHasher::HashSequentialString(
680 reinterpret_cast<const char*>(wire_bytes.module_bytes.start()),
681 wire_bytes.module_bytes.length(), kZeroHashSeed);
682
683 const int kBufferSize = 50;
684 char buffer[kBufferSize];
685 int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash);
686 DCHECK(url_chars >= 0 && url_chars < kBufferSize);
687 MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte(
688 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars),
689 TENURED);
690 script->set_source_url(*url_str.ToHandleChecked());
691
692 int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash);
693 DCHECK(name_chars >= 0 && name_chars < kBufferSize);
694 MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte(
695 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars),
696 TENURED);
697 script->set_name(*name_str.ToHandleChecked());
698
699 return script;
700 }
673 } // namespace 701 } // namespace
674 702
675 Handle<JSArrayBuffer> wasm::NewArrayBuffer(Isolate* isolate, size_t size, 703 Handle<JSArrayBuffer> wasm::NewArrayBuffer(Isolate* isolate, size_t size,
676 bool enable_guard_regions) { 704 bool enable_guard_regions) {
677 if (size > (kV8MaxWasmMemoryPages * WasmModule::kPageSize)) { 705 if (size > (kV8MaxWasmMemoryPages * WasmModule::kPageSize)) {
678 // TODO(titzer): lift restriction on maximum memory allocated here. 706 // TODO(titzer): lift restriction on maximum memory allocated here.
679 return Handle<JSArrayBuffer>::null(); 707 return Handle<JSArrayBuffer>::null();
680 } 708 }
681 709
682 enable_guard_regions = enable_guard_regions && kGuardRegionsSupported; 710 enable_guard_regions = enable_guard_regions && kGuardRegionsSupported;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, 825 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
798 int func_index) { 826 int func_index) {
799 return GetFunctionOffsetAndLength(compiled_module, func_index).first; 827 return GetFunctionOffsetAndLength(compiled_module, func_index).first;
800 } 828 }
801 829
802 WasmModule::WasmModule(Zone* owned) 830 WasmModule::WasmModule(Zone* owned)
803 : owned_zone(owned), pending_tasks(new base::Semaphore(0)) {} 831 : owned_zone(owned), pending_tasks(new base::Semaphore(0)) {}
804 832
805 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( 833 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
806 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, 834 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper,
807 ErrorThrower* thrower, const ModuleWireBytes& wire_bytes) const { 835 ErrorThrower* thrower, const ModuleWireBytes& wire_bytes,
836 Handle<Script> asm_js_script,
837 Vector<const byte> asm_js_offset_table_bytes) const {
808 Factory* factory = isolate->factory(); 838 Factory* factory = isolate->factory();
809 839
810 MaybeHandle<WasmCompiledModule> nothing; 840 MaybeHandle<WasmCompiledModule> nothing;
811 841
812 WasmInstance temp_instance(this); 842 WasmInstance temp_instance(this);
813 temp_instance.context = isolate->native_context(); 843 temp_instance.context = isolate->native_context();
814 temp_instance.mem_size = WasmModule::kPageSize * min_mem_pages; 844 temp_instance.mem_size = WasmModule::kPageSize * min_mem_pages;
815 temp_instance.mem_start = nullptr; 845 temp_instance.mem_start = nullptr;
816 temp_instance.globals_start = nullptr; 846 temp_instance.globals_start = nullptr;
817 847
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 i < temp_instance.function_code.size(); ++i) { 908 i < temp_instance.function_code.size(); ++i) {
879 Handle<Code> code = temp_instance.function_code[i]; 909 Handle<Code> code = temp_instance.function_code[i];
880 bool modified = LinkFunction(code, temp_instance.function_code); 910 bool modified = LinkFunction(code, temp_instance.function_code);
881 if (modified) { 911 if (modified) {
882 // TODO(mtrofin): do we need to flush the cache here? 912 // TODO(mtrofin): do we need to flush the cache here?
883 Assembler::FlushICache(isolate, code->instruction_start(), 913 Assembler::FlushICache(isolate, code->instruction_start(),
884 code->instruction_size()); 914 code->instruction_size());
885 } 915 }
886 } 916 }
887 917
918 // Create heap objects for script, module bytes and asm.js offset table to be
919 // stored in the shared module data.
920 Handle<Script> script;
921 Handle<ByteArray> asm_js_offset_table;
922 if (asm_js_script.is_null()) {
923 script = CreateWasmScript(isolate, wire_bytes);
924 } else {
925 script = asm_js_script;
926 asm_js_offset_table =
927 isolate->factory()->NewByteArray(asm_js_offset_table_bytes.length());
928 asm_js_offset_table->copy_in(0, asm_js_offset_table_bytes.start(),
929 asm_js_offset_table_bytes.length());
930 }
931 // TODO(wasm): only save the sections necessary to deserialize a
932 // {WasmModule}. E.g. function bodies could be omitted.
933 Handle<String> module_bytes =
934 factory->NewStringFromOneByte(wire_bytes.module_bytes, TENURED)
935 .ToHandleChecked();
936 DCHECK(module_bytes->IsSeqOneByteString());
937
938 // Create the shared module data.
939 // TODO(clemensh): For the same module (same bytes / same hash), we should
940 // only have one WasmSharedModuleData. Otherwise, we might only set
941 // breakpoints on a (potentially empty) subset of the instances.
942
943 Handle<WasmSharedModuleData> shared = WasmSharedModuleData::New(
944 isolate, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes),
945 script, asm_js_offset_table);
946
888 // Create the compiled module object, and populate with compiled functions 947 // Create the compiled module object, and populate with compiled functions
889 // and information needed at instantiation time. This object needs to be 948 // and information needed at instantiation time. This object needs to be
890 // serializable. Instantiation may occur off a deserialized version of this 949 // serializable. Instantiation may occur off a deserialized version of this
891 // object. 950 // object.
892 Handle<WasmCompiledModule> ret = 951 Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate, shared);
893 WasmCompiledModule::New(isolate, module_wrapper);
894 ret->set_code_table(code_table); 952 ret->set_code_table(code_table);
895 ret->set_min_mem_pages(min_mem_pages); 953 ret->set_min_mem_pages(min_mem_pages);
896 ret->set_max_mem_pages(max_mem_pages); 954 ret->set_max_mem_pages(max_mem_pages);
897 if (function_table_count > 0) { 955 if (function_table_count > 0) {
898 ret->set_function_tables(function_tables); 956 ret->set_function_tables(function_tables);
899 ret->set_empty_function_tables(function_tables); 957 ret->set_empty_function_tables(function_tables);
900 } 958 }
901 959
960 // If we created a wasm script, finish it now and make it public to the
961 // debugger.
962 if (asm_js_script.is_null()) {
963 script->set_wasm_compiled_module(*ret);
964 isolate->debug()->OnAfterCompile(script);
965 }
966
902 // Compile JS->WASM wrappers for exported functions. 967 // Compile JS->WASM wrappers for exported functions.
903 int func_index = 0; 968 int func_index = 0;
904 for (auto exp : export_table) { 969 for (auto exp : export_table) {
905 if (exp.kind != kExternalFunction) continue; 970 if (exp.kind != kExternalFunction) continue;
906 Handle<Code> wasm_code = 971 Handle<Code> wasm_code =
907 code_table->GetValueChecked<Code>(isolate, exp.index); 972 code_table->GetValueChecked<Code>(isolate, exp.index);
908 Handle<Code> wrapper_code = 973 Handle<Code> wrapper_code =
909 compiler::CompileJSToWasmWrapper(isolate, this, wasm_code, exp.index); 974 compiler::CompileJSToWasmWrapper(isolate, this, wasm_code, exp.index);
910 int export_index = static_cast<int>(functions.size() + func_index); 975 int export_index = static_cast<int>(functions.size() + func_index);
911 code_table->set(export_index, *wrapper_code); 976 code_table->set(export_index, *wrapper_code);
912 RecordStats(isolate, *wrapper_code); 977 RecordStats(isolate, *wrapper_code);
913 func_index++; 978 func_index++;
914 } 979 }
915 980
916 {
917 // TODO(wasm): only save the sections necessary to deserialize a
918 // {WasmModule}. E.g. function bodies could be omitted.
919 Handle<String> module_bytes_string =
920 factory->NewStringFromOneByte(wire_bytes.module_bytes, TENURED)
921 .ToHandleChecked();
922 DCHECK(module_bytes_string->IsSeqOneByteString());
923 ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string));
924 }
925
926 return ret; 981 return ret;
927 } 982 }
928 983
929 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, 984 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate,
930 Handle<Object> target) { 985 Handle<Object> target) {
931 if (target->IsJSFunction()) { 986 if (target->IsJSFunction()) {
932 Handle<JSFunction> func = Handle<JSFunction>::cast(target); 987 Handle<JSFunction> func = Handle<JSFunction>::cast(target);
933 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) { 988 if (func->code()->kind() == Code::JS_TO_WASM_FUNCTION) {
934 auto exported = Handle<WasmExportedFunction>::cast(func); 989 auto exported = Handle<WasmExportedFunction>::cast(func);
935 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate); 990 Handle<WasmInstanceObject> other_instance(exported->instance(), isolate);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 } 1162 }
1108 RecordStats(isolate_, code_table); 1163 RecordStats(isolate_, code_table);
1109 } else { 1164 } else {
1110 // There was no owner, so we can reuse the original. 1165 // There was no owner, so we can reuse the original.
1111 compiled_module_ = original; 1166 compiled_module_ = original;
1112 TRACE("Reusing existing instance %d\n", 1167 TRACE("Reusing existing instance %d\n",
1113 compiled_module_->instance_id()); 1168 compiled_module_->instance_id());
1114 } 1169 }
1115 compiled_module_->set_code_table(code_table); 1170 compiled_module_->set_code_table(code_table);
1116 } 1171 }
1117 module_ = reinterpret_cast<WasmModuleWrapper*>( 1172 module_ = compiled_module_->module();
1118 *compiled_module_->module_wrapper())
1119 ->get();
1120 1173
1121 //-------------------------------------------------------------------------- 1174 //--------------------------------------------------------------------------
1122 // Allocate the instance object. 1175 // Allocate the instance object.
1123 //-------------------------------------------------------------------------- 1176 //--------------------------------------------------------------------------
1124 Handle<WasmInstanceObject> instance = 1177 Handle<WasmInstanceObject> instance =
1125 WasmInstanceObject::New(isolate_, compiled_module_); 1178 WasmInstanceObject::New(isolate_, compiled_module_);
1126 1179
1127 //-------------------------------------------------------------------------- 1180 //--------------------------------------------------------------------------
1128 // Set up the globals for the new instance. 1181 // Set up the globals for the new instance.
1129 //-------------------------------------------------------------------------- 1182 //--------------------------------------------------------------------------
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 //-------------------------------------------------------------------------- 1282 //--------------------------------------------------------------------------
1230 // Set up the exports object for the new instance. 1283 // Set up the exports object for the new instance.
1231 //-------------------------------------------------------------------------- 1284 //--------------------------------------------------------------------------
1232 ProcessExports(code_table, instance); 1285 ProcessExports(code_table, instance);
1233 1286
1234 //-------------------------------------------------------------------------- 1287 //--------------------------------------------------------------------------
1235 // Add instance to Memory object 1288 // Add instance to Memory object
1236 //-------------------------------------------------------------------------- 1289 //--------------------------------------------------------------------------
1237 DCHECK(wasm::IsWasmInstance(*instance)); 1290 DCHECK(wasm::IsWasmInstance(*instance));
1238 if (instance->has_memory_object()) { 1291 if (instance->has_memory_object()) {
1239 instance->get_memory_object()->AddInstance(isolate_, instance); 1292 instance->memory_object()->AddInstance(isolate_, instance);
1240 } 1293 }
1241 1294
1242 //-------------------------------------------------------------------------- 1295 //--------------------------------------------------------------------------
1243 // Set up the indirect function tables for the new instance. 1296 // Set up the indirect function tables for the new instance.
1244 //-------------------------------------------------------------------------- 1297 //--------------------------------------------------------------------------
1245 if (function_table_count > 0) InitializeTables(code_table, instance); 1298 if (function_table_count > 0) InitializeTables(code_table, instance);
1246 1299
1247 if (num_imported_functions > 0 || !owner.is_null()) { 1300 if (num_imported_functions > 0 || !owner.is_null()) {
1248 // If the code was cloned, or new imports were compiled, patch. 1301 // If the code was cloned, or new imports were compiled, patch.
1249 PatchDirectCalls(old_code_table, code_table, num_imported_functions); 1302 PatchDirectCalls(old_code_table, code_table, num_imported_functions);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_); 1346 Handle<WeakCell> link_to_clone = factory->NewWeakCell(compiled_module_);
1294 Handle<WeakCell> link_to_owning_instance = factory->NewWeakCell(instance); 1347 Handle<WeakCell> link_to_owning_instance = factory->NewWeakCell(instance);
1295 MaybeHandle<WeakCell> link_to_original; 1348 MaybeHandle<WeakCell> link_to_original;
1296 MaybeHandle<WasmCompiledModule> original; 1349 MaybeHandle<WasmCompiledModule> original;
1297 if (!owner.is_null()) { 1350 if (!owner.is_null()) {
1298 // prepare the data needed for publishing in a chain, but don't link 1351 // prepare the data needed for publishing in a chain, but don't link
1299 // just yet, because 1352 // just yet, because
1300 // we want all the publishing to happen free from GC interruptions, and 1353 // we want all the publishing to happen free from GC interruptions, and
1301 // so we do it in 1354 // so we do it in
1302 // one GC-free scope afterwards. 1355 // one GC-free scope afterwards.
1303 original = handle(owner.ToHandleChecked()->get_compiled_module()); 1356 original = handle(owner.ToHandleChecked()->compiled_module());
1304 link_to_original = factory->NewWeakCell(original.ToHandleChecked()); 1357 link_to_original = factory->NewWeakCell(original.ToHandleChecked());
1305 } 1358 }
1306 // Publish the new instance to the instances chain. 1359 // Publish the new instance to the instances chain.
1307 { 1360 {
1308 DisallowHeapAllocation no_gc; 1361 DisallowHeapAllocation no_gc;
1309 if (!link_to_original.is_null()) { 1362 if (!link_to_original.is_null()) {
1310 compiled_module_->set_weak_next_instance( 1363 compiled_module_->set_weak_next_instance(
1311 link_to_original.ToHandleChecked()); 1364 link_to_original.ToHandleChecked());
1312 original.ToHandleChecked()->set_weak_prev_instance(link_to_clone); 1365 original.ToHandleChecked()->set_weak_prev_instance(link_to_clone);
1313 compiled_module_->set_weak_wasm_module( 1366 compiled_module_->set_weak_wasm_module(
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 return *reinterpret_cast<uint32_t*>(raw_buffer_ptr(globals_, offset)); 1491 return *reinterpret_cast<uint32_t*>(raw_buffer_ptr(globals_, offset));
1439 } 1492 }
1440 default: 1493 default:
1441 UNREACHABLE(); 1494 UNREACHABLE();
1442 return 0; 1495 return 0;
1443 } 1496 }
1444 } 1497 }
1445 1498
1446 // Load data segments into the memory. 1499 // Load data segments into the memory.
1447 void LoadDataSegments(Address mem_addr, size_t mem_size) { 1500 void LoadDataSegments(Address mem_addr, size_t mem_size) {
1448 Handle<SeqOneByteString> module_bytes = compiled_module_->module_bytes(); 1501 Handle<SeqOneByteString> module_bytes(compiled_module_->module_bytes(),
1502 isolate_);
1449 for (const WasmDataSegment& segment : module_->data_segments) { 1503 for (const WasmDataSegment& segment : module_->data_segments) {
1450 uint32_t source_size = segment.source_size; 1504 uint32_t source_size = segment.source_size;
1451 // Segments of size == 0 are just nops. 1505 // Segments of size == 0 are just nops.
1452 if (source_size == 0) continue; 1506 if (source_size == 0) continue;
1453 uint32_t dest_offset = EvalUint32InitExpr(segment.dest_addr); 1507 uint32_t dest_offset = EvalUint32InitExpr(segment.dest_addr);
1454 if (dest_offset >= mem_size || source_size >= mem_size || 1508 if (dest_offset >= mem_size || source_size >= mem_size ||
1455 dest_offset > (mem_size - source_size)) { 1509 dest_offset > (mem_size - source_size)) {
1456 thrower_->LinkError("data segment (start = %" PRIu32 ", size = %" PRIu32 1510 thrower_->LinkError("data segment (start = %" PRIu32 ", size = %" PRIu32
1457 ") does not fit into memory (size = %" PRIuS ")", 1511 ") does not fit into memory (size = %" PRIuS ")",
1458 dest_offset, source_size, mem_size); 1512 dest_offset, source_size, mem_size);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1553 if (!WasmJs::IsWasmTableObject(isolate_, value)) { 1607 if (!WasmJs::IsWasmTableObject(isolate_, value)) {
1554 ReportLinkError("table import requires a WebAssembly.Table", index, 1608 ReportLinkError("table import requires a WebAssembly.Table", index,
1555 module_name, import_name); 1609 module_name, import_name);
1556 return -1; 1610 return -1;
1557 } 1611 }
1558 WasmIndirectFunctionTable& table = 1612 WasmIndirectFunctionTable& table =
1559 module_->function_tables[num_imported_tables]; 1613 module_->function_tables[num_imported_tables];
1560 TableInstance& table_instance = table_instances_[num_imported_tables]; 1614 TableInstance& table_instance = table_instances_[num_imported_tables];
1561 table_instance.table_object = Handle<WasmTableObject>::cast(value); 1615 table_instance.table_object = Handle<WasmTableObject>::cast(value);
1562 table_instance.js_wrappers = Handle<FixedArray>( 1616 table_instance.js_wrappers = Handle<FixedArray>(
1563 table_instance.table_object->get_functions(), isolate_); 1617 table_instance.table_object->functions(), isolate_);
1564 1618
1565 // TODO(titzer): import table size must match exactly for now. 1619 // TODO(titzer): import table size must match exactly for now.
1566 int table_size = table_instance.js_wrappers->length(); 1620 int table_size = table_instance.js_wrappers->length();
1567 if (table_size != static_cast<int>(table.min_size)) { 1621 if (table_size != static_cast<int>(table.min_size)) {
1568 thrower_->LinkError( 1622 thrower_->LinkError(
1569 "table import %d is wrong size (%d), expected %u", index, 1623 "table import %d is wrong size (%d), expected %u", index,
1570 table_size, table.min_size); 1624 table_size, table.min_size);
1571 return -1; 1625 return -1;
1572 } 1626 }
1573 1627
(...skipping 27 matching lines...) Expand all
1601 } 1655 }
1602 case kExternalMemory: { 1656 case kExternalMemory: {
1603 if (!WasmJs::IsWasmMemoryObject(isolate_, value)) { 1657 if (!WasmJs::IsWasmMemoryObject(isolate_, value)) {
1604 ReportLinkError("memory import must be a WebAssembly.Memory object", 1658 ReportLinkError("memory import must be a WebAssembly.Memory object",
1605 index, module_name, import_name); 1659 index, module_name, import_name);
1606 return -1; 1660 return -1;
1607 } 1661 }
1608 auto memory = Handle<WasmMemoryObject>::cast(value); 1662 auto memory = Handle<WasmMemoryObject>::cast(value);
1609 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory)); 1663 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory));
1610 instance->set_memory_object(*memory); 1664 instance->set_memory_object(*memory);
1611 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_); 1665 memory_ = Handle<JSArrayBuffer>(memory->buffer(), isolate_);
1612 break; 1666 break;
1613 } 1667 }
1614 case kExternalGlobal: { 1668 case kExternalGlobal: {
1615 // Global imports are converted to numbers and written into the 1669 // Global imports are converted to numbers and written into the
1616 // {globals_} array buffer. 1670 // {globals_} array buffer.
1617 if (!value->IsNumber()) { 1671 if (!value->IsNumber()) {
1618 ReportLinkError("global import must be a number", index, 1672 ReportLinkError("global import must be a number", index,
1619 module_name, import_name); 1673 module_name, import_name);
1620 return -1; 1674 return -1;
1621 } 1675 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 isolate_, table.min_size, maximum, &table_instance.js_wrappers); 1836 isolate_, table.min_size, maximum, &table_instance.js_wrappers);
1783 } 1837 }
1784 desc.set_value(table_instance.table_object); 1838 desc.set_value(table_instance.table_object);
1785 break; 1839 break;
1786 } 1840 }
1787 case kExternalMemory: { 1841 case kExternalMemory: {
1788 // Export the memory as a WebAssembly.Memory object. 1842 // Export the memory as a WebAssembly.Memory object.
1789 Handle<WasmMemoryObject> memory_object; 1843 Handle<WasmMemoryObject> memory_object;
1790 if (!instance->has_memory_object()) { 1844 if (!instance->has_memory_object()) {
1791 // If there was no imported WebAssembly.Memory object, create one. 1845 // If there was no imported WebAssembly.Memory object, create one.
1792 Handle<JSArrayBuffer> buffer(instance->get_memory_buffer(), 1846 Handle<JSArrayBuffer> buffer(instance->memory_buffer(), isolate_);
1793 isolate_);
1794 memory_object = WasmMemoryObject::New( 1847 memory_object = WasmMemoryObject::New(
1795 isolate_, buffer, 1848 isolate_, buffer,
1796 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1); 1849 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1);
1797 instance->set_memory_object(*memory_object); 1850 instance->set_memory_object(*memory_object);
1798 } else { 1851 } else {
1799 memory_object = Handle<WasmMemoryObject>( 1852 memory_object =
1800 instance->get_memory_object(), isolate_); 1853 Handle<WasmMemoryObject>(instance->memory_object(), isolate_);
1801 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory_object)); 1854 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory_object));
1802 memory_object->ResetInstancesLink(isolate_); 1855 memory_object->ResetInstancesLink(isolate_);
1803 } 1856 }
1804 1857
1805 desc.set_value(memory_object); 1858 desc.set_value(memory_object);
1806 break; 1859 break;
1807 } 1860 }
1808 case kExternalGlobal: { 1861 case kExternalGlobal: {
1809 // Export the value of the global variable as a number. 1862 // Export the value of the global variable as a number.
1810 WasmGlobal& global = module_->globals[exp.index]; 1863 WasmGlobal& global = module_->globals[exp.index];
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1978 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); 2031 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
1979 return builder.Build(); 2032 return builder.Build();
1980 } 2033 }
1981 2034
1982 bool wasm::IsWasmInstance(Object* object) { 2035 bool wasm::IsWasmInstance(Object* object) {
1983 return WasmInstanceObject::IsWasmInstanceObject(object); 2036 return WasmInstanceObject::IsWasmInstanceObject(object);
1984 } 2037 }
1985 2038
1986 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { 2039 Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
1987 WasmCompiledModule* compiled_module = 2040 WasmCompiledModule* compiled_module =
1988 WasmInstanceObject::cast(*instance)->get_compiled_module(); 2041 WasmInstanceObject::cast(*instance)->compiled_module();
1989 DCHECK(compiled_module->has_script()); 2042 return handle(compiled_module->script());
1990 return compiled_module->script();
1991 }
1992
1993 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) {
1994 auto instance = Handle<WasmInstanceObject>::cast(object);
1995 if (instance->has_debug_info()) {
1996 Handle<WasmDebugInfo> info(instance->get_debug_info(),
1997 instance->GetIsolate());
1998 return info;
1999 }
2000 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(instance);
2001 instance->set_debug_info(*new_info);
2002 return new_info;
2003 } 2043 }
2004 2044
2005 // TODO(clemensh): origin can be inferred from asm_js_script; remove it. 2045 // TODO(clemensh): origin can be inferred from asm_js_script; remove it.
2006 MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes( 2046 MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
2007 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, 2047 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
2008 ModuleOrigin origin, Handle<Script> asm_js_script, 2048 ModuleOrigin origin, Handle<Script> asm_js_script,
2009 const byte* asm_js_offset_tables_start, 2049 Vector<const byte> asm_js_offset_table_bytes) {
2010 const byte* asm_js_offset_tables_end) {
2011 MaybeHandle<WasmModuleObject> nothing; 2050 MaybeHandle<WasmModuleObject> nothing;
2012 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); 2051 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
2013 if (result.failed()) { 2052 if (result.failed()) {
2014 if (result.val) delete result.val; 2053 if (result.val) delete result.val;
2015 thrower->CompileFailed("Wasm decoding failed", result); 2054 thrower->CompileFailed("Wasm decoding failed", result);
2016 return nothing; 2055 return nothing;
2017 } 2056 }
2018 2057
2019 // The {module_wrapper} will take ownership of the {WasmModule} object, 2058 // The {module_wrapper} will take ownership of the {WasmModule} object,
2020 // and it will be destroyed when the GC reclaims the wrapper object. 2059 // and it will be destroyed when the GC reclaims the wrapper object.
2021 Handle<WasmModuleWrapper> module_wrapper = 2060 Handle<WasmModuleWrapper> module_wrapper =
2022 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); 2061 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val));
2023 2062
2024 // Compile the functions of the module, producing a compiled module. 2063 // Compile the functions of the module, producing a compiled module.
2025 MaybeHandle<WasmCompiledModule> maybe_compiled_module = 2064 MaybeHandle<WasmCompiledModule> maybe_compiled_module =
2026 result.val->CompileFunctions(isolate, module_wrapper, thrower, 2065 result.val->CompileFunctions(isolate, module_wrapper, thrower,
2027 ModuleWireBytes(start, end)); 2066 ModuleWireBytes(start, end), asm_js_script,
2067 asm_js_offset_table_bytes);
2028 2068
2029 if (maybe_compiled_module.is_null()) return nothing; 2069 if (maybe_compiled_module.is_null()) return nothing;
2030 2070
2031 Handle<WasmCompiledModule> compiled_module = 2071 Handle<WasmCompiledModule> compiled_module =
2032 maybe_compiled_module.ToHandleChecked(); 2072 maybe_compiled_module.ToHandleChecked();
2033 2073
2034 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null());
2035 DCHECK(!compiled_module->has_script());
2036 DCHECK(!compiled_module->has_asm_js_offset_table());
2037 if (origin == kAsmJsOrigin) {
2038 // Set script for the asm.js source, and the offset table mapping wasm byte
2039 // offsets to source positions.
2040 compiled_module->set_script(asm_js_script);
2041 size_t offset_table_len =
2042 asm_js_offset_tables_end - asm_js_offset_tables_start;
2043 DCHECK_GE(kMaxInt, offset_table_len);
2044 Handle<ByteArray> offset_table =
2045 isolate->factory()->NewByteArray(static_cast<int>(offset_table_len));
2046 memcpy(offset_table->GetDataStartAddress(), asm_js_offset_tables_start,
2047 offset_table_len);
2048 compiled_module->set_asm_js_offset_table(offset_table);
2049 } else {
2050 // Create a new Script object representing this wasm module, store it in the
2051 // compiled wasm module, and register it at the debugger.
2052 Handle<Script> script =
2053 isolate->factory()->NewScript(isolate->factory()->empty_string());
2054 script->set_type(Script::TYPE_WASM);
2055
2056 DCHECK_GE(kMaxInt, end - start);
2057 int hash = StringHasher::HashSequentialString(
2058 reinterpret_cast<const char*>(start), static_cast<int>(end - start),
2059 kZeroHashSeed);
2060
2061 const int kBufferSize = 50;
2062 char buffer[kBufferSize];
2063 int url_chars = SNPrintF(ArrayVector(buffer), "wasm://wasm/%08x", hash);
2064 DCHECK(url_chars >= 0 && url_chars < kBufferSize);
2065 MaybeHandle<String> url_str = isolate->factory()->NewStringFromOneByte(
2066 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), url_chars),
2067 TENURED);
2068 script->set_source_url(*url_str.ToHandleChecked());
2069
2070 int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash);
2071 DCHECK(name_chars >= 0 && name_chars < kBufferSize);
2072 MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte(
2073 Vector<const uint8_t>(reinterpret_cast<uint8_t*>(buffer), name_chars),
2074 TENURED);
2075 script->set_name(*name_str.ToHandleChecked());
2076
2077 script->set_wasm_compiled_module(*compiled_module);
2078 compiled_module->set_script(script);
2079 isolate->debug()->OnAfterCompile(script);
2080 }
2081
2082 return WasmModuleObject::New(isolate, compiled_module); 2074 return WasmModuleObject::New(isolate, compiled_module);
2083 } 2075 }
2084 2076
2085 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, 2077 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
2086 const byte* end, ErrorThrower* thrower, 2078 const byte* end, ErrorThrower* thrower,
2087 ModuleOrigin origin) { 2079 ModuleOrigin origin) {
2088 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin); 2080 ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
2089 if (result.val) { 2081 if (result.val) {
2090 delete result.val; 2082 delete result.val;
2091 } else { 2083 } else {
2092 DCHECK(!result.ok()); 2084 DCHECK(!result.ok());
2093 } 2085 }
2094 return result.ok(); 2086 return result.ok();
2095 } 2087 }
2096 2088
2097 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory( 2089 MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
2098 Isolate* isolate, Handle<WasmInstanceObject> object) { 2090 Isolate* isolate, Handle<WasmInstanceObject> object) {
2099 auto instance = Handle<WasmInstanceObject>::cast(object); 2091 auto instance = Handle<WasmInstanceObject>::cast(object);
2100 if (instance->has_memory_buffer()) { 2092 if (instance->has_memory_buffer()) {
2101 return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate); 2093 return Handle<JSArrayBuffer>(instance->memory_buffer(), isolate);
2102 } 2094 }
2103 return MaybeHandle<JSArrayBuffer>(); 2095 return MaybeHandle<JSArrayBuffer>();
2104 } 2096 }
2105 2097
2106 void SetInstanceMemory(Handle<WasmInstanceObject> instance, 2098 void SetInstanceMemory(Handle<WasmInstanceObject> instance,
2107 JSArrayBuffer* buffer) { 2099 JSArrayBuffer* buffer) {
2108 DisallowHeapAllocation no_gc; 2100 DisallowHeapAllocation no_gc;
2109 instance->set_memory_buffer(buffer); 2101 instance->set_memory_buffer(buffer);
2110 instance->get_compiled_module()->set_ptr_to_memory(buffer); 2102 instance->compiled_module()->set_ptr_to_memory(buffer);
2111 } 2103 }
2112 2104
2113 int32_t wasm::GetInstanceMemorySize(Isolate* isolate, 2105 int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
2114 Handle<WasmInstanceObject> instance) { 2106 Handle<WasmInstanceObject> instance) {
2115 DCHECK(IsWasmInstance(*instance)); 2107 DCHECK(IsWasmInstance(*instance));
2116 MaybeHandle<JSArrayBuffer> maybe_mem_buffer = 2108 MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
2117 GetInstanceMemory(isolate, instance); 2109 GetInstanceMemory(isolate, instance);
2118 Handle<JSArrayBuffer> buffer; 2110 Handle<JSArrayBuffer> buffer;
2119 if (!maybe_mem_buffer.ToHandle(&buffer)) { 2111 if (!maybe_mem_buffer.ToHandle(&buffer)) {
2120 return 0; 2112 return 0;
2121 } else { 2113 } else {
2122 return buffer->byte_length()->Number() / WasmModule::kPageSize; 2114 return buffer->byte_length()->Number() / WasmModule::kPageSize;
2123 } 2115 }
2124 } 2116 }
2125 2117
2126 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, 2118 uint32_t GetMaxInstanceMemorySize(Isolate* isolate,
2127 Handle<WasmInstanceObject> instance) { 2119 Handle<WasmInstanceObject> instance) {
2128 if (instance->has_memory_object()) { 2120 if (instance->has_memory_object()) {
2129 Handle<WasmMemoryObject> memory_object(instance->get_memory_object(), 2121 Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate);
2130 isolate);
2131 2122
2132 int maximum = memory_object->maximum_pages(); 2123 int maximum = memory_object->maximum_pages();
2133 if (maximum > 0) return static_cast<uint32_t>(maximum); 2124 if (maximum > 0) return static_cast<uint32_t>(maximum);
2134 } 2125 }
2135 uint32_t compiled_max_pages = 2126 uint32_t compiled_max_pages = instance->compiled_module()->max_mem_pages();
2136 instance->get_compiled_module()->max_mem_pages();
2137 isolate->counters()->wasm_max_mem_pages_count()->AddSample( 2127 isolate->counters()->wasm_max_mem_pages_count()->AddSample(
2138 compiled_max_pages); 2128 compiled_max_pages);
2139 if (compiled_max_pages != 0) return compiled_max_pages; 2129 if (compiled_max_pages != 0) return compiled_max_pages;
2140 return kV8MaxWasmMemoryPages; 2130 return kV8MaxWasmMemoryPages;
2141 } 2131 }
2142 2132
2143 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate, 2133 Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate,
2144 MaybeHandle<JSArrayBuffer> buffer, 2134 MaybeHandle<JSArrayBuffer> buffer,
2145 uint32_t pages, uint32_t max_pages) { 2135 uint32_t pages, uint32_t max_pages) {
2146 Handle<JSArrayBuffer> old_buffer; 2136 Handle<JSArrayBuffer> old_buffer;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 memcpy(new_mem_start, old_mem_start, old_size); 2169 memcpy(new_mem_start, old_mem_start, old_size);
2180 } 2170 }
2181 } 2171 }
2182 return new_buffer; 2172 return new_buffer;
2183 } 2173 }
2184 2174
2185 void UncheckedUpdateInstanceMemory(Isolate* isolate, 2175 void UncheckedUpdateInstanceMemory(Isolate* isolate,
2186 Handle<WasmInstanceObject> instance, 2176 Handle<WasmInstanceObject> instance,
2187 Address old_mem_start, uint32_t old_size) { 2177 Address old_mem_start, uint32_t old_size) {
2188 DCHECK(instance->has_memory_buffer()); 2178 DCHECK(instance->has_memory_buffer());
2189 Handle<JSArrayBuffer> new_buffer(instance->get_memory_buffer()); 2179 Handle<JSArrayBuffer> new_buffer(instance->memory_buffer());
2190 uint32_t new_size = new_buffer->byte_length()->Number(); 2180 uint32_t new_size = new_buffer->byte_length()->Number();
2191 DCHECK(new_size <= std::numeric_limits<uint32_t>::max()); 2181 DCHECK(new_size <= std::numeric_limits<uint32_t>::max());
2192 Address new_mem_start = static_cast<Address>(new_buffer->backing_store()); 2182 Address new_mem_start = static_cast<Address>(new_buffer->backing_store());
2193 DCHECK_NOT_NULL(new_mem_start); 2183 DCHECK_NOT_NULL(new_mem_start);
2194 Handle<FixedArray> code_table = instance->get_compiled_module()->code_table(); 2184 Handle<FixedArray> code_table = instance->compiled_module()->code_table();
2195 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start, 2185 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start,
2196 old_size, new_size); 2186 old_size, new_size);
2197 } 2187 }
2198 2188
2199 int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, Handle<Object> receiver, 2189 int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, Handle<Object> receiver,
2200 uint32_t pages) { 2190 uint32_t pages) {
2201 DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver)); 2191 DCHECK(WasmJs::IsWasmMemoryObject(isolate, receiver));
2202 Handle<WasmMemoryObject> memory_object = 2192 Handle<WasmMemoryObject> memory_object =
2203 handle(WasmMemoryObject::cast(*receiver)); 2193 handle(WasmMemoryObject::cast(*receiver));
2204 Handle<WasmInstanceWrapper> instance_wrapper( 2194 Handle<WasmInstanceWrapper> instance_wrapper(memory_object->instances_link());
2205 memory_object->get_instances_link());
2206 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); 2195 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
2207 DCHECK(instance_wrapper->has_instance()); 2196 DCHECK(instance_wrapper->has_instance());
2208 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object(); 2197 Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
2209 DCHECK(IsWasmInstance(*instance)); 2198 DCHECK(IsWasmInstance(*instance));
2210 if (pages == 0) return GetInstanceMemorySize(isolate, instance); 2199 if (pages == 0) return GetInstanceMemorySize(isolate, instance);
2211 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); 2200 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
2212 2201
2213 // Grow memory object buffer and update instances associated with it. 2202 // Grow memory object buffer and update instances associated with it.
2214 MaybeHandle<JSArrayBuffer> memory_buffer = 2203 MaybeHandle<JSArrayBuffer> memory_buffer = handle(memory_object->buffer());
2215 handle(memory_object->get_buffer());
2216 Handle<JSArrayBuffer> old_buffer; 2204 Handle<JSArrayBuffer> old_buffer;
2217 uint32_t old_size = 0; 2205 uint32_t old_size = 0;
2218 Address old_mem_start = nullptr; 2206 Address old_mem_start = nullptr;
2219 if (memory_buffer.ToHandle(&old_buffer) && 2207 if (memory_buffer.ToHandle(&old_buffer) &&
2220 old_buffer->backing_store() != nullptr) { 2208 old_buffer->backing_store() != nullptr) {
2221 old_size = old_buffer->byte_length()->Number(); 2209 old_size = old_buffer->byte_length()->Number();
2222 old_mem_start = static_cast<Address>(old_buffer->backing_store()); 2210 old_mem_start = static_cast<Address>(old_buffer->backing_store());
2223 } 2211 }
2224 Handle<JSArrayBuffer> new_buffer = 2212 Handle<JSArrayBuffer> new_buffer =
2225 GrowMemoryBuffer(isolate, memory_buffer, pages, max_pages); 2213 GrowMemoryBuffer(isolate, memory_buffer, pages, max_pages);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 } 2247 }
2260 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance_obj); 2248 uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance_obj);
2261 Handle<JSArrayBuffer> buffer = 2249 Handle<JSArrayBuffer> buffer =
2262 GrowMemoryBuffer(isolate, instance_buffer, pages, max_pages); 2250 GrowMemoryBuffer(isolate, instance_buffer, pages, max_pages);
2263 if (buffer.is_null()) return -1; 2251 if (buffer.is_null()) return -1;
2264 SetInstanceMemory(instance, *buffer); 2252 SetInstanceMemory(instance, *buffer);
2265 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size); 2253 UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
2266 DCHECK(old_size % WasmModule::kPageSize == 0); 2254 DCHECK(old_size % WasmModule::kPageSize == 0);
2267 return (old_size / WasmModule::kPageSize); 2255 return (old_size / WasmModule::kPageSize);
2268 } else { 2256 } else {
2269 return GrowWebAssemblyMemory( 2257 return GrowWebAssemblyMemory(isolate, handle(instance_obj->memory_object()),
2270 isolate, handle(instance_obj->get_memory_object()), pages); 2258 pages);
2271 } 2259 }
2272 } 2260 }
2273 2261
2274 void testing::ValidateInstancesChain(Isolate* isolate, 2262 void testing::ValidateInstancesChain(Isolate* isolate,
2275 Handle<WasmModuleObject> module_obj, 2263 Handle<WasmModuleObject> module_obj,
2276 int instance_count) { 2264 int instance_count) {
2277 CHECK_GE(instance_count, 0); 2265 CHECK_GE(instance_count, 0);
2278 DisallowHeapAllocation no_gc; 2266 DisallowHeapAllocation no_gc;
2279 WasmCompiledModule* compiled_module = module_obj->get_compiled_module(); 2267 WasmCompiledModule* compiled_module = module_obj->compiled_module();
2280 CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()), 2268 CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()),
2281 *module_obj); 2269 *module_obj);
2282 Object* prev = nullptr; 2270 Object* prev = nullptr;
2283 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0; 2271 int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0;
2284 WasmCompiledModule* current_instance = compiled_module; 2272 WasmCompiledModule* current_instance = compiled_module;
2285 while (current_instance->has_weak_next_instance()) { 2273 while (current_instance->has_weak_next_instance()) {
2286 CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) || 2274 CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) ||
2287 current_instance->ptr_to_weak_prev_instance()->value() == prev); 2275 current_instance->ptr_to_weak_prev_instance()->value() == prev);
2288 CHECK_EQ(current_instance->ptr_to_weak_wasm_module()->value(), *module_obj); 2276 CHECK_EQ(current_instance->ptr_to_weak_wasm_module()->value(), *module_obj);
2289 CHECK(IsWasmInstance( 2277 CHECK(IsWasmInstance(
2290 current_instance->ptr_to_weak_owning_instance()->value())); 2278 current_instance->ptr_to_weak_owning_instance()->value()));
2291 prev = current_instance; 2279 prev = current_instance;
2292 current_instance = WasmCompiledModule::cast( 2280 current_instance = WasmCompiledModule::cast(
2293 current_instance->ptr_to_weak_next_instance()->value()); 2281 current_instance->ptr_to_weak_next_instance()->value());
2294 ++found_instances; 2282 ++found_instances;
2295 CHECK_LE(found_instances, instance_count); 2283 CHECK_LE(found_instances, instance_count);
2296 } 2284 }
2297 CHECK_EQ(found_instances, instance_count); 2285 CHECK_EQ(found_instances, instance_count);
2298 } 2286 }
2299 2287
2300 void testing::ValidateModuleState(Isolate* isolate, 2288 void testing::ValidateModuleState(Isolate* isolate,
2301 Handle<WasmModuleObject> module_obj) { 2289 Handle<WasmModuleObject> module_obj) {
2302 DisallowHeapAllocation no_gc; 2290 DisallowHeapAllocation no_gc;
2303 WasmCompiledModule* compiled_module = module_obj->get_compiled_module(); 2291 WasmCompiledModule* compiled_module = module_obj->compiled_module();
2304 CHECK(compiled_module->has_weak_wasm_module()); 2292 CHECK(compiled_module->has_weak_wasm_module());
2305 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *module_obj); 2293 CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *module_obj);
2306 CHECK(!compiled_module->has_weak_prev_instance()); 2294 CHECK(!compiled_module->has_weak_prev_instance());
2307 CHECK(!compiled_module->has_weak_next_instance()); 2295 CHECK(!compiled_module->has_weak_next_instance());
2308 CHECK(!compiled_module->has_weak_owning_instance()); 2296 CHECK(!compiled_module->has_weak_owning_instance());
2309 } 2297 }
2310 2298
2311 void testing::ValidateOrphanedInstance(Isolate* isolate, 2299 void testing::ValidateOrphanedInstance(Isolate* isolate,
2312 Handle<WasmInstanceObject> instance) { 2300 Handle<WasmInstanceObject> instance) {
2313 DisallowHeapAllocation no_gc; 2301 DisallowHeapAllocation no_gc;
2314 WasmCompiledModule* compiled_module = instance->get_compiled_module(); 2302 WasmCompiledModule* compiled_module = instance->compiled_module();
2315 CHECK(compiled_module->has_weak_wasm_module()); 2303 CHECK(compiled_module->has_weak_wasm_module());
2316 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); 2304 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
2317 } 2305 }
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