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 |