Commit 7c5af8ba authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Patch new jump tables with existing functions

If a new code space is added after functions have already been
compiled, we need to initialize the new jump tables to contain all
these functions.

R=mstarzinger@chromium.org

Bug: v8:9477
Change-Id: Ie960966ec5ad667e0626f86eceb7c2b4da72e5bd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1803337
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63792}
parent ba9775fd
......@@ -1149,26 +1149,38 @@ void NativeModule::PatchJumpTablesLocked(uint32_t func_index, Address target) {
for (auto& code_space_data : code_space_data_) {
DCHECK_IMPLIES(code_space_data.jump_table, code_space_data.far_jump_table);
if (!code_space_data.jump_table) continue;
uint32_t slot_index = func_index - module_->num_imported_functions;
Address jump_table_slot =
code_space_data.jump_table->instruction_start() +
JumpTableAssembler::JumpSlotIndexToOffset(slot_index);
uint32_t far_jump_table_offset =
JumpTableAssembler::FarJumpSlotIndexToOffset(
WasmCode::kRuntimeStubCount + slot_index);
// Only pass the far jump table start if the far jump table actually has a
// slot for this function index (i.e. does not only contain runtime stubs).
Address far_jump_table_slot =
far_jump_table_offset <
code_space_data.far_jump_table->instructions().size()
? code_space_data.far_jump_table->instruction_start() +
far_jump_table_offset
: kNullAddress;
JumpTableAssembler::PatchJumpTableSlot(jump_table_slot, far_jump_table_slot,
target);
PatchJumpTableLocked(code_space_data, func_index, target);
}
}
void NativeModule::PatchJumpTableLocked(const CodeSpaceData& code_space_data,
uint32_t func_index, Address target) {
// The caller must hold the {allocation_mutex_}, thus we fail to lock it here.
DCHECK(!allocation_mutex_.TryLock());
DCHECK_NOT_NULL(code_space_data.jump_table);
DCHECK_NOT_NULL(code_space_data.far_jump_table);
uint32_t slot_index = func_index - module_->num_imported_functions;
Address jump_table_slot =
code_space_data.jump_table->instruction_start() +
JumpTableAssembler::JumpSlotIndexToOffset(slot_index);
uint32_t far_jump_table_offset = JumpTableAssembler::FarJumpSlotIndexToOffset(
WasmCode::kRuntimeStubCount + slot_index);
// Only pass the far jump table start if the far jump table actually has a
// slot for this function index (i.e. does not only contain runtime stubs).
bool has_far_jump_slot =
far_jump_table_offset <
code_space_data.far_jump_table->instructions().size();
Address far_jump_table_start =
code_space_data.far_jump_table->instruction_start();
Address far_jump_table_slot =
has_far_jump_slot ? far_jump_table_start + far_jump_table_offset
: kNullAddress;
JumpTableAssembler::PatchJumpTableSlot(jump_table_slot, far_jump_table_slot,
target);
}
void NativeModule::AddCodeSpace(base::AddressRegion region) {
#ifndef V8_EMBEDDED_BUILTINS
// The far jump table contains far jumps to the embedded builtins. This
......@@ -1254,6 +1266,17 @@ void NativeModule::AddCodeSpace(base::AddressRegion region) {
base::MutexGuard guard(&allocation_mutex_);
code_space_data_.push_back(CodeSpaceData{region, jump_table, far_jump_table});
if (jump_table && !is_first_code_space) {
// Patch the new jump table(s) with existing functions. If this is the first
// code space, there cannot be any functions that have been compiled yet.
for (uint32_t func_index = 0; func_index < num_wasm_functions;
++func_index) {
if (!code_table_[func_index]) continue;
PatchJumpTableLocked(code_space_data_.back(), func_index,
code_table_[func_index]->instruction_start());
}
}
}
namespace {
......
......@@ -533,8 +533,10 @@ class V8_EXPORT_PRIVATE NativeModule final {
WasmCode* CreateEmptyJumpTableInRegion(uint32_t jump_table_size,
base::AddressRegion);
// Hold the {allocation_mutex_} when calling this method.
// Hold the {allocation_mutex_} when calling one of these methods.
void PatchJumpTablesLocked(uint32_t func_index, Address target);
void PatchJumpTableLocked(const CodeSpaceData&, uint32_t func_index,
Address target);
// Called by the {WasmCodeAllocator} to register a new code space.
void AddCodeSpace(base::AddressRegion);
......@@ -608,7 +610,9 @@ class V8_EXPORT_PRIVATE NativeModule final {
// instruction start address of the value.
std::map<Address, std::unique_ptr<WasmCode>> owned_code_;
std::unique_ptr<WasmCode* []> code_table_;
// Table of the latest code object per function, updated on initial
// compilation and tier up.
std::unique_ptr<WasmCode*[]> code_table_;
// Null if no redirections exist, otherwise a bitset over all functions in
// this module marking those functions that have been redirected.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment