[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:
parent
9ee78d965b
commit
2dda64aabf
2
BUILD.gn
2
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",
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
32
src/wasm/jump-table-assembler.cc
Normal file
32
src/wasm/jump-table-assembler.cc
Normal 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
|
37
src/wasm/jump-table-assembler.h
Normal file
37
src/wasm/jump-table-assembler.h
Normal 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_
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user