Commit b9fca91f authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Call the ArgumentsAdaptor directly from the wasm2js wrapper

When we know that the imported JavaScript function, and we cannot
generate a direct call because the parameter count does not match, then
we can call directly to the ArgumentsAdaptor instead of the Call
builtin.

R=bmeurer@chromium.org

Change-Id: I72882c2edf170d88135d12352852302d56cc54a5
Reviewed-on: https://chromium-review.googlesource.com/986095Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52316}
parent aa302056
...@@ -3160,7 +3160,7 @@ bool WasmGraphBuilder::BuildWasmToJSWrapper( ...@@ -3160,7 +3160,7 @@ bool WasmGraphBuilder::BuildWasmToJSWrapper(
return false; return false;
} }
Node** args = Buffer(wasm_count + 7); Node** args = Buffer(wasm_count + 9);
Node* call = nullptr; Node* call = nullptr;
...@@ -3168,41 +3168,71 @@ bool WasmGraphBuilder::BuildWasmToJSWrapper( ...@@ -3168,41 +3168,71 @@ bool WasmGraphBuilder::BuildWasmToJSWrapper(
if (target->IsJSFunction()) { if (target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(target); Handle<JSFunction> function = Handle<JSFunction>::cast(target);
if (function->shared()->internal_formal_parameter_count() == wasm_count && if (!IsClassConstructor(function->shared()->kind())) {
!IsClassConstructor(function->shared()->kind())) { if (function->shared()->internal_formal_parameter_count() == wasm_count) {
int pos = 0; int pos = 0;
args[pos++] = args[pos++] =
LoadImportData(index, kFunction, table); // target callable. LoadImportData(index, kFunction, table); // target callable.
// Receiver. // Receiver.
if (is_sloppy(function->shared()->language_mode()) && if (is_sloppy(function->shared()->language_mode()) &&
!function->shared()->native()) { !function->shared()->native()) {
args[pos++] = LoadImportData(index, kGlobalProxy, table); args[pos++] = LoadImportData(index, kGlobalProxy, table);
} else { } else {
args[pos++] = jsgraph()->Constant( args[pos++] = jsgraph()->Constant(
handle(isolate->heap()->undefined_value(), isolate)); handle(isolate->heap()->undefined_value(), isolate));
} }
call_descriptor = Linkage::GetJSCallDescriptor(
graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags);
// Convert wasm numbers to JS values.
pos = AddParameterNodes(args, pos, wasm_count, sig_);
args[pos++] = jsgraph()->UndefinedConstant(); // new target call_descriptor = Linkage::GetJSCallDescriptor(
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags);
args[pos++] = LoadImportData(index, kFunctionContext, table);
args[pos++] = *effect_; // Convert wasm numbers to JS values.
args[pos++] = *control_; pos = AddParameterNodes(args, pos, wasm_count, sig_);
args[pos++] = jsgraph()->UndefinedConstant(); // new target
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
args[pos++] = LoadImportData(index, kFunctionContext, table);
args[pos++] = *effect_;
args[pos++] = *control_;
call = graph()->NewNode(jsgraph()->common()->Call(call_descriptor), pos,
args);
} else if (function->shared()->internal_formal_parameter_count() >= 0) {
Callable callable = CodeFactory::ArgumentAdaptor(isolate);
int pos = 0;
args[pos++] = jsgraph()->HeapConstant(callable.code());
args[pos++] =
LoadImportData(index, kFunction, table); // target callable
args[pos++] = jsgraph()->UndefinedConstant(); // new target
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
args[pos++] = jsgraph()->Int32Constant(
function->shared()->internal_formal_parameter_count());
// Receiver.
if (is_sloppy(function->shared()->language_mode()) &&
!function->shared()->native()) {
args[pos++] = LoadImportData(index, kGlobalProxy, table);
} else {
args[pos++] = jsgraph()->Constant(
handle(isolate->heap()->undefined_value(), isolate));
}
call = graph()->NewNode(jsgraph()->common()->Call(call_descriptor), pos, // Convert wasm numbers to JS values.
args); pos = AddParameterNodes(args, pos, wasm_count, sig_);
args[pos++] = LoadImportData(index, kFunctionContext, table);
args[pos++] = *effect_;
args[pos++] = *control_;
call = graph()->NewNode(
jsgraph()->common()->Call(Linkage::GetStubCallDescriptor(
isolate, jsgraph()->zone(), callable.descriptor(),
1 + wasm_count, CallDescriptor::kNoFlags)),
pos, args);
}
} }
} }
// We cannot call the target directly, we have to use the Call builtin.
Node* native_context = nullptr; Node* native_context = nullptr;
if (!call) { if (!call) {
int pos = 0; int pos = 0;
// We cannot call the target directly, we have to use the Call builtin.
Callable callable = CodeFactory::Call(isolate); Callable callable = CodeFactory::Call(isolate);
args[pos++] = jsgraph()->HeapConstant(callable.code()); args[pos++] = jsgraph()->HeapConstant(callable.code());
args[pos++] = LoadImportData(index, kFunction, table); // target callable. args[pos++] = LoadImportData(index, kFunction, table); // target callable.
...@@ -4790,7 +4820,6 @@ Handle<Code> CompileWasmToJSWrapper( ...@@ -4790,7 +4820,6 @@ Handle<Code> CompileWasmToJSWrapper(
function->context()->global_proxy()); function->context()->global_proxy());
} }
} }
if (FLAG_trace_turbo_graph) { // Simple textual RPO. if (FLAG_trace_turbo_graph) { // Simple textual RPO.
OFStream os(stdout); OFStream os(stdout);
os << "-- Graph after change lowering -- " << std::endl; os << "-- Graph after change lowering -- " << std::endl;
...@@ -4824,11 +4853,11 @@ Handle<Code> CompileWasmToJSWrapper( ...@@ -4824,11 +4853,11 @@ Handle<Code> CompileWasmToJSWrapper(
deopt_data->set(1, *index_handle); deopt_data->set(1, *index_handle);
code->set_deoptimization_data(*deopt_data); code->set_deoptimization_data(*deopt_data);
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
if (FLAG_print_opt_code && !code.is_null()) { if (FLAG_print_opt_code && !code.is_null()) {
CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
OFStream os(tracing_scope.file()); OFStream os(tracing_scope.file());
code->Disassemble(func_name.start(), os); code->Disassemble(func_name.start(), os);
} }
#endif #endif
if (must_record_function_compilation(isolate)) { if (must_record_function_compilation(isolate)) {
......
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