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 {
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 count =
wasm_count + 4; // wasm_code, instance_node, effect, and control.
......@@ -4327,10 +4327,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
DCHECK_NULL(instance_node_);
instance_node_ = BuildLoadInstanceFromExportedFunction(js_closure);
Address instr_start =
wasm_code == nullptr ? kNullAddress : wasm_code->instruction_start();
Node* wasm_code_node = mcgraph()->RelocatableIntPtrConstant(
instr_start, RelocInfo::JS_TO_WASM_CALL);
call_target, RelocInfo::JS_TO_WASM_CALL);
if (!wasm::IsJSCompatibleSignature(sig_)) {
// Throw a TypeError. Use the js_context of the calling javascript
// function (passed as a parameter), such that the generated code is
......@@ -4691,7 +4689,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
} // namespace
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) {
const wasm::WasmFunction* func = &module->functions[index];
......@@ -4714,7 +4712,7 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
WasmWrapperGraphBuilder builder(&zone, &env, &jsgraph, func->sig, nullptr);
builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect);
builder.BuildJSToWasmWrapper(wasm_code);
builder.BuildJSToWasmWrapper(call_target);
//----------------------------------------------------------------------------
// Run the compilation pipeline.
......
......@@ -110,7 +110,7 @@ Handle<Code> CompileWasmToJSWrapper(Isolate*, Handle<JSReceiver> target,
// Wraps a given wasm code object, producing a code object.
V8_EXPORT_PRIVATE Handle<Code> CompileJSToWasmWrapper(Isolate*,
wasm::WasmModule*,
wasm::WasmCode*,
Address call_target,
uint32_t index,
wasm::UseTrapHandler);
......
This diff is collapsed.
......@@ -697,16 +697,19 @@ WasmCode* NativeModule::Lookup(Address pc) {
WasmCodeUniquePtrComparator());
if (iter == owned_code_.begin()) return nullptr;
--iter;
WasmCode* candidate = (*iter).get();
WasmCode* candidate = iter->get();
DCHECK_NOT_NULL(candidate);
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);
if (!wasm_code || wasm_code->kind() != WasmCode::kLazyStub) {
return wasm_code;
if (!wasm_code) return kNullAddress;
if (wasm_code->kind() != WasmCode::kLazyStub) {
return wasm_code->instruction_start();
}
#if DEBUG
auto num_imported_functions =
shared_module_data()->module()->num_imported_functions;
......@@ -718,7 +721,7 @@ WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) {
// If the function wasn't imported, its index should match.
DCHECK_IMPLIES(func_index >= num_imported_functions,
func_index == wasm_code->index());
return wasm_code;
return wasm_code->instruction_start();
}
if (!lazy_compile_stubs_.get()) {
lazy_compile_stubs_ =
......@@ -732,7 +735,7 @@ WasmCode* NativeModule::GetIndirectlyCallableCode(uint32_t func_index) {
lazy_compile_stubs_.get()->at(func_index) = cloned_code;
}
DCHECK_EQ(func_index, cloned_code->index());
return cloned_code;
return cloned_code->instruction_start();
}
WasmCode* NativeModule::CloneCode(const WasmCode* original_code,
......
......@@ -259,15 +259,21 @@ class V8_EXPORT_PRIVATE NativeModule final {
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
// global trap handler for this process.
void UnpackAndRegisterProtectedInstructions();
void ReleaseProtectedInstructions();
// Gets code suitable for indirect or import calls for the given function
// index. If the code at the given index is the lazy compile stub, it will
// clone a non-anonymous lazy compile stub for the purpose.
WasmCode* GetIndirectlyCallableCode(uint32_t func_index);
// Returns the instruction start of code suitable for indirect or import calls
// for the given function index. If the code at the given index is the lazy
// compile stub, it will clone a non-anonymous lazy compile stub for the
// purpose. This will soon change to always return a jump table slot.
Address GetCallTargetForFunction(uint32_t index);
bool SetExecutable(bool executable);
......
......@@ -113,10 +113,9 @@ bool CodeSpecialization::ApplyToWholeModule(
switch (mode) {
case RelocInfo::JS_TO_WASM_CALL: {
changed = true;
const WasmCode* new_code =
native_module->GetIndirectlyCallableCode(exp.index);
it.rinfo()->set_js_to_wasm_address(new_code->instruction_start(),
icache_flush_mode);
Address new_target =
native_module->GetCallTargetForFunction(exp.index);
it.rinfo()->set_js_to_wasm_address(new_target, icache_flush_mode);
} break;
default:
UNREACHABLE();
......
......@@ -405,16 +405,16 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
auto* wasm_function = &other_instance->module()->functions[func_index];
DCHECK_NOT_NULL(wasm_function);
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,
handle(exported_function->instance()), wasm_code);
handle(exported_function->instance()), call_target);
array->set(table_index, *function);
}
void WasmTableObject::UpdateDispatchTables(
Isolate* isolate, Handle<WasmTableObject> table, int table_index,
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
// this table.
Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
......@@ -430,7 +430,7 @@ void WasmTableObject::UpdateDispatchTables(
// not found; it will simply never match any check.
auto sig_id = to_instance->module()->signature_map.Find(sig);
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() {
}
void IndirectFunctionTableEntry::set(int sig_id, WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code) {
TRACE_IFT("IFT entry %p[%d] = {sig_id=%d, instance=%p, target=%p}\n",
*instance_, index_, sig_id, instance,
wasm_code->instructions().start());
Address call_target) {
TRACE_IFT("IFT entry %p[%d] = {sig_id=%d, instance=%p, target=%" PRIuPTR
"}\n",
*instance_, index_, sig_id, instance, call_target);
instance_->indirect_function_table_sig_ids()[index_] = sig_id;
instance_->indirect_function_table_targets()[index_] =
wasm_code->instruction_start();
instance_->indirect_function_table_targets()[index_] = call_target;
instance_->indirect_function_table_instances()->set(index_, instance);
}
......@@ -707,14 +706,13 @@ void ImportedFunctionEntry::set_wasm_to_js(
}
void ImportedFunctionEntry::set_wasm_to_wasm(WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code) {
TRACE_IFT("Import WASM %p[%d] = {instance=%p, target=%p}\n", *instance_,
index_, instance, wasm_code->instructions().start());
Address call_target) {
TRACE_IFT("Import WASM %p[%d] = {instance=%p, target=%" PRIuPTR "}\n",
*instance_, index_, instance, call_target);
instance_->imported_function_instances()->set(index_, instance);
instance_->imported_function_callables()->set(
index_, instance_->GetHeap()->undefined_value());
instance_->imported_function_targets()[index_] =
wasm_code->instruction_start();
instance_->imported_function_targets()[index_] = call_target;
}
WasmInstanceObject* ImportedFunctionEntry::instance() {
......@@ -947,15 +945,19 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
}
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;
Handle<Code> export_wrapper_code = handle(this->code());
DCHECK_EQ(export_wrapper_code->kind(), Code::JS_TO_WASM_FUNCTION);
DCHECK_EQ(code()->kind(), Code::JS_TO_WASM_FUNCTION);
int mask = RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL);
RelocIterator it(*export_wrapper_code, mask);
RelocIterator it(code(), mask);
DCHECK(!it.done());
wasm::WasmCode* target =
GetIsolate()->wasm_engine()->code_manager()->LookupCode(
it.rinfo()->js_to_wasm_address());
Address target = it.rinfo()->js_to_wasm_address();
#ifdef DEBUG
// There should only be this one call to wasm code.
it.next();
......
......@@ -57,8 +57,7 @@ class IndirectFunctionTableEntry {
inline IndirectFunctionTableEntry(Handle<WasmInstanceObject>, int index);
void clear();
void set(int sig_id, WasmInstanceObject* instance,
const wasm::WasmCode* wasm_code);
void set(int sig_id, WasmInstanceObject* instance, Address call_target);
WasmInstanceObject* instance();
int sig_id();
......@@ -89,7 +88,7 @@ class ImportedFunctionEntry {
const wasm::WasmCode* wasm_to_js_wrapper);
// Initialize this entry as a WASM to WASM call.
void set_wasm_to_wasm(WasmInstanceObject* target_instance,
const wasm::WasmCode* wasm_function);
Address call_target);
WasmInstanceObject* instance();
JSReceiver* callable();
......@@ -176,7 +175,7 @@ class WasmTableObject : public JSObject {
Handle<WasmTableObject> table,
int table_index, wasm::FunctionSig* sig,
Handle<WasmInstanceObject> from_instance,
wasm::WasmCode* wasm_code);
Address call_target);
static void ClearDispatchTables(Isolate* isolate,
Handle<WasmTableObject> table, int index);
......@@ -377,7 +376,12 @@ class WasmExportedFunction : public JSFunction {
int func_index, int arity,
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();
Address GetWasmCallTarget();
};
// Information for a WasmExportedFunction which is referenced as the function
......
......@@ -120,7 +120,7 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
Link();
wasm::WasmCode* code = native_module_->code(index);
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);
Handle<JSFunction> ret = WasmExportedFunction::New(
isolate_, instance_object(), MaybeHandle<String>(),
......@@ -166,7 +166,8 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() {
WasmFunction& function = test_module_->functions[table.values[j]];
int sig_id = test_module_->signature_map.Find(function.sig);
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