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 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2728 Handle<WasmModuleObject> module_object_; | 2725 Handle<WasmModuleObject> module_object_; |
2729 Handle<FixedArray> function_tables_; | 2726 Handle<FixedArray> function_tables_; |
2730 Handle<FixedArray> signature_tables_; | 2727 Handle<FixedArray> signature_tables_; |
2731 Handle<WasmCompiledModule> compiled_module_; | 2728 Handle<WasmCompiledModule> compiled_module_; |
2732 Handle<FixedArray> code_table_; | 2729 Handle<FixedArray> code_table_; |
2733 std::unique_ptr<WasmInstance> temp_instance_ = nullptr; | 2730 std::unique_ptr<WasmInstance> temp_instance_ = nullptr; |
2734 std::unique_ptr<uint32_t[]> task_ids_ = nullptr; | 2731 std::unique_ptr<uint32_t[]> task_ids_ = nullptr; |
2735 size_t outstanding_units_ = 0; | 2732 size_t outstanding_units_ = 0; |
2736 size_t num_background_tasks_ = 0; | 2733 size_t num_background_tasks_ = 0; |
2737 | 2734 |
2735 void MoveHandlesToDeferred() { | |
2736 DeferredHandleScope deferred(isolate_); | |
2737 module_wrapper_ = handle(*module_wrapper_, isolate_); | |
2738 function_tables_ = handle(*function_tables_, isolate_); | |
2739 signature_tables_ = handle(*signature_tables_, isolate_); | |
2740 code_table_ = handle(*code_table_, isolate_); | |
2741 temp_instance_->ReopenHandles(isolate_); | |
2742 helper_->InitializeHandles(); | |
2743 deferred_handles_.push_back(deferred.Detach()); | |
2744 } | |
2745 | |
2738 //========================================================================== | 2746 //========================================================================== |
2739 // Step 1: (async) Decode the module. | 2747 // Step 1: (async) Decode the module. |
2740 //========================================================================== | 2748 //========================================================================== |
2741 bool DecodeModule() { | 2749 bool DecodeModule() { |
2742 { | 2750 { |
2743 DisallowHandleAllocation no_handle; | 2751 DisallowHandleAllocation no_handle; |
2744 DisallowHeapAllocation no_allocation; | 2752 DisallowHeapAllocation no_allocation; |
2745 // Decode the module bytes. | 2753 // Decode the module bytes. |
2746 TRACE_COMPILE("(1) Decoding module...\n"); | 2754 TRACE_COMPILE("(1) Decoding module...\n"); |
2747 result_ = DecodeWasmModule(isolate_, wire_bytes_.start(), | 2755 result_ = DecodeWasmModule(isolate_, wire_bytes_.start(), |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2816 | 2824 |
2817 isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( | 2825 isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( |
2818 static_cast<int>(module_->functions.size())); | 2826 static_cast<int>(module_->functions.size())); |
2819 | 2827 |
2820 helper_.reset(new CompilationHelper(isolate_, module_)); | 2828 helper_.reset(new CompilationHelper(isolate_, module_)); |
2821 | 2829 |
2822 DCHECK_LE(module_->num_imported_functions, module_->functions.size()); | 2830 DCHECK_LE(module_->num_imported_functions, module_->functions.size()); |
2823 size_t num_functions = | 2831 size_t num_functions = |
2824 module_->functions.size() - module_->num_imported_functions; | 2832 module_->functions.size() - module_->num_imported_functions; |
2825 if (num_functions == 0) { | 2833 if (num_functions == 0) { |
2826 DeferredHandleScope deferred(isolate_); | 2834 MoveHandlesToDeferred(); |
ahaas
2017/04/10 07:01:38
The usual name that is used elsewhere in V8 is {Re
Mircea Trofin
2017/04/10 13:35:09
Thanks - I assume you mean ReopenHandles as a suff
| |
2827 module_wrapper_ = handle(*module_wrapper_, isolate_); | |
2828 deferred_handles_.push_back(deferred.Detach()); | |
2829 // Degenerate case of an empty module. | 2835 // Degenerate case of an empty module. |
2830 return DoSync(&AsyncCompileJob::FinishCompile); | 2836 return DoSync(&AsyncCompileJob::FinishCompile); |
2831 } | 2837 } |
2832 | 2838 |
2833 // Start asynchronous compilation tasks. | 2839 // Start asynchronous compilation tasks. |
2834 num_background_tasks_ = | 2840 num_background_tasks_ = |
2835 Max(static_cast<size_t>(1), | 2841 Max(static_cast<size_t>(1), |
2836 Min(num_functions, | 2842 Min(num_functions, |
2837 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), | 2843 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), |
2838 V8::GetCurrentPlatform() | 2844 V8::GetCurrentPlatform() |
2839 ->NumberOfAvailableBackgroundThreads()))); | 2845 ->NumberOfAvailableBackgroundThreads()))); |
2840 module_bytes_env_ = std::unique_ptr<ModuleBytesEnv>( | 2846 module_bytes_env_ = std::unique_ptr<ModuleBytesEnv>( |
2841 new ModuleBytesEnv(module_, temp_instance_.get(), wire_bytes_)); | 2847 new ModuleBytesEnv(module_, temp_instance_.get(), wire_bytes_)); |
2842 outstanding_units_ = helper_->InitializeParallelCompilation( | 2848 outstanding_units_ = helper_->InitializeParallelCompilation( |
2843 module_->functions, *module_bytes_env_); | 2849 module_->functions, *module_bytes_env_); |
2844 | 2850 |
2845 // Reopen all handles which should survive in the DeferredHandleScope. | 2851 // Reopen all handles which should survive in the DeferredHandleScope. |
2846 DeferredHandleScope deferred(isolate_); | 2852 MoveHandlesToDeferred(); |
2847 module_wrapper_ = handle(*module_wrapper_, isolate_); | |
2848 function_tables_ = handle(*function_tables_, isolate_); | |
2849 signature_tables_ = handle(*signature_tables_, isolate_); | |
2850 code_table_ = handle(*code_table_, isolate_); | |
2851 temp_instance_->ReopenHandles(isolate_); | |
2852 helper_->InitializeHandles(); | |
2853 deferred_handles_.push_back(deferred.Detach()); | |
2854 | |
2855 task_ids_ = | 2853 task_ids_ = |
2856 std::unique_ptr<uint32_t[]>(new uint32_t[num_background_tasks_]); | 2854 std::unique_ptr<uint32_t[]>(new uint32_t[num_background_tasks_]); |
2857 for (size_t i = 0; i < num_background_tasks_; ++i) { | 2855 for (size_t i = 0; i < num_background_tasks_; ++i) { |
2858 DoAsync(&AsyncCompileJob::ExecuteCompilationUnits, &(task_ids_.get())[i]); | 2856 DoAsync(&AsyncCompileJob::ExecuteCompilationUnits, &(task_ids_.get())[i]); |
2859 } | 2857 } |
2860 return true; | 2858 return true; |
2861 } | 2859 } |
2862 | 2860 |
2863 //========================================================================== | 2861 //========================================================================== |
2864 // Step 3 (async x K tasks): Execute compilation units. | 2862 // Step 3 (async x K tasks): Execute compilation units. |
(...skipping 27 matching lines...) Expand all Loading... | |
2892 if (failed_) return true; // already failed | 2890 if (failed_) return true; // already failed |
2893 | 2891 |
2894 int func_index = -1; | 2892 int func_index = -1; |
2895 ErrorThrower thrower(isolate_, nullptr); | 2893 ErrorThrower thrower(isolate_, nullptr); |
2896 Handle<Code> result = helper_->FinishCompilationUnit(&thrower, &func_index); | 2894 Handle<Code> result = helper_->FinishCompilationUnit(&thrower, &func_index); |
2897 if (thrower.error()) { | 2895 if (thrower.error()) { |
2898 RejectPromise(isolate_, context_, &thrower, module_promise_); | 2896 RejectPromise(isolate_, context_, &thrower, module_promise_); |
2899 failed_ = true; | 2897 failed_ = true; |
2900 } else { | 2898 } else { |
2901 DCHECK(func_index >= 0); | 2899 DCHECK(func_index >= 0); |
2902 code_table_->set(func_index + module_->num_imported_functions, *(result)); | 2900 code_table_->set(func_index, *(result)); |
2903 } | 2901 } |
2904 if (failed_ || --outstanding_units_ == 0) { | 2902 if (failed_ || --outstanding_units_ == 0) { |
2905 // All compilation units are done. We still need to wait for the | 2903 // All compilation units are done. We still need to wait for the |
2906 // background tasks to shut down and only then is it safe to finish the | 2904 // background tasks to shut down and only then is it safe to finish the |
2907 // compile and delete this job. We can wait for that to happen also | 2905 // compile and delete this job. We can wait for that to happen also |
2908 // in a background task. | 2906 // in a background task. |
2909 DoAsync(&AsyncCompileJob::WaitForBackgroundTasks); | 2907 DoAsync(&AsyncCompileJob::WaitForBackgroundTasks); |
2910 } | 2908 } |
2911 return true; | 2909 return true; |
2912 } | 2910 } |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3341 callee_compiled->instruction_start()); | 3339 callee_compiled->instruction_start()); |
3342 } | 3340 } |
3343 DCHECK_EQ(non_compiled_functions.size(), idx); | 3341 DCHECK_EQ(non_compiled_functions.size(), idx); |
3344 } | 3342 } |
3345 | 3343 |
3346 Code* ret = | 3344 Code* ret = |
3347 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 3345 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
3348 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 3346 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
3349 return handle(ret, isolate); | 3347 return handle(ret, isolate); |
3350 } | 3348 } |
OLD | NEW |