[wasm] Remove IndirectFunctionTableEntry
Since the indirect function table at index 0 in an instance is now represented like the other tables, the IndirectFunctionTableEntry abstraction is no more useful. We replace it with direct access to the tables and a simpler abstraction {FunctionTargetAndRef}. Bug: v8:11510 Change-Id: Iab4a6ca7eda8eb1757dbd321cb3997e98e78267e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3247030 Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/main@{#77754}
This commit is contained in:
parent
04899013ba
commit
5bf06b536d
@ -1185,9 +1185,10 @@ bool InstanceBuilder::InitializeImportedIndirectFunctionTable(
|
||||
// Look up the signature's canonical id. If there is no canonical
|
||||
// id, then the signature does not appear at all in this module,
|
||||
// so putting {-1} in the table will cause checks to always fail.
|
||||
IndirectFunctionTableEntry(instance, table_index, i)
|
||||
.Set(module_->signature_map.Find(*sig), target_instance,
|
||||
function_index);
|
||||
FunctionTargetAndRef entry(target_instance, function_index);
|
||||
instance->GetIndirectFunctionTable(isolate_, table_index)
|
||||
->Set(i, module_->signature_map.Find(*sig), entry.call_target(),
|
||||
*entry.ref());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1869,7 +1870,8 @@ void SetNullTableEntry(Isolate* isolate, Handle<WasmInstanceObject> instance,
|
||||
uint32_t table_index, uint32_t entry_index) {
|
||||
const WasmModule* module = instance->module();
|
||||
if (IsSubtypeOf(table_object->type(), kWasmFuncRef, module)) {
|
||||
IndirectFunctionTableEntry(instance, table_index, entry_index).clear();
|
||||
instance->GetIndirectFunctionTable(isolate, table_index)
|
||||
->Clear(entry_index);
|
||||
}
|
||||
WasmTableObject::Set(isolate, table_object, entry_index,
|
||||
isolate->factory()->null_value());
|
||||
@ -1896,8 +1898,9 @@ void SetFunctionTableEntry(Isolate* isolate,
|
||||
|
||||
// Update the local dispatch table first if necessary.
|
||||
uint32_t sig_id = module->canonicalized_type_ids[function->sig_index];
|
||||
IndirectFunctionTableEntry(instance, table_index, entry_index)
|
||||
.Set(sig_id, instance, func_index);
|
||||
FunctionTargetAndRef entry(instance, func_index);
|
||||
instance->GetIndirectFunctionTable(isolate, table_index)
|
||||
->Set(entry_index, sig_id, entry.call_target(), *entry.ref());
|
||||
|
||||
// Update the table object's other dispatch tables.
|
||||
MaybeHandle<WasmExternalFunction> wasm_external_function =
|
||||
|
@ -269,22 +269,6 @@ void WasmInstanceObject::clear_padding() {
|
||||
}
|
||||
}
|
||||
|
||||
IndirectFunctionTableEntry::IndirectFunctionTableEntry(
|
||||
Handle<WasmInstanceObject> instance, int table_index, int entry_index)
|
||||
: IndirectFunctionTableEntry(
|
||||
handle(WasmIndirectFunctionTable::cast(
|
||||
instance->indirect_function_tables().get(table_index)),
|
||||
instance->GetIsolate()),
|
||||
entry_index) {}
|
||||
|
||||
IndirectFunctionTableEntry::IndirectFunctionTableEntry(
|
||||
Handle<WasmIndirectFunctionTable> table, int entry_index)
|
||||
: table_(table), index_(entry_index) {
|
||||
DCHECK(!table->is_null());
|
||||
DCHECK_GE(entry_index, 0);
|
||||
DCHECK_LT(entry_index, table_->size());
|
||||
}
|
||||
|
||||
ImportedFunctionEntry::ImportedFunctionEntry(
|
||||
Handle<WasmInstanceObject> instance, int index)
|
||||
: instance_(instance), index_(index) {
|
||||
|
@ -319,8 +319,8 @@ int WasmTableObject::Grow(Isolate* isolate, Handle<WasmTableObject> table,
|
||||
Handle<WasmInstanceObject> instance(
|
||||
WasmInstanceObject::cast(dispatch_tables->get(i)), isolate);
|
||||
|
||||
DCHECK_EQ(old_size, WasmInstanceObject::IndirectFunctionTableSize(
|
||||
isolate, instance, table_index));
|
||||
DCHECK_EQ(old_size,
|
||||
instance->GetIndirectFunctionTable(isolate, table_index)->size());
|
||||
WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
|
||||
instance, table_index, new_size);
|
||||
}
|
||||
@ -513,8 +513,9 @@ void WasmTableObject::UpdateDispatchTables(
|
||||
// Note that {SignatureMap::Find} may return {-1} if the signature is
|
||||
// not found; it will simply never match any check.
|
||||
auto sig_id = instance->module()->signature_map.Find(*sig);
|
||||
IndirectFunctionTableEntry(instance, table_index, entry_index)
|
||||
.Set(sig_id, target_instance, target_func_index);
|
||||
FunctionTargetAndRef entry(target_instance, target_func_index);
|
||||
instance->GetIndirectFunctionTable(isolate, table_index)
|
||||
->Set(entry_index, sig_id, entry.call_target(), *entry.ref());
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,11 +595,11 @@ void WasmTableObject::UpdateDispatchTables(
|
||||
// Note that {SignatureMap::Find} may return {-1} if the signature is
|
||||
// not found; it will simply never match any check.
|
||||
auto sig_id = instance->module()->signature_map.Find(sig);
|
||||
IndirectFunctionTableEntry(instance, table_index, entry_index)
|
||||
.Set(sig_id, wasm_code->instruction_start(),
|
||||
WasmCapiFunctionData::cast(
|
||||
capi_function->shared().function_data(kAcquireLoad))
|
||||
.ref());
|
||||
instance->GetIndirectFunctionTable(isolate, table_index)
|
||||
->Set(entry_index, sig_id, wasm_code->instruction_start(),
|
||||
WasmCapiFunctionData::cast(
|
||||
capi_function->shared().function_data(kAcquireLoad))
|
||||
.ref());
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,9 +616,10 @@ void WasmTableObject::ClearDispatchTables(Isolate* isolate,
|
||||
WasmInstanceObject::cast(
|
||||
dispatch_tables->get(i + kDispatchTableInstanceOffset)),
|
||||
isolate);
|
||||
DCHECK_LT(index, WasmInstanceObject::IndirectFunctionTableSize(
|
||||
isolate, target_instance, table_index));
|
||||
IndirectFunctionTableEntry(target_instance, table_index, index).clear();
|
||||
Handle<WasmIndirectFunctionTable> table =
|
||||
target_instance->GetIndirectFunctionTable(isolate, table_index);
|
||||
DCHECK_LT(index, table->size());
|
||||
table->Clear(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -709,10 +711,24 @@ Handle<WasmIndirectFunctionTable> WasmIndirectFunctionTable::New(
|
||||
isolate, IftNativeAllocations::SizeInMemory(size), table, size);
|
||||
table->set_managed_native_allocations(*native_allocations);
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
IndirectFunctionTableEntry(table, static_cast<int>(i)).clear();
|
||||
table->Clear(i);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
void WasmIndirectFunctionTable::Set(uint32_t index, int sig_id,
|
||||
Address call_target, Object ref) {
|
||||
sig_ids()[index] = sig_id;
|
||||
targets()[index] = call_target;
|
||||
refs().set(index, ref);
|
||||
}
|
||||
|
||||
void WasmIndirectFunctionTable::Clear(uint32_t index) {
|
||||
sig_ids()[index] = -1;
|
||||
targets()[index] = 0;
|
||||
refs().set(
|
||||
index,
|
||||
ReadOnlyRoots(GetIsolateFromWritableObject(*this)).undefined_value());
|
||||
}
|
||||
|
||||
void WasmIndirectFunctionTable::Resize(Isolate* isolate,
|
||||
Handle<WasmIndirectFunctionTable> table,
|
||||
@ -730,7 +746,7 @@ void WasmIndirectFunctionTable::Resize(Isolate* isolate,
|
||||
table->set_refs(*new_refs);
|
||||
table->set_size(new_size);
|
||||
for (uint32_t i = old_size; i < new_size; ++i) {
|
||||
IndirectFunctionTableEntry(table, static_cast<int>(i)).clear();
|
||||
table->Clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1026,56 +1042,21 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New(
|
||||
return global_obj;
|
||||
}
|
||||
|
||||
void IndirectFunctionTableEntry::clear() {
|
||||
table_->sig_ids()[index_] = -1;
|
||||
table_->targets()[index_] = 0;
|
||||
table_->refs().set(
|
||||
index_,
|
||||
ReadOnlyRoots(GetIsolateFromWritableObject(*table_)).undefined_value());
|
||||
}
|
||||
|
||||
void IndirectFunctionTableEntry::Set(int sig_id,
|
||||
Handle<WasmInstanceObject> target_instance,
|
||||
int target_func_index) {
|
||||
TRACE_IFT(
|
||||
"IFT entry 0x%" PRIxPTR "[%d] = {sig_id=%d, target_instance=0x%" PRIxPTR
|
||||
", target_func_index=%d}\n",
|
||||
table_->ptr(), index_, sig_id, target_instance->ptr(), target_func_index);
|
||||
|
||||
Object ref;
|
||||
Address call_target = 0;
|
||||
FunctionTargetAndRef::FunctionTargetAndRef(
|
||||
Handle<WasmInstanceObject> target_instance, int target_func_index) {
|
||||
Isolate* isolate = target_instance->native_context().GetIsolate();
|
||||
if (target_func_index <
|
||||
static_cast<int>(target_instance->module()->num_imported_functions)) {
|
||||
// The function in the target instance was imported. Use its imports table,
|
||||
// which contains a tuple needed by the import wrapper.
|
||||
ImportedFunctionEntry entry(target_instance, target_func_index);
|
||||
ref = entry.object_ref();
|
||||
call_target = entry.target();
|
||||
ref_ = handle(entry.object_ref(), isolate);
|
||||
call_target_ = entry.target();
|
||||
} else {
|
||||
// The function in the target instance was not imported.
|
||||
ref = *target_instance;
|
||||
call_target = target_instance->GetCallTarget(target_func_index);
|
||||
ref_ = target_instance;
|
||||
call_target_ = target_instance->GetCallTarget(target_func_index);
|
||||
}
|
||||
Set(sig_id, call_target, ref);
|
||||
}
|
||||
|
||||
void IndirectFunctionTableEntry::Set(int sig_id, Address call_target,
|
||||
Object ref) {
|
||||
table_->sig_ids()[index_] = sig_id;
|
||||
table_->targets()[index_] = call_target;
|
||||
table_->refs().set(index_, ref);
|
||||
}
|
||||
|
||||
Object IndirectFunctionTableEntry::object_ref() const {
|
||||
return table_->refs().get(index_);
|
||||
}
|
||||
|
||||
int IndirectFunctionTableEntry::sig_id() const {
|
||||
return table_->sig_ids()[index_];
|
||||
}
|
||||
|
||||
Address IndirectFunctionTableEntry::target() const {
|
||||
return table_->targets()[index_];
|
||||
}
|
||||
|
||||
void ImportedFunctionEntry::SetWasmToJs(
|
||||
@ -1132,10 +1113,8 @@ bool WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
|
||||
uint32_t minimum_size) {
|
||||
Isolate* isolate = instance->GetIsolate();
|
||||
DCHECK_LT(table_index, instance->indirect_function_tables().length());
|
||||
auto table =
|
||||
handle(WasmIndirectFunctionTable::cast(
|
||||
instance->indirect_function_tables().get(table_index)),
|
||||
isolate);
|
||||
Handle<WasmIndirectFunctionTable> table =
|
||||
instance->GetIndirectFunctionTable(isolate, table_index);
|
||||
WasmIndirectFunctionTable::Resize(isolate, table, minimum_size);
|
||||
if (table_index == 0) {
|
||||
instance->SetIndirectFunctionTableShortcuts(isolate);
|
||||
@ -1295,13 +1274,20 @@ Address WasmInstanceObject::GetCallTarget(uint32_t func_index) {
|
||||
return native_module->GetCallTargetForFunction(func_index);
|
||||
}
|
||||
|
||||
Handle<WasmIndirectFunctionTable> WasmInstanceObject::GetIndirectFunctionTable(
|
||||
Isolate* isolate, uint32_t table_index) {
|
||||
DCHECK_LT(table_index, indirect_function_tables().length());
|
||||
return handle(WasmIndirectFunctionTable::cast(
|
||||
indirect_function_tables().get(table_index)),
|
||||
isolate);
|
||||
}
|
||||
|
||||
void WasmInstanceObject::SetIndirectFunctionTableShortcuts(Isolate* isolate) {
|
||||
if (indirect_function_tables().length() > 0 &&
|
||||
indirect_function_tables().get(0).IsWasmIndirectFunctionTable()) {
|
||||
HandleScope scope(isolate);
|
||||
auto table0 = handle(
|
||||
WasmIndirectFunctionTable::cast(indirect_function_tables().get(0)),
|
||||
isolate);
|
||||
Handle<WasmIndirectFunctionTable> table0 =
|
||||
GetIndirectFunctionTable(isolate, 0);
|
||||
set_indirect_function_table_size(table0->size());
|
||||
set_indirect_function_table_refs(table0->refs());
|
||||
set_indirect_function_table_sig_ids(table0->sig_ids());
|
||||
@ -1309,16 +1295,6 @@ void WasmInstanceObject::SetIndirectFunctionTableShortcuts(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
int WasmInstanceObject::IndirectFunctionTableSize(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance,
|
||||
uint32_t table_index) {
|
||||
auto table =
|
||||
handle(WasmIndirectFunctionTable::cast(
|
||||
instance->indirect_function_tables().get(table_index)),
|
||||
isolate);
|
||||
return table->size();
|
||||
}
|
||||
|
||||
// static
|
||||
bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance,
|
||||
@ -1494,8 +1470,9 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable(
|
||||
// Update the dispatch table.
|
||||
Handle<WasmApiFunctionRef> ref =
|
||||
isolate->factory()->NewWasmApiFunctionRef(callable);
|
||||
IndirectFunctionTableEntry(instance, table_index, entry_index)
|
||||
.Set(sig_id, call_target, *ref);
|
||||
WasmIndirectFunctionTable::cast(
|
||||
instance->indirect_function_tables().get(table_index))
|
||||
.Set(entry_index, sig_id, call_target, *ref);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -61,33 +61,16 @@ class Managed;
|
||||
DECL_GETTER(has_##name, bool) \
|
||||
DECL_ACCESSORS(name, type)
|
||||
|
||||
// A helper for an entry in an indirect function table (IFT).
|
||||
// The underlying storage in the instance is used by generated code to
|
||||
// call functions indirectly at runtime.
|
||||
// Each entry has the following fields:
|
||||
// - object = target instance, if a Wasm function, tuple if imported
|
||||
// - sig_id = signature id of function
|
||||
// - target = entrypoint to Wasm code or import wrapper code
|
||||
class V8_EXPORT_PRIVATE IndirectFunctionTableEntry {
|
||||
class V8_EXPORT_PRIVATE FunctionTargetAndRef {
|
||||
public:
|
||||
inline IndirectFunctionTableEntry(Handle<WasmInstanceObject>, int table_index,
|
||||
int entry_index);
|
||||
|
||||
inline IndirectFunctionTableEntry(Handle<WasmIndirectFunctionTable> table,
|
||||
int entry_index);
|
||||
|
||||
void clear();
|
||||
void Set(int sig_id, Handle<WasmInstanceObject> target_instance,
|
||||
int target_func_index);
|
||||
void Set(int sig_id, Address call_target, Object ref);
|
||||
|
||||
Object object_ref() const;
|
||||
int sig_id() const;
|
||||
Address target() const;
|
||||
FunctionTargetAndRef(Handle<WasmInstanceObject> target_instance,
|
||||
int target_func_index);
|
||||
Handle<Object> ref() { return ref_; }
|
||||
Address call_target() { return call_target_; }
|
||||
|
||||
private:
|
||||
Handle<WasmIndirectFunctionTable> const table_;
|
||||
int const index_;
|
||||
Handle<Object> ref_;
|
||||
Address call_target_;
|
||||
};
|
||||
|
||||
// A helper for an entry for an imported function, indexed statically.
|
||||
@ -478,11 +461,10 @@ class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject {
|
||||
|
||||
Address GetCallTarget(uint32_t func_index);
|
||||
|
||||
void SetIndirectFunctionTableShortcuts(Isolate* isolate);
|
||||
Handle<WasmIndirectFunctionTable> GetIndirectFunctionTable(
|
||||
Isolate*, uint32_t table_index);
|
||||
|
||||
static int IndirectFunctionTableSize(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance,
|
||||
uint32_t table_index);
|
||||
void SetIndirectFunctionTableShortcuts(Isolate* isolate);
|
||||
|
||||
// Copies table entries. Returns {false} if the ranges are out-of-bounds.
|
||||
static bool CopyTableEntries(Isolate* isolate,
|
||||
@ -695,6 +677,9 @@ class WasmIndirectFunctionTable
|
||||
Isolate* isolate, uint32_t size);
|
||||
static void Resize(Isolate* isolate, Handle<WasmIndirectFunctionTable> table,
|
||||
uint32_t new_size);
|
||||
V8_EXPORT_PRIVATE void Set(uint32_t index, int sig_id, Address call_target,
|
||||
Object ref);
|
||||
void Clear(uint32_t index);
|
||||
|
||||
DECL_PRINTER(WasmIndirectFunctionTable)
|
||||
|
||||
|
@ -231,8 +231,9 @@ void TestingModuleBuilder::AddIndirectFunctionTable(
|
||||
for (uint32_t i = 0; i < table_size; ++i) {
|
||||
WasmFunction& function = test_module_->functions[function_indexes[i]];
|
||||
int sig_id = test_module_->signature_map.Find(*function.sig);
|
||||
IndirectFunctionTableEntry(instance, table_index, i)
|
||||
.Set(sig_id, instance, function.func_index);
|
||||
FunctionTargetAndRef entry(instance, function.func_index);
|
||||
instance->GetIndirectFunctionTable(isolate_, table_index)
|
||||
->Set(i, sig_id, entry.call_target(), *entry.ref());
|
||||
WasmTableObject::SetFunctionTablePlaceholder(
|
||||
isolate_, table_obj, i, instance_object_, function_indexes[i]);
|
||||
}
|
||||
|
@ -4094,21 +4094,20 @@ class WasmInterpreterInternals {
|
||||
uint32_t expected_sig_id = module()->canonicalized_type_ids[sig_index];
|
||||
DCHECK_EQ(expected_sig_id,
|
||||
module()->signature_map.Find(*module()->signature(sig_index)));
|
||||
// Bounds check against table size.
|
||||
if (entry_index >=
|
||||
static_cast<uint32_t>(WasmInstanceObject::IndirectFunctionTableSize(
|
||||
isolate_, instance_object_, table_index))) {
|
||||
return {CallResult::INVALID_FUNC};
|
||||
}
|
||||
|
||||
IndirectFunctionTableEntry entry(instance_object_, table_index,
|
||||
entry_index);
|
||||
Handle<WasmIndirectFunctionTable> table =
|
||||
instance_object_->GetIndirectFunctionTable(isolate_, table_index);
|
||||
|
||||
// Bounds check against table size.
|
||||
if (entry_index >= table->size()) return {CallResult::INVALID_FUNC};
|
||||
|
||||
// Signature check.
|
||||
if (entry.sig_id() != static_cast<int32_t>(expected_sig_id)) {
|
||||
if (table->sig_ids()[entry_index] != expected_sig_id) {
|
||||
return {CallResult::SIGNATURE_MISMATCH};
|
||||
}
|
||||
|
||||
Handle<Object> object_ref = handle(entry.object_ref(), isolate_);
|
||||
Handle<Object> object_ref =
|
||||
handle(table->refs().get(entry_index), isolate_);
|
||||
// Check that this is an internal call (within the same instance).
|
||||
CHECK(object_ref->IsWasmInstanceObject() &&
|
||||
instance_object_.is_identical_to(object_ref));
|
||||
@ -4118,13 +4117,14 @@ class WasmInterpreterInternals {
|
||||
#ifdef DEBUG
|
||||
{
|
||||
WasmCodeRefScope code_ref_scope;
|
||||
WasmCode* wasm_code = native_module->Lookup(entry.target());
|
||||
WasmCode* wasm_code =
|
||||
native_module->Lookup(table->targets()[entry_index]);
|
||||
DCHECK_EQ(native_module, wasm_code->native_module());
|
||||
DCHECK_EQ(WasmCode::kJumpTable, wasm_code->kind());
|
||||
}
|
||||
#endif
|
||||
uint32_t func_index =
|
||||
native_module->GetFunctionIndexFromJumpTableSlot(entry.target());
|
||||
uint32_t func_index = native_module->GetFunctionIndexFromJumpTableSlot(
|
||||
table->targets()[entry_index]);
|
||||
|
||||
return {CallResult::INTERNAL, codemap_.GetCode(func_index)};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user