Chromium Code Reviews| 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 |