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(); | |
1040 std::vector<NonCompiledFunction> non_compiled_functions; | 1037 std::vector<NonCompiledFunction> non_compiled_functions; |
1041 int func_to_return_idx = exported_func_index; | 1038 int func_to_return_idx = exported_func_index; |
1042 wasm::Decoder decoder(nullptr, nullptr); | 1039 wasm::Decoder decoder(nullptr, nullptr); |
1043 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; | 1040 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; |
1044 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), | 1041 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), |
1045 isolate); | 1042 isolate); |
1046 | 1043 |
1047 if (is_js_to_wasm) { | 1044 if (is_js_to_wasm) { |
1048 non_compiled_functions.push_back({0, exported_func_index}); | 1045 non_compiled_functions.push_back({0, exported_func_index}); |
1049 } else if (patch_caller) { | 1046 } else if (patch_caller) { |
(...skipping 24 matching lines...) Expand all Loading... |
1074 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); | 1071 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); |
1075 non_compiled_functions.push_back({offset, called_func_index}); | 1072 non_compiled_functions.push_back({offset, called_func_index}); |
1076 // Call offset one instruction after the call. Remember the last called | 1073 // Call offset one instruction after the call. Remember the last called |
1077 // function before that offset. | 1074 // function before that offset. |
1078 if (offset < call_offset) func_to_return_idx = called_func_index; | 1075 if (offset < call_offset) func_to_return_idx = called_func_index; |
1079 } | 1076 } |
1080 } | 1077 } |
1081 | 1078 |
1082 // TODO(clemensh): compile all functions in non_compiled_functions in | 1079 // TODO(clemensh): compile all functions in non_compiled_functions in |
1083 // background, wait for func_to_return_idx. | 1080 // background, wait for func_to_return_idx. |
1084 CompileFunction(isolate, instance, func_to_return_idx, counters_shared.get()); | 1081 CompileFunction(isolate, instance, func_to_return_idx); |
1085 | 1082 |
1086 if (is_js_to_wasm || patch_caller) { | 1083 if (is_js_to_wasm || patch_caller) { |
1087 DisallowHeapAllocation no_gc; | 1084 DisallowHeapAllocation no_gc; |
1088 // Now patch the code object with all functions which are now compiled. | 1085 // Now patch the code object with all functions which are now compiled. |
1089 int idx = 0; | 1086 int idx = 0; |
1090 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); | 1087 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); |
1091 it.next()) { | 1088 it.next()) { |
1092 Code* callee = | 1089 Code* callee = |
1093 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); | 1090 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
1094 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; | 1091 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; |
(...skipping 22 matching lines...) Expand all Loading... |
1117 callee_compiled->instruction_start()); | 1114 callee_compiled->instruction_start()); |
1118 } | 1115 } |
1119 DCHECK_EQ(non_compiled_functions.size(), idx); | 1116 DCHECK_EQ(non_compiled_functions.size(), idx); |
1120 } | 1117 } |
1121 | 1118 |
1122 Code* ret = | 1119 Code* ret = |
1123 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 1120 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
1124 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 1121 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
1125 return handle(ret, isolate); | 1122 return handle(ret, isolate); |
1126 } | 1123 } |
OLD | NEW |