Commit 8ba3f136 authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Handlify table entry helpers

R=clemensh@chromium.org

Change-Id: Iade16b07a24dca8ac542e68becad734d977b673a
Reviewed-on: https://chromium-review.googlesource.com/1032778Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52852}
parent 61c95039
...@@ -375,15 +375,14 @@ MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject( ...@@ -375,15 +375,14 @@ MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject(
// Utilizes a reverse mapping to prevent O(n^2) behavior. // Utilizes a reverse mapping to prevent O(n^2) behavior.
class IndirectPatcher { class IndirectPatcher {
public: public:
void Patch(WasmInstanceObject* caller_instance, void Patch(Handle<WasmInstanceObject> caller_instance,
WasmInstanceObject* target_instance, int func_index, Handle<WasmInstanceObject> target_instance, int func_index,
Address old_target, const WasmCode* new_code) { Address old_target, const WasmCode* new_code) {
DisallowHeapAllocation no_gc;
TRACE_LAZY( TRACE_LAZY(
"IndirectPatcher::Patch(caller=%p, target=%p, func_index=%i, " "IndirectPatcher::Patch(caller=%p, target=%p, func_index=%i, "
"old_target=%p, " "old_target=%p, "
"new_code=%p)\n", "new_code=%p)\n",
caller_instance, target_instance, func_index, *caller_instance, *target_instance, func_index,
reinterpret_cast<void*>(old_target), new_code); reinterpret_cast<void*>(old_target), new_code);
if (mapping_.size() == 0 || misses_ >= kMaxMisses) { if (mapping_.size() == 0 || misses_ >= kMaxMisses) {
BuildMapping(caller_instance); BuildMapping(caller_instance);
...@@ -403,7 +402,7 @@ class IndirectPatcher { ...@@ -403,7 +402,7 @@ class IndirectPatcher {
DCHECK_EQ( DCHECK_EQ(
func_index, func_index,
code_manager->GetCodeFromStartAddress(entry.target())->index()); code_manager->GetCodeFromStartAddress(entry.target())->index());
entry.set(target_instance, new_code); entry.set(*target_instance, new_code);
patched++; patched++;
} }
} else { } else {
...@@ -414,7 +413,7 @@ class IndirectPatcher { ...@@ -414,7 +413,7 @@ class IndirectPatcher {
DCHECK_EQ( DCHECK_EQ(
func_index, func_index,
code_manager->GetCodeFromStartAddress(entry.target())->index()); code_manager->GetCodeFromStartAddress(entry.target())->index());
entry.set(entry.sig_id(), target_instance, new_code); entry.set(entry.sig_id(), *target_instance, new_code);
patched++; patched++;
} }
} }
...@@ -423,10 +422,10 @@ class IndirectPatcher { ...@@ -423,10 +422,10 @@ class IndirectPatcher {
} }
private: private:
void BuildMapping(WasmInstanceObject* caller_instance) { void BuildMapping(Handle<WasmInstanceObject> caller_instance) {
mapping_.clear(); mapping_.clear();
misses_ = 0; misses_ = 0;
TRACE_LAZY("BuildMapping for (caller=%p)...\n", caller_instance); TRACE_LAZY("BuildMapping for (caller=%p)...\n", *caller_instance);
Isolate* isolate = caller_instance->GetIsolate(); Isolate* isolate = caller_instance->GetIsolate();
WasmCodeManager* code_manager = isolate->wasm_engine()->code_manager(); WasmCodeManager* code_manager = isolate->wasm_engine()->code_manager();
uint32_t num_imported_functions = uint32_t num_imported_functions =
...@@ -862,7 +861,7 @@ Address CompileLazy(Isolate* isolate, ...@@ -862,7 +861,7 @@ Address CompileLazy(Isolate* isolate,
caller_instance->managed_indirect_patcher()) caller_instance->managed_indirect_patcher())
->raw(); ->raw();
Address old_target = lazy_stub->instruction_start(); Address old_target = lazy_stub->instruction_start();
patcher->Patch(*caller_instance, *target_instance, target_func_index, patcher->Patch(caller_instance, target_instance, target_func_index,
old_target, result); old_target, result);
} }
...@@ -2175,7 +2174,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -2175,7 +2174,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
} }
// The import reference is the instance object itself. // The import reference is the instance object itself.
auto wasm_code = imported_function->GetWasmCode(); auto wasm_code = imported_function->GetWasmCode();
ImportedFunctionEntry(*instance, func_index) ImportedFunctionEntry(instance, func_index)
.set(*imported_instance, wasm_code); .set(*imported_instance, wasm_code);
native_module->SetCode(func_index, wasm_code); native_module->SetCode(func_index, wasm_code);
} else { } else {
...@@ -2188,7 +2187,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -2188,7 +2187,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
WasmCode* wasm_code = native_module->AddCodeCopy( WasmCode* wasm_code = native_module->AddCodeCopy(
wrapper_code, wasm::WasmCode::kWasmToJsWrapper, func_index); wrapper_code, wasm::WasmCode::kWasmToJsWrapper, func_index);
ImportedFunctionEntry(*instance, func_index) ImportedFunctionEntry(instance, func_index)
.set(*js_receiver, wasm_code); .set(*js_receiver, wasm_code);
} }
num_imported_functions++; num_imported_functions++;
...@@ -2264,7 +2263,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -2264,7 +2263,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
FunctionSig* sig = imported_instance->module() FunctionSig* sig = imported_instance->module()
->functions[exported_code->index()] ->functions[exported_code->index()]
.sig; .sig;
IndirectFunctionTableEntry(*instance, i) IndirectFunctionTableEntry(instance, i)
.set(module_->signature_map.Find(sig), *imported_instance, .set(module_->signature_map.Find(sig), *imported_instance,
exported_code); exported_code);
} }
...@@ -2708,11 +2707,11 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) { ...@@ -2708,11 +2707,11 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
if (func_index < module_->num_imported_functions) { if (func_index < module_->num_imported_functions) {
// Imported functions have the target instance put into the IFT. // Imported functions have the target instance put into the IFT.
WasmInstanceObject* target_instance = WasmInstanceObject* target_instance =
ImportedFunctionEntry(*instance, func_index).instance(); ImportedFunctionEntry(instance, func_index).instance();
IndirectFunctionTableEntry(*instance, table_index) IndirectFunctionTableEntry(instance, table_index)
.set(sig_id, target_instance, wasm_code); .set(sig_id, target_instance, wasm_code);
} else { } else {
IndirectFunctionTableEntry(*instance, table_index) IndirectFunctionTableEntry(instance, table_index)
.set(sig_id, *instance, wasm_code); .set(sig_id, *instance, wasm_code);
} }
......
...@@ -2392,7 +2392,7 @@ class ThreadImpl { ...@@ -2392,7 +2392,7 @@ class ThreadImpl {
Handle<WasmInstanceObject> instance; Handle<WasmInstanceObject> instance;
WasmCode* code; WasmCode* code;
{ {
ImportedFunctionEntry entry(*instance_object_, function_index); ImportedFunctionEntry entry(instance_object_, function_index);
instance = handle(entry.instance(), isolate); instance = handle(entry.instance(), isolate);
code = isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress( code = isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress(
entry.target()); entry.target());
...@@ -2439,7 +2439,7 @@ class ThreadImpl { ...@@ -2439,7 +2439,7 @@ class ThreadImpl {
WasmCode* code; WasmCode* code;
Handle<WasmInstanceObject> instance; Handle<WasmInstanceObject> instance;
{ {
IndirectFunctionTableEntry entry(*instance_object_, entry_index); IndirectFunctionTableEntry entry(instance_object_, entry_index);
// Signature check. // Signature check.
if (entry.sig_id() != static_cast<int32_t>(expected_sig_id)) { if (entry.sig_id() != static_cast<int32_t>(expected_sig_id)) {
return {ExternalCallResult::SIGNATURE_MISMATCH}; return {ExternalCallResult::SIGNATURE_MISMATCH};
......
...@@ -154,14 +154,14 @@ inline bool WasmInstanceObject::has_indirect_function_table() { ...@@ -154,14 +154,14 @@ inline bool WasmInstanceObject::has_indirect_function_table() {
} }
IndirectFunctionTableEntry::IndirectFunctionTableEntry( IndirectFunctionTableEntry::IndirectFunctionTableEntry(
WasmInstanceObject* instance, int index) Handle<WasmInstanceObject> instance, int index)
: instance_(instance), index_(index) { : instance_(instance), index_(index) {
DCHECK_GE(index, 0); DCHECK_GE(index, 0);
DCHECK_LT(index, instance->indirect_function_table_size()); DCHECK_LT(index, instance->indirect_function_table_size());
} }
ImportedFunctionEntry::ImportedFunctionEntry(WasmInstanceObject* instance, ImportedFunctionEntry::ImportedFunctionEntry(
int index) Handle<WasmInstanceObject> instance, int index)
: instance_(instance), index_(index) { : instance_(instance), index_(index) {
DCHECK_GE(index, 0); DCHECK_GE(index, 0);
DCHECK_LT(index, instance->module()->num_imported_functions); DCHECK_LT(index, instance->module()->num_imported_functions);
......
...@@ -116,7 +116,7 @@ class WasmInstanceNativeAllocations { ...@@ -116,7 +116,7 @@ class WasmInstanceNativeAllocations {
instance->set_indirect_function_table_instances(*new_instances); instance->set_indirect_function_table_instances(*new_instances);
for (uint32_t j = old_size; j < new_size; j++) { for (uint32_t j = old_size; j < new_size; j++) {
IndirectFunctionTableEntry(*instance, static_cast<int>(j)).clear(); IndirectFunctionTableEntry(instance, static_cast<int>(j)).clear();
} }
} }
uint32_t* indirect_function_table_sig_ids_ = nullptr; uint32_t* indirect_function_table_sig_ids_ = nullptr;
...@@ -359,7 +359,7 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table, ...@@ -359,7 +359,7 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
int32_t table_index, Handle<JSFunction> function) { int32_t table_index, Handle<JSFunction> function) {
Handle<FixedArray> array(table->functions(), isolate); Handle<FixedArray> array(table->functions(), isolate);
if (function.is_null()) { if (function.is_null()) {
ClearDispatchTables(table, table_index); // Degenerate case of null value. ClearDispatchTables(isolate, table, table_index); // Degenerate case.
array->set(table_index, isolate->heap()->null_value()); array->set(table_index, isolate->heap()->null_value());
return; return;
} }
...@@ -384,31 +384,34 @@ void WasmTableObject::UpdateDispatchTables( ...@@ -384,31 +384,34 @@ void WasmTableObject::UpdateDispatchTables(
wasm::WasmCode* wasm_code) { wasm::WasmCode* wasm_code) {
// We simply need to update the IFTs for each instance that imports // We simply need to update the IFTs for each instance that imports
// this table. // this table.
DisallowHeapAllocation no_gc; Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
FixedArray* dispatch_tables = table->dispatch_tables();
DCHECK_EQ(0, dispatch_tables->length() % kDispatchTableNumElements); DCHECK_EQ(0, dispatch_tables->length() % kDispatchTableNumElements);
for (int i = 0; i < dispatch_tables->length(); for (int i = 0; i < dispatch_tables->length();
i += kDispatchTableNumElements) { i += kDispatchTableNumElements) {
Handle<WasmInstanceObject> to_instance(
WasmInstanceObject::cast(
dispatch_tables->get(i + kDispatchTableInstanceOffset)),
isolate);
// Note that {SignatureMap::Find} may return {-1} if the signature is // Note that {SignatureMap::Find} may return {-1} if the signature is
// not found; it will simply never match any check. // not found; it will simply never match any check.
WasmInstanceObject* to_instance = WasmInstanceObject::cast(
dispatch_tables->get(i + kDispatchTableInstanceOffset));
auto sig_id = to_instance->module()->signature_map.Find(sig); auto sig_id = to_instance->module()->signature_map.Find(sig);
IndirectFunctionTableEntry(to_instance, table_index) IndirectFunctionTableEntry(to_instance, table_index)
.set(sig_id, *from_instance, wasm_code); .set(sig_id, *from_instance, wasm_code);
} }
} }
void WasmTableObject::ClearDispatchTables(Handle<WasmTableObject> table, void WasmTableObject::ClearDispatchTables(Isolate* isolate,
Handle<WasmTableObject> table,
int index) { int index) {
DisallowHeapAllocation no_gc; Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
FixedArray* dispatch_tables = table->dispatch_tables();
DCHECK_EQ(0, dispatch_tables->length() % kDispatchTableNumElements); DCHECK_EQ(0, dispatch_tables->length() % kDispatchTableNumElements);
for (int i = 0; i < dispatch_tables->length(); for (int i = 0; i < dispatch_tables->length();
i += kDispatchTableNumElements) { i += kDispatchTableNumElements) {
WasmInstanceObject* target_instance = WasmInstanceObject::cast( Handle<WasmInstanceObject> target_instance(
dispatch_tables->get(i + kDispatchTableInstanceOffset)); WasmInstanceObject::cast(
dispatch_tables->get(i + kDispatchTableInstanceOffset)),
isolate);
DCHECK_LT(index, target_instance->indirect_function_table_size()); DCHECK_LT(index, target_instance->indirect_function_table_size());
IndirectFunctionTableEntry(target_instance, index).clear(); IndirectFunctionTableEntry(target_instance, index).clear();
} }
...@@ -643,7 +646,7 @@ void IndirectFunctionTableEntry::clear() { ...@@ -643,7 +646,7 @@ void IndirectFunctionTableEntry::clear() {
void IndirectFunctionTableEntry::set(int sig_id, WasmInstanceObject* instance, void IndirectFunctionTableEntry::set(int sig_id, WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code) { const wasm::WasmCode* wasm_code) {
TRACE_IFT("IFT entry %p[%d] = {sig_id=%d, instance=%p, target=%p}\n", TRACE_IFT("IFT entry %p[%d] = {sig_id=%d, instance=%p, target=%p}\n",
instance_, index_, sig_id, instance, *instance_, index_, sig_id, instance,
wasm_code->instructions().start()); wasm_code->instructions().start());
instance_->indirect_function_table_sig_ids()[index_] = sig_id; instance_->indirect_function_table_sig_ids()[index_] = sig_id;
instance_->indirect_function_table_targets()[index_] = instance_->indirect_function_table_targets()[index_] =
...@@ -666,10 +669,10 @@ Address IndirectFunctionTableEntry::target() { ...@@ -666,10 +669,10 @@ Address IndirectFunctionTableEntry::target() {
void ImportedFunctionEntry::set(JSReceiver* callable, void ImportedFunctionEntry::set(JSReceiver* callable,
const wasm::WasmCode* wasm_to_js_wrapper) { const wasm::WasmCode* wasm_to_js_wrapper) {
TRACE_IFT("Import callable %p[%d] = {callable=%p, target=%p}\n", instance_, TRACE_IFT("Import callable %p[%d] = {callable=%p, target=%p}\n", *instance_,
index_, callable, wasm_to_js_wrapper->instructions().start()); index_, callable, wasm_to_js_wrapper->instructions().start());
DCHECK_EQ(wasm::WasmCode::kWasmToJsWrapper, wasm_to_js_wrapper->kind()); DCHECK_EQ(wasm::WasmCode::kWasmToJsWrapper, wasm_to_js_wrapper->kind());
instance_->imported_function_instances()->set(index_, instance_); instance_->imported_function_instances()->set(index_, *instance_);
instance_->imported_function_callables()->set(index_, callable); instance_->imported_function_callables()->set(index_, callable);
instance_->imported_function_targets()[index_] = instance_->imported_function_targets()[index_] =
wasm_to_js_wrapper->instruction_start(); wasm_to_js_wrapper->instruction_start();
...@@ -677,7 +680,7 @@ void ImportedFunctionEntry::set(JSReceiver* callable, ...@@ -677,7 +680,7 @@ void ImportedFunctionEntry::set(JSReceiver* callable,
void ImportedFunctionEntry::set(WasmInstanceObject* instance, void ImportedFunctionEntry::set(WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code) { const wasm::WasmCode* wasm_code) {
TRACE_IFT("Import WASM %p[%d] = {instance=%p, target=%p}\n", instance_, TRACE_IFT("Import WASM %p[%d] = {instance=%p, target=%p}\n", *instance_,
index_, instance, wasm_code->instructions().start()); index_, instance, wasm_code->instructions().start());
instance_->imported_function_instances()->set(index_, instance); instance_->imported_function_instances()->set(index_, instance);
instance_->imported_function_callables()->set( instance_->imported_function_callables()->set(
......
...@@ -49,7 +49,7 @@ class WasmInstanceObject; ...@@ -49,7 +49,7 @@ class WasmInstanceObject;
// - target = entrypoint to wasm code for the function, or wasm-to-js wrapper // - target = entrypoint to wasm code for the function, or wasm-to-js wrapper
class IndirectFunctionTableEntry { class IndirectFunctionTableEntry {
public: public:
inline IndirectFunctionTableEntry(WasmInstanceObject*, int index); inline IndirectFunctionTableEntry(Handle<WasmInstanceObject>, int index);
void clear(); void clear();
void set(int sig_id, WasmInstanceObject* instance, void set(int sig_id, WasmInstanceObject* instance,
...@@ -60,10 +60,7 @@ class IndirectFunctionTableEntry { ...@@ -60,10 +60,7 @@ class IndirectFunctionTableEntry {
Address target(); Address target();
private: private:
#ifdef DEBUG Handle<WasmInstanceObject> const instance_;
DisallowHeapAllocation no_gc;
#endif
WasmInstanceObject* const instance_;
int const index_; int const index_;
}; };
...@@ -80,7 +77,7 @@ class IndirectFunctionTableEntry { ...@@ -80,7 +77,7 @@ class IndirectFunctionTableEntry {
// - target = entrypoint to wasm code of the function // - target = entrypoint to wasm code of the function
class ImportedFunctionEntry { class ImportedFunctionEntry {
public: public:
inline ImportedFunctionEntry(WasmInstanceObject*, int index); inline ImportedFunctionEntry(Handle<WasmInstanceObject>, int index);
// Initialize this entry as a {JSReceiver} call. // Initialize this entry as a {JSReceiver} call.
void set(JSReceiver* callable, const wasm::WasmCode* wasm_to_js_wrapper); void set(JSReceiver* callable, const wasm::WasmCode* wasm_to_js_wrapper);
...@@ -94,10 +91,7 @@ class ImportedFunctionEntry { ...@@ -94,10 +91,7 @@ class ImportedFunctionEntry {
bool is_js_receiver_entry(); bool is_js_receiver_entry();
private: private:
#ifdef DEBUG Handle<WasmInstanceObject> const instance_;
DisallowHeapAllocation no_gc;
#endif
WasmInstanceObject* const instance_;
int const index_; int const index_;
}; };
...@@ -164,7 +158,8 @@ class WasmTableObject : public JSObject { ...@@ -164,7 +158,8 @@ class WasmTableObject : public JSObject {
Handle<WasmInstanceObject> from_instance, Handle<WasmInstanceObject> from_instance,
wasm::WasmCode* wasm_code); wasm::WasmCode* wasm_code);
static void ClearDispatchTables(Handle<WasmTableObject> table, int index); static void ClearDispatchTables(Isolate* isolate,
Handle<WasmTableObject> table, int index);
}; };
// Representation of a WebAssembly.Memory JavaScript-level object. // Representation of a WebAssembly.Memory JavaScript-level object.
......
...@@ -52,7 +52,7 @@ TestingModuleBuilder::TestingModuleBuilder( ...@@ -52,7 +52,7 @@ TestingModuleBuilder::TestingModuleBuilder(
auto wasm_to_js_wrapper = native_module_->AddCodeCopy( auto wasm_to_js_wrapper = native_module_->AddCodeCopy(
code, wasm::WasmCode::kWasmToJsWrapper, maybe_import_index); code, wasm::WasmCode::kWasmToJsWrapper, maybe_import_index);
ImportedFunctionEntry(*instance_object_, maybe_import_index) ImportedFunctionEntry(instance_object_, maybe_import_index)
.set(*maybe_import->js_function, wasm_to_js_wrapper); .set(*maybe_import->js_function, wasm_to_js_wrapper);
} }
...@@ -170,8 +170,7 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() { ...@@ -170,8 +170,7 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() {
WasmFunction& function = test_module_->functions[table.values[j]]; WasmFunction& function = test_module_->functions[table.values[j]];
int sig_id = test_module_->signature_map.Find(function.sig); int sig_id = test_module_->signature_map.Find(function.sig);
auto wasm_code = native_module_->GetCode(function.func_index); auto wasm_code = native_module_->GetCode(function.func_index);
IndirectFunctionTableEntry(*instance, j) IndirectFunctionTableEntry(instance, j).set(sig_id, *instance, wasm_code);
.set(sig_id, *instance, wasm_code);
} }
} }
} }
......
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