diff --git a/BUILD.gn b/BUILD.gn index 81000732bf..8d8db93ab6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2431,6 +2431,8 @@ v8_source_set("v8_base") { "src/wasm/function-body-decoder.h", "src/wasm/function-compiler.cc", "src/wasm/function-compiler.h", + "src/wasm/jump-table-assembler.cc", + "src/wasm/jump-table-assembler.h", "src/wasm/leb-helper.h", "src/wasm/local-decl-encoder.cc", "src/wasm/local-decl-encoder.h", diff --git a/src/assembler.cc b/src/assembler.cc index 18695b2f6b..39bb1dcf62 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -53,15 +53,16 @@ const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING"; // ----------------------------------------------------------------------------- // Implementation of AssemblerBase -AssemblerBase::IsolateData::IsolateData(Isolate* isolate) - : serializer_enabled(isolate->serializer_enabled()) #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 - , - code_range_start( - isolate->heap()->memory_allocator()->code_range()->start()) +AssemblerBase::IsolateData::IsolateData(Isolate* isolate) + : IsolateData(isolate->serializer_enabled() ? kSerializerEnabled + : kSerializerDisabled, + isolate->heap()->memory_allocator()->code_range()->start()) {} +#else +AssemblerBase::IsolateData::IsolateData(Isolate* isolate) + : IsolateData(isolate->serializer_enabled() ? kSerializerEnabled + : kSerializerDisabled) {} #endif -{ -} AssemblerBase::AssemblerBase(IsolateData isolate_data, void* buffer, int buffer_size) diff --git a/src/assembler.h b/src/assembler.h index 147fe9d076..bc222ab226 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -134,10 +134,24 @@ enum class CodeObjectRequired { kNo, kYes }; class AssemblerBase : public Malloced { public: + enum SerializerEnabled : bool { + kSerializerEnabled = true, + kSerializerDisabled = false + }; struct IsolateData { explicit IsolateData(Isolate* isolate); - bool serializer_enabled; +#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 + constexpr IsolateData(SerializerEnabled serializer_enabled, + Address code_range_start) + : serializer_enabled(serializer_enabled), + code_range_start(code_range_start) {} +#else + explicit constexpr IsolateData(SerializerEnabled serializer_enabled) + : serializer_enabled(serializer_enabled) {} +#endif + + SerializerEnabled serializer_enabled; #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 Address code_range_start; #endif @@ -149,7 +163,9 @@ class AssemblerBase : public Malloced { IsolateData isolate_data() const { return isolate_data_; } bool serializer_enabled() const { return isolate_data_.serializer_enabled; } - void enable_serializer() { isolate_data_.serializer_enabled = true; } + void enable_serializer() { + isolate_data_.serializer_enabled = kSerializerEnabled; + } bool emit_debug_code() const { return emit_debug_code_; } void set_emit_debug_code(bool value) { emit_debug_code_ = value; } diff --git a/src/wasm/jump-table-assembler.cc b/src/wasm/jump-table-assembler.cc new file mode 100644 index 0000000000..2a17992546 --- /dev/null +++ b/src/wasm/jump-table-assembler.cc @@ -0,0 +1,32 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/wasm/jump-table-assembler.h" + +#include "src/macro-assembler-inl.h" + +namespace v8 { +namespace internal { +namespace wasm { + +void JumpTableAssembler::EmitJumpTrampoline(Address target) { +#if V8_TARGET_ARCH_X64 + movq(kScratchRegister, static_cast(target)); + jmp(kScratchRegister); +#elif V8_TARGET_ARCH_ARM64 + UseScratchRegisterScope temps(this); + Register scratch = temps.AcquireX(); + Mov(scratch, static_cast(target)); + Br(scratch); +#elif V8_TARGET_ARCH_S390X + mov(ip, Operand(bit_cast(target))); + b(ip); +#else + UNIMPLEMENTED(); +#endif +} + +} // namespace wasm +} // namespace internal +} // namespace v8 diff --git a/src/wasm/jump-table-assembler.h b/src/wasm/jump-table-assembler.h new file mode 100644 index 0000000000..6b73623e93 --- /dev/null +++ b/src/wasm/jump-table-assembler.h @@ -0,0 +1,37 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_WASM_JUMP_TABLE_ASSEMBLER_H_ +#define V8_WASM_JUMP_TABLE_ASSEMBLER_H_ + +#include "src/macro-assembler.h" + +namespace v8 { +namespace internal { +namespace wasm { + +class JumpTableAssembler : public TurboAssembler { + // {JumpTableAssembler} is never used during snapshot generation, and its code + // must be independent of the code range of any isolate anyway. So just use + // this default {IsolateData} for each {JumpTableAssembler}. + static constexpr IsolateData GetDefaultIsolateData() { +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 + return IsolateData(kSerializerDisabled, kNullAddress); +#else + return IsolateData(kSerializerDisabled); +#endif + } + + public: + JumpTableAssembler() : TurboAssembler(GetDefaultIsolateData(), nullptr, 0) {} + + // Emit a trampoline to a possibly far away code target. + void EmitJumpTrampoline(Address target); +}; + +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif // V8_WASM_JUMP_TABLE_ASSEMBLER_H_ diff --git a/src/wasm/wasm-code-manager.cc b/src/wasm/wasm-code-manager.cc index ce15f30cde..a56255a992 100644 --- a/src/wasm/wasm-code-manager.cc +++ b/src/wasm/wasm-code-manager.cc @@ -17,6 +17,7 @@ #include "src/macro-assembler.h" #include "src/objects-inl.h" #include "src/wasm/function-compiler.h" +#include "src/wasm/jump-table-assembler.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-objects.h" @@ -42,39 +43,14 @@ struct WasmCodeUniquePtrComparator { } }; -#if V8_TARGET_ARCH_X64 -#define __ masm-> +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64 constexpr bool kModuleCanAllocateMoreMemory = false; - -void GenerateJumpTrampoline(MacroAssembler* masm, Address target) { - __ movq(kScratchRegister, static_cast(target)); - __ jmp(kScratchRegister); -} -#undef __ -#elif V8_TARGET_ARCH_S390X -#define __ masm-> -constexpr bool kModuleCanAllocateMoreMemory = false; - -void GenerateJumpTrampoline(MacroAssembler* masm, Address target) { - __ mov(ip, Operand(bit_cast(target))); - __ b(ip); -} -#undef __ -#elif V8_TARGET_ARCH_ARM64 -#define __ masm-> -constexpr bool kModuleCanAllocateMoreMemory = false; - -void GenerateJumpTrampoline(MacroAssembler* masm, Address target) { - UseScratchRegisterScope temps(masm); - Register scratch = temps.AcquireX(); - __ Mov(scratch, static_cast(target)); - __ Br(scratch); -} -#undef __ #else -const bool kModuleCanAllocateMoreMemory = true; +constexpr bool kModuleCanAllocateMoreMemory = true; #endif +constexpr bool kNeedsTrampoline = !kModuleCanAllocateMoreMemory; + void RelocateCode(WasmCode* code, const WasmCode* orig, WasmCode::FlushICache flush_icache) { intptr_t delta = code->instruction_start() - orig->instruction_start(); @@ -621,40 +597,36 @@ WasmCode* NativeModule::AddCode( return ret; } -#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64 Address NativeModule::CreateTrampolineTo(Handle code) { - MacroAssembler masm(code->GetIsolate(), nullptr, 0, CodeObjectRequired::kNo); Address dest = code->raw_instruction_start(); - GenerateJumpTrampoline(&masm, dest); - CodeDesc code_desc; - masm.GetCode(nullptr, &code_desc); - Vector instructions(code_desc.buffer, - static_cast(code_desc.instr_size)); - WasmCode* wasm_code = AddOwnedCode(instructions, // instructions - nullptr, // reloc_info - 0, // reloc_size - nullptr, // source_pos - 0, // source_pos_size - Nothing(), // index - WasmCode::kTrampoline, // kind - 0, // constant_pool_offset - 0, // stack_slots - 0, // safepoint_table_offset - 0, // handler_table_offset - {}, // protected_instructions - WasmCode::kOther, // tier - WasmCode::kFlushICache); // flush_icache - Address ret = wasm_code->instruction_start(); + Address ret = dest; + if (kNeedsTrampoline) { + JumpTableAssembler jtasm; + jtasm.EmitJumpTrampoline(dest); + CodeDesc code_desc; + jtasm.GetCode(nullptr, &code_desc); + Vector instructions(code_desc.buffer, + static_cast(code_desc.instr_size)); + WasmCode* wasm_code = AddOwnedCode(instructions, // instructions + nullptr, // reloc_info + 0, // reloc_size + nullptr, // source_pos + 0, // source_pos_size + Nothing(), // index + WasmCode::kTrampoline, // kind + 0, // constant_pool_offset + 0, // stack_slots + 0, // safepoint_table_offset + 0, // handler_table_offset + {}, // protected_instructions + WasmCode::kOther, // tier + WasmCode::kFlushICache); // flush_icache + ret = wasm_code->instruction_start(); + } + DCHECK_EQ(0, trampolines_.count(dest)); trampolines_.emplace(std::make_pair(dest, ret)); return ret; } -#else -Address NativeModule::CreateTrampolineTo(Handle code) { - Address ret = code->raw_instruction_start(); - trampolines_.insert(std::make_pair(ret, ret)); - return ret; -} -#endif Address NativeModule::GetLocalAddressFor(Handle code) { DCHECK(Heap::IsImmovable(*code));