| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "src/assembler-inl.h" | 7 #include "src/assembler-inl.h" |
| 8 #include "src/base/adapters.h" | 8 #include "src/base/adapters.h" |
| 9 #include "src/base/atomic-utils.h" | 9 #include "src/base/atomic-utils.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 uint32_t start = module_env.module_env.module->num_imported_functions + | 352 uint32_t start = module_env.module_env.module->num_imported_functions + |
| 353 FLAG_skip_compiling_wasm_funcs; | 353 FLAG_skip_compiling_wasm_funcs; |
| 354 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); | 354 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); |
| 355 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; | 355 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; |
| 356 compilation_units_.reserve(funcs_to_compile); | 356 compilation_units_.reserve(funcs_to_compile); |
| 357 for (uint32_t i = start; i < num_funcs; ++i) { | 357 for (uint32_t i = start; i < num_funcs; ++i) { |
| 358 const WasmFunction* func = &functions[i]; | 358 const WasmFunction* func = &functions[i]; |
| 359 compilation_units_.push_back( | 359 compilation_units_.push_back( |
| 360 new compiler::WasmCompilationUnit(isolate_, &module_env, func)); | 360 new compiler::WasmCompilationUnit(isolate_, &module_env, func)); |
| 361 } | 361 } |
| 362 return num_funcs; | 362 return funcs_to_compile; |
| 363 } | 363 } |
| 364 | 364 |
| 365 void InitializeHandles() { | 365 void InitializeHandles() { |
| 366 for (auto unit : compilation_units_) { | 366 for (auto unit : compilation_units_) { |
| 367 unit->InitializeHandles(); | 367 unit->InitializeHandles(); |
| 368 } | 368 } |
| 369 } | 369 } |
| 370 | 370 |
| 371 uint32_t* StartCompilationTasks() { | 371 uint32_t* StartCompilationTasks() { |
| 372 num_background_tasks_ = | 372 num_background_tasks_ = |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 isolate_, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes), | 618 isolate_, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes), |
| 619 script, asm_js_offset_table); | 619 script, asm_js_offset_table); |
| 620 if (lazy_compile) WasmSharedModuleData::PrepareForLazyCompilation(shared); | 620 if (lazy_compile) WasmSharedModuleData::PrepareForLazyCompilation(shared); |
| 621 | 621 |
| 622 // Create the compiled module object, and populate with compiled functions | 622 // Create the compiled module object, and populate with compiled functions |
| 623 // and information needed at instantiation time. This object needs to be | 623 // and information needed at instantiation time. This object needs to be |
| 624 // serializable. Instantiation may occur off a deserialized version of this | 624 // serializable. Instantiation may occur off a deserialized version of this |
| 625 // object. | 625 // object. |
| 626 Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New( | 626 Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New( |
| 627 isolate_, shared, code_table, function_tables, signature_tables); | 627 isolate_, shared, code_table, function_tables, signature_tables); |
| 628 if (function_table_count > 0) { | |
| 629 compiled_module->set_function_tables(function_tables); | |
| 630 } | |
| 631 | 628 |
| 632 // If we created a wasm script, finish it now and make it public to the | 629 // If we created a wasm script, finish it now and make it public to the |
| 633 // debugger. | 630 // debugger. |
| 634 if (asm_js_script.is_null()) { | 631 if (asm_js_script.is_null()) { |
| 635 script->set_wasm_compiled_module(*compiled_module); | 632 script->set_wasm_compiled_module(*compiled_module); |
| 636 isolate_->debug()->OnAfterCompile(script); | 633 isolate_->debug()->OnAfterCompile(script); |
| 637 } | 634 } |
| 638 | 635 |
| 639 // Compile JS->WASM wrappers for exported functions. | 636 // Compile JS->WASM wrappers for exported functions. |
| 640 JSToWasmWrapperCache js_to_wasm_cache; | 637 JSToWasmWrapperCache js_to_wasm_cache; |
| (...skipping 2051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 Handle<WasmModuleObject> module_object_; | 2689 Handle<WasmModuleObject> module_object_; |
| 2693 Handle<FixedArray> function_tables_; | 2690 Handle<FixedArray> function_tables_; |
| 2694 Handle<FixedArray> signature_tables_; | 2691 Handle<FixedArray> signature_tables_; |
| 2695 Handle<WasmCompiledModule> compiled_module_; | 2692 Handle<WasmCompiledModule> compiled_module_; |
| 2696 Handle<FixedArray> code_table_; | 2693 Handle<FixedArray> code_table_; |
| 2697 std::unique_ptr<WasmInstance> temp_instance_ = nullptr; | 2694 std::unique_ptr<WasmInstance> temp_instance_ = nullptr; |
| 2698 std::unique_ptr<uint32_t[]> task_ids_ = nullptr; | 2695 std::unique_ptr<uint32_t[]> task_ids_ = nullptr; |
| 2699 size_t outstanding_units_ = 0; | 2696 size_t outstanding_units_ = 0; |
| 2700 size_t num_background_tasks_ = 0; | 2697 size_t num_background_tasks_ = 0; |
| 2701 | 2698 |
| 2699 void ReopenHandlesInDeferredScope() { |
| 2700 DeferredHandleScope deferred(isolate_); |
| 2701 module_wrapper_ = handle(*module_wrapper_, isolate_); |
| 2702 function_tables_ = handle(*function_tables_, isolate_); |
| 2703 signature_tables_ = handle(*signature_tables_, isolate_); |
| 2704 code_table_ = handle(*code_table_, isolate_); |
| 2705 temp_instance_->ReopenHandles(isolate_); |
| 2706 helper_->InitializeHandles(); |
| 2707 deferred_handles_.push_back(deferred.Detach()); |
| 2708 } |
| 2709 |
| 2702 //========================================================================== | 2710 //========================================================================== |
| 2703 // Step 1: (async) Decode the module. | 2711 // Step 1: (async) Decode the module. |
| 2704 //========================================================================== | 2712 //========================================================================== |
| 2705 bool DecodeModule() { | 2713 bool DecodeModule() { |
| 2706 { | 2714 { |
| 2707 DisallowHandleAllocation no_handle; | 2715 DisallowHandleAllocation no_handle; |
| 2708 DisallowHeapAllocation no_allocation; | 2716 DisallowHeapAllocation no_allocation; |
| 2709 // Decode the module bytes. | 2717 // Decode the module bytes. |
| 2710 TRACE_COMPILE("(1) Decoding module...\n"); | 2718 TRACE_COMPILE("(1) Decoding module...\n"); |
| 2711 result_ = DecodeWasmModule(isolate_, wire_bytes_.start(), | 2719 result_ = DecodeWasmModule(isolate_, wire_bytes_.start(), |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 | 2788 |
| 2781 isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( | 2789 isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( |
| 2782 static_cast<int>(module_->functions.size())); | 2790 static_cast<int>(module_->functions.size())); |
| 2783 | 2791 |
| 2784 helper_.reset(new CompilationHelper(isolate_, module_)); | 2792 helper_.reset(new CompilationHelper(isolate_, module_)); |
| 2785 | 2793 |
| 2786 DCHECK_LE(module_->num_imported_functions, module_->functions.size()); | 2794 DCHECK_LE(module_->num_imported_functions, module_->functions.size()); |
| 2787 size_t num_functions = | 2795 size_t num_functions = |
| 2788 module_->functions.size() - module_->num_imported_functions; | 2796 module_->functions.size() - module_->num_imported_functions; |
| 2789 if (num_functions == 0) { | 2797 if (num_functions == 0) { |
| 2790 DeferredHandleScope deferred(isolate_); | 2798 ReopenHandlesInDeferredScope(); |
| 2791 module_wrapper_ = handle(*module_wrapper_, isolate_); | |
| 2792 deferred_handles_.push_back(deferred.Detach()); | |
| 2793 // Degenerate case of an empty module. | 2799 // Degenerate case of an empty module. |
| 2794 return DoSync(&AsyncCompileJob::FinishCompile); | 2800 return DoSync(&AsyncCompileJob::FinishCompile); |
| 2795 } | 2801 } |
| 2796 | 2802 |
| 2797 // Start asynchronous compilation tasks. | 2803 // Start asynchronous compilation tasks. |
| 2798 num_background_tasks_ = | 2804 num_background_tasks_ = |
| 2799 Max(static_cast<size_t>(1), | 2805 Max(static_cast<size_t>(1), |
| 2800 Min(num_functions, | 2806 Min(num_functions, |
| 2801 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), | 2807 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), |
| 2802 V8::GetCurrentPlatform() | 2808 V8::GetCurrentPlatform() |
| 2803 ->NumberOfAvailableBackgroundThreads()))); | 2809 ->NumberOfAvailableBackgroundThreads()))); |
| 2804 module_bytes_env_ = std::unique_ptr<ModuleBytesEnv>( | 2810 module_bytes_env_ = std::unique_ptr<ModuleBytesEnv>( |
| 2805 new ModuleBytesEnv(module_, temp_instance_.get(), wire_bytes_)); | 2811 new ModuleBytesEnv(module_, temp_instance_.get(), wire_bytes_)); |
| 2806 outstanding_units_ = helper_->InitializeParallelCompilation( | 2812 outstanding_units_ = helper_->InitializeParallelCompilation( |
| 2807 module_->functions, *module_bytes_env_); | 2813 module_->functions, *module_bytes_env_); |
| 2808 | 2814 |
| 2809 // Reopen all handles which should survive in the DeferredHandleScope. | 2815 // Reopen all handles which should survive in the DeferredHandleScope. |
| 2810 DeferredHandleScope deferred(isolate_); | 2816 ReopenHandlesInDeferredScope(); |
| 2811 module_wrapper_ = handle(*module_wrapper_, isolate_); | |
| 2812 function_tables_ = handle(*function_tables_, isolate_); | |
| 2813 signature_tables_ = handle(*signature_tables_, isolate_); | |
| 2814 code_table_ = handle(*code_table_, isolate_); | |
| 2815 temp_instance_->ReopenHandles(isolate_); | |
| 2816 helper_->InitializeHandles(); | |
| 2817 deferred_handles_.push_back(deferred.Detach()); | |
| 2818 | |
| 2819 task_ids_ = | 2817 task_ids_ = |
| 2820 std::unique_ptr<uint32_t[]>(new uint32_t[num_background_tasks_]); | 2818 std::unique_ptr<uint32_t[]>(new uint32_t[num_background_tasks_]); |
| 2821 for (size_t i = 0; i < num_background_tasks_; ++i) { | 2819 for (size_t i = 0; i < num_background_tasks_; ++i) { |
| 2822 DoAsync(&AsyncCompileJob::ExecuteCompilationUnits, &(task_ids_.get())[i]); | 2820 DoAsync(&AsyncCompileJob::ExecuteCompilationUnits, &(task_ids_.get())[i]); |
| 2823 } | 2821 } |
| 2824 return true; | 2822 return true; |
| 2825 } | 2823 } |
| 2826 | 2824 |
| 2827 //========================================================================== | 2825 //========================================================================== |
| 2828 // Step 3 (async x K tasks): Execute compilation units. | 2826 // Step 3 (async x K tasks): Execute compilation units. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2856 if (failed_) return true; // already failed | 2854 if (failed_) return true; // already failed |
| 2857 | 2855 |
| 2858 int func_index = -1; | 2856 int func_index = -1; |
| 2859 ErrorThrower thrower(isolate_, nullptr); | 2857 ErrorThrower thrower(isolate_, nullptr); |
| 2860 Handle<Code> result = helper_->FinishCompilationUnit(&thrower, &func_index); | 2858 Handle<Code> result = helper_->FinishCompilationUnit(&thrower, &func_index); |
| 2861 if (thrower.error()) { | 2859 if (thrower.error()) { |
| 2862 RejectPromise(isolate_, context_, &thrower, module_promise_); | 2860 RejectPromise(isolate_, context_, &thrower, module_promise_); |
| 2863 failed_ = true; | 2861 failed_ = true; |
| 2864 } else { | 2862 } else { |
| 2865 DCHECK(func_index >= 0); | 2863 DCHECK(func_index >= 0); |
| 2866 code_table_->set(func_index + module_->num_imported_functions, *(result)); | 2864 code_table_->set(func_index, *(result)); |
| 2867 } | 2865 } |
| 2868 if (failed_ || --outstanding_units_ == 0) { | 2866 if (failed_ || --outstanding_units_ == 0) { |
| 2869 // All compilation units are done. We still need to wait for the | 2867 // All compilation units are done. We still need to wait for the |
| 2870 // background tasks to shut down and only then is it safe to finish the | 2868 // background tasks to shut down and only then is it safe to finish the |
| 2871 // compile and delete this job. We can wait for that to happen also | 2869 // compile and delete this job. We can wait for that to happen also |
| 2872 // in a background task. | 2870 // in a background task. |
| 2873 DoAsync(&AsyncCompileJob::WaitForBackgroundTasks); | 2871 DoAsync(&AsyncCompileJob::WaitForBackgroundTasks); |
| 2874 } | 2872 } |
| 2875 return true; | 2873 return true; |
| 2876 } | 2874 } |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3305 callee_compiled->instruction_start()); | 3303 callee_compiled->instruction_start()); |
| 3306 } | 3304 } |
| 3307 DCHECK_EQ(non_compiled_functions.size(), idx); | 3305 DCHECK_EQ(non_compiled_functions.size(), idx); |
| 3308 } | 3306 } |
| 3309 | 3307 |
| 3310 Code* ret = | 3308 Code* ret = |
| 3311 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 3309 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
| 3312 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 3310 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
| 3313 return handle(ret, isolate); | 3311 return handle(ret, isolate); |
| 3314 } | 3312 } |
| OLD | NEW |