Commit 389272ac authored by evih's avatar evih Committed by Commit Bot

[wasm] Use generic js-to-wasm wrapper for 0 and 1 param cases

A new field for signature type was added to WasmExportedFunctionData.
It is set to 0 or 1 depending on the parameter count.
(It's set and being used only in 0 and 1 parameter cases.)

Added new JS tests for 1 parameter wasm functions.

Bug: v8:10701
Change-Id: I349d881a2860f1a50b91e08d0126ca71c5f6483b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2339622
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69302}
parent 5acf8ec0
......@@ -3224,6 +3224,31 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
MemOperand(function_data,
WasmExportedFunctionData::kInstanceOffset - kHeapObjectTag));
// Int signature_type gives the number of int32 params (can be only 0 or 1).
Register signature_type = r9;
__ SmiUntagField(
signature_type,
MemOperand(function_data, WasmExportedFunctionData::kSignatureTypeOffset -
kHeapObjectTag));
__ cmpl(signature_type, Immediate(0));
// In 0 param case jump through parameter handling.
Label params_done;
__ j(equal, &params_done);
// Param handling.
Register param = rax;
const int firstParamOffset = 16;
__ movq(param, MemOperand(rbp, firstParamOffset));
Label not_smi;
__ JumpIfNotSmi(param, &not_smi);
// Change from smi to int32.
__ SmiUntag(param);
__ bind(&params_done);
int isolate_root_offset =
wasm::ObjectAccess::ToTagged(WasmInstanceObject::kIsolateRootOffset);
......@@ -3250,24 +3275,22 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
MemOperand(
function_data,
WasmExportedFunctionData::kJumpTableOffsetOffset - kHeapObjectTag));
function_data = no_reg;
// Change from smi to int64.
__ sarl(jump_table_offset, Immediate(1));
__ movsxlq(jump_table_offset, jump_table_offset);
// Change from smi to integer.
__ SmiUntag(jump_table_offset);
Register function_entry = jump_table_offset;
__ addq(function_entry, jump_table_start);
jump_table_offset = no_reg;
jump_table_start = no_reg;
// Save wasm_instance on the stack.
__ pushq(wasm_instance);
__ pushq(signature_type);
__ call(function_entry);
function_entry = no_reg;
// Restore wasm_instance.
__ popq(signature_type);
__ popq(wasm_instance);
// Unset thread_in_wasm_flag.
......@@ -3287,7 +3310,36 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// Deconstrunct the stack frame.
__ LeaveFrame(StackFrame::JS_TO_WASM);
__ cmpl(signature_type, Immediate(0));
Label ret_0_param;
__ j(equal, &ret_0_param);
__ ret(16);
__ bind(&ret_0_param);
__ ret(8);
// Handle the conversion to int32 when the param is not a smi.
__ bind(&not_smi);
__ pushq(wasm_instance);
__ pushq(function_data);
__ pushq(signature_type);
__ LoadAnyTaggedField(
rsi,
MemOperand(wasm_instance, wasm::ObjectAccess::ToTagged(
WasmInstanceObject::kNativeContextOffset)));
// We had to prepare the parameters for the Call:
// put the value into rax, and the context to rsi.
__ Call(BUILTIN_CODE(masm->isolate(), WasmTaggedNonSmiToInt32),
RelocInfo::CODE_TARGET);
__ popq(signature_type);
__ popq(function_data);
__ popq(wasm_instance);
__ jmp(&params_done);
}
namespace {
......
......@@ -265,23 +265,34 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate,
}
}
namespace {
bool UseGenericWrapper(const FunctionSig* sig) {
// Work only for 0 and 1 int32 param case for now.
#if V8_TARGET_ARCH_X64
if (sig->parameters().size() > 1) {
return false;
}
if (sig->parameters().size() == 1 &&
sig->GetParam(0).kind() != ValueType::kI32) {
return false;
}
return FLAG_wasm_generic_wrapper && sig->returns().empty();
#else
return false;
#endif
}
} // namespace
JSToWasmWrapperCompilationUnit::JSToWasmWrapperCompilationUnit(
Isolate* isolate, WasmEngine* wasm_engine, const FunctionSig* sig,
bool is_import, const WasmFeatures& enabled_features)
: is_import_(is_import),
sig_(sig),
#if V8_TARGET_ARCH_X64
use_generic_wrapper_(FLAG_wasm_generic_wrapper &&
sig->parameters().empty() &&
sig->returns().empty() && !is_import),
#else
use_generic_wrapper_(false),
#endif
use_generic_wrapper_(UseGenericWrapper(sig) && !is_import),
job_(use_generic_wrapper_
? nullptr
: compiler::NewJSToWasmCompilationJob(
isolate, wasm_engine, sig, is_import, enabled_features)) {
}
isolate, wasm_engine, sig, is_import, enabled_features)) {}
JSToWasmWrapperCompilationUnit::~JSToWasmWrapperCompilationUnit() = default;
......
......@@ -330,6 +330,7 @@ ACCESSORS(WasmExportedFunctionData, c_wrapper_code, Object, kCWrapperCodeOffset)
ACCESSORS(WasmExportedFunctionData, wasm_call_target, Object,
kWasmCallTargetOffset)
SMI_ACCESSORS(WasmExportedFunctionData, packed_args_size, kPackedArgsSizeOffset)
SMI_ACCESSORS(WasmExportedFunctionData, signature_type, kSignatureTypeOffset)
// WasmJSFunction
WasmJSFunction::WasmJSFunction(Address ptr) : JSFunction(ptr) {
......
......@@ -1824,6 +1824,9 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
function_data->set_c_wrapper_code(Smi::zero(), SKIP_WRITE_BARRIER);
function_data->set_wasm_call_target(Smi::zero(), SKIP_WRITE_BARRIER);
function_data->set_packed_args_size(0);
const wasm::FunctionSig* sig = instance->module()->functions[func_index].sig;
sig->parameters().empty() ? function_data->set_signature_type(0)
: function_data->set_signature_type(1);
MaybeHandle<String> maybe_name;
bool is_asm_js_module = instance->module_object().is_asm_js();
......
......@@ -768,6 +768,7 @@ class WasmExportedFunctionData : public Struct {
DECL_ACCESSORS(c_wrapper_code, Object)
DECL_ACCESSORS(wasm_call_target, Object)
DECL_INT_ACCESSORS(packed_args_size)
DECL_INT_ACCESSORS(signature_type)
DECL_CAST(WasmExportedFunctionData)
......
......@@ -14,6 +14,7 @@ extern class WasmExportedFunctionData extends Struct {
c_wrapper_code: Object;
wasm_call_target: Smi|Foreign;
packed_args_size: Smi;
signature_type: Smi;
}
extern class WasmJSFunctionData extends Struct {
......
......@@ -6,7 +6,7 @@
load("test/mjsunit/wasm/wasm-module-builder.js");
(function testGenericWrapper() {
(function testGenericWrapper0Param() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_v);
......@@ -26,7 +26,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(x, 20);
})();
(function testGenericWrapperFunctionTraps() {
(function testGenericWrapper0ParamTraps() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_v);
......@@ -39,3 +39,60 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
let instance = builder.instantiate();
assertTraps(kTrapUnreachable, instance.exports.main);
})();
(function testGenericWrapper1ParamTrap() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_i);
builder.addFunction("main", sig_index)
.addBody([
kExprLocalGet, 0, kExprUnreachable
])
.exportFunc();
let instance = builder.instantiate();
assertTraps(kTrapUnreachable, () => instance.exports.main(1));
})();
(function testGenericWrapper1ParamGeneral() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_i);
let func_index = builder.addImport("mod", "func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
kExprLocalGet, 0, kExprCallFunction, func_index
])
.exportFunc();
let x = 12;
function import_func(param) {
x += param;
}
let instance = builder.instantiate({ mod: { func: import_func } });
instance.exports.main(5);
assertEquals(17, x);
})();
(function testGenericWrapper1ParamNotSmi() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_i);
let func_index = builder.addImport("mod", "func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
kExprLocalGet, 0, kExprCallFunction, func_index
])
.exportFunc();
let x = 12;
function import_func(param) {
x += param;
}
let y = {valueOf:() => {return 24;}};
let instance = builder.instantiate({ mod: { func: import_func } });
instance.exports.main(y);
assertEquals(36, x);
})();
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