| 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 |