Commit 3b59a3dd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Refactor all call targets to be Addresses

With the introduction of a jump table, call targets will not be
{WasmCode} objects any more. Instead, we just call any {Address}.
This CL does not change anything yet, but changes interfaces to accept
an {Address} instead of {WasmCode*}.

R=titzer@chromium.org

Bug: v8:7758
Change-Id: Id299738bb7cc6a1891e4a03d7f67c24cde6d1699
Reviewed-on: https://chromium-review.googlesource.com/1058793
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53191}
parent 37e9017f
...@@ -4298,7 +4298,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4298,7 +4298,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return instance; return instance;
} }
void BuildJSToWasmWrapper(wasm::WasmCode* wasm_code) { void BuildJSToWasmWrapper(Address call_target) {
const int wasm_count = static_cast<int>(sig_->parameter_count()); const int wasm_count = static_cast<int>(sig_->parameter_count());
const int count = const int count =
wasm_count + 4; // wasm_code, instance_node, effect, and control. wasm_count + 4; // wasm_code, instance_node, effect, and control.
...@@ -4327,10 +4327,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4327,10 +4327,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
DCHECK_NULL(instance_node_); DCHECK_NULL(instance_node_);
instance_node_ = BuildLoadInstanceFromExportedFunction(js_closure); instance_node_ = BuildLoadInstanceFromExportedFunction(js_closure);
Address instr_start =
wasm_code == nullptr ? kNullAddress : wasm_code->instruction_start();
Node* wasm_code_node = mcgraph()->RelocatableIntPtrConstant( Node* wasm_code_node = mcgraph()->RelocatableIntPtrConstant(
instr_start, RelocInfo::JS_TO_WASM_CALL); call_target, RelocInfo::JS_TO_WASM_CALL);
if (!wasm::IsJSCompatibleSignature(sig_)) { if (!wasm::IsJSCompatibleSignature(sig_)) {
// Throw a TypeError. Use the js_context of the calling javascript // Throw a TypeError. Use the js_context of the calling javascript
// function (passed as a parameter), such that the generated code is // function (passed as a parameter), such that the generated code is
...@@ -4691,7 +4689,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4691,7 +4689,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
} // namespace } // namespace
Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module, Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
wasm::WasmCode* wasm_code, uint32_t index, Address call_target, uint32_t index,
wasm::UseTrapHandler use_trap_handler) { wasm::UseTrapHandler use_trap_handler) {
const wasm::WasmFunction* func = &module->functions[index]; const wasm::WasmFunction* func = &module->functions[index];
...@@ -4714,7 +4712,7 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module, ...@@ -4714,7 +4712,7 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
WasmWrapperGraphBuilder builder(&zone, &env, &jsgraph, func->sig, nullptr); WasmWrapperGraphBuilder builder(&zone, &env, &jsgraph, func->sig, nullptr);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.BuildJSToWasmWrapper(wasm_code); builder.BuildJSToWasmWrapper(call_target);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Run the compilation pipeline. // Run the compilation pipeline.
......
...@@ -110,7 +110,7 @@ Handle<Code> CompileWasmToJSWrapper(Isolate*, Handle<JSReceiver> target, ...@@ -110,7 +110,7 @@ Handle<Code> CompileWasmToJSWrapper(Isolate*, Handle<JSReceiver> target,
// Wraps a given wasm code object, producing a code object. // Wraps a given wasm code object, producing a code object.
V8_EXPORT_PRIVATE Handle<Code> CompileJSToWasmWrapper(Isolate*, V8_EXPORT_PRIVATE Handle<Code> CompileJSToWasmWrapper(Isolate*,
wasm::WasmModule*, wasm::WasmModule*,
wasm::WasmCode*, Address call_target,
uint32_t index, uint32_t index,
wasm::UseTrapHandler); wasm::UseTrapHandler);
......
...@@ -195,7 +195,7 @@ namespace { ...@@ -195,7 +195,7 @@ namespace {
class JSToWasmWrapperCache { class JSToWasmWrapperCache {
public: public:
Handle<Code> CloneOrCompileJSToWasmWrapper( Handle<Code> CloneOrCompileJSToWasmWrapper(
Isolate* isolate, wasm::WasmModule* module, wasm::WasmCode* wasm_code, Isolate* isolate, wasm::WasmModule* module, Address call_target,
uint32_t index, wasm::UseTrapHandler use_trap_handler) { uint32_t index, wasm::UseTrapHandler use_trap_handler) {
const wasm::WasmFunction* func = &module->functions[index]; const wasm::WasmFunction* func = &module->functions[index];
int cached_idx = sig_map_.Find(func->sig); int cached_idx = sig_map_.Find(func->sig);
...@@ -204,13 +204,12 @@ class JSToWasmWrapperCache { ...@@ -204,13 +204,12 @@ class JSToWasmWrapperCache {
// Now patch the call to wasm code. // Now patch the call to wasm code.
RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL)); RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL));
DCHECK(!it.done()); DCHECK(!it.done());
it.rinfo()->set_js_to_wasm_address( it.rinfo()->set_js_to_wasm_address(call_target);
wasm_code == nullptr ? kNullAddress : wasm_code->instruction_start());
return code; return code;
} }
Handle<Code> code = compiler::CompileJSToWasmWrapper( Handle<Code> code = compiler::CompileJSToWasmWrapper(
isolate, module, wasm_code, index, use_trap_handler); isolate, module, call_target, index, use_trap_handler);
uint32_t new_cache_idx = sig_map_.FindOrInsert(func->sig); uint32_t new_cache_idx = sig_map_.FindOrInsert(func->sig);
DCHECK_EQ(code_cache_.size(), new_cache_idx); DCHECK_EQ(code_cache_.size(), new_cache_idx);
USE(new_cache_idx); USE(new_cache_idx);
...@@ -369,13 +368,11 @@ class IndirectPatcher { ...@@ -369,13 +368,11 @@ class IndirectPatcher {
public: public:
void Patch(Handle<WasmInstanceObject> caller_instance, void Patch(Handle<WasmInstanceObject> caller_instance,
Handle<WasmInstanceObject> target_instance, int func_index, Handle<WasmInstanceObject> target_instance, int func_index,
Address old_target, const WasmCode* new_code) { Address old_target, Address new_target) {
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=%" PRIuPTR ", new_target=%" PRIuPTR ")\n",
"new_code=%p)\n", *caller_instance, *target_instance, func_index, old_target, new_target);
*caller_instance, *target_instance, func_index,
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);
} }
...@@ -394,7 +391,7 @@ class IndirectPatcher { ...@@ -394,7 +391,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_wasm_to_wasm(*target_instance, new_code); entry.set_wasm_to_wasm(*target_instance, new_target);
patched++; patched++;
} }
} else { } else {
...@@ -405,7 +402,7 @@ class IndirectPatcher { ...@@ -405,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(entry.sig_id(), *target_instance, new_code); entry.set(entry.sig_id(), *target_instance, new_target);
patched++; patched++;
} }
} }
...@@ -436,7 +433,7 @@ class IndirectPatcher { ...@@ -436,7 +433,7 @@ class IndirectPatcher {
code->index()); code->index());
if (new_code->kind() != WasmCode::kLazyStub) { if (new_code->kind() != WasmCode::kLazyStub) {
// Patch an imported function entry which is already compiled. // Patch an imported function entry which is already compiled.
entry.set_wasm_to_wasm(target_instance, new_code); entry.set_wasm_to_wasm(target_instance, new_code->instruction_start());
} else { } else {
int key = code->index(); int key = code->index();
int index = -1 - i; int index = -1 - i;
...@@ -458,7 +455,8 @@ class IndirectPatcher { ...@@ -458,7 +455,8 @@ class IndirectPatcher {
code->index()); code->index());
if (new_code->kind() != WasmCode::kLazyStub) { if (new_code->kind() != WasmCode::kLazyStub) {
// Patch an indirect function table entry which is already compiled. // Patch an indirect function table entry which is already compiled.
entry.set(entry.sig_id(), target_instance, new_code); entry.set(entry.sig_id(), target_instance,
new_code->instruction_start());
} else { } else {
int key = code->index(); int key = code->index();
int index = i; int index = i;
...@@ -849,7 +847,7 @@ Address CompileLazy(Isolate* isolate, ...@@ -849,7 +847,7 @@ Address CompileLazy(Isolate* isolate,
->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->instruction_start());
} }
return result->instruction_start(); return result->instruction_start();
...@@ -1829,21 +1827,19 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -1829,21 +1827,19 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
if (module_->start_function_index >= 0) { if (module_->start_function_index >= 0) {
int start_index = module_->start_function_index; int start_index = module_->start_function_index;
Handle<WasmInstanceObject> start_function_instance = instance; Handle<WasmInstanceObject> start_function_instance = instance;
wasm::WasmCode* start_code; Address start_call_address;
if (static_cast<uint32_t>(start_index) < module_->num_imported_functions) { if (static_cast<uint32_t>(start_index) < module_->num_imported_functions) {
ImportedFunctionEntry entry(instance, start_index); ImportedFunctionEntry entry(instance, start_index);
start_function_instance = handle(entry.instance(), isolate_); start_function_instance = handle(entry.instance(), isolate_);
start_code = start_call_address = entry.target();
isolate_->wasm_engine()->code_manager()->GetCodeFromStartAddress(
entry.target());
DCHECK_EQ(start_code->native_module(),
start_function_instance->compiled_module()->GetNativeModule());
} else { } else {
start_code = native_module->GetIndirectlyCallableCode(start_index); start_call_address = native_module->GetCallTargetForFunction(start_index);
} }
FunctionSig* sig = module_->functions[start_index].sig; FunctionSig* sig = module_->functions[start_index].sig;
Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
isolate_, module_, start_code, start_index, use_trap_handler()); isolate_, module_, start_call_address, start_index, use_trap_handler());
// TODO(clemensh): Don't generate an exported function for the start
// function. Use CWasmEntry instead.
start_function_ = WasmExportedFunction::New( start_function_ = WasmExportedFunction::New(
isolate_, start_function_instance, MaybeHandle<String>(), start_index, isolate_, start_function_instance, MaybeHandle<String>(), start_index,
static_cast<int>(sig->parameter_count()), wrapper_code); static_cast<int>(sig->parameter_count()), wrapper_code);
...@@ -2119,10 +2115,12 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -2119,10 +2115,12 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
return -1; return -1;
} }
// The import reference is the instance object itself. // The import reference is the instance object itself.
auto wasm_code = imported_function->GetWasmCode();
ImportedFunctionEntry(instance, func_index) ImportedFunctionEntry(instance, func_index)
.set_wasm_to_wasm(*imported_instance, wasm_code); .set_wasm_to_wasm(*imported_instance,
native_module->set_code(func_index, wasm_code); imported_function->GetWasmCallTarget());
// TODO(clemensh): Remove this. NativeModule must be instance
// independent.
native_module->set_code(func_index, imported_function->GetWasmCode());
} else { } else {
// The imported function is a callable. // The imported function is a callable.
Handle<JSReceiver> js_receiver(JSReceiver::cast(*value), isolate_); Handle<JSReceiver> js_receiver(JSReceiver::cast(*value), isolate_);
...@@ -2205,13 +2203,13 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -2205,13 +2203,13 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
auto target = Handle<WasmExportedFunction>::cast(val); auto target = Handle<WasmExportedFunction>::cast(val);
Handle<WasmInstanceObject> imported_instance = Handle<WasmInstanceObject> imported_instance =
handle(target->instance()); handle(target->instance());
const wasm::WasmCode* exported_code = target->GetWasmCode(); Address exported_call_target = target->GetWasmCallTarget();
FunctionSig* sig = imported_instance->module() FunctionSig* sig = imported_instance->module()
->functions[exported_code->index()] ->functions[target->function_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_call_target);
} }
num_imported_tables++; num_imported_tables++;
break; break;
...@@ -2646,18 +2644,18 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) { ...@@ -2646,18 +2644,18 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
// Update the local dispatch table first. // Update the local dispatch table first.
uint32_t sig_id = module_->signature_ids[function->sig_index]; uint32_t sig_id = module_->signature_ids[function->sig_index];
wasm::WasmCode* wasm_code = Address call_target =
native_module->GetIndirectlyCallableCode(func_index); native_module->GetCallTargetForFunction(func_index);
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, call_target);
} else { } else {
IndirectFunctionTableEntry(instance, table_index) IndirectFunctionTableEntry(instance, table_index)
.set(sig_id, *instance, wasm_code); .set(sig_id, *instance, call_target);
} }
if (!table_instance.table_object.is_null()) { if (!table_instance.table_object.is_null()) {
...@@ -2670,7 +2668,7 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) { ...@@ -2670,7 +2668,7 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
Handle<Code> wrapper_code = Handle<Code> wrapper_code =
js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
isolate_, module_, wasm_code, func_index, isolate_, module_, call_target, func_index,
use_trap_handler()); use_trap_handler());
MaybeHandle<String> func_name; MaybeHandle<String> func_name;
if (module_->is_asm_js()) { if (module_->is_asm_js()) {
...@@ -2695,7 +2693,7 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) { ...@@ -2695,7 +2693,7 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
// UpdateDispatchTables() should update this instance as well. // UpdateDispatchTables() should update this instance as well.
WasmTableObject::UpdateDispatchTables( WasmTableObject::UpdateDispatchTables(
isolate_, table_instance.table_object, table_index, function->sig, isolate_, table_instance.table_object, table_index, function->sig,
instance, wasm_code); instance, call_target);
} }
} }
} }
...@@ -3646,13 +3644,12 @@ void CompileJsToWasmWrappers(Isolate* isolate, ...@@ -3646,13 +3644,12 @@ void CompileJsToWasmWrappers(Isolate* isolate,
module_object->compiled_module()->GetNativeModule(); module_object->compiled_module()->GetNativeModule();
wasm::UseTrapHandler use_trap_handler = wasm::UseTrapHandler use_trap_handler =
native_module->use_trap_handler() ? kUseTrapHandler : kNoTrapHandler; native_module->use_trap_handler() ? kUseTrapHandler : kNoTrapHandler;
for (auto exp : module_object->shared()->module()->export_table) { WasmModule* module = native_module->shared_module_data()->module();
for (auto exp : module->export_table) {
if (exp.kind != kExternalFunction) continue; if (exp.kind != kExternalFunction) continue;
wasm::WasmCode* wasm_code = Address call_target = native_module->GetCallTargetForFunction(exp.index);
native_module->GetIndirectlyCallableCode(exp.index);
Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(
isolate, module_object->shared()->module(), wasm_code, exp.index, isolate, module, call_target, exp.index, use_trap_handler);
use_trap_handler);
export_wrappers->set(wrapper_index, *wrapper_code); export_wrappers->set(wrapper_index, *wrapper_code);
RecordStats(*wrapper_code, counters); RecordStats(*wrapper_code, counters);
++wrapper_index; ++wrapper_index;
......
...@@ -697,16 +697,19 @@ WasmCode* NativeModule::Lookup(Address pc) { ...@@ -697,16 +697,19 @@ WasmCode* NativeModule::Lookup(Address pc) {
WasmCodeUniquePtrComparator()); WasmCodeUniquePtrComparator());
if (iter == owned_code_.begin()) return nullptr; if (iter == owned_code_.begin()) return nullptr;
--iter; --iter;
WasmCode* candidate = (*iter).get(); WasmCode* candidate = iter->get();
DCHECK_NOT_NULL(candidate); DCHECK_NOT_NULL(candidate);
return candidate->contains(pc) ? candidate : nullptr; return candidate->contains(pc) ? candidate : nullptr;
} }
WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) { Address NativeModule::GetCallTargetForFunction(uint32_t func_index) {
// TODO(clemensh): Introduce a jump table and return a slot of it here.
WasmCode* wasm_code = code(func_index); WasmCode* wasm_code = code(func_index);
if (!wasm_code || wasm_code->kind() != WasmCode::kLazyStub) { if (!wasm_code) return kNullAddress;
return wasm_code; if (wasm_code->kind() != WasmCode::kLazyStub) {
return wasm_code->instruction_start();
} }
#if DEBUG #if DEBUG
auto num_imported_functions = auto num_imported_functions =
shared_module_data()->module()->num_imported_functions; shared_module_data()->module()->num_imported_functions;
...@@ -718,7 +721,7 @@ WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) { ...@@ -718,7 +721,7 @@ WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) {
// If the function wasn't imported, its index should match. // If the function wasn't imported, its index should match.
DCHECK_IMPLIES(func_index >= num_imported_functions, DCHECK_IMPLIES(func_index >= num_imported_functions,
func_index == wasm_code->index()); func_index == wasm_code->index());
return wasm_code; return wasm_code->instruction_start();
} }
if (!lazy_compile_stubs_.get()) { if (!lazy_compile_stubs_.get()) {
lazy_compile_stubs_ = lazy_compile_stubs_ =
...@@ -732,7 +735,7 @@ WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) { ...@@ -732,7 +735,7 @@ WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) {
lazy_compile_stubs_.get()->at(func_index) = cloned_code; lazy_compile_stubs_.get()->at(func_index) = cloned_code;
} }
DCHECK_EQ(func_index, cloned_code->index()); DCHECK_EQ(func_index, cloned_code->index());
return cloned_code; return cloned_code->instruction_start();
} }
WasmCode* NativeModule::CloneCode(const WasmCode* original_code, WasmCode* NativeModule::CloneCode(const WasmCode* original_code,
......
...@@ -259,15 +259,21 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -259,15 +259,21 @@ class V8_EXPORT_PRIVATE NativeModule final {
code_table_[index] = wasm_code; code_table_[index] = wasm_code;
} }
bool has_code(uint32_t index) const {
DCHECK_LT(index, function_count());
return code_table_[index] != nullptr;
}
// Register/release the protected instructions in all code objects with the // Register/release the protected instructions in all code objects with the
// global trap handler for this process. // global trap handler for this process.
void UnpackAndRegisterProtectedInstructions(); void UnpackAndRegisterProtectedInstructions();
void ReleaseProtectedInstructions(); void ReleaseProtectedInstructions();
// Gets code suitable for indirect or import calls for the given function // Returns the instruction start of code suitable for indirect or import calls
// index. If the code at the given index is the lazy compile stub, it will // for the given function index. If the code at the given index is the lazy
// clone a non-anonymous lazy compile stub for the purpose. // compile stub, it will clone a non-anonymous lazy compile stub for the
WasmCode* GetIndirectlyCallableCode(uint32_t func_index); // purpose. This will soon change to always return a jump table slot.
Address GetCallTargetForFunction(uint32_t index);
bool SetExecutable(bool executable); bool SetExecutable(bool executable);
......
...@@ -113,10 +113,9 @@ bool CodeSpecialization::ApplyToWholeModule( ...@@ -113,10 +113,9 @@ bool CodeSpecialization::ApplyToWholeModule(
switch (mode) { switch (mode) {
case RelocInfo::JS_TO_WASM_CALL: { case RelocInfo::JS_TO_WASM_CALL: {
changed = true; changed = true;
const WasmCode* new_code = Address new_target =
native_module->GetIndirectlyCallableCode(exp.index); native_module->GetCallTargetForFunction(exp.index);
it.rinfo()->set_js_to_wasm_address(new_code->instruction_start(), it.rinfo()->set_js_to_wasm_address(new_target, icache_flush_mode);
icache_flush_mode);
} break; } break;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -405,16 +405,16 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table, ...@@ -405,16 +405,16 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
auto* wasm_function = &other_instance->module()->functions[func_index]; auto* wasm_function = &other_instance->module()->functions[func_index];
DCHECK_NOT_NULL(wasm_function); DCHECK_NOT_NULL(wasm_function);
DCHECK_NOT_NULL(wasm_function->sig); DCHECK_NOT_NULL(wasm_function->sig);
wasm::WasmCode* wasm_code = exported_function->GetWasmCode(); Address call_target = exported_function->GetWasmCallTarget();
UpdateDispatchTables(isolate, table, table_index, wasm_function->sig, UpdateDispatchTables(isolate, table, table_index, wasm_function->sig,
handle(exported_function->instance()), wasm_code); handle(exported_function->instance()), call_target);
array->set(table_index, *function); array->set(table_index, *function);
} }
void WasmTableObject::UpdateDispatchTables( void WasmTableObject::UpdateDispatchTables(
Isolate* isolate, Handle<WasmTableObject> table, int table_index, Isolate* isolate, Handle<WasmTableObject> table, int table_index,
wasm::FunctionSig* sig, Handle<WasmInstanceObject> from_instance, wasm::FunctionSig* sig, Handle<WasmInstanceObject> from_instance,
wasm::WasmCode* wasm_code) { Address call_target) {
// 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.
Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate); Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
...@@ -430,7 +430,7 @@ void WasmTableObject::UpdateDispatchTables( ...@@ -430,7 +430,7 @@ void WasmTableObject::UpdateDispatchTables(
// not found; it will simply never match any check. // not found; it will simply never match any check.
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, call_target);
} }
} }
...@@ -672,13 +672,12 @@ void IndirectFunctionTableEntry::clear() { ...@@ -672,13 +672,12 @@ void IndirectFunctionTableEntry::clear() {
} }
void IndirectFunctionTableEntry::set(int sig_id, WasmInstanceObject* instance, void IndirectFunctionTableEntry::set(int sig_id, WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code) { Address call_target) {
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=%" PRIuPTR
*instance_, index_, sig_id, instance, "}\n",
wasm_code->instructions().start()); *instance_, index_, sig_id, instance, call_target);
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_] = call_target;
wasm_code->instruction_start();
instance_->indirect_function_table_instances()->set(index_, instance); instance_->indirect_function_table_instances()->set(index_, instance);
} }
...@@ -707,14 +706,13 @@ void ImportedFunctionEntry::set_wasm_to_js( ...@@ -707,14 +706,13 @@ void ImportedFunctionEntry::set_wasm_to_js(
} }
void ImportedFunctionEntry::set_wasm_to_wasm(WasmInstanceObject* instance, void ImportedFunctionEntry::set_wasm_to_wasm(WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code) { Address call_target) {
TRACE_IFT("Import WASM %p[%d] = {instance=%p, target=%p}\n", *instance_, TRACE_IFT("Import WASM %p[%d] = {instance=%p, target=%" PRIuPTR "}\n",
index_, instance, wasm_code->instructions().start()); *instance_, index_, instance, call_target);
instance_->imported_function_instances()->set(index_, instance); instance_->imported_function_instances()->set(index_, instance);
instance_->imported_function_callables()->set( instance_->imported_function_callables()->set(
index_, instance_->GetHeap()->undefined_value()); index_, instance_->GetHeap()->undefined_value());
instance_->imported_function_targets()[index_] = instance_->imported_function_targets()[index_] = call_target;
wasm_code->instruction_start();
} }
WasmInstanceObject* ImportedFunctionEntry::instance() { WasmInstanceObject* ImportedFunctionEntry::instance() {
...@@ -947,15 +945,19 @@ Handle<WasmExportedFunction> WasmExportedFunction::New( ...@@ -947,15 +945,19 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
} }
wasm::WasmCode* WasmExportedFunction::GetWasmCode() { wasm::WasmCode* WasmExportedFunction::GetWasmCode() {
Address target = GetWasmCallTarget();
wasm::WasmCode* wasm_code =
GetIsolate()->wasm_engine()->code_manager()->LookupCode(target);
return wasm_code;
}
Address WasmExportedFunction::GetWasmCallTarget() {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Handle<Code> export_wrapper_code = handle(this->code()); DCHECK_EQ(code()->kind(), Code::JS_TO_WASM_FUNCTION);
DCHECK_EQ(export_wrapper_code->kind(), Code::JS_TO_WASM_FUNCTION);
int mask = RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL); int mask = RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL);
RelocIterator it(*export_wrapper_code, mask); RelocIterator it(code(), mask);
DCHECK(!it.done()); DCHECK(!it.done());
wasm::WasmCode* target = Address target = it.rinfo()->js_to_wasm_address();
GetIsolate()->wasm_engine()->code_manager()->LookupCode(
it.rinfo()->js_to_wasm_address());
#ifdef DEBUG #ifdef DEBUG
// There should only be this one call to wasm code. // There should only be this one call to wasm code.
it.next(); it.next();
......
...@@ -57,8 +57,7 @@ class IndirectFunctionTableEntry { ...@@ -57,8 +57,7 @@ class IndirectFunctionTableEntry {
inline IndirectFunctionTableEntry(Handle<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, Address call_target);
const wasm::WasmCode* wasm_code);
WasmInstanceObject* instance(); WasmInstanceObject* instance();
int sig_id(); int sig_id();
...@@ -89,7 +88,7 @@ class ImportedFunctionEntry { ...@@ -89,7 +88,7 @@ class ImportedFunctionEntry {
const wasm::WasmCode* wasm_to_js_wrapper); const wasm::WasmCode* wasm_to_js_wrapper);
// Initialize this entry as a WASM to WASM call. // Initialize this entry as a WASM to WASM call.
void set_wasm_to_wasm(WasmInstanceObject* target_instance, void set_wasm_to_wasm(WasmInstanceObject* target_instance,
const wasm::WasmCode* wasm_function); Address call_target);
WasmInstanceObject* instance(); WasmInstanceObject* instance();
JSReceiver* callable(); JSReceiver* callable();
...@@ -176,7 +175,7 @@ class WasmTableObject : public JSObject { ...@@ -176,7 +175,7 @@ class WasmTableObject : public JSObject {
Handle<WasmTableObject> table, Handle<WasmTableObject> table,
int table_index, wasm::FunctionSig* sig, int table_index, wasm::FunctionSig* sig,
Handle<WasmInstanceObject> from_instance, Handle<WasmInstanceObject> from_instance,
wasm::WasmCode* wasm_code); Address call_target);
static void ClearDispatchTables(Isolate* isolate, static void ClearDispatchTables(Isolate* isolate,
Handle<WasmTableObject> table, int index); Handle<WasmTableObject> table, int index);
...@@ -377,7 +376,12 @@ class WasmExportedFunction : public JSFunction { ...@@ -377,7 +376,12 @@ class WasmExportedFunction : public JSFunction {
int func_index, int arity, int func_index, int arity,
Handle<Code> export_wrapper); Handle<Code> export_wrapper);
// TODO(clemensh): Remove this. There might not be a WasmCode object available
// yet.
// TODO(all): Replace all uses by {GetWasmCallTarget()}.
wasm::WasmCode* GetWasmCode(); wasm::WasmCode* GetWasmCode();
Address GetWasmCallTarget();
}; };
// Information for a WasmExportedFunction which is referenced as the function // Information for a WasmExportedFunction which is referenced as the function
......
...@@ -120,7 +120,7 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) { ...@@ -120,7 +120,7 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
Link(); Link();
wasm::WasmCode* code = native_module_->code(index); wasm::WasmCode* code = native_module_->code(index);
Handle<Code> ret_code = compiler::CompileJSToWasmWrapper( Handle<Code> ret_code = compiler::CompileJSToWasmWrapper(
isolate_, test_module_ptr_, code, index, isolate_, test_module_ptr_, code->instruction_start(), index,
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler); trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler);
Handle<JSFunction> ret = WasmExportedFunction::New( Handle<JSFunction> ret = WasmExportedFunction::New(
isolate_, instance_object(), MaybeHandle<String>(), isolate_, instance_object(), MaybeHandle<String>(),
...@@ -166,7 +166,8 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() { ...@@ -166,7 +166,8 @@ 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_->code(function.func_index); auto wasm_code = native_module_->code(function.func_index);
IndirectFunctionTableEntry(instance, j).set(sig_id, *instance, wasm_code); IndirectFunctionTableEntry(instance, j)
.set(sig_id, *instance, wasm_code->instruction_start());
} }
} }
} }
......
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