| 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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 | 738 |
| 739 for (int i = 0; i < num_custom_sections; i++) { | 739 for (int i = 0; i < num_custom_sections; i++) { |
| 740 storage->set(i, *matching_sections[i]); | 740 storage->set(i, *matching_sections[i]); |
| 741 } | 741 } |
| 742 | 742 |
| 743 return array_object; | 743 return array_object; |
| 744 } | 744 } |
| 745 | 745 |
| 746 bool wasm::SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes) { | 746 bool wasm::SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes) { |
| 747 if (bytes.start() == nullptr || bytes.length() == 0) return false; | 747 if (bytes.start() == nullptr || bytes.length() == 0) return false; |
| 748 ModuleResult result = | 748 ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(), |
| 749 DecodeWasmModule(isolate, bytes.start(), bytes.end(), true, kWasmOrigin); | 749 bytes.end(), true, kWasmOrigin); |
| 750 return result.ok(); | 750 return result.ok(); |
| 751 } | 751 } |
| 752 | 752 |
| 753 MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs( | 753 MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs( |
| 754 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, | 754 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, |
| 755 Handle<Script> asm_js_script, | 755 Handle<Script> asm_js_script, |
| 756 Vector<const byte> asm_js_offset_table_bytes) { | 756 Vector<const byte> asm_js_offset_table_bytes) { |
| 757 | 757 ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(), |
| 758 ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(), | 758 bytes.end(), false, kAsmJsOrigin); |
| 759 false, kAsmJsOrigin); | |
| 760 if (result.failed()) { | 759 if (result.failed()) { |
| 761 thrower->CompileFailed("Wasm decoding failed", result); | 760 thrower->CompileFailed("Wasm decoding failed", result); |
| 762 return {}; | 761 return {}; |
| 763 } | 762 } |
| 764 | 763 |
| 765 // Transfer ownership to the {WasmModuleWrapper} generated in | 764 // Transfer ownership to the {WasmModuleWrapper} generated in |
| 766 // {CompileToModuleObject}. | 765 // {CompileToModuleObject}. |
| 767 constexpr bool is_sync = true; | 766 constexpr bool is_sync = true; |
| 768 ModuleCompiler helper(isolate, std::move(result.val), is_sync); | 767 ModuleCompiler helper(isolate, std::move(result.val), is_sync); |
| 769 return helper.CompileToModuleObject(thrower, bytes, asm_js_script, | 768 return helper.CompileToModuleObject(thrower, bytes, asm_js_script, |
| 770 asm_js_offset_table_bytes); | 769 asm_js_offset_table_bytes); |
| 771 } | 770 } |
| 772 | 771 |
| 773 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate, | 772 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate, |
| 774 ErrorThrower* thrower, | 773 ErrorThrower* thrower, |
| 775 const ModuleWireBytes& bytes) { | 774 const ModuleWireBytes& bytes) { |
| 776 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) { | 775 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) { |
| 777 thrower->CompileError("Wasm code generation disallowed in this context"); | 776 thrower->CompileError("Wasm code generation disallowed in this context"); |
| 778 return {}; | 777 return {}; |
| 779 } | 778 } |
| 780 | 779 |
| 781 ModuleResult result = | 780 ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(), |
| 782 DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin); | 781 bytes.end(), false, kWasmOrigin); |
| 783 if (result.failed()) { | 782 if (result.failed()) { |
| 784 thrower->CompileFailed("Wasm decoding failed", result); | 783 thrower->CompileFailed("Wasm decoding failed", result); |
| 785 return {}; | 784 return {}; |
| 786 } | 785 } |
| 787 | 786 |
| 788 // Transfer ownership to the {WasmModuleWrapper} generated in | 787 // Transfer ownership to the {WasmModuleWrapper} generated in |
| 789 // {CompileToModuleObject}. | 788 // {CompileToModuleObject}. |
| 790 constexpr bool is_sync = true; | 789 constexpr bool is_sync = true; |
| 791 ModuleCompiler helper(isolate, std::move(result.val), is_sync); | 790 ModuleCompiler helper(isolate, std::move(result.val), is_sync); |
| 792 return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(), | 791 return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(), |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 // do the patching redundantly. | 929 // do the patching redundantly. |
| 931 Handle<FixedArray> new_deopt_data = | 930 Handle<FixedArray> new_deopt_data = |
| 932 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED); | 931 isolate->factory()->CopyFixedArrayUpTo(exp_deopt_data, 2, TENURED); |
| 933 lazy_compile_code->set_deoptimization_data(*new_deopt_data); | 932 lazy_compile_code->set_deoptimization_data(*new_deopt_data); |
| 934 } | 933 } |
| 935 | 934 |
| 936 return compiled_code; | 935 return compiled_code; |
| 937 } | 936 } |
| 938 | 937 |
| 939 void LazyCompilationOrchestrator::CompileFunction( | 938 void LazyCompilationOrchestrator::CompileFunction( |
| 940 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index, | 939 Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index) { |
| 941 Counters* counters) { | |
| 942 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), | 940 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), |
| 943 isolate); | 941 isolate); |
| 944 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() == | 942 if (Code::cast(compiled_module->code_table()->get(func_index))->kind() == |
| 945 Code::WASM_FUNCTION) { | 943 Code::WASM_FUNCTION) { |
| 946 return; | 944 return; |
| 947 } | 945 } |
| 948 | 946 |
| 949 size_t num_function_tables = | 947 size_t num_function_tables = |
| 950 compiled_module->module()->function_tables.size(); | 948 compiled_module->module()->function_tables.size(); |
| 951 // Store a vector of handles to be embedded in the generated code. | 949 // Store a vector of handles to be embedded in the generated code. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr); | 1017 DCHECK_IMPLIES(mem_size == 0, mem_start == nullptr); |
| 1020 if (mem_size > 0) { | 1018 if (mem_size > 0) { |
| 1021 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start, | 1019 code_specialization.RelocateMemoryReferences(nullptr, 0, mem_start, |
| 1022 mem_size); | 1020 mem_size); |
| 1023 } | 1021 } |
| 1024 } | 1022 } |
| 1025 code_specialization.RelocateDirectCalls(instance); | 1023 code_specialization.RelocateDirectCalls(instance); |
| 1026 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH); | 1024 code_specialization.ApplyToWasmCode(*code, SKIP_ICACHE_FLUSH); |
| 1027 Assembler::FlushICache(isolate, code->instruction_start(), | 1025 Assembler::FlushICache(isolate, code->instruction_start(), |
| 1028 code->instruction_size()); | 1026 code->instruction_size()); |
| 1029 RecordLazyCodeStats(*code, counters); | 1027 RecordLazyCodeStats(*code, isolate->counters()); |
| 1030 } | 1028 } |
| 1031 | 1029 |
| 1032 Handle<Code> LazyCompilationOrchestrator::CompileLazy( | 1030 Handle<Code> LazyCompilationOrchestrator::CompileLazy( |
| 1033 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, | 1031 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, |
| 1034 int call_offset, int exported_func_index, bool patch_caller) { | 1032 int call_offset, int exported_func_index, bool patch_caller) { |
| 1035 struct NonCompiledFunction { | 1033 struct NonCompiledFunction { |
| 1036 int offset; | 1034 int offset; |
| 1037 int func_index; | 1035 int func_index; |
| 1038 }; | 1036 }; |
| 1039 std::shared_ptr<Counters> counters_shared = isolate->counters_shared(); | 1037 const std::shared_ptr<Counters> counters_shared = isolate->counters_shared(); |
| 1040 std::vector<NonCompiledFunction> non_compiled_functions; | 1038 std::vector<NonCompiledFunction> non_compiled_functions; |
| 1041 int func_to_return_idx = exported_func_index; | 1039 int func_to_return_idx = exported_func_index; |
| 1042 wasm::Decoder decoder(nullptr, nullptr); | 1040 wasm::Decoder decoder(nullptr, nullptr); |
| 1043 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; | 1041 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; |
| 1044 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), | 1042 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), |
| 1045 isolate); | 1043 isolate); |
| 1046 | 1044 |
| 1047 if (is_js_to_wasm) { | 1045 if (is_js_to_wasm) { |
| 1048 non_compiled_functions.push_back({0, exported_func_index}); | 1046 non_compiled_functions.push_back({0, exported_func_index}); |
| 1049 } else if (patch_caller) { | 1047 } else if (patch_caller) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1074 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); | 1072 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); |
| 1075 non_compiled_functions.push_back({offset, called_func_index}); | 1073 non_compiled_functions.push_back({offset, called_func_index}); |
| 1076 // Call offset one instruction after the call. Remember the last called | 1074 // Call offset one instruction after the call. Remember the last called |
| 1077 // function before that offset. | 1075 // function before that offset. |
| 1078 if (offset < call_offset) func_to_return_idx = called_func_index; | 1076 if (offset < call_offset) func_to_return_idx = called_func_index; |
| 1079 } | 1077 } |
| 1080 } | 1078 } |
| 1081 | 1079 |
| 1082 // TODO(clemensh): compile all functions in non_compiled_functions in | 1080 // TODO(clemensh): compile all functions in non_compiled_functions in |
| 1083 // background, wait for func_to_return_idx. | 1081 // background, wait for func_to_return_idx. |
| 1084 CompileFunction(isolate, instance, func_to_return_idx, counters_shared.get()); | 1082 CompileFunction(isolate, instance, func_to_return_idx); |
| 1085 | 1083 |
| 1086 if (is_js_to_wasm || patch_caller) { | 1084 if (is_js_to_wasm || patch_caller) { |
| 1087 DisallowHeapAllocation no_gc; | 1085 DisallowHeapAllocation no_gc; |
| 1088 // Now patch the code object with all functions which are now compiled. | 1086 // Now patch the code object with all functions which are now compiled. |
| 1089 int idx = 0; | 1087 int idx = 0; |
| 1090 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); | 1088 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); |
| 1091 it.next()) { | 1089 it.next()) { |
| 1092 Code* callee = | 1090 Code* callee = |
| 1093 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); | 1091 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
| 1094 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; | 1092 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1117 callee_compiled->instruction_start()); | 1115 callee_compiled->instruction_start()); |
| 1118 } | 1116 } |
| 1119 DCHECK_EQ(non_compiled_functions.size(), idx); | 1117 DCHECK_EQ(non_compiled_functions.size(), idx); |
| 1120 } | 1118 } |
| 1121 | 1119 |
| 1122 Code* ret = | 1120 Code* ret = |
| 1123 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 1121 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
| 1124 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 1122 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
| 1125 return handle(ret, isolate); | 1123 return handle(ret, isolate); |
| 1126 } | 1124 } |
| OLD | NEW |