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 { ...@@ -33,49 +33,32 @@ class WasmBuiltinsAssembler : public CodeStubAssembler {
IntPtrConstant(WasmInstanceObject::kNativeContextOffset - IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
kHeapObjectTag))); 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) { TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, context); TailCallRuntime(Runtime::kWasmStackGuard, context);
} }
TF_BUILTIN(WasmStackOverflow, WasmBuiltinsAssembler) { TF_BUILTIN(WasmStackOverflow, WasmBuiltinsAssembler) {
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kThrowWasmStackOverflow, centry, context); TailCallRuntime(Runtime::kThrowWasmStackOverflow, context);
} }
TF_BUILTIN(WasmThrow, WasmBuiltinsAssembler) { TF_BUILTIN(WasmThrow, WasmBuiltinsAssembler) {
TNode<Object> exception = UncheckedParameter(Descriptor::kException); TNode<Object> exception = UncheckedParameter(Descriptor::kException);
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kThrow, centry, context, exception); TailCallRuntime(Runtime::kThrow, context, exception);
} }
TF_BUILTIN(WasmRethrow, WasmBuiltinsAssembler) { TF_BUILTIN(WasmRethrow, WasmBuiltinsAssembler) {
TNode<Object> exception = UncheckedParameter(Descriptor::kException); TNode<Object> exception = UncheckedParameter(Descriptor::kException);
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kReThrow, centry, context, exception); TailCallRuntime(Runtime::kReThrow, context, exception);
} }
TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) { TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
...@@ -84,7 +67,6 @@ TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) { ...@@ -84,7 +67,6 @@ TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
TNode<Uint32T> count = UncheckedCast<Uint32T>(Parameter(Descriptor::kCount)); TNode<Uint32T> count = UncheckedCast<Uint32T>(Parameter(Descriptor::kCount));
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
// TODO(aseemgarg): Use SMIs if possible for address and count // TODO(aseemgarg): Use SMIs if possible for address and count
TNode<HeapNumber> address_heap = TNode<HeapNumber> address_heap =
...@@ -92,9 +74,9 @@ TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) { ...@@ -92,9 +74,9 @@ TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
TNode<HeapNumber> count_heap = TNode<HeapNumber> count_heap =
AllocateHeapNumberWithValue(ChangeUint32ToFloat64(count)); AllocateHeapNumberWithValue(ChangeUint32ToFloat64(count));
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry( TNode<Smi> result_smi = UncheckedCast<Smi>(
Runtime::kWasmAtomicNotify, centry, NoContextConstant(), instance, CallRuntime(Runtime::kWasmAtomicNotify, NoContextConstant(), instance,
address_heap, count_heap)); address_heap, count_heap));
ReturnRaw(SmiToInt32(result_smi)); ReturnRaw(SmiToInt32(result_smi));
} }
...@@ -107,7 +89,6 @@ TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) { ...@@ -107,7 +89,6 @@ TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) {
UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout)); UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
// TODO(aseemgarg): Use SMIs if possible for address and expected_value // TODO(aseemgarg): Use SMIs if possible for address and expected_value
TNode<HeapNumber> address_heap = TNode<HeapNumber> address_heap =
...@@ -116,9 +97,9 @@ TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) { ...@@ -116,9 +97,9 @@ TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) {
AllocateHeapNumberWithValue(ChangeInt32ToFloat64(expected_value)); AllocateHeapNumberWithValue(ChangeInt32ToFloat64(expected_value));
TNode<HeapNumber> timeout_heap = AllocateHeapNumberWithValue(timeout); TNode<HeapNumber> timeout_heap = AllocateHeapNumberWithValue(timeout);
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry( TNode<Smi> result_smi = UncheckedCast<Smi>(
Runtime::kWasmI32AtomicWait, centry, NoContextConstant(), instance, CallRuntime(Runtime::kWasmI32AtomicWait, NoContextConstant(), instance,
address_heap, expected_value_heap, timeout_heap)); address_heap, expected_value_heap, timeout_heap));
ReturnRaw(SmiToInt32(result_smi)); ReturnRaw(SmiToInt32(result_smi));
} }
...@@ -133,7 +114,6 @@ TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) { ...@@ -133,7 +114,6 @@ TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) {
UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout)); UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
// TODO(aseemgarg): Use SMIs if possible for address and expected_value // TODO(aseemgarg): Use SMIs if possible for address and expected_value
TNode<HeapNumber> address_heap = TNode<HeapNumber> address_heap =
...@@ -144,10 +124,9 @@ TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) { ...@@ -144,10 +124,9 @@ TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) {
AllocateHeapNumberWithValue(ChangeUint32ToFloat64(expected_value_low)); AllocateHeapNumberWithValue(ChangeUint32ToFloat64(expected_value_low));
TNode<HeapNumber> timeout_heap = AllocateHeapNumberWithValue(timeout); TNode<HeapNumber> timeout_heap = AllocateHeapNumberWithValue(timeout);
TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry( TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntime(
Runtime::kWasmI64AtomicWait, centry, NoContextConstant(), instance, Runtime::kWasmI64AtomicWait, NoContextConstant(), instance, address_heap,
address_heap, expected_value_high_heap, expected_value_low_heap, expected_value_high_heap, expected_value_low_heap, timeout_heap));
timeout_heap));
ReturnRaw(SmiToInt32(result_smi)); ReturnRaw(SmiToInt32(result_smi));
} }
...@@ -162,10 +141,9 @@ TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) { ...@@ -162,10 +141,9 @@ TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
TNode<Smi> num_pages_smi = SmiFromInt32(num_pages); TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
TNode<Smi> ret_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry( TNode<Smi> ret_smi = UncheckedCast<Smi>(
Runtime::kWasmMemoryGrow, centry, context, instance, num_pages_smi)); CallRuntime(Runtime::kWasmMemoryGrow, context, instance, num_pages_smi));
TNode<Int32T> ret = SmiToInt32(ret_smi); TNode<Int32T> ret = SmiToInt32(ret_smi);
ReturnRaw(ret); ReturnRaw(ret);
...@@ -177,7 +155,6 @@ TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) { ...@@ -177,7 +155,6 @@ TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) {
TNode<Int32T> entry_index = TNode<Int32T> entry_index =
UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex)); UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
Label entry_index_out_of_range(this, Label::kDeferred); Label entry_index_out_of_range(this, Label::kDeferred);
...@@ -189,21 +166,20 @@ TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) { ...@@ -189,21 +166,20 @@ TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) {
TNode<Smi> table_index_smi = TNode<Smi> table_index_smi =
UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex)); UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
TailCallRuntimeWithCEntry(Runtime::kWasmFunctionTableGet, centry, context, TailCallRuntime(Runtime::kWasmFunctionTableGet, context, instance,
instance, table_index_smi, entry_index_smi); table_index_smi, entry_index_smi);
BIND(&entry_index_out_of_range); BIND(&entry_index_out_of_range);
MessageTemplate message_id = MessageTemplate message_id =
wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds); wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds);
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context, TailCallRuntime(Runtime::kThrowWasmError, context,
SmiConstant(static_cast<int>(message_id))); SmiConstant(static_cast<int>(message_id)));
} }
TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) { TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) {
TNode<Int32T> entry_index = TNode<Int32T> entry_index =
UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex)); UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));
TNode<Object> instance = LoadInstanceFromFrame(); TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance); TNode<Object> context = LoadContextFromInstance(instance);
Label entry_index_out_of_range(this, Label::kDeferred); Label entry_index_out_of_range(this, Label::kDeferred);
...@@ -215,25 +191,24 @@ TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) { ...@@ -215,25 +191,24 @@ TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) {
TNode<Smi> table_index_smi = TNode<Smi> table_index_smi =
UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex)); UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
TNode<Object> value = UncheckedCast<Object>(Parameter(Descriptor::kValue)); TNode<Object> value = UncheckedCast<Object>(Parameter(Descriptor::kValue));
TailCallRuntimeWithCEntry(Runtime::kWasmFunctionTableSet, centry, context, TailCallRuntime(Runtime::kWasmFunctionTableSet, context, instance,
instance, table_index_smi, entry_index_smi, value); table_index_smi, entry_index_smi, value);
BIND(&entry_index_out_of_range); BIND(&entry_index_out_of_range);
MessageTemplate message_id = MessageTemplate message_id =
wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds); wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds);
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context, TailCallRuntime(Runtime::kThrowWasmError, context,
SmiConstant(static_cast<int>(message_id))); SmiConstant(static_cast<int>(message_id)));
} }
#define DECLARE_ENUM(name) \ #define DECLARE_ENUM(name) \
TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) { \ TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) { \
TNode<Object> instance = LoadInstanceFromFrame(); \ TNode<Object> instance = LoadInstanceFromFrame(); \
TNode<Code> centry = LoadCEntryFromInstance(instance); \ TNode<Object> context = LoadContextFromInstance(instance); \
TNode<Object> context = LoadContextFromInstance(instance); \ MessageTemplate message_id = \
MessageTemplate message_id = \ wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \
wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \ TailCallRuntime(Runtime::kThrowWasmError, context, \
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context, \ SmiConstant(static_cast<int>(message_id))); \
SmiConstant(static_cast<int>(message_id))); \
} }
FOREACH_WASM_TRAPREASON(DECLARE_ENUM) FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
#undef DECLARE_ENUM #undef DECLARE_ENUM
......
...@@ -1234,12 +1234,6 @@ TNode<Object> CodeAssembler::CallRuntimeImpl( ...@@ -1234,12 +1234,6 @@ TNode<Object> CodeAssembler::CallRuntimeImpl(
int result_size = Runtime::FunctionForId(function)->result_size; int result_size = Runtime::FunctionForId(function)->result_size;
TNode<Code> centry = TNode<Code> centry =
HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size)); 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; constexpr size_t kMaxNumArgs = 6;
DCHECK_GE(kMaxNumArgs, args.size()); DCHECK_GE(kMaxNumArgs, args.size());
int argc = static_cast<int>(args.size()); int argc = static_cast<int>(args.size());
...@@ -1273,12 +1267,6 @@ void CodeAssembler::TailCallRuntimeImpl( ...@@ -1273,12 +1267,6 @@ void CodeAssembler::TailCallRuntimeImpl(
int result_size = Runtime::FunctionForId(function)->result_size; int result_size = Runtime::FunctionForId(function)->result_size;
TNode<Code> centry = TNode<Code> centry =
HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size)); 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; constexpr size_t kMaxNumArgs = 6;
DCHECK_GE(kMaxNumArgs, args.size()); DCHECK_GE(kMaxNumArgs, args.size());
int argc = static_cast<int>(args.size()); int argc = static_cast<int>(args.size());
......
...@@ -951,14 +951,6 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -951,14 +951,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
{implicit_cast<SloppyTNode<Object>>(args)...}); {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> template <class... TArgs>
void TailCallRuntime(Runtime::FunctionId function, void TailCallRuntime(Runtime::FunctionId function,
SloppyTNode<Object> context, TArgs... args) { SloppyTNode<Object> context, TArgs... args) {
...@@ -975,17 +967,6 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -975,17 +967,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
{implicit_cast<SloppyTNode<Object>>(args)...}); {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. // If context passed to CallStub is nullptr, it won't be passed to the stub.
// //
...@@ -1176,19 +1157,10 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -1176,19 +1157,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<Object> context, TNode<Object> context,
std::initializer_list<TNode<Object>> args); 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, void TailCallRuntimeImpl(Runtime::FunctionId function, TNode<Int32T> arity,
TNode<Object> context, TNode<Object> context,
std::initializer_list<TNode<Object>> args); 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, void TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
TNode<Code> target, TNode<Object> context, TNode<Code> target, TNode<Object> context,
std::initializer_list<Node*> args); std::initializer_list<Node*> args);
......
...@@ -6853,7 +6853,7 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) { ...@@ -6853,7 +6853,7 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
MachineType::Pointer(), // argv MachineType::Pointer(), // argv
MachineType::Pointer()}; // c_entry_fp MachineType::Pointer()}; // c_entry_fp
MachineSignature incoming_sig(1, 4, sig_types); 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. // Runtime::kThrowWasmError.
CallDescriptor::Flags flags = CallDescriptor::kInitializeRootRegister; CallDescriptor::Flags flags = CallDescriptor::kInitializeRootRegister;
CallDescriptor* incoming = 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