[wasm] Prepare for multiple jump tables
This adds logic to choose the closest jump table for each call in wasm code. The "main jump table" (held in {NativeModule::main_jump_table_}) is still kept though and used for any external or indirect call. Any direct call from within wasm now chooses the jump table that corresponds to the code space that the code lives in. R=mstarzinger@chromium.org Bug: v8:9477 Change-Id: Ie52b5bb3a4a160cb754b8702c530f6feb182b3a9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1800576 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#63760}
This commit is contained in:
parent
b9a393a201
commit
4d97099c65
@ -235,7 +235,10 @@ void WasmCode::Validate() const {
|
||||
switch (mode) {
|
||||
case RelocInfo::WASM_CALL: {
|
||||
Address target = it.rinfo()->wasm_call_address();
|
||||
DCHECK(native_module_->is_jump_table_slot(target));
|
||||
WasmCode* code = native_module_->Lookup(target);
|
||||
CHECK_NOT_NULL(code);
|
||||
CHECK_EQ(WasmCode::kJumpTable, code->kind());
|
||||
CHECK(code->contains(target));
|
||||
break;
|
||||
}
|
||||
case RelocInfo::WASM_STUB_CALL: {
|
||||
@ -952,7 +955,7 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
|
||||
RelocInfo::Mode mode = it.rinfo()->rmode();
|
||||
if (RelocInfo::IsWasmCall(mode)) {
|
||||
uint32_t call_tag = it.rinfo()->wasm_call_tag();
|
||||
Address target = GetCallTargetForFunction(call_tag);
|
||||
Address target = GetNearCallTargetForFunction(call_tag, code_start);
|
||||
it.rinfo()->set_wasm_call_address(target, SKIP_ICACHE_FLUSH);
|
||||
} else if (RelocInfo::IsWasmStubCall(mode)) {
|
||||
uint32_t stub_call_tag = it.rinfo()->wasm_call_tag();
|
||||
@ -1306,6 +1309,21 @@ Address NativeModule::GetCallTargetForFunction(uint32_t func_index) const {
|
||||
return main_jump_table_->instruction_start() + slot_offset;
|
||||
}
|
||||
|
||||
Address NativeModule::GetNearCallTargetForFunction(uint32_t func_index,
|
||||
Address near_to) const {
|
||||
uint32_t slot_offset = GetJumpTableOffset(func_index);
|
||||
base::MutexGuard guard(&allocation_mutex_);
|
||||
for (auto& code_space_data : code_space_data_) {
|
||||
const bool jump_table_reachable = !kNeedsFarJumpsBetweenCodeSpaces ||
|
||||
code_space_data.region.contains(near_to);
|
||||
if (jump_table_reachable && code_space_data.jump_table) {
|
||||
DCHECK_LT(slot_offset, code_space_data.jump_table->instructions().size());
|
||||
return code_space_data.jump_table->instruction_start() + slot_offset;
|
||||
}
|
||||
}
|
||||
FATAL("near_to is not part of a code space");
|
||||
}
|
||||
|
||||
Address NativeModule::GetNearRuntimeStubEntry(WasmCode::RuntimeStubId index,
|
||||
Address near_to) const {
|
||||
base::MutexGuard guard(&allocation_mutex_);
|
||||
@ -1321,11 +1339,17 @@ Address NativeModule::GetNearRuntimeStubEntry(WasmCode::RuntimeStubId index,
|
||||
|
||||
uint32_t NativeModule::GetFunctionIndexFromJumpTableSlot(
|
||||
Address slot_address) const {
|
||||
DCHECK(is_jump_table_slot(slot_address));
|
||||
uint32_t slot_offset = static_cast<uint32_t>(
|
||||
slot_address - main_jump_table_->instruction_start());
|
||||
WasmCodeRefScope code_refs;
|
||||
WasmCode* code = Lookup(slot_address);
|
||||
DCHECK_NOT_NULL(code);
|
||||
DCHECK_EQ(WasmCode::kJumpTable, code->kind());
|
||||
uint32_t slot_offset =
|
||||
static_cast<uint32_t>(slot_address - code->instruction_start());
|
||||
uint32_t slot_idx = JumpTableAssembler::SlotOffsetToIndex(slot_offset);
|
||||
DCHECK_LT(slot_idx, module_->num_declared_functions);
|
||||
DCHECK_EQ(slot_address,
|
||||
code->instruction_start() +
|
||||
JumpTableAssembler::JumpSlotIndexToOffset(slot_idx));
|
||||
return module_->num_imported_functions + slot_idx;
|
||||
}
|
||||
|
||||
|
@ -345,6 +345,8 @@ class WasmCodeAllocator {
|
||||
|
||||
bool is_executable_ = false;
|
||||
|
||||
// TODO(clemensh): Remove this field once multiple code spaces are supported
|
||||
// everywhere.
|
||||
const bool can_request_more_memory_;
|
||||
|
||||
std::shared_ptr<Counters> async_counters_;
|
||||
@ -412,22 +414,23 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
||||
|
||||
uint32_t GetJumpTableOffset(uint32_t func_index) const;
|
||||
|
||||
bool is_jump_table_slot(Address address) const {
|
||||
return main_jump_table_->contains(address);
|
||||
}
|
||||
|
||||
// Returns the canonical target to call for the given function (the slot in
|
||||
// the first jump table).
|
||||
Address GetCallTargetForFunction(uint32_t func_index) const;
|
||||
|
||||
// Similarly to {GetCallTargetForFunction}, but ensures that the returned
|
||||
// address is near to the {near_to} address by finding the closest jump table.
|
||||
Address GetNearCallTargetForFunction(uint32_t func_index,
|
||||
Address near_to) const;
|
||||
|
||||
// Get a runtime stub entry (which is a far jump table slot) within near-call
|
||||
// distance to {near_to}. Fails if {near_to} is not part of any code space of
|
||||
// this module.
|
||||
Address GetNearRuntimeStubEntry(WasmCode::RuntimeStubId index,
|
||||
Address near_to) const;
|
||||
|
||||
// Reverse lookup from a given call target (i.e. a jump table slot as the
|
||||
// above {GetCallTargetForFunction} returns) to a function index.
|
||||
// Reverse lookup from a given call target (which must be a jump table slot)
|
||||
// to a function index.
|
||||
uint32_t GetFunctionIndexFromJumpTableSlot(Address slot_address) const;
|
||||
|
||||
bool SetExecutable(bool executable) {
|
||||
|
@ -3779,7 +3779,8 @@ class ThreadImpl {
|
||||
static WasmCode* GetTargetCode(Isolate* isolate, Address target) {
|
||||
WasmCodeManager* code_manager = isolate->wasm_engine()->code_manager();
|
||||
NativeModule* native_module = code_manager->LookupNativeModule(target);
|
||||
if (native_module->is_jump_table_slot(target)) {
|
||||
WasmCode* code = native_module->Lookup(target);
|
||||
if (code->kind() == WasmCode::kJumpTable) {
|
||||
uint32_t func_index =
|
||||
native_module->GetFunctionIndexFromJumpTableSlot(target);
|
||||
|
||||
@ -3793,7 +3794,6 @@ class ThreadImpl {
|
||||
|
||||
return native_module->GetCode(func_index);
|
||||
}
|
||||
WasmCode* code = native_module->Lookup(target);
|
||||
DCHECK_EQ(code->instruction_start(), target);
|
||||
return code;
|
||||
}
|
||||
|
@ -548,7 +548,8 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
|
||||
switch (mode) {
|
||||
case RelocInfo::WASM_CALL: {
|
||||
uint32_t tag = GetWasmCalleeTag(iter.rinfo());
|
||||
Address target = native_module_->GetCallTargetForFunction(tag);
|
||||
Address target = native_module_->GetNearCallTargetForFunction(
|
||||
tag, code->instruction_start());
|
||||
iter.rinfo()->set_wasm_call_address(target, SKIP_ICACHE_FLUSH);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user