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 <atomic> | 7 #include <atomic> |
8 | 8 |
9 #include "src/asmjs/asm-js.h" | 9 #include "src/asmjs/asm-js.h" |
10 #include "src/assembler-inl.h" | 10 #include "src/assembler-inl.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 executed_units_( | 90 executed_units_( |
91 isolate->random_number_generator(), | 91 isolate->random_number_generator(), |
92 (isolate->heap()->memory_allocator()->code_range()->valid() | 92 (isolate->heap()->memory_allocator()->code_range()->valid() |
93 ? isolate->heap()->memory_allocator()->code_range()->size() | 93 ? isolate->heap()->memory_allocator()->code_range()->size() |
94 : isolate->heap()->code_space()->Capacity()) / | 94 : isolate->heap()->code_space()->Capacity()) / |
95 2), | 95 2), |
96 num_background_tasks_( | 96 num_background_tasks_( |
97 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), | 97 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), |
98 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())), | 98 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())), |
99 stopped_compilation_tasks_(num_background_tasks_) { | 99 stopped_compilation_tasks_(num_background_tasks_) { |
100 counters_ = counters_shared_.get(); | |
101 } | 100 } |
102 | 101 |
103 bool ModuleCompiler::GetNextUncompiledFunctionId(size_t* index) { | 102 bool ModuleCompiler::GetNextUncompiledFunctionId(size_t* index) { |
104 DCHECK_NOT_NULL(index); | 103 DCHECK_NOT_NULL(index); |
105 // - 1 because AtomicIncrement returns the value after the atomic increment. | 104 // - 1 because AtomicIncrement returns the value after the atomic increment. |
106 *index = next_unit_.Increment(1) - 1; | 105 *index = next_unit_.Increment(1) - 1; |
107 return *index < compilation_units_.size(); | 106 return *index < compilation_units_.size(); |
108 } | 107 } |
109 | 108 |
110 // The actual runnable task that performs compilations in the background. | 109 // The actual runnable task that performs compilations in the background. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 | 176 |
178 size_t ModuleCompiler::InitializeParallelCompilation( | 177 size_t ModuleCompiler::InitializeParallelCompilation( |
179 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { | 178 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { |
180 uint32_t start = module_env.module_env.module->num_imported_functions + | 179 uint32_t start = module_env.module_env.module->num_imported_functions + |
181 FLAG_skip_compiling_wasm_funcs; | 180 FLAG_skip_compiling_wasm_funcs; |
182 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); | 181 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); |
183 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; | 182 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; |
184 compilation_units_.reserve(funcs_to_compile); | 183 compilation_units_.reserve(funcs_to_compile); |
185 for (uint32_t i = start; i < num_funcs; ++i) { | 184 for (uint32_t i = start; i < num_funcs; ++i) { |
186 const WasmFunction* func = &functions[i]; | 185 const WasmFunction* func = &functions[i]; |
187 constexpr bool is_sync = true; | |
188 compilation_units_.push_back(std::unique_ptr<compiler::WasmCompilationUnit>( | 186 compilation_units_.push_back(std::unique_ptr<compiler::WasmCompilationUnit>( |
189 new compiler::WasmCompilationUnit(isolate_, &module_env, func, | 187 new compiler::WasmCompilationUnit(isolate_, &module_env, func))); |
190 !is_sync))); | |
191 } | 188 } |
192 return funcs_to_compile; | 189 return funcs_to_compile; |
193 } | 190 } |
194 | 191 |
195 void ModuleCompiler::RestartCompilationTasks() { | 192 void ModuleCompiler::RestartCompilationTasks() { |
196 base::LockGuard<base::Mutex> guard(&tasks_mutex_); | 193 base::LockGuard<base::Mutex> guard(&tasks_mutex_); |
197 for (; stopped_compilation_tasks_ > 0; --stopped_compilation_tasks_) { | 194 for (; stopped_compilation_tasks_ > 0; --stopped_compilation_tasks_) { |
198 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 195 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
199 new CompilationTask(this), | 196 new CompilationTask(this), |
200 v8::Platform::ExpectedRuntime::kShortRunningTask); | 197 v8::Platform::ExpectedRuntime::kShortRunningTask); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 Handle<FixedArray> function_tables = | 355 Handle<FixedArray> function_tables = |
359 factory->NewFixedArray(function_table_count, TENURED); | 356 factory->NewFixedArray(function_table_count, TENURED); |
360 Handle<FixedArray> signature_tables = | 357 Handle<FixedArray> signature_tables = |
361 factory->NewFixedArray(function_table_count, TENURED); | 358 factory->NewFixedArray(function_table_count, TENURED); |
362 for (int i = 0; i < function_table_count; ++i) { | 359 for (int i = 0; i < function_table_count; ++i) { |
363 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED); | 360 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED); |
364 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED); | 361 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED); |
365 function_tables->set(i, *temp_instance.function_tables[i]); | 362 function_tables->set(i, *temp_instance.function_tables[i]); |
366 signature_tables->set(i, *temp_instance.signature_tables[i]); | 363 signature_tables->set(i, *temp_instance.signature_tables[i]); |
367 } | 364 } |
368 | 365 TimedHistogramScope wasm_compile_module_time_scope( |
369 if (is_sync_) { | 366 module_->is_wasm() ? counters()->wasm_compile_wasm_module_time() |
Mircea Trofin
2017/06/22 18:42:24
can this test be encapsulated in a method, it appe
kschimpf
2017/06/22 20:38:31
When I tried that in an earlier review, there was
| |
370 // TODO(karlschimpf): Make this work when asynchronous. | 367 : counters()->wasm_compile_asm_module_time()); |
371 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | |
372 HistogramTimerScope wasm_compile_module_time_scope( | |
373 module_->is_wasm() | |
374 ? isolate_->counters()->wasm_compile_wasm_module_time() | |
375 : isolate_->counters()->wasm_compile_asm_module_time()); | |
376 return CompileToModuleObjectInternal( | |
377 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory, | |
378 &temp_instance, &function_tables, &signature_tables); | |
379 } | |
380 return CompileToModuleObjectInternal( | 368 return CompileToModuleObjectInternal( |
381 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory, | 369 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory, |
382 &temp_instance, &function_tables, &signature_tables); | 370 &temp_instance, &function_tables, &signature_tables); |
383 } | 371 } |
384 | 372 |
385 namespace { | 373 namespace { |
386 bool compile_lazy(const WasmModule* module) { | 374 bool compile_lazy(const WasmModule* module) { |
387 return FLAG_wasm_lazy_compilation || | 375 return FLAG_wasm_lazy_compilation || |
388 (FLAG_asm_wasm_lazy_compilation && module->is_asm_js()); | 376 (FLAG_asm_wasm_lazy_compilation && module->is_asm_js()); |
389 } | 377 } |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
608 ? isolate_->builtins()->WasmCompileLazy() | 596 ? isolate_->builtins()->WasmCompileLazy() |
609 : isolate_->builtins()->Illegal(); | 597 : isolate_->builtins()->Illegal(); |
610 for (int i = 0, e = static_cast<int>(module_->functions.size()); i < e; ++i) { | 598 for (int i = 0, e = static_cast<int>(module_->functions.size()); i < e; ++i) { |
611 code_table->set(i, *init_builtin); | 599 code_table->set(i, *init_builtin); |
612 temp_instance->function_code[i] = init_builtin; | 600 temp_instance->function_code[i] = init_builtin; |
613 } | 601 } |
614 | 602 |
615 if (is_sync_) | 603 if (is_sync_) |
616 // TODO(karlschimpf): Make this work when asynchronous. | 604 // TODO(karlschimpf): Make this work when asynchronous. |
617 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 | 605 // https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
618 (module_->is_wasm() ? isolate_->counters()->wasm_functions_per_wasm_module() | 606 (module_->is_wasm() ? counters()->wasm_functions_per_wasm_module() |
619 : isolate_->counters()->wasm_functions_per_asm_module()) | 607 : counters()->wasm_functions_per_asm_module()) |
620 ->AddSample(static_cast<int>(module_->functions.size())); | 608 ->AddSample(static_cast<int>(module_->functions.size())); |
621 | 609 |
622 if (!lazy_compile) { | 610 if (!lazy_compile) { |
623 size_t funcs_to_compile = | 611 size_t funcs_to_compile = |
624 module_->functions.size() - module_->num_imported_functions; | 612 module_->functions.size() - module_->num_imported_functions; |
625 bool compile_parallel = | 613 bool compile_parallel = |
626 !FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks > 0 && | 614 !FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks > 0 && |
627 funcs_to_compile > 1 && | 615 funcs_to_compile > 1 && |
628 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads() > 0; | 616 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads() > 0; |
629 if (compile_parallel) { | 617 if (compile_parallel) { |
(...skipping 13 matching lines...) Expand all Loading... | |
643 // (lazy) compilation time. | 631 // (lazy) compilation time. |
644 ValidateSequentially(&module_env, thrower); | 632 ValidateSequentially(&module_env, thrower); |
645 } | 633 } |
646 if (thrower->error()) return {}; | 634 if (thrower->error()) return {}; |
647 | 635 |
648 // At this point, compilation has completed. Update the code table. | 636 // At this point, compilation has completed. Update the code table. |
649 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 637 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
650 i < temp_instance->function_code.size(); ++i) { | 638 i < temp_instance->function_code.size(); ++i) { |
651 Code* code = *temp_instance->function_code[i]; | 639 Code* code = *temp_instance->function_code[i]; |
652 code_table->set(static_cast<int>(i), code); | 640 code_table->set(static_cast<int>(i), code); |
653 RecordStats(code, counters_); | 641 RecordStats(code, counters()); |
654 } | 642 } |
655 | 643 |
656 // Create heap objects for script, module bytes and asm.js offset table to | 644 // Create heap objects for script, module bytes and asm.js offset table to |
657 // be stored in the shared module data. | 645 // be stored in the shared module data. |
658 Handle<Script> script; | 646 Handle<Script> script; |
659 Handle<ByteArray> asm_js_offset_table; | 647 Handle<ByteArray> asm_js_offset_table; |
660 if (asm_js_script.is_null()) { | 648 if (asm_js_script.is_null()) { |
661 script = CreateWasmScript(isolate_, wire_bytes); | 649 script = CreateWasmScript(isolate_, wire_bytes); |
662 } else { | 650 } else { |
663 script = asm_js_script; | 651 script = asm_js_script; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 JSToWasmWrapperCache js_to_wasm_cache; | 697 JSToWasmWrapperCache js_to_wasm_cache; |
710 int func_index = 0; | 698 int func_index = 0; |
711 for (auto exp : module->export_table) { | 699 for (auto exp : module->export_table) { |
712 if (exp.kind != kExternalFunction) continue; | 700 if (exp.kind != kExternalFunction) continue; |
713 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( | 701 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( |
714 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); | 702 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); |
715 Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( | 703 Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( |
716 isolate_, module, wasm_code, exp.index); | 704 isolate_, module, wasm_code, exp.index); |
717 int export_index = static_cast<int>(module->functions.size() + func_index); | 705 int export_index = static_cast<int>(module->functions.size() + func_index); |
718 code_table->set(export_index, *wrapper_code); | 706 code_table->set(export_index, *wrapper_code); |
719 RecordStats(*wrapper_code, counters_); | 707 RecordStats(*wrapper_code, counters()); |
720 func_index++; | 708 func_index++; |
721 } | 709 } |
722 | 710 |
723 return WasmModuleObject::New(isolate_, compiled_module); | 711 return WasmModuleObject::New(isolate_, compiled_module); |
724 } | 712 } |
725 | 713 |
726 Handle<Code> JSToWasmWrapperCache::CloneOrCompileJSToWasmWrapper( | 714 Handle<Code> JSToWasmWrapperCache::CloneOrCompileJSToWasmWrapper( |
727 Isolate* isolate, const wasm::WasmModule* module, Handle<Code> wasm_code, | 715 Isolate* isolate, const wasm::WasmModule* module, Handle<Code> wasm_code, |
728 uint32_t index) { | 716 uint32_t index) { |
729 const wasm::WasmFunction* func = &module->functions[index]; | 717 const wasm::WasmFunction* func = &module->functions[index]; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
762 WeakCallbackInfo<void>::Callback instance_finalizer_callback) | 750 WeakCallbackInfo<void>::Callback instance_finalizer_callback) |
763 : isolate_(isolate), | 751 : isolate_(isolate), |
764 module_(module_object->compiled_module()->module()), | 752 module_(module_object->compiled_module()->module()), |
765 counters_shared_(isolate->counters_shared()), | 753 counters_shared_(isolate->counters_shared()), |
766 thrower_(thrower), | 754 thrower_(thrower), |
767 module_object_(module_object), | 755 module_object_(module_object), |
768 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() : ffi.ToHandleChecked()), | 756 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() : ffi.ToHandleChecked()), |
769 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() | 757 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() |
770 : memory.ToHandleChecked()), | 758 : memory.ToHandleChecked()), |
771 instance_finalizer_callback_(instance_finalizer_callback) { | 759 instance_finalizer_callback_(instance_finalizer_callback) { |
772 counters_ = counters_shared_.get(); | |
773 } | 760 } |
774 | 761 |
775 // Build an instance, in all of its glory. | 762 // Build an instance, in all of its glory. |
776 MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { | 763 MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { |
777 // Check that an imports argument was provided, if the module requires it. | 764 // Check that an imports argument was provided, if the module requires it. |
778 // No point in continuing otherwise. | 765 // No point in continuing otherwise. |
779 if (!module_->import_table.empty() && ffi_.is_null()) { | 766 if (!module_->import_table.empty() && ffi_.is_null()) { |
780 thrower_->TypeError( | 767 thrower_->TypeError( |
781 "Imports argument must be present and must be an object"); | 768 "Imports argument must be present and must be an object"); |
782 return {}; | 769 return {}; |
783 } | 770 } |
784 | 771 |
785 // Record build time into correct bucket, then build instance. | 772 // Record build time into correct bucket, then build instance. |
786 HistogramTimerScope wasm_instantiate_module_time_scope( | 773 HistogramTimerScope wasm_instantiate_module_time_scope( |
787 module_->is_wasm() | 774 module_->is_wasm() ? counters()->wasm_instantiate_wasm_module_time() |
788 ? isolate_->counters()->wasm_instantiate_wasm_module_time() | 775 : counters()->wasm_instantiate_asm_module_time()); |
789 : isolate_->counters()->wasm_instantiate_asm_module_time()); | |
790 Factory* factory = isolate_->factory(); | 776 Factory* factory = isolate_->factory(); |
791 | 777 |
792 //-------------------------------------------------------------------------- | 778 //-------------------------------------------------------------------------- |
793 // Reuse the compiled module (if no owner), otherwise clone. | 779 // Reuse the compiled module (if no owner), otherwise clone. |
794 //-------------------------------------------------------------------------- | 780 //-------------------------------------------------------------------------- |
795 Handle<FixedArray> code_table; | 781 Handle<FixedArray> code_table; |
796 // We keep around a copy of the old code table, because we'll be replacing | 782 // We keep around a copy of the old code table, because we'll be replacing |
797 // imports for the new instance, and then we need the old imports to be | 783 // imports for the new instance, and then we need the old imports to be |
798 // able to relocate. | 784 // able to relocate. |
799 Handle<FixedArray> old_code_table; | 785 Handle<FixedArray> old_code_table; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
853 case Code::JS_TO_WASM_FUNCTION: | 839 case Code::JS_TO_WASM_FUNCTION: |
854 case Code::WASM_FUNCTION: { | 840 case Code::WASM_FUNCTION: { |
855 Handle<Code> code = factory->CopyCode(orig_code); | 841 Handle<Code> code = factory->CopyCode(orig_code); |
856 code_table->set(i, *code); | 842 code_table->set(i, *code); |
857 break; | 843 break; |
858 } | 844 } |
859 default: | 845 default: |
860 UNREACHABLE(); | 846 UNREACHABLE(); |
861 } | 847 } |
862 } | 848 } |
863 RecordStats(code_table, counters_); | 849 RecordStats(code_table, counters()); |
864 } else { | 850 } else { |
865 // There was no owner, so we can reuse the original. | 851 // There was no owner, so we can reuse the original. |
866 compiled_module_ = original; | 852 compiled_module_ = original; |
867 old_code_table = factory->CopyFixedArray(compiled_module_->code_table()); | 853 old_code_table = factory->CopyFixedArray(compiled_module_->code_table()); |
868 code_table = compiled_module_->code_table(); | 854 code_table = compiled_module_->code_table(); |
869 TRACE("Reusing existing instance %d\n", compiled_module_->instance_id()); | 855 TRACE("Reusing existing instance %d\n", compiled_module_->instance_id()); |
870 } | 856 } |
871 compiled_module_->set_native_context(isolate_->native_context()); | 857 compiled_module_->set_native_context(isolate_->native_context()); |
872 } | 858 } |
873 | 859 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
932 //-------------------------------------------------------------------------- | 918 //-------------------------------------------------------------------------- |
933 // Set up the indirect function tables for the new instance. | 919 // Set up the indirect function tables for the new instance. |
934 //-------------------------------------------------------------------------- | 920 //-------------------------------------------------------------------------- |
935 if (function_table_count > 0) | 921 if (function_table_count > 0) |
936 InitializeTables(instance, &code_specialization); | 922 InitializeTables(instance, &code_specialization); |
937 | 923 |
938 //-------------------------------------------------------------------------- | 924 //-------------------------------------------------------------------------- |
939 // Set up the memory for the new instance. | 925 // Set up the memory for the new instance. |
940 //-------------------------------------------------------------------------- | 926 //-------------------------------------------------------------------------- |
941 uint32_t min_mem_pages = module_->min_mem_pages; | 927 uint32_t min_mem_pages = module_->min_mem_pages; |
942 (module_->is_wasm() ? isolate_->counters()->wasm_wasm_min_mem_pages_count() | 928 (module_->is_wasm() ? counters()->wasm_wasm_min_mem_pages_count() |
943 : isolate_->counters()->wasm_asm_min_mem_pages_count()) | 929 : counters()->wasm_asm_min_mem_pages_count()) |
944 ->AddSample(min_mem_pages); | 930 ->AddSample(min_mem_pages); |
945 | 931 |
946 if (!memory_.is_null()) { | 932 if (!memory_.is_null()) { |
947 // Set externally passed ArrayBuffer non neuterable. | 933 // Set externally passed ArrayBuffer non neuterable. |
948 memory_->set_is_neuterable(false); | 934 memory_->set_is_neuterable(false); |
949 memory_->set_is_wasm_buffer(true); | 935 memory_->set_is_wasm_buffer(true); |
950 | 936 |
951 DCHECK_IMPLIES(EnableGuardRegions(), | 937 DCHECK_IMPLIES(EnableGuardRegions(), |
952 module_->is_asm_js() || memory_->has_guard_region()); | 938 module_->is_asm_js() || memory_->has_guard_region()); |
953 } else if (min_mem_pages > 0) { | 939 } else if (min_mem_pages > 0) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1135 HandleScope scope(isolate_); | 1121 HandleScope scope(isolate_); |
1136 int start_index = module_->start_function_index; | 1122 int start_index = module_->start_function_index; |
1137 Handle<Code> startup_code = EnsureExportedLazyDeoptData( | 1123 Handle<Code> startup_code = EnsureExportedLazyDeoptData( |
1138 isolate_, instance, code_table, start_index); | 1124 isolate_, instance, code_table, start_index); |
1139 FunctionSig* sig = module_->functions[start_index].sig; | 1125 FunctionSig* sig = module_->functions[start_index].sig; |
1140 Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( | 1126 Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( |
1141 isolate_, module_, startup_code, start_index); | 1127 isolate_, module_, startup_code, start_index); |
1142 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( | 1128 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( |
1143 isolate_, instance, MaybeHandle<String>(), start_index, | 1129 isolate_, instance, MaybeHandle<String>(), start_index, |
1144 static_cast<int>(sig->parameter_count()), wrapper_code); | 1130 static_cast<int>(sig->parameter_count()), wrapper_code); |
1145 RecordStats(*startup_code, counters_); | 1131 RecordStats(*startup_code, counters()); |
1146 // Call the JS function. | 1132 // Call the JS function. |
1147 Handle<Object> undefined = factory->undefined_value(); | 1133 Handle<Object> undefined = factory->undefined_value(); |
1148 MaybeHandle<Object> retval = | 1134 MaybeHandle<Object> retval = |
1149 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1135 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
1150 | 1136 |
1151 if (retval.is_null()) { | 1137 if (retval.is_null()) { |
1152 DCHECK(isolate_->has_pending_exception()); | 1138 DCHECK(isolate_->has_pending_exception()); |
1153 isolate_->OptionalRescheduleException(false); | 1139 isolate_->OptionalRescheduleException(false); |
1154 // It's unfortunate that the new instance is already linked in the | 1140 // It's unfortunate that the new instance is already linked in the |
1155 // chain. However, we need to set up everything before executing the | 1141 // chain. However, we need to set up everything before executing the |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1332 Handle<Code> import_wrapper = UnwrapOrCompileImportWrapper( | 1318 Handle<Code> import_wrapper = UnwrapOrCompileImportWrapper( |
1333 isolate_, index, module_->functions[import.index].sig, | 1319 isolate_, index, module_->functions[import.index].sig, |
1334 Handle<JSReceiver>::cast(value), module_name, import_name, | 1320 Handle<JSReceiver>::cast(value), module_name, import_name, |
1335 module_->get_origin(), &imported_wasm_instances); | 1321 module_->get_origin(), &imported_wasm_instances); |
1336 if (import_wrapper.is_null()) { | 1322 if (import_wrapper.is_null()) { |
1337 ReportLinkError("imported function does not match the expected type", | 1323 ReportLinkError("imported function does not match the expected type", |
1338 index, module_name, import_name); | 1324 index, module_name, import_name); |
1339 return -1; | 1325 return -1; |
1340 } | 1326 } |
1341 code_table->set(num_imported_functions, *import_wrapper); | 1327 code_table->set(num_imported_functions, *import_wrapper); |
1342 RecordStats(*import_wrapper, counters_); | 1328 RecordStats(*import_wrapper, counters()); |
1343 num_imported_functions++; | 1329 num_imported_functions++; |
1344 break; | 1330 break; |
1345 } | 1331 } |
1346 case kExternalTable: { | 1332 case kExternalTable: { |
1347 if (!WasmJs::IsWasmTableObject(isolate_, value)) { | 1333 if (!WasmJs::IsWasmTableObject(isolate_, value)) { |
1348 ReportLinkError("table import requires a WebAssembly.Table", index, | 1334 ReportLinkError("table import requires a WebAssembly.Table", index, |
1349 module_name, import_name); | 1335 module_name, import_name); |
1350 return -1; | 1336 return -1; |
1351 } | 1337 } |
1352 WasmIndirectFunctionTable& table = | 1338 WasmIndirectFunctionTable& table = |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1917 Handle<JSPromise> promise) | 1903 Handle<JSPromise> promise) |
1918 : isolate_(isolate), | 1904 : isolate_(isolate), |
1919 counters_shared_(isolate->counters_shared()), | 1905 counters_shared_(isolate->counters_shared()), |
1920 bytes_copy_(std::move(bytes_copy)), | 1906 bytes_copy_(std::move(bytes_copy)), |
1921 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { | 1907 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { |
1922 // The handles for the context and promise must be deferred. | 1908 // The handles for the context and promise must be deferred. |
1923 DeferredHandleScope deferred(isolate); | 1909 DeferredHandleScope deferred(isolate); |
1924 context_ = Handle<Context>(*context); | 1910 context_ = Handle<Context>(*context); |
1925 module_promise_ = Handle<JSPromise>(*promise); | 1911 module_promise_ = Handle<JSPromise>(*promise); |
1926 deferred_handles_.push_back(deferred.Detach()); | 1912 deferred_handles_.push_back(deferred.Detach()); |
1927 counters_ = counters_shared_.get(); | |
1928 } | 1913 } |
1929 | 1914 |
1930 void AsyncCompileJob::Start() { | 1915 void AsyncCompileJob::Start() { |
1931 DoAsync<DecodeModule>(); // -- | 1916 DoAsync<DecodeModule>(); // -- |
1932 } | 1917 } |
1933 | 1918 |
1934 AsyncCompileJob::~AsyncCompileJob() { | 1919 AsyncCompileJob::~AsyncCompileJob() { |
1935 background_task_manager_.CancelAndWait(); | 1920 background_task_manager_.CancelAndWait(); |
1936 for (auto d : deferred_handles_) delete d; | 1921 for (auto d : deferred_handles_) delete d; |
1937 } | 1922 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2042 public: | 2027 public: |
2043 DecodeModule() : CompileStep(1) {} | 2028 DecodeModule() : CompileStep(1) {} |
2044 | 2029 |
2045 void RunInBackground() override { | 2030 void RunInBackground() override { |
2046 ModuleResult result; | 2031 ModuleResult result; |
2047 { | 2032 { |
2048 DisallowHandleAllocation no_handle; | 2033 DisallowHandleAllocation no_handle; |
2049 DisallowHeapAllocation no_allocation; | 2034 DisallowHeapAllocation no_allocation; |
2050 // Decode the module bytes. | 2035 // Decode the module bytes. |
2051 TRACE_COMPILE("(1) Decoding module...\n"); | 2036 TRACE_COMPILE("(1) Decoding module...\n"); |
2052 constexpr bool is_sync = true; | 2037 result = AsyncDecodeWasmModule(job_->isolate_, job_->wire_bytes_.start(), |
2053 result = DecodeWasmModule(job_->isolate_, job_->wire_bytes_.start(), | 2038 job_->wire_bytes_.end(), false, |
2054 job_->wire_bytes_.end(), false, kWasmOrigin, | 2039 kWasmOrigin, job_->counters_shared_); |
Mircea Trofin
2017/06/22 18:42:24
why not the accessor call (job_->counters()) ?
kschimpf
2017/06/22 20:38:31
Because the API expected a shared_ptr<Counters>. H
| |
2055 !is_sync); | |
2056 } | 2040 } |
2057 if (result.failed()) { | 2041 if (result.failed()) { |
2058 // Decoding failure; reject the promise and clean up. | 2042 // Decoding failure; reject the promise and clean up. |
2059 job_->DoSync<DecodeFail>(std::move(result)); | 2043 job_->DoSync<DecodeFail>(std::move(result)); |
2060 } else { | 2044 } else { |
2061 // Decode passed. | 2045 // Decode passed. |
2062 job_->DoSync<PrepareAndStartCompile>(std::move(result.val)); | 2046 job_->DoSync<PrepareAndStartCompile>(std::move(result.val)); |
2063 } | 2047 } |
2064 } | 2048 } |
2065 }; | 2049 }; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2131 | 2115 |
2132 // Initialize {code_table_} with the illegal builtin. All call sites | 2116 // Initialize {code_table_} with the illegal builtin. All call sites |
2133 // will be patched at instantiation. | 2117 // will be patched at instantiation. |
2134 Handle<Code> illegal_builtin = job_->isolate_->builtins()->Illegal(); | 2118 Handle<Code> illegal_builtin = job_->isolate_->builtins()->Illegal(); |
2135 // TODO(wasm): Fix this for lazy compilation. | 2119 // TODO(wasm): Fix this for lazy compilation. |
2136 for (uint32_t i = 0; i < module_->functions.size(); ++i) { | 2120 for (uint32_t i = 0; i < module_->functions.size(); ++i) { |
2137 job_->code_table_->set(static_cast<int>(i), *illegal_builtin); | 2121 job_->code_table_->set(static_cast<int>(i), *illegal_builtin); |
2138 job_->temp_instance_->function_code[i] = illegal_builtin; | 2122 job_->temp_instance_->function_code[i] = illegal_builtin; |
2139 } | 2123 } |
2140 | 2124 |
2141 job_->isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( | 2125 job_->counters()->wasm_functions_per_wasm_module()->AddSample( |
2142 static_cast<int>(module_->functions.size())); | 2126 static_cast<int>(module_->functions.size())); |
2143 | 2127 |
2144 // Transfer ownership of the {WasmModule} to the {ModuleCompiler}, but | 2128 // Transfer ownership of the {WasmModule} to the {ModuleCompiler}, but |
2145 // keep a pointer. | 2129 // keep a pointer. |
2146 WasmModule* module = module_.get(); | 2130 WasmModule* module = module_.get(); |
2147 constexpr bool is_sync = true; | 2131 constexpr bool is_sync = true; |
2148 job_->compiler_.reset( | 2132 job_->compiler_.reset( |
2149 new ModuleCompiler(job_->isolate_, std::move(module_), !is_sync)); | 2133 new ModuleCompiler(job_->isolate_, std::move(module_), !is_sync)); |
2150 job_->compiler_->EnableThrottling(); | 2134 job_->compiler_->EnableThrottling(); |
2151 | 2135 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2285 // Step 5 (sync): Finish heap-allocated data structures. | 2269 // Step 5 (sync): Finish heap-allocated data structures. |
2286 //========================================================================== | 2270 //========================================================================== |
2287 class AsyncCompileJob::FinishCompile : public CompileStep { | 2271 class AsyncCompileJob::FinishCompile : public CompileStep { |
2288 void RunInForeground() override { | 2272 void RunInForeground() override { |
2289 TRACE_COMPILE("(5b) Finish compile...\n"); | 2273 TRACE_COMPILE("(5b) Finish compile...\n"); |
2290 HandleScope scope(job_->isolate_); | 2274 HandleScope scope(job_->isolate_); |
2291 // At this point, compilation has completed. Update the code table. | 2275 // At this point, compilation has completed. Update the code table. |
2292 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 2276 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
2293 i < job_->temp_instance_->function_code.size(); ++i) { | 2277 i < job_->temp_instance_->function_code.size(); ++i) { |
2294 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); | 2278 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); |
2295 RecordStats(code, job_->counters_); | 2279 RecordStats(code, job_->counters()); |
2296 } | 2280 } |
2297 | 2281 |
2298 // Create heap objects for script and module bytes to be stored in the | 2282 // Create heap objects for script and module bytes to be stored in the |
2299 // shared module data. Asm.js is not compiled asynchronously. | 2283 // shared module data. Asm.js is not compiled asynchronously. |
2300 Handle<Script> script = CreateWasmScript(job_->isolate_, job_->wire_bytes_); | 2284 Handle<Script> script = CreateWasmScript(job_->isolate_, job_->wire_bytes_); |
2301 Handle<ByteArray> asm_js_offset_table; | 2285 Handle<ByteArray> asm_js_offset_table; |
2302 // TODO(wasm): Improve efficiency of storing module wire bytes. | 2286 // TODO(wasm): Improve efficiency of storing module wire bytes. |
2303 // 1. Only store relevant sections, not function bodies | 2287 // 1. Only store relevant sections, not function bodies |
2304 // 2. Don't make a second copy of the bytes here; reuse the copy made | 2288 // 2. Don't make a second copy of the bytes here; reuse the copy made |
2305 // for asynchronous compilation and store it as an external one | 2289 // for asynchronous compilation and store it as an external one |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2361 for (auto exp : module->export_table) { | 2345 for (auto exp : module->export_table) { |
2362 if (exp.kind != kExternalFunction) continue; | 2346 if (exp.kind != kExternalFunction) continue; |
2363 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), | 2347 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), |
2364 job_->isolate_); | 2348 job_->isolate_); |
2365 Handle<Code> wrapper_code = | 2349 Handle<Code> wrapper_code = |
2366 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(job_->isolate_, module, | 2350 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(job_->isolate_, module, |
2367 wasm_code, exp.index); | 2351 wasm_code, exp.index); |
2368 int export_index = | 2352 int export_index = |
2369 static_cast<int>(module->functions.size() + func_index); | 2353 static_cast<int>(module->functions.size() + func_index); |
2370 job_->code_table_->set(export_index, *wrapper_code); | 2354 job_->code_table_->set(export_index, *wrapper_code); |
2371 RecordStats(*wrapper_code, job_->counters_); | 2355 RecordStats(*wrapper_code, job_->counters()); |
2372 func_index++; | 2356 func_index++; |
2373 } | 2357 } |
2374 | 2358 |
2375 job_->DoSync<FinishModule>(); | 2359 job_->DoSync<FinishModule>(); |
2376 } | 2360 } |
2377 }; | 2361 }; |
2378 | 2362 |
2379 //========================================================================== | 2363 //========================================================================== |
2380 // Step 7 (sync): Finish the module and resolve the promise. | 2364 // Step 7 (sync): Finish the module and resolve the promise. |
2381 //========================================================================== | 2365 //========================================================================== |
2382 class AsyncCompileJob::FinishModule : public CompileStep { | 2366 class AsyncCompileJob::FinishModule : public CompileStep { |
2383 void RunInForeground() override { | 2367 void RunInForeground() override { |
2384 TRACE_COMPILE("(7) Finish module...\n"); | 2368 TRACE_COMPILE("(7) Finish module...\n"); |
2385 HandleScope scope(job_->isolate_); | 2369 HandleScope scope(job_->isolate_); |
2386 Handle<WasmModuleObject> result = | 2370 Handle<WasmModuleObject> result = |
2387 WasmModuleObject::New(job_->isolate_, job_->compiled_module_); | 2371 WasmModuleObject::New(job_->isolate_, job_->compiled_module_); |
2388 // {job_} is deleted in AsyncCompileSucceeded, therefore the {return}. | 2372 // {job_} is deleted in AsyncCompileSucceeded, therefore the {return}. |
2389 return job_->AsyncCompileSucceeded(result); | 2373 return job_->AsyncCompileSucceeded(result); |
2390 } | 2374 } |
2391 }; | 2375 }; |
2392 } // namespace wasm | 2376 } // namespace wasm |
2393 } // namespace internal | 2377 } // namespace internal |
2394 } // namespace v8 | 2378 } // namespace v8 |
OLD | NEW |