OLD | NEW |
1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <src/wasm/module-compiler.h> | 5 #include <src/wasm/module-compiler.h> |
6 | 6 |
7 #include <src/counters.h> | 7 #include <src/counters.h> |
8 #include "src/asmjs/asm-js.h" | 8 #include "src/asmjs/asm-js.h" |
9 #include "src/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
10 #include "src/property-descriptor.h" | 10 #include "src/property-descriptor.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 return index; | 64 return index; |
65 } | 65 } |
66 | 66 |
67 ModuleCompiler::ModuleCompiler(Isolate* isolate, | 67 ModuleCompiler::ModuleCompiler(Isolate* isolate, |
68 std::unique_ptr<WasmModule> module, bool is_sync) | 68 std::unique_ptr<WasmModule> module, bool is_sync) |
69 : isolate_(isolate), | 69 : isolate_(isolate), |
70 module_(std::move(module)), | 70 module_(std::move(module)), |
71 counters_shared_(isolate->counters_shared()), | 71 counters_shared_(isolate->counters_shared()), |
72 is_sync_(is_sync), | 72 is_sync_(is_sync), |
73 executed_units_(isolate->random_number_generator()) { | 73 executed_units_(isolate->random_number_generator()) { |
74 counters_ = counters_shared_.get(); | |
75 } | 74 } |
76 | 75 |
77 // The actual runnable task that performs compilations in the background. | 76 // The actual runnable task that performs compilations in the background. |
78 ModuleCompiler::CompilationTask::CompilationTask(ModuleCompiler* compiler) | 77 ModuleCompiler::CompilationTask::CompilationTask(ModuleCompiler* compiler) |
79 : CancelableTask(compiler->isolate_), compiler_(compiler) {} | 78 : CancelableTask(compiler->isolate_), compiler_(compiler) {} |
80 | 79 |
81 void ModuleCompiler::CompilationTask::RunInternal() { | 80 void ModuleCompiler::CompilationTask::RunInternal() { |
82 while (compiler_->FetchAndExecuteCompilationUnit()) { | 81 while (compiler_->FetchAndExecuteCompilationUnit()) { |
83 } | 82 } |
84 compiler_->module_->pending_tasks.get()->Signal(); | 83 compiler_->module_->pending_tasks.get()->Signal(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 117 |
119 size_t ModuleCompiler::InitializeParallelCompilation( | 118 size_t ModuleCompiler::InitializeParallelCompilation( |
120 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { | 119 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { |
121 uint32_t start = module_env.module_env.module->num_imported_functions + | 120 uint32_t start = module_env.module_env.module->num_imported_functions + |
122 FLAG_skip_compiling_wasm_funcs; | 121 FLAG_skip_compiling_wasm_funcs; |
123 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); | 122 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); |
124 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; | 123 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; |
125 compilation_units_.reserve(funcs_to_compile); | 124 compilation_units_.reserve(funcs_to_compile); |
126 for (uint32_t i = start; i < num_funcs; ++i) { | 125 for (uint32_t i = start; i < num_funcs; ++i) { |
127 const WasmFunction* func = &functions[i]; | 126 const WasmFunction* func = &functions[i]; |
128 constexpr bool is_sync = true; | |
129 compilation_units_.push_back(std::unique_ptr<compiler::WasmCompilationUnit>( | 127 compilation_units_.push_back(std::unique_ptr<compiler::WasmCompilationUnit>( |
130 new compiler::WasmCompilationUnit(isolate_, &module_env, func, | 128 new compiler::WasmCompilationUnit(isolate_, &module_env, func))); |
131 !is_sync))); | |
132 } | 129 } |
133 return funcs_to_compile; | 130 return funcs_to_compile; |
134 } | 131 } |
135 | 132 |
136 void ModuleCompiler::InitializeHandles() { | 133 void ModuleCompiler::InitializeHandles() { |
137 for (auto& unit : compilation_units_) { | 134 for (auto& unit : compilation_units_) { |
138 unit->InitializeHandles(); | 135 unit->InitializeHandles(); |
139 } | 136 } |
140 } | 137 } |
141 | 138 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 Handle<FixedArray> function_tables = | 312 Handle<FixedArray> function_tables = |
316 factory->NewFixedArray(function_table_count, TENURED); | 313 factory->NewFixedArray(function_table_count, TENURED); |
317 Handle<FixedArray> signature_tables = | 314 Handle<FixedArray> signature_tables = |
318 factory->NewFixedArray(function_table_count, TENURED); | 315 factory->NewFixedArray(function_table_count, TENURED); |
319 for (int i = 0; i < function_table_count; ++i) { | 316 for (int i = 0; i < function_table_count; ++i) { |
320 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED); | 317 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED); |
321 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED); | 318 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED); |
322 function_tables->set(i, *temp_instance.function_tables[i]); | 319 function_tables->set(i, *temp_instance.function_tables[i]); |
323 signature_tables->set(i, *temp_instance.signature_tables[i]); | 320 signature_tables->set(i, *temp_instance.signature_tables[i]); |
324 } | 321 } |
325 | 322 TimedHistogramScope wasm_compile_module_time_scope( |
326 if (is_sync_) { | 323 module_->is_wasm() ? counters()->wasm_compile_wasm_module_time() |
327 // TODO(karlschimpf): Make this work when asynchronous. | 324 : counters()->wasm_compile_asm_module_time()); |
328 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | |
329 HistogramTimerScope wasm_compile_module_time_scope( | |
330 module_->is_wasm() | |
331 ? isolate_->counters()->wasm_compile_wasm_module_time() | |
332 : isolate_->counters()->wasm_compile_asm_module_time()); | |
333 return CompileToModuleObjectInternal( | |
334 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory, | |
335 &temp_instance, &function_tables, &signature_tables); | |
336 } | |
337 return CompileToModuleObjectInternal( | 325 return CompileToModuleObjectInternal( |
338 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory, | 326 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory, |
339 &temp_instance, &function_tables, &signature_tables); | 327 &temp_instance, &function_tables, &signature_tables); |
340 } | 328 } |
341 | 329 |
342 namespace { | 330 namespace { |
343 bool compile_lazy(const WasmModule* module) { | 331 bool compile_lazy(const WasmModule* module) { |
344 return FLAG_wasm_lazy_compilation || | 332 return FLAG_wasm_lazy_compilation || |
345 (FLAG_asm_wasm_lazy_compilation && module->is_asm_js()); | 333 (FLAG_asm_wasm_lazy_compilation && module->is_asm_js()); |
346 } | 334 } |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 ? isolate_->builtins()->WasmCompileLazy() | 548 ? isolate_->builtins()->WasmCompileLazy() |
561 : isolate_->builtins()->Illegal(); | 549 : isolate_->builtins()->Illegal(); |
562 for (int i = 0, e = static_cast<int>(module_->functions.size()); i < e; ++i) { | 550 for (int i = 0, e = static_cast<int>(module_->functions.size()); i < e; ++i) { |
563 code_table->set(i, *init_builtin); | 551 code_table->set(i, *init_builtin); |
564 temp_instance->function_code[i] = init_builtin; | 552 temp_instance->function_code[i] = init_builtin; |
565 } | 553 } |
566 | 554 |
567 if (is_sync_) | 555 if (is_sync_) |
568 // TODO(karlschimpf): Make this work when asynchronous. | 556 // TODO(karlschimpf): Make this work when asynchronous. |
569 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 557 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
570 (module_->is_wasm() ? isolate_->counters()->wasm_functions_per_wasm_module() | 558 (module_->is_wasm() ? counters()->wasm_functions_per_wasm_module() |
571 : isolate_->counters()->wasm_functions_per_asm_module()) | 559 : counters()->wasm_functions_per_asm_module()) |
572 ->AddSample(static_cast<int>(module_->functions.size())); | 560 ->AddSample(static_cast<int>(module_->functions.size())); |
573 | 561 |
574 if (!lazy_compile) { | 562 if (!lazy_compile) { |
575 size_t funcs_to_compile = | 563 size_t funcs_to_compile = |
576 module_->functions.size() - module_->num_imported_functions; | 564 module_->functions.size() - module_->num_imported_functions; |
577 bool compile_parallel = | 565 bool compile_parallel = |
578 !FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks > 0 && | 566 !FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks > 0 && |
579 funcs_to_compile > 1 && | 567 funcs_to_compile > 1 && |
580 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads() > 0; | 568 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads() > 0; |
581 if (compile_parallel) { | 569 if (compile_parallel) { |
(...skipping 13 matching lines...) Expand all Loading... |
595 // (lazy) compilation time. | 583 // (lazy) compilation time. |
596 ValidateSequentially(&module_env, thrower); | 584 ValidateSequentially(&module_env, thrower); |
597 } | 585 } |
598 if (thrower->error()) return {}; | 586 if (thrower->error()) return {}; |
599 | 587 |
600 // At this point, compilation has completed. Update the code table. | 588 // At this point, compilation has completed. Update the code table. |
601 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 589 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
602 i < temp_instance->function_code.size(); ++i) { | 590 i < temp_instance->function_code.size(); ++i) { |
603 Code* code = *temp_instance->function_code[i]; | 591 Code* code = *temp_instance->function_code[i]; |
604 code_table->set(static_cast<int>(i), code); | 592 code_table->set(static_cast<int>(i), code); |
605 RecordStats(code, counters_); | 593 RecordStats(code, counters()); |
606 } | 594 } |
607 | 595 |
608 // Create heap objects for script, module bytes and asm.js offset table to | 596 // Create heap objects for script, module bytes and asm.js offset table to |
609 // be stored in the shared module data. | 597 // be stored in the shared module data. |
610 Handle<Script> script; | 598 Handle<Script> script; |
611 Handle<ByteArray> asm_js_offset_table; | 599 Handle<ByteArray> asm_js_offset_table; |
612 if (asm_js_script.is_null()) { | 600 if (asm_js_script.is_null()) { |
613 script = CreateWasmScript(isolate_, wire_bytes); | 601 script = CreateWasmScript(isolate_, wire_bytes); |
614 } else { | 602 } else { |
615 script = asm_js_script; | 603 script = asm_js_script; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 JSToWasmWrapperCache js_to_wasm_cache; | 649 JSToWasmWrapperCache js_to_wasm_cache; |
662 int func_index = 0; | 650 int func_index = 0; |
663 for (auto exp : module->export_table) { | 651 for (auto exp : module->export_table) { |
664 if (exp.kind != kExternalFunction) continue; | 652 if (exp.kind != kExternalFunction) continue; |
665 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( | 653 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( |
666 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); | 654 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); |
667 Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( | 655 Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( |
668 isolate_, module, wasm_code, exp.index); | 656 isolate_, module, wasm_code, exp.index); |
669 int export_index = static_cast<int>(module->functions.size() + func_index); | 657 int export_index = static_cast<int>(module->functions.size() + func_index); |
670 code_table->set(export_index, *wrapper_code); | 658 code_table->set(export_index, *wrapper_code); |
671 RecordStats(*wrapper_code, counters_); | 659 RecordStats(*wrapper_code, counters()); |
672 func_index++; | 660 func_index++; |
673 } | 661 } |
674 | 662 |
675 return WasmModuleObject::New(isolate_, compiled_module); | 663 return WasmModuleObject::New(isolate_, compiled_module); |
676 } | 664 } |
677 | 665 |
678 Handle<Code> JSToWasmWrapperCache::CloneOrCompileJSToWasmWrapper( | 666 Handle<Code> JSToWasmWrapperCache::CloneOrCompileJSToWasmWrapper( |
679 Isolate* isolate, const wasm::WasmModule* module, Handle<Code> wasm_code, | 667 Isolate* isolate, const wasm::WasmModule* module, Handle<Code> wasm_code, |
680 uint32_t index) { | 668 uint32_t index) { |
681 const wasm::WasmFunction* func = &module->functions[index]; | 669 const wasm::WasmFunction* func = &module->functions[index]; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 WeakCallbackInfo<void>::Callback instance_finalizer_callback) | 702 WeakCallbackInfo<void>::Callback instance_finalizer_callback) |
715 : isolate_(isolate), | 703 : isolate_(isolate), |
716 module_(module_object->compiled_module()->module()), | 704 module_(module_object->compiled_module()->module()), |
717 counters_shared_(isolate->counters_shared()), | 705 counters_shared_(isolate->counters_shared()), |
718 thrower_(thrower), | 706 thrower_(thrower), |
719 module_object_(module_object), | 707 module_object_(module_object), |
720 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() : ffi.ToHandleChecked()), | 708 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() : ffi.ToHandleChecked()), |
721 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() | 709 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() |
722 : memory.ToHandleChecked()), | 710 : memory.ToHandleChecked()), |
723 instance_finalizer_callback_(instance_finalizer_callback) { | 711 instance_finalizer_callback_(instance_finalizer_callback) { |
724 counters_ = counters_shared_.get(); | |
725 } | 712 } |
726 | 713 |
727 // Build an instance, in all of its glory. | 714 // Build an instance, in all of its glory. |
728 MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { | 715 MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { |
729 // Check that an imports argument was provided, if the module requires it. | 716 // Check that an imports argument was provided, if the module requires it. |
730 // No point in continuing otherwise. | 717 // No point in continuing otherwise. |
731 if (!module_->import_table.empty() && ffi_.is_null()) { | 718 if (!module_->import_table.empty() && ffi_.is_null()) { |
732 thrower_->TypeError( | 719 thrower_->TypeError( |
733 "Imports argument must be present and must be an object"); | 720 "Imports argument must be present and must be an object"); |
734 return {}; | 721 return {}; |
735 } | 722 } |
736 | 723 |
737 // Record build time into correct bucket, then build instance. | 724 // Record build time into correct bucket, then build instance. |
738 HistogramTimerScope wasm_instantiate_module_time_scope( | 725 HistogramTimerScope wasm_instantiate_module_time_scope( |
739 module_->is_wasm() | 726 module_->is_wasm() ? counters()->wasm_instantiate_wasm_module_time() |
740 ? isolate_->counters()->wasm_instantiate_wasm_module_time() | 727 : counters()->wasm_instantiate_asm_module_time()); |
741 : isolate_->counters()->wasm_instantiate_asm_module_time()); | |
742 Factory* factory = isolate_->factory(); | 728 Factory* factory = isolate_->factory(); |
743 | 729 |
744 //-------------------------------------------------------------------------- | 730 //-------------------------------------------------------------------------- |
745 // Reuse the compiled module (if no owner), otherwise clone. | 731 // Reuse the compiled module (if no owner), otherwise clone. |
746 //-------------------------------------------------------------------------- | 732 //-------------------------------------------------------------------------- |
747 Handle<FixedArray> code_table; | 733 Handle<FixedArray> code_table; |
748 // We keep around a copy of the old code table, because we'll be replacing | 734 // We keep around a copy of the old code table, because we'll be replacing |
749 // imports for the new instance, and then we need the old imports to be | 735 // imports for the new instance, and then we need the old imports to be |
750 // able to relocate. | 736 // able to relocate. |
751 Handle<FixedArray> old_code_table; | 737 Handle<FixedArray> old_code_table; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 case Code::JS_TO_WASM_FUNCTION: | 791 case Code::JS_TO_WASM_FUNCTION: |
806 case Code::WASM_FUNCTION: { | 792 case Code::WASM_FUNCTION: { |
807 Handle<Code> code = factory->CopyCode(orig_code); | 793 Handle<Code> code = factory->CopyCode(orig_code); |
808 code_table->set(i, *code); | 794 code_table->set(i, *code); |
809 break; | 795 break; |
810 } | 796 } |
811 default: | 797 default: |
812 UNREACHABLE(); | 798 UNREACHABLE(); |
813 } | 799 } |
814 } | 800 } |
815 RecordStats(code_table, counters_); | 801 RecordStats(code_table, counters()); |
816 } else { | 802 } else { |
817 // There was no owner, so we can reuse the original. | 803 // There was no owner, so we can reuse the original. |
818 compiled_module_ = original; | 804 compiled_module_ = original; |
819 old_code_table = factory->CopyFixedArray(compiled_module_->code_table()); | 805 old_code_table = factory->CopyFixedArray(compiled_module_->code_table()); |
820 code_table = compiled_module_->code_table(); | 806 code_table = compiled_module_->code_table(); |
821 TRACE("Reusing existing instance %d\n", compiled_module_->instance_id()); | 807 TRACE("Reusing existing instance %d\n", compiled_module_->instance_id()); |
822 } | 808 } |
823 compiled_module_->set_native_context(isolate_->native_context()); | 809 compiled_module_->set_native_context(isolate_->native_context()); |
824 } | 810 } |
825 | 811 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 //-------------------------------------------------------------------------- | 870 //-------------------------------------------------------------------------- |
885 // Set up the indirect function tables for the new instance. | 871 // Set up the indirect function tables for the new instance. |
886 //-------------------------------------------------------------------------- | 872 //-------------------------------------------------------------------------- |
887 if (function_table_count > 0) | 873 if (function_table_count > 0) |
888 InitializeTables(instance, &code_specialization); | 874 InitializeTables(instance, &code_specialization); |
889 | 875 |
890 //-------------------------------------------------------------------------- | 876 //-------------------------------------------------------------------------- |
891 // Set up the memory for the new instance. | 877 // Set up the memory for the new instance. |
892 //-------------------------------------------------------------------------- | 878 //-------------------------------------------------------------------------- |
893 uint32_t min_mem_pages = module_->min_mem_pages; | 879 uint32_t min_mem_pages = module_->min_mem_pages; |
894 (module_->is_wasm() ? isolate_->counters()->wasm_wasm_min_mem_pages_count() | 880 (module_->is_wasm() ? counters()->wasm_wasm_min_mem_pages_count() |
895 : isolate_->counters()->wasm_asm_min_mem_pages_count()) | 881 : counters()->wasm_asm_min_mem_pages_count()) |
896 ->AddSample(min_mem_pages); | 882 ->AddSample(min_mem_pages); |
897 | 883 |
898 if (!memory_.is_null()) { | 884 if (!memory_.is_null()) { |
899 // Set externally passed ArrayBuffer non neuterable. | 885 // Set externally passed ArrayBuffer non neuterable. |
900 memory_->set_is_neuterable(false); | 886 memory_->set_is_neuterable(false); |
901 memory_->set_is_wasm_buffer(true); | 887 memory_->set_is_wasm_buffer(true); |
902 | 888 |
903 DCHECK_IMPLIES(EnableGuardRegions(), | 889 DCHECK_IMPLIES(EnableGuardRegions(), |
904 module_->is_asm_js() || memory_->has_guard_region()); | 890 module_->is_asm_js() || memory_->has_guard_region()); |
905 } else if (min_mem_pages > 0) { | 891 } else if (min_mem_pages > 0) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 HandleScope scope(isolate_); | 1072 HandleScope scope(isolate_); |
1087 int start_index = module_->start_function_index; | 1073 int start_index = module_->start_function_index; |
1088 Handle<Code> startup_code = EnsureExportedLazyDeoptData( | 1074 Handle<Code> startup_code = EnsureExportedLazyDeoptData( |
1089 isolate_, instance, code_table, start_index); | 1075 isolate_, instance, code_table, start_index); |
1090 FunctionSig* sig = module_->functions[start_index].sig; | 1076 FunctionSig* sig = module_->functions[start_index].sig; |
1091 Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( | 1077 Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( |
1092 isolate_, module_, startup_code, start_index); | 1078 isolate_, module_, startup_code, start_index); |
1093 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( | 1079 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( |
1094 isolate_, instance, MaybeHandle<String>(), start_index, | 1080 isolate_, instance, MaybeHandle<String>(), start_index, |
1095 static_cast<int>(sig->parameter_count()), wrapper_code); | 1081 static_cast<int>(sig->parameter_count()), wrapper_code); |
1096 RecordStats(*startup_code, counters_); | 1082 RecordStats(*startup_code, counters()); |
1097 // Call the JS function. | 1083 // Call the JS function. |
1098 Handle<Object> undefined = factory->undefined_value(); | 1084 Handle<Object> undefined = factory->undefined_value(); |
1099 MaybeHandle<Object> retval = | 1085 MaybeHandle<Object> retval = |
1100 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1086 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
1101 | 1087 |
1102 if (retval.is_null()) { | 1088 if (retval.is_null()) { |
1103 DCHECK(isolate_->has_pending_exception()); | 1089 DCHECK(isolate_->has_pending_exception()); |
1104 isolate_->OptionalRescheduleException(false); | 1090 isolate_->OptionalRescheduleException(false); |
1105 // It's unfortunate that the new instance is already linked in the | 1091 // It's unfortunate that the new instance is already linked in the |
1106 // chain. However, we need to set up everything before executing the | 1092 // chain. However, we need to set up everything before executing the |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 Handle<Code> import_wrapper = CompileImportWrapper( | 1270 Handle<Code> import_wrapper = CompileImportWrapper( |
1285 isolate_, index, module_->functions[import.index].sig, | 1271 isolate_, index, module_->functions[import.index].sig, |
1286 Handle<JSReceiver>::cast(value), module_name, import_name, | 1272 Handle<JSReceiver>::cast(value), module_name, import_name, |
1287 module_->get_origin()); | 1273 module_->get_origin()); |
1288 if (import_wrapper.is_null()) { | 1274 if (import_wrapper.is_null()) { |
1289 ReportLinkError("imported function does not match the expected type", | 1275 ReportLinkError("imported function does not match the expected type", |
1290 index, module_name, import_name); | 1276 index, module_name, import_name); |
1291 return -1; | 1277 return -1; |
1292 } | 1278 } |
1293 code_table->set(num_imported_functions, *import_wrapper); | 1279 code_table->set(num_imported_functions, *import_wrapper); |
1294 RecordStats(*import_wrapper, counters_); | 1280 RecordStats(*import_wrapper, counters()); |
1295 num_imported_functions++; | 1281 num_imported_functions++; |
1296 break; | 1282 break; |
1297 } | 1283 } |
1298 case kExternalTable: { | 1284 case kExternalTable: { |
1299 if (!WasmJs::IsWasmTableObject(isolate_, value)) { | 1285 if (!WasmJs::IsWasmTableObject(isolate_, value)) { |
1300 ReportLinkError("table import requires a WebAssembly.Table", index, | 1286 ReportLinkError("table import requires a WebAssembly.Table", index, |
1301 module_name, import_name); | 1287 module_name, import_name); |
1302 return -1; | 1288 return -1; |
1303 } | 1289 } |
1304 WasmIndirectFunctionTable& table = | 1290 WasmIndirectFunctionTable& table = |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 Handle<JSPromise> promise) | 1836 Handle<JSPromise> promise) |
1851 : isolate_(isolate), | 1837 : isolate_(isolate), |
1852 counters_shared_(isolate->counters_shared()), | 1838 counters_shared_(isolate->counters_shared()), |
1853 bytes_copy_(std::move(bytes_copy)), | 1839 bytes_copy_(std::move(bytes_copy)), |
1854 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { | 1840 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { |
1855 // The handles for the context and promise must be deferred. | 1841 // The handles for the context and promise must be deferred. |
1856 DeferredHandleScope deferred(isolate); | 1842 DeferredHandleScope deferred(isolate); |
1857 context_ = Handle<Context>(*context); | 1843 context_ = Handle<Context>(*context); |
1858 module_promise_ = Handle<JSPromise>(*promise); | 1844 module_promise_ = Handle<JSPromise>(*promise); |
1859 deferred_handles_.push_back(deferred.Detach()); | 1845 deferred_handles_.push_back(deferred.Detach()); |
1860 counters_ = counters_shared_.get(); | |
1861 } | 1846 } |
1862 | 1847 |
1863 void AsyncCompileJob::Start() { | 1848 void AsyncCompileJob::Start() { |
1864 DoAsync<DecodeModule>(); // -- | 1849 DoAsync<DecodeModule>(); // -- |
1865 } | 1850 } |
1866 | 1851 |
1867 AsyncCompileJob::~AsyncCompileJob() { | 1852 AsyncCompileJob::~AsyncCompileJob() { |
1868 for (auto d : deferred_handles_) delete d; | 1853 for (auto d : deferred_handles_) delete d; |
1869 } | 1854 } |
1870 | 1855 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1939 // Step 1: (async) Decode the module. | 1924 // Step 1: (async) Decode the module. |
1940 //========================================================================== | 1925 //========================================================================== |
1941 class AsyncCompileJob::DecodeModule : public AsyncCompileJob::AsyncCompileTask { | 1926 class AsyncCompileJob::DecodeModule : public AsyncCompileJob::AsyncCompileTask { |
1942 void Run() override { | 1927 void Run() override { |
1943 ModuleResult result; | 1928 ModuleResult result; |
1944 { | 1929 { |
1945 DisallowHandleAllocation no_handle; | 1930 DisallowHandleAllocation no_handle; |
1946 DisallowHeapAllocation no_allocation; | 1931 DisallowHeapAllocation no_allocation; |
1947 // Decode the module bytes. | 1932 // Decode the module bytes. |
1948 TRACE_COMPILE("(1) Decoding module...\n"); | 1933 TRACE_COMPILE("(1) Decoding module...\n"); |
1949 constexpr bool is_sync = true; | 1934 result = AsyncDecodeWasmModule(job_->isolate_, job_->wire_bytes_.start(), |
1950 result = DecodeWasmModule(job_->isolate_, job_->wire_bytes_.start(), | 1935 job_->wire_bytes_.end(), false, |
1951 job_->wire_bytes_.end(), false, kWasmOrigin, | 1936 kWasmOrigin, job_->counters_shared_); |
1952 !is_sync); | |
1953 } | 1937 } |
1954 if (result.failed()) { | 1938 if (result.failed()) { |
1955 // Decoding failure; reject the promise and clean up. | 1939 // Decoding failure; reject the promise and clean up. |
1956 job_->DoSync<DecodeFail>(std::move(result)); | 1940 job_->DoSync<DecodeFail>(std::move(result)); |
1957 } else { | 1941 } else { |
1958 // Decode passed. | 1942 // Decode passed. |
1959 job_->DoSync<PrepareAndStartCompile>(std::move(result.val)); | 1943 job_->DoSync<PrepareAndStartCompile>(std::move(result.val)); |
1960 } | 1944 } |
1961 } | 1945 } |
1962 }; | 1946 }; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2028 | 2012 |
2029 // Initialize {code_table_} with the illegal builtin. All call sites | 2013 // Initialize {code_table_} with the illegal builtin. All call sites |
2030 // will be patched at instantiation. | 2014 // will be patched at instantiation. |
2031 Handle<Code> illegal_builtin = job_->isolate_->builtins()->Illegal(); | 2015 Handle<Code> illegal_builtin = job_->isolate_->builtins()->Illegal(); |
2032 // TODO(wasm): Fix this for lazy compilation. | 2016 // TODO(wasm): Fix this for lazy compilation. |
2033 for (uint32_t i = 0; i < module_->functions.size(); ++i) { | 2017 for (uint32_t i = 0; i < module_->functions.size(); ++i) { |
2034 job_->code_table_->set(static_cast<int>(i), *illegal_builtin); | 2018 job_->code_table_->set(static_cast<int>(i), *illegal_builtin); |
2035 job_->temp_instance_->function_code[i] = illegal_builtin; | 2019 job_->temp_instance_->function_code[i] = illegal_builtin; |
2036 } | 2020 } |
2037 | 2021 |
2038 job_->isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( | 2022 job_->counters()->wasm_functions_per_wasm_module()->AddSample( |
2039 static_cast<int>(module_->functions.size())); | 2023 static_cast<int>(module_->functions.size())); |
2040 | 2024 |
2041 // Transfer ownership of the {WasmModule} to the {ModuleCompiler}, but | 2025 // Transfer ownership of the {WasmModule} to the {ModuleCompiler}, but |
2042 // keep a pointer. | 2026 // keep a pointer. |
2043 WasmModule* module = module_.get(); | 2027 WasmModule* module = module_.get(); |
2044 constexpr bool is_sync = true; | 2028 constexpr bool is_sync = true; |
2045 job_->compiler_.reset( | 2029 job_->compiler_.reset( |
2046 new ModuleCompiler(job_->isolate_, std::move(module_), !is_sync)); | 2030 new ModuleCompiler(job_->isolate_, std::move(module_), !is_sync)); |
2047 | 2031 |
2048 DCHECK_LE(module->num_imported_functions, module->functions.size()); | 2032 DCHECK_LE(module->num_imported_functions, module->functions.size()); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 // Step 5b (sync): Finish heap-allocated data structures. | 2191 // Step 5b (sync): Finish heap-allocated data structures. |
2208 //========================================================================== | 2192 //========================================================================== |
2209 class AsyncCompileJob::FinishCompile : public SyncCompileTask { | 2193 class AsyncCompileJob::FinishCompile : public SyncCompileTask { |
2210 void RunImpl() override { | 2194 void RunImpl() override { |
2211 TRACE_COMPILE("(5b) Finish compile...\n"); | 2195 TRACE_COMPILE("(5b) Finish compile...\n"); |
2212 HandleScope scope(job_->isolate_); | 2196 HandleScope scope(job_->isolate_); |
2213 // At this point, compilation has completed. Update the code table. | 2197 // At this point, compilation has completed. Update the code table. |
2214 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 2198 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
2215 i < job_->temp_instance_->function_code.size(); ++i) { | 2199 i < job_->temp_instance_->function_code.size(); ++i) { |
2216 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); | 2200 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); |
2217 RecordStats(code, job_->counters_); | 2201 RecordStats(code, job_->counters()); |
2218 } | 2202 } |
2219 | 2203 |
2220 // Create heap objects for script and module bytes to be stored in the | 2204 // Create heap objects for script and module bytes to be stored in the |
2221 // shared module data. Asm.js is not compiled asynchronously. | 2205 // shared module data. Asm.js is not compiled asynchronously. |
2222 Handle<Script> script = CreateWasmScript(job_->isolate_, job_->wire_bytes_); | 2206 Handle<Script> script = CreateWasmScript(job_->isolate_, job_->wire_bytes_); |
2223 Handle<ByteArray> asm_js_offset_table; | 2207 Handle<ByteArray> asm_js_offset_table; |
2224 // TODO(wasm): Improve efficiency of storing module wire bytes. | 2208 // TODO(wasm): Improve efficiency of storing module wire bytes. |
2225 // 1. Only store relevant sections, not function bodies | 2209 // 1. Only store relevant sections, not function bodies |
2226 // 2. Don't make a second copy of the bytes here; reuse the copy made | 2210 // 2. Don't make a second copy of the bytes here; reuse the copy made |
2227 // for asynchronous compilation and store it as an external one | 2211 // for asynchronous compilation and store it as an external one |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2283 for (auto exp : module->export_table) { | 2267 for (auto exp : module->export_table) { |
2284 if (exp.kind != kExternalFunction) continue; | 2268 if (exp.kind != kExternalFunction) continue; |
2285 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), | 2269 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), |
2286 job_->isolate_); | 2270 job_->isolate_); |
2287 Handle<Code> wrapper_code = | 2271 Handle<Code> wrapper_code = |
2288 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(job_->isolate_, module, | 2272 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(job_->isolate_, module, |
2289 wasm_code, exp.index); | 2273 wasm_code, exp.index); |
2290 int export_index = | 2274 int export_index = |
2291 static_cast<int>(module->functions.size() + func_index); | 2275 static_cast<int>(module->functions.size() + func_index); |
2292 job_->code_table_->set(export_index, *wrapper_code); | 2276 job_->code_table_->set(export_index, *wrapper_code); |
2293 RecordStats(*wrapper_code, job_->counters_); | 2277 RecordStats(*wrapper_code, job_->counters()); |
2294 func_index++; | 2278 func_index++; |
2295 } | 2279 } |
2296 | 2280 |
2297 job_->DoSync<FinishModule>(); | 2281 job_->DoSync<FinishModule>(); |
2298 } | 2282 } |
2299 }; | 2283 }; |
2300 | 2284 |
2301 //========================================================================== | 2285 //========================================================================== |
2302 // Step 7 (sync): Finish the module and resolve the promise. | 2286 // Step 7 (sync): Finish the module and resolve the promise. |
2303 //========================================================================== | 2287 //========================================================================== |
2304 class AsyncCompileJob::FinishModule : public SyncCompileTask { | 2288 class AsyncCompileJob::FinishModule : public SyncCompileTask { |
2305 void RunImpl() override { | 2289 void RunImpl() override { |
2306 TRACE_COMPILE("(7) Finish module...\n"); | 2290 TRACE_COMPILE("(7) Finish module...\n"); |
2307 HandleScope scope(job_->isolate_); | 2291 HandleScope scope(job_->isolate_); |
2308 Handle<WasmModuleObject> result = | 2292 Handle<WasmModuleObject> result = |
2309 WasmModuleObject::New(job_->isolate_, job_->compiled_module_); | 2293 WasmModuleObject::New(job_->isolate_, job_->compiled_module_); |
2310 // {job_} is deleted in AsyncCompileSucceeded, therefore the {return}. | 2294 // {job_} is deleted in AsyncCompileSucceeded, therefore the {return}. |
2311 return job_->AsyncCompileSucceeded(result); | 2295 return job_->AsyncCompileSucceeded(result); |
2312 } | 2296 } |
2313 }; | 2297 }; |
2314 } // namespace wasm | 2298 } // namespace wasm |
2315 } // namespace internal | 2299 } // namespace internal |
2316 } // namespace v8 | 2300 } // namespace v8 |
OLD | NEW |