Commit 6f783066 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Embed CEntry builtin into wasm runtime stubs.

Now that embedded builtins are mandatory and non-embedded builtins no
longer need to be supported, it is safe to embed the target of the
CEntry builtin directly into WebAssembly runtime stubs. This produces
more efficient code and simplifies the runtime stubs.

R=clemensb@chromium.org

Change-Id: If2f91fa733edc266af3a204ac17ff36e4c0b41a3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1895567
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64739}
parent ab9cd1ab
......@@ -33,49 +33,32 @@ class WasmBuiltinsAssembler : public CodeStubAssembler {
IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
kHeapObjectTag)));
}
TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) {
TNode<IntPtrT> isolate_root = UncheckedCast<IntPtrT>(
Load(MachineType::Pointer(), instance,
IntPtrConstant(WasmInstanceObject::kIsolateRootOffset -
kHeapObjectTag)));
auto centry_id =
Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit;
TNode<Code> target = UncheckedCast<Code>(
Load(MachineType::TaggedPointer(), isolate_root,
IntPtrConstant(IsolateData::builtin_slot_offset(centry_id))));
return target;
}
};
TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, context);
TailCallRuntime(Runtime::kWasmStackGuard, context);
}
TF_BUILTIN(WasmStackOverflow, WasmBuiltinsAssembler) {
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kThrowWasmStackOverflow, centry, context);
TailCallRuntime(Runtime::kThrowWasmStackOverflow, context);
}
TF_BUILTIN(WasmThrow, WasmBuiltinsAssembler) {
TNode<Object> exception = UncheckedParameter(Descriptor::kException);
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kThrow, centry, context, exception);
TailCallRuntime(Runtime::kThrow, context, exception);
}
TF_BUILTIN(WasmRethrow, WasmBuiltinsAssembler) {
TNode<Object> exception = UncheckedParameter(Descriptor::kException);
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kReThrow, centry, context, exception);
TailCallRuntime(Runtime::kReThrow, context, exception);
}
TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
......@@ -84,7 +67,6 @@ TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
TNode<Uint32T> count = UncheckedCast<Uint32T>(Parameter(Descriptor::kCount));
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
// TODO(aseemgarg): Use SMIs if possible for address and count
TNode<HeapNumber> address_heap =
......@@ -92,8 +74,8 @@ TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
TNode<HeapNumber> count_heap =
AllocateHeapNumberWithValue(ChangeUint32ToFloat64(count));
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
Runtime::kWasmAtomicNotify, centry, NoContextConstant(), instance,
TNode<Smi> result_smi = UncheckedCast<Smi>(
CallRuntime(Runtime::kWasmAtomicNotify, NoContextConstant(), instance,
address_heap, count_heap));
ReturnRaw(SmiToInt32(result_smi));
}
......@@ -107,7 +89,6 @@ TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) {
UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
// TODO(aseemgarg): Use SMIs if possible for address and expected_value
TNode<HeapNumber> address_heap =
......@@ -116,8 +97,8 @@ TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) {
AllocateHeapNumberWithValue(ChangeInt32ToFloat64(expected_value));
TNode<HeapNumber> timeout_heap = AllocateHeapNumberWithValue(timeout);
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
Runtime::kWasmI32AtomicWait, centry, NoContextConstant(), instance,
TNode<Smi> result_smi = UncheckedCast<Smi>(
CallRuntime(Runtime::kWasmI32AtomicWait, NoContextConstant(), instance,
address_heap, expected_value_heap, timeout_heap));
ReturnRaw(SmiToInt32(result_smi));
}
......@@ -133,7 +114,6 @@ TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) {
UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
// TODO(aseemgarg): Use SMIs if possible for address and expected_value
TNode<HeapNumber> address_heap =
......@@ -144,10 +124,9 @@ TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) {
AllocateHeapNumberWithValue(ChangeUint32ToFloat64(expected_value_low));
TNode<HeapNumber> timeout_heap = AllocateHeapNumberWithValue(timeout);
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
Runtime::kWasmI64AtomicWait, centry, NoContextConstant(), instance,
address_heap, expected_value_high_heap, expected_value_low_heap,
timeout_heap));
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntime(
Runtime::kWasmI64AtomicWait, NoContextConstant(), instance, address_heap,
expected_value_high_heap, expected_value_low_heap, timeout_heap));
ReturnRaw(SmiToInt32(result_smi));
}
......@@ -162,10 +141,9 @@ TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
TNode<Smi> ret_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
Runtime::kWasmMemoryGrow, centry, context, instance, num_pages_smi));
TNode<Smi> ret_smi = UncheckedCast<Smi>(
CallRuntime(Runtime::kWasmMemoryGrow, context, instance, num_pages_smi));
TNode<Int32T> ret = SmiToInt32(ret_smi);
ReturnRaw(ret);
......@@ -177,7 +155,6 @@ TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) {
TNode<Int32T> entry_index =
UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
Label entry_index_out_of_range(this, Label::kDeferred);
......@@ -189,13 +166,13 @@ TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) {
TNode<Smi> table_index_smi =
UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
TailCallRuntimeWithCEntry(Runtime::kWasmFunctionTableGet, centry, context,
instance, table_index_smi, entry_index_smi);
TailCallRuntime(Runtime::kWasmFunctionTableGet, context, instance,
table_index_smi, entry_index_smi);
BIND(&entry_index_out_of_range);
MessageTemplate message_id =
wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds);
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,
TailCallRuntime(Runtime::kThrowWasmError, context,
SmiConstant(static_cast<int>(message_id)));
}
......@@ -203,7 +180,6 @@ TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) {
TNode<Int32T> entry_index =
UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
Label entry_index_out_of_range(this, Label::kDeferred);
......@@ -215,24 +191,23 @@ TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) {
TNode<Smi> table_index_smi =
UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
TNode<Object> value = UncheckedCast<Object>(Parameter(Descriptor::kValue));
TailCallRuntimeWithCEntry(Runtime::kWasmFunctionTableSet, centry, context,
instance, table_index_smi, entry_index_smi, value);
TailCallRuntime(Runtime::kWasmFunctionTableSet, context, instance,
table_index_smi, entry_index_smi, value);
BIND(&entry_index_out_of_range);
MessageTemplate message_id =
wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds);
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,
TailCallRuntime(Runtime::kThrowWasmError, context,
SmiConstant(static_cast<int>(message_id)));
}
#define DECLARE_ENUM(name) \
TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) { \
TNode<Object> instance = LoadInstanceFromFrame(); \
TNode<Code> centry = LoadCEntryFromInstance(instance); \
TNode<Object> context = LoadContextFromInstance(instance); \
MessageTemplate message_id = \
wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context, \
TailCallRuntime(Runtime::kThrowWasmError, context, \
SmiConstant(static_cast<int>(message_id))); \
}
FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
......
......@@ -1234,12 +1234,6 @@ TNode<Object> CodeAssembler::CallRuntimeImpl(
int result_size = Runtime::FunctionForId(function)->result_size;
TNode<Code> centry =
HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
return CallRuntimeWithCEntryImpl(function, centry, context, args);
}
TNode<Object> CodeAssembler::CallRuntimeWithCEntryImpl(
Runtime::FunctionId function, TNode<Code> centry, TNode<Object> context,
std::initializer_list<TNode<Object>> args) {
constexpr size_t kMaxNumArgs = 6;
DCHECK_GE(kMaxNumArgs, args.size());
int argc = static_cast<int>(args.size());
......@@ -1273,12 +1267,6 @@ void CodeAssembler::TailCallRuntimeImpl(
int result_size = Runtime::FunctionForId(function)->result_size;
TNode<Code> centry =
HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
return TailCallRuntimeWithCEntryImpl(function, arity, centry, context, args);
}
void CodeAssembler::TailCallRuntimeWithCEntryImpl(
Runtime::FunctionId function, TNode<Int32T> arity, TNode<Code> centry,
TNode<Object> context, std::initializer_list<TNode<Object>> args) {
constexpr size_t kMaxNumArgs = 6;
DCHECK_GE(kMaxNumArgs, args.size());
int argc = static_cast<int>(args.size());
......
......@@ -951,14 +951,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
{implicit_cast<SloppyTNode<Object>>(args)...});
}
template <class... TArgs>
TNode<Object> CallRuntimeWithCEntry(Runtime::FunctionId function,
TNode<Code> centry,
SloppyTNode<Object> context,
TArgs... args) {
return CallRuntimeWithCEntryImpl(function, centry, context, {args...});
}
template <class... TArgs>
void TailCallRuntime(Runtime::FunctionId function,
SloppyTNode<Object> context, TArgs... args) {
......@@ -975,17 +967,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
{implicit_cast<SloppyTNode<Object>>(args)...});
}
template <class... TArgs>
void TailCallRuntimeWithCEntry(Runtime::FunctionId function,
TNode<Code> centry, TNode<Object> context,
TArgs... args) {
int argc = sizeof...(args);
TNode<Int32T> arity = Int32Constant(argc);
return TailCallRuntimeWithCEntryImpl(
function, arity, centry, context,
{implicit_cast<SloppyTNode<Object>>(args)...});
}
//
// If context passed to CallStub is nullptr, it won't be passed to the stub.
//
......@@ -1176,19 +1157,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<Object> context,
std::initializer_list<TNode<Object>> args);
TNode<Object> CallRuntimeWithCEntryImpl(
Runtime::FunctionId function, TNode<Code> centry, TNode<Object> context,
std::initializer_list<TNode<Object>> args);
void TailCallRuntimeImpl(Runtime::FunctionId function, TNode<Int32T> arity,
TNode<Object> context,
std::initializer_list<TNode<Object>> args);
void TailCallRuntimeWithCEntryImpl(Runtime::FunctionId function,
TNode<Int32T> arity, TNode<Code> centry,
TNode<Object> context,
std::initializer_list<TNode<Object>> args);
void TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
TNode<Code> target, TNode<Object> context,
std::initializer_list<Node*> args);
......
......@@ -6853,7 +6853,7 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
MachineType::Pointer(), // argv
MachineType::Pointer()}; // c_entry_fp
MachineSignature incoming_sig(1, 4, sig_types);
// Traps need the root register, for TailCallRuntimeWithCEntry to call
// Traps need the root register, for TailCallRuntime to call
// Runtime::kThrowWasmError.
CallDescriptor::Flags flags = CallDescriptor::kInitializeRootRegister;
CallDescriptor* incoming =
......
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