[wasm] Introduce JumpTableAssembler

Extract code generation (for the trampoline) from {wasm-code-manager.cc}
to a new {JumpTableAssembler}. This prepares a CL to add more logic to
the {JumpTableAssembler} to also generate jump tables for lazy
compilation and tier up.

R=mstarzinger@chromium.org

Change-Id: I383585b7e4b5a4af3ca08d07e374b44654c1a09f
Reviewed-on: https://chromium-review.googlesource.com/1046585
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53729}
This commit is contained in:
Clemens Hammacher 2018-06-14 11:17:47 +02:00 committed by Commit Bot
parent 9ee78d965b
commit 2dda64aabf
6 changed files with 127 additions and 67 deletions

View File

@ -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",

View File

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

View File

@ -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; }

View File

@ -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<uint64_t>(target));
jmp(kScratchRegister);
#elif V8_TARGET_ARCH_ARM64
UseScratchRegisterScope temps(this);
Register scratch = temps.AcquireX();
Mov(scratch, static_cast<uint64_t>(target));
Br(scratch);
#elif V8_TARGET_ARCH_S390X
mov(ip, Operand(bit_cast<intptr_t, Address>(target)));
b(ip);
#else
UNIMPLEMENTED();
#endif
}
} // namespace wasm
} // namespace internal
} // namespace v8

View File

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

View File

@ -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<uint64_t>(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<intptr_t, Address>(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<uint64_t>(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> 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<const byte> instructions(code_desc.buffer,
static_cast<size_t>(code_desc.instr_size));
WasmCode* wasm_code = AddOwnedCode(instructions, // instructions
nullptr, // reloc_info
0, // reloc_size
nullptr, // source_pos
0, // source_pos_size
Nothing<uint32_t>(), // 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<const byte> instructions(code_desc.buffer,
static_cast<size_t>(code_desc.instr_size));
WasmCode* wasm_code = AddOwnedCode(instructions, // instructions
nullptr, // reloc_info
0, // reloc_size
nullptr, // source_pos
0, // source_pos_size
Nothing<uint32_t>(), // 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> code) {
Address ret = code->raw_instruction_start();
trampolines_.insert(std::make_pair(ret, ret));
return ret;
}
#endif
Address NativeModule::GetLocalAddressFor(Handle<Code> code) {
DCHECK(Heap::IsImmovable(*code));