Commit cffaee55 authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[wasm] Move fast path of wasm RefFunc to a builtin

- Use a builtin for the fast path of Wasm RefFunc.
- Simplify the runtime function by passing instance as first
  argument.

Change-Id: I5f6993cae21a878cee21a391a25c4d574243058b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2144533
Commit-Queue: Bill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67346}
parent bf5312b6
......@@ -850,6 +850,7 @@ namespace internal {
TFC(WasmI64AtomicWait32, WasmI64AtomicWait32) \
TFC(WasmI64AtomicWait64, WasmI64AtomicWait64) \
TFC(WasmMemoryGrow, WasmMemoryGrow) \
TFC(WasmRefFunc, WasmRefFunc) \
TFC(WasmTableInit, WasmTableInit) \
TFC(WasmTableCopy, WasmTableCopy) \
TFC(WasmTableGet, WasmTableGet) \
......
......@@ -256,6 +256,32 @@ TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
Return(Int32Constant(-1));
}
TF_BUILTIN(WasmRefFunc, WasmBuiltinsAssembler) {
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
Label call_runtime(this, Label::kDeferred);
TNode<Uint32T> raw_index =
UncheckedCast<Uint32T>(Parameter(Descriptor::kFunctionIndex));
TNode<FixedArray> table = LoadObjectField<FixedArray>(
instance, WasmInstanceObject::kWasmExternalFunctionsOffset);
GotoIf(IsUndefined(table), &call_runtime);
TNode<IntPtrT> function_index =
UncheckedCast<IntPtrT>(ChangeUint32ToWord(raw_index));
// Function index should be in range.
TNode<Object> result = LoadFixedArrayElement(table, function_index);
GotoIf(IsUndefined(result), &call_runtime);
Return(result);
BIND(&call_runtime);
// Fall back to the runtime call for more complex cases.
// function_index is known to be in Smi range.
TailCallRuntime(Runtime::kWasmRefFunc, LoadContextFromInstance(instance),
instance, SmiFromUint32(raw_index));
}
TF_BUILTIN(WasmTableInit, WasmBuiltinsAssembler) {
TNode<Uint32T> dst_raw =
UncheckedCast<Uint32T>(Parameter(Descriptor::kDestination));
......
......@@ -411,6 +411,11 @@ void WasmMemoryGrowDescriptor::InitializePlatformSpecific(
DefaultInitializePlatformSpecific(data, kParameterCount);
}
void WasmRefFuncDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
void WasmTableInitDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data,
......
......@@ -101,6 +101,7 @@ namespace internal {
V(WasmI64AtomicWait32) \
V(WasmI64AtomicWait64) \
V(WasmMemoryGrow) \
V(WasmRefFunc) \
V(WasmTableInit) \
V(WasmTableCopy) \
V(WasmTableGet) \
......@@ -1363,6 +1364,14 @@ class WasmMemoryGrowDescriptor final : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(WasmMemoryGrowDescriptor, CallInterfaceDescriptor)
};
class WasmRefFuncDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kFunctionIndex)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result
MachineType::Uint32()) // kFunctionIndex
DECLARE_DESCRIPTOR(WasmRefFuncDescriptor, CallInterfaceDescriptor)
};
class WasmTableInitDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kDestination, kSource, kSize, kTableIndex,
......
......@@ -144,6 +144,19 @@ bool ContainsInt64(const wasm::FunctionSig* sig) {
}
return false;
}
template <typename BuiltinDescriptor>
CallDescriptor* GetBuiltinCallDescriptor(WasmGraphBuilder* builder,
StubCallMode stub_mode) {
BuiltinDescriptor interface_descriptor;
return Linkage::GetStubCallDescriptor(
builder->mcgraph()->zone(), // zone
interface_descriptor, // descriptor
interface_descriptor.GetStackParameterCount(), // stack parameter count
CallDescriptor::kNoFlags, // flags
Operator::kNoProperties, // properties
stub_mode); // stub call mode
}
} // namespace
class WasmGraphAssembler : public GraphAssembler {
......@@ -262,11 +275,16 @@ Node* WasmGraphBuilder::RefNull() {
}
Node* WasmGraphBuilder::RefFunc(uint32_t function_index) {
Node* args[] = {
graph()->NewNode(mcgraph()->common()->NumberConstant(function_index))};
Node* result =
BuildCallToRuntime(Runtime::kWasmRefFunc, args, arraysize(args));
return result;
auto call_descriptor = GetBuiltinCallDescriptor<WasmRefFuncDescriptor>(
this, StubCallMode::kCallWasmRuntimeStub);
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched at relocation.
Node* call_target = mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmRefFunc, RelocInfo::WASM_STUB_CALL);
return SetEffectControl(
graph()->NewNode(mcgraph()->common()->Call(call_descriptor), call_target,
Uint32Constant(function_index), effect(), control()));
}
Node* WasmGraphBuilder::NoContextConstant() {
......@@ -1938,19 +1956,6 @@ ExternalReference convert_ccall_ref(WasmGraphBuilder* builder,
}
}
template <typename BuiltinDescriptor>
CallDescriptor* GetBuiltinCallDescriptor(WasmGraphBuilder* builder,
StubCallMode stub_mode) {
BuiltinDescriptor interface_descriptor;
return Linkage::GetStubCallDescriptor(
builder->mcgraph()->zone(), // zone
interface_descriptor, // descriptor
interface_descriptor.GetStackParameterCount(), // stack parameter count
CallDescriptor::kNoFlags, // flags
Operator::kNoProperties, // properties
stub_mode); // stub call mode
}
} // namespace
Node* WasmGraphBuilder::BuildCcallConvertFloat(Node* input,
......
......@@ -447,12 +447,9 @@ Object ThrowTableOutOfBounds(Isolate* isolate,
RUNTIME_FUNCTION(Runtime_WasmRefFunc) {
ClearThreadInWasmScope flag_scope;
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
auto instance =
Handle<WasmInstanceObject>(GetWasmInstanceOnStackTop(isolate), isolate);
DCHECK(isolate->context().is_null());
isolate->set_context(instance->native_context());
CONVERT_UINT32_ARG_CHECKED(function_index, 0);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
CONVERT_UINT32_ARG_CHECKED(function_index, 1);
Handle<WasmExternalFunction> function =
WasmInstanceObject::GetOrCreateWasmExternalFunction(isolate, instance,
......
......@@ -60,6 +60,7 @@ struct WasmModule;
V(WasmI32AtomicWait64) \
V(WasmI64AtomicWait32) \
V(WasmI64AtomicWait64) \
V(WasmRefFunc) \
V(WasmMemoryGrow) \
V(WasmTableInit) \
V(WasmTableCopy) \
......
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