[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-body-decoder.h",
|
||||||
"src/wasm/function-compiler.cc",
|
"src/wasm/function-compiler.cc",
|
||||||
"src/wasm/function-compiler.h",
|
"src/wasm/function-compiler.h",
|
||||||
|
"src/wasm/jump-table-assembler.cc",
|
||||||
|
"src/wasm/jump-table-assembler.h",
|
||||||
"src/wasm/leb-helper.h",
|
"src/wasm/leb-helper.h",
|
||||||
"src/wasm/local-decl-encoder.cc",
|
"src/wasm/local-decl-encoder.cc",
|
||||||
"src/wasm/local-decl-encoder.h",
|
"src/wasm/local-decl-encoder.h",
|
||||||
|
@ -53,15 +53,16 @@ const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Implementation of AssemblerBase
|
// Implementation of AssemblerBase
|
||||||
|
|
||||||
AssemblerBase::IsolateData::IsolateData(Isolate* isolate)
|
|
||||||
: serializer_enabled(isolate->serializer_enabled())
|
|
||||||
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
|
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
|
||||||
,
|
AssemblerBase::IsolateData::IsolateData(Isolate* isolate)
|
||||||
code_range_start(
|
: IsolateData(isolate->serializer_enabled() ? kSerializerEnabled
|
||||||
isolate->heap()->memory_allocator()->code_range()->start())
|
: kSerializerDisabled,
|
||||||
|
isolate->heap()->memory_allocator()->code_range()->start()) {}
|
||||||
|
#else
|
||||||
|
AssemblerBase::IsolateData::IsolateData(Isolate* isolate)
|
||||||
|
: IsolateData(isolate->serializer_enabled() ? kSerializerEnabled
|
||||||
|
: kSerializerDisabled) {}
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AssemblerBase::AssemblerBase(IsolateData isolate_data, void* buffer,
|
AssemblerBase::AssemblerBase(IsolateData isolate_data, void* buffer,
|
||||||
int buffer_size)
|
int buffer_size)
|
||||||
|
@ -134,10 +134,24 @@ enum class CodeObjectRequired { kNo, kYes };
|
|||||||
|
|
||||||
class AssemblerBase : public Malloced {
|
class AssemblerBase : public Malloced {
|
||||||
public:
|
public:
|
||||||
|
enum SerializerEnabled : bool {
|
||||||
|
kSerializerEnabled = true,
|
||||||
|
kSerializerDisabled = false
|
||||||
|
};
|
||||||
struct IsolateData {
|
struct IsolateData {
|
||||||
explicit IsolateData(Isolate* isolate);
|
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
|
#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64
|
||||||
Address code_range_start;
|
Address code_range_start;
|
||||||
#endif
|
#endif
|
||||||
@ -149,7 +163,9 @@ class AssemblerBase : public Malloced {
|
|||||||
IsolateData isolate_data() const { return isolate_data_; }
|
IsolateData isolate_data() const { return isolate_data_; }
|
||||||
|
|
||||||
bool serializer_enabled() const { return isolate_data_.serializer_enabled; }
|
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_; }
|
bool emit_debug_code() const { return emit_debug_code_; }
|
||||||
void set_emit_debug_code(bool value) { emit_debug_code_ = value; }
|
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/macro-assembler.h"
|
||||||
#include "src/objects-inl.h"
|
#include "src/objects-inl.h"
|
||||||
#include "src/wasm/function-compiler.h"
|
#include "src/wasm/function-compiler.h"
|
||||||
|
#include "src/wasm/jump-table-assembler.h"
|
||||||
#include "src/wasm/wasm-module.h"
|
#include "src/wasm/wasm-module.h"
|
||||||
#include "src/wasm/wasm-objects-inl.h"
|
#include "src/wasm/wasm-objects-inl.h"
|
||||||
#include "src/wasm/wasm-objects.h"
|
#include "src/wasm/wasm-objects.h"
|
||||||
@ -42,39 +43,14 @@ struct WasmCodeUniquePtrComparator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if V8_TARGET_ARCH_X64
|
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64
|
||||||
#define __ masm->
|
|
||||||
constexpr bool kModuleCanAllocateMoreMemory = false;
|
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
|
#else
|
||||||
const bool kModuleCanAllocateMoreMemory = true;
|
constexpr bool kModuleCanAllocateMoreMemory = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
constexpr bool kNeedsTrampoline = !kModuleCanAllocateMoreMemory;
|
||||||
|
|
||||||
void RelocateCode(WasmCode* code, const WasmCode* orig,
|
void RelocateCode(WasmCode* code, const WasmCode* orig,
|
||||||
WasmCode::FlushICache flush_icache) {
|
WasmCode::FlushICache flush_icache) {
|
||||||
intptr_t delta = code->instruction_start() - orig->instruction_start();
|
intptr_t delta = code->instruction_start() - orig->instruction_start();
|
||||||
@ -621,40 +597,36 @@ WasmCode* NativeModule::AddCode(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64
|
|
||||||
Address NativeModule::CreateTrampolineTo(Handle<Code> code) {
|
Address NativeModule::CreateTrampolineTo(Handle<Code> code) {
|
||||||
MacroAssembler masm(code->GetIsolate(), nullptr, 0, CodeObjectRequired::kNo);
|
|
||||||
Address dest = code->raw_instruction_start();
|
Address dest = code->raw_instruction_start();
|
||||||
GenerateJumpTrampoline(&masm, dest);
|
Address ret = dest;
|
||||||
CodeDesc code_desc;
|
if (kNeedsTrampoline) {
|
||||||
masm.GetCode(nullptr, &code_desc);
|
JumpTableAssembler jtasm;
|
||||||
Vector<const byte> instructions(code_desc.buffer,
|
jtasm.EmitJumpTrampoline(dest);
|
||||||
static_cast<size_t>(code_desc.instr_size));
|
CodeDesc code_desc;
|
||||||
WasmCode* wasm_code = AddOwnedCode(instructions, // instructions
|
jtasm.GetCode(nullptr, &code_desc);
|
||||||
nullptr, // reloc_info
|
Vector<const byte> instructions(code_desc.buffer,
|
||||||
0, // reloc_size
|
static_cast<size_t>(code_desc.instr_size));
|
||||||
nullptr, // source_pos
|
WasmCode* wasm_code = AddOwnedCode(instructions, // instructions
|
||||||
0, // source_pos_size
|
nullptr, // reloc_info
|
||||||
Nothing<uint32_t>(), // index
|
0, // reloc_size
|
||||||
WasmCode::kTrampoline, // kind
|
nullptr, // source_pos
|
||||||
0, // constant_pool_offset
|
0, // source_pos_size
|
||||||
0, // stack_slots
|
Nothing<uint32_t>(), // index
|
||||||
0, // safepoint_table_offset
|
WasmCode::kTrampoline, // kind
|
||||||
0, // handler_table_offset
|
0, // constant_pool_offset
|
||||||
{}, // protected_instructions
|
0, // stack_slots
|
||||||
WasmCode::kOther, // tier
|
0, // safepoint_table_offset
|
||||||
WasmCode::kFlushICache); // flush_icache
|
0, // handler_table_offset
|
||||||
Address ret = wasm_code->instruction_start();
|
{}, // 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));
|
trampolines_.emplace(std::make_pair(dest, ret));
|
||||||
return 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) {
|
Address NativeModule::GetLocalAddressFor(Handle<Code> code) {
|
||||||
DCHECK(Heap::IsImmovable(*code));
|
DCHECK(Heap::IsImmovable(*code));
|
||||||
|
Loading…
Reference in New Issue
Block a user