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 <functional> | 5 #include <functional> |
6 #include <memory> | 6 #include <memory> |
7 | 7 |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/debug/interface-types.h" | 9 #include "src/debug/interface-types.h" |
10 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 | 744 |
745 for (int i = 0; i < num_custom_sections; i++) { | 745 for (int i = 0; i < num_custom_sections; i++) { |
746 storage->set(i, *matching_sections[i]); | 746 storage->set(i, *matching_sections[i]); |
747 } | 747 } |
748 | 748 |
749 return array_object; | 749 return array_object; |
750 } | 750 } |
751 | 751 |
752 bool wasm::SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes) { | 752 bool wasm::SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes) { |
753 if (bytes.start() == nullptr || bytes.length() == 0) return false; | 753 if (bytes.start() == nullptr || bytes.length() == 0) return false; |
754 ModuleResult result = | 754 ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(), |
755 DecodeWasmModule(isolate, bytes.start(), bytes.end(), true, kWasmOrigin); | 755 bytes.end(), true, kWasmOrigin); |
756 return result.ok(); | 756 return result.ok(); |
757 } | 757 } |
758 | 758 |
759 MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs( | 759 MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs( |
760 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, | 760 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, |
761 Handle<Script> asm_js_script, | 761 Handle<Script> asm_js_script, |
762 Vector<const byte> asm_js_offset_table_bytes) { | 762 Vector<const byte> asm_js_offset_table_bytes) { |
763 | 763 ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(), |
764 ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(), | 764 bytes.end(), false, kAsmJsOrigin); |
765 false, kAsmJsOrigin); | |
766 if (result.failed()) { | 765 if (result.failed()) { |
767 thrower->CompileFailed("Wasm decoding failed", result); | 766 thrower->CompileFailed("Wasm decoding failed", result); |
768 return {}; | 767 return {}; |
769 } | 768 } |
770 | 769 |
771 // Transfer ownership to the {WasmModuleWrapper} generated in | 770 // Transfer ownership to the {WasmModuleWrapper} generated in |
772 // {CompileToModuleObject}. | 771 // {CompileToModuleObject}. |
773 constexpr bool is_sync = true; | 772 constexpr bool is_sync = true; |
774 ModuleCompiler helper(isolate, std::move(result.val), is_sync); | 773 ModuleCompiler helper(isolate, std::move(result.val), is_sync); |
775 return helper.CompileToModuleObject(thrower, bytes, asm_js_script, | 774 return helper.CompileToModuleObject(thrower, bytes, asm_js_script, |
776 asm_js_offset_table_bytes); | 775 asm_js_offset_table_bytes); |
777 } | 776 } |
778 | 777 |
779 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate, | 778 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate, |
780 ErrorThrower* thrower, | 779 ErrorThrower* thrower, |
781 const ModuleWireBytes& bytes) { | 780 const ModuleWireBytes& bytes) { |
782 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) { | 781 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) { |
783 thrower->CompileError("Wasm code generation disallowed in this context"); | 782 thrower->CompileError("Wasm code generation disallowed in this context"); |
784 return {}; | 783 return {}; |
785 } | 784 } |
786 | 785 |
787 ModuleResult result = | 786 ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(), |
788 DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin); | 787 bytes.end(), false, kWasmOrigin); |
789 if (result.failed()) { | 788 if (result.failed()) { |
790 thrower->CompileFailed("Wasm decoding failed", result); | 789 thrower->CompileFailed("Wasm decoding failed", result); |
791 return {}; | 790 return {}; |
792 } | 791 } |
793 | 792 |
794 // Transfer ownership to the {WasmModuleWrapper} generated in | 793 // Transfer ownership to the {WasmModuleWrapper} generated in |
795 // {CompileToModuleObject}. | 794 // {CompileToModuleObject}. |
796 constexpr bool is_sync = true; | 795 constexpr bool is_sync = true; |
797 ModuleCompiler helper(isolate, std::move(result.val), is_sync); | 796 ModuleCompiler helper(isolate, std::move(result.val), is_sync); |
798 return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(), | 797 return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(), |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 // do the patching redundantly. | 950 // do the patching redundantly. |
952 Handle<FixedArray> new_deopt_data = | 951 Handle<FixedArray> new_deopt_data = |
953 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED); | 952 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED); |
954 lazy_compile_code->set_deoptimization_data(*new_deopt_data); | 953 lazy_compile_code->set_deoptimization_data(*new_deopt_data); |
955 } | 954 } |
956 | 955 |
957 return compiled_code; | 956 return compiled_code; |
958 } | 957 } |
959 | 958 |
960 void LazyCompilationOrchestrator::CompileFunction( | 959 void LazyCompilationOrchestrator::CompileFunction( |
961 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index, | 960 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index) { |
962 Counters* counters) { | |
963 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), | 961 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), |
964 isolate); | 962 isolate); |
965 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() == | 963 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() == |
966 Code::WASM_FUNCTION) { | 964 Code::WASM_FUNCTION) { |
967 return; | 965 return; |
968 } | 966 } |
969 | 967 |
970 size_t num_function_tables = | 968 size_t num_function_tables = |
971 compiled_module->module()->function_tables.size(); | 969 compiled_module->module()->function_tables.size(); |
972 // Store a vector of handles to be embedded in the generated code. | 970 // Store a vector of handles to be embedded in the generated code. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr); | 1037 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr); |
1040 if (mem_size > 0) { | 1038 if (mem_size > 0) { |
1041 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start, | 1039 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start, |
1042 mem_size); | 1040 mem_size); |
1043 } | 1041 } |
1044 } | 1042 } |
1045 code_specialization.RelocateDirectCalls(instance); | 1043 code_specialization.RelocateDirectCalls(instance); |
1046 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH); | 1044 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH); |
1047 Assembler::FlushICache(isolate, code->instruction_start(), | 1045 Assembler::FlushICache(isolate, code->instruction_start(), |
1048 code->instruction_size()); | 1046 code->instruction_size()); |
1049 RecordLazyCodeStats(*code, counters); | 1047 RecordLazyCodeStats(*code, isolate->counters()); |
1050 } | 1048 } |
1051 | 1049 |
1052 Handle<Code> LazyCompilationOrchestrator::CompileLazy( | 1050 Handle<Code> LazyCompilationOrchestrator::CompileLazy( |
1053 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, | 1051 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, |
1054 int call_offset, int exported_func_index, bool patch_caller) { | 1052 int call_offset, int exported_func_index, bool patch_caller) { |
1055 struct NonCompiledFunction { | 1053 struct NonCompiledFunction { |
1056 int offset; | 1054 int offset; |
1057 int func_index; | 1055 int func_index; |
1058 }; | 1056 }; |
1059 std::shared_ptr<Counters> counters_shared = isolate->counters_shared(); | |
1060 std::vector<NonCompiledFunction> non_compiled_functions; | 1057 std::vector<NonCompiledFunction> non_compiled_functions; |
1061 int func_to_return_idx = exported_func_index; | 1058 int func_to_return_idx = exported_func_index; |
1062 wasm::Decoder decoder(nullptr, nullptr); | 1059 wasm::Decoder decoder(nullptr, nullptr); |
1063 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; | 1060 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; |
1064 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), | 1061 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), |
1065 isolate); | 1062 isolate); |
1066 | 1063 |
1067 if (is_js_to_wasm) { | 1064 if (is_js_to_wasm) { |
1068 non_compiled_functions.push_back({0, exported_func_index}); | 1065 non_compiled_functions.push_back({0, exported_func_index}); |
1069 } else if (patch_caller) { | 1066 } else if (patch_caller) { |
(...skipping 23 matching lines...) Expand all Loading... |
1093 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); | 1090 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); |
1094 non_compiled_functions.push_back({offset, called_func_index}); | 1091 non_compiled_functions.push_back({offset, called_func_index}); |
1095 // Call offset one instruction after the call. Remember the last called | 1092 // Call offset one instruction after the call. Remember the last called |
1096 // function before that offset. | 1093 // function before that offset. |
1097 if (offset < call_offset) func_to_return_idx = called_func_index; | 1094 if (offset < call_offset) func_to_return_idx = called_func_index; |
1098 } | 1095 } |
1099 } | 1096 } |
1100 | 1097 |
1101 // TODO(clemensh): compile all functions in non_compiled_functions in | 1098 // TODO(clemensh): compile all functions in non_compiled_functions in |
1102 // background, wait for func_to_return_idx. | 1099 // background, wait for func_to_return_idx. |
1103 CompileFunction(isolate, instance, func_to_return_idx, counters_shared.get()); | 1100 CompileFunction(isolate, instance, func_to_return_idx); |
1104 | 1101 |
1105 if (is_js_to_wasm || patch_caller) { | 1102 if (is_js_to_wasm || patch_caller) { |
1106 DisallowHeapAllocation no_gc; | 1103 DisallowHeapAllocation no_gc; |
1107 // Now patch the code object with all functions which are now compiled. | 1104 // Now patch the code object with all functions which are now compiled. |
1108 int idx = 0; | 1105 int idx = 0; |
1109 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); | 1106 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); |
1110 it.next()) { | 1107 it.next()) { |
1111 Code* callee = | 1108 Code* callee = |
1112 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); | 1109 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
1113 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; | 1110 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; |
(...skipping 22 matching lines...) Expand all Loading... |
1136 callee_compiled->instruction_start()); | 1133 callee_compiled->instruction_start()); |
1137 } | 1134 } |
1138 DCHECK_EQ(non_compiled_functions.size(), idx); | 1135 DCHECK_EQ(non_compiled_functions.size(), idx); |
1139 } | 1136 } |
1140 | 1137 |
1141 Code* ret = | 1138 Code* ret = |
1142 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 1139 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
1143 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 1140 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
1144 return handle(ret, isolate); | 1141 return handle(ret, isolate); |
1145 } | 1142 } |
OLD | NEW |