[wasm] Remove runtime call support from Liftoff.
This removes the support to emit runtime calls in Liftoff code and uses WebAssembly runtime stubs instead. Calls to such stubs are smaller and more efficient. They also use embedded builtins directly instead of the on-heap {Code} object trampolines. This also removes the last use of a runtime call that passes a dynamically loaded CEntry builtin from the macro assembler. R=clemensb@chromium.org Change-Id: I9fa9f3b7a2b66cb76a677b70ce3cee49cb340f0f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903443 Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#64855}
This commit is contained in:
parent
2daa1138e3
commit
bfe1328565
@ -949,6 +949,7 @@ namespace internal {
|
||||
TFC(WasmStackOverflow, NoContext) \
|
||||
TFC(WasmThrow, WasmThrow) \
|
||||
TFC(WasmRethrow, WasmThrow) \
|
||||
TFS(WasmTraceMemory, kMemoryTracingInfo) \
|
||||
TFS(ThrowWasmTrapUnreachable) \
|
||||
TFS(ThrowWasmTrapMemOutOfBounds) \
|
||||
TFS(ThrowWasmTrapUnalignedAccess) \
|
||||
@ -1263,6 +1264,7 @@ namespace internal {
|
||||
V(WasmStackOverflow) \
|
||||
V(WasmThrow) \
|
||||
V(WasmRethrow) \
|
||||
V(WasmTraceMemory) \
|
||||
V(AllocateHeapNumber) \
|
||||
V(ArgumentsAdaptorTrampoline) \
|
||||
V(BigIntToI32Pair) \
|
||||
|
@ -61,6 +61,13 @@ TF_BUILTIN(WasmRethrow, WasmBuiltinsAssembler) {
|
||||
TailCallRuntime(Runtime::kReThrow, context, exception);
|
||||
}
|
||||
|
||||
TF_BUILTIN(WasmTraceMemory, WasmBuiltinsAssembler) {
|
||||
TNode<Object> info = UncheckedParameter(Descriptor::kMemoryTracingInfo);
|
||||
TNode<Object> instance = LoadInstanceFromFrame();
|
||||
TNode<Object> context = LoadContextFromInstance(instance);
|
||||
TailCallRuntime(Runtime::kWasmTraceMemory, context, info);
|
||||
}
|
||||
|
||||
TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
|
||||
TNode<Uint32T> address =
|
||||
UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
|
||||
|
@ -1826,19 +1826,6 @@ void TurboAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone,
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
mov(r0, Operand(f->nargs));
|
||||
Move(r1, ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, r0, r1));
|
||||
CallCodeObject(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// All parameters are on the stack. r0 has the return value after call.
|
||||
|
@ -287,10 +287,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
void LoadRootRegisterOffset(Register destination, intptr_t offset) override;
|
||||
void LoadRootRelative(Register destination, int32_t offset) override;
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
// Jump, Call, and Ret pseudo instructions implementing inter-working.
|
||||
void Call(Register target, Condition cond = al);
|
||||
void Call(Address target, RelocInfo::Mode rmode, Condition cond = al,
|
||||
|
@ -1618,19 +1618,6 @@ void TurboAssembler::AssertPositiveOrZero(Register value) {
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
Mov(x0, f->nargs);
|
||||
Mov(x1, ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, x0, x1));
|
||||
CallCodeObject(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// All arguments must be on the stack before this function is called.
|
||||
|
@ -560,10 +560,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
inline void Isb();
|
||||
inline void Csdb();
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
// Removes current frame and its arguments from the stack preserving
|
||||
// the arguments and a return address pushed to the stack for the next call.
|
||||
// Both |callee_args_count| and |caller_args_count| do not include
|
||||
|
@ -980,20 +980,6 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
Call(code, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
Move(kRuntimeCallArgCountRegister, Immediate(f->nargs));
|
||||
Move(kRuntimeCallFunctionRegister, Immediate(ExternalReference::Create(f)));
|
||||
DCHECK(!AreAliased(centry, kRuntimeCallArgCountRegister,
|
||||
kRuntimeCallFunctionRegister));
|
||||
CallCodeObject(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- esp[0] : return address
|
||||
|
@ -111,10 +111,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
|
||||
void CallForDeoptimization(Address target, int deopt_id);
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
// Jump the register contains a smi.
|
||||
inline void JumpIfSmi(Register value, Label* smi_label,
|
||||
Label::Distance distance = Label::kFar) {
|
||||
|
@ -4566,19 +4566,6 @@ void TurboAssembler::MulOverflow(Register dst, Register left,
|
||||
}
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
PrepareCEntryArgs(f->nargs);
|
||||
PrepareCEntryFunction(ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, a0, a1));
|
||||
Call(centry, Code::kHeaderSize - kHeapObjectTag);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// All parameters are on the stack. v0 has the return value after call.
|
||||
|
@ -504,10 +504,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
Label* condition_met);
|
||||
#undef COND_ARGS
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
// Performs a truncating conversion of a floating point number as used by
|
||||
// the JS bitwise operations. See ECMA-262 9.5: ToInt32.
|
||||
// Exits with 'result' holding the answer.
|
||||
|
@ -4881,20 +4881,6 @@ void TurboAssembler::MulOverflow(Register dst, Register left,
|
||||
xor_(overflow, overflow, scratch);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
PrepareCEntryArgs(f->nargs);
|
||||
PrepareCEntryFunction(ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, a0, a1));
|
||||
Daddu(centry, centry, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
Call(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// All parameters are on the stack. v0 has the return value after call.
|
||||
|
@ -527,10 +527,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
Label* condition_met);
|
||||
#undef COND_ARGS
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
// Performs a truncating conversion of a floating point number as used by
|
||||
// the JS bitwise operations. See ECMA-262 9.5: ToInt32.
|
||||
// Exits with 'result' holding the answer.
|
||||
|
@ -1573,19 +1573,6 @@ void TurboAssembler::TryInlineTruncateDoubleToI(Register result,
|
||||
beq(done);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
mov(r3, Operand(f->nargs));
|
||||
Move(r4, ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, r3, r4));
|
||||
CallCodeObject(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// All parameters are on the stack. r3 has the return value after call.
|
||||
|
@ -361,10 +361,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
int num_double_arguments,
|
||||
bool has_function_descriptor = true);
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
void MovFromFloatParameter(DoubleRegister dst);
|
||||
void MovFromFloatResult(DoubleRegister dst);
|
||||
|
||||
|
@ -1518,15 +1518,6 @@ void TurboAssembler::TryInlineTruncateDoubleToI(Register result,
|
||||
beq(done);
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
mov(r2, Operand(f->nargs));
|
||||
Move(r3, ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, r2, r3));
|
||||
CallCodeObject(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// All parameters are on the stack. r2 has the return value after call.
|
||||
|
@ -811,10 +811,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
// ---------------------------------------------------------------------------
|
||||
// Runtime calls
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
// Before calling a C-function from generated code, align arguments on stack.
|
||||
// After aligning the frame, non-register arguments must be stored in
|
||||
// sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
|
||||
|
@ -590,20 +590,6 @@ void TurboAssembler::Abort(AbortReason reason) {
|
||||
int3();
|
||||
}
|
||||
|
||||
void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid,
|
||||
Register centry) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
Set(rax, f->nargs);
|
||||
LoadAddress(rbx, ExternalReference::Create(f));
|
||||
DCHECK(!AreAliased(centry, rax, rbx));
|
||||
DCHECK(centry == rcx);
|
||||
CallCodeObject(centry);
|
||||
}
|
||||
|
||||
void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
// If the expected number of arguments of the runtime function is
|
||||
|
@ -494,10 +494,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
Register caller_args_count, Register scratch0,
|
||||
Register scratch1);
|
||||
|
||||
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
|
||||
// builtin for the target runtime function and uses an indirect call.
|
||||
void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
|
||||
|
||||
void InitializeRootRegister() {
|
||||
ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
|
||||
Move(kRootRegister, isolate_root);
|
||||
|
@ -1669,47 +1669,20 @@ class LiftoffCompiler {
|
||||
__ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, mem_rep), address,
|
||||
StoreType::kI32Store8, pinned);
|
||||
|
||||
WasmTraceMemoryDescriptor descriptor;
|
||||
DCHECK_EQ(0, descriptor.GetStackParameterCount());
|
||||
DCHECK_EQ(1, descriptor.GetRegisterParameterCount());
|
||||
Register param_reg = descriptor.GetRegisterParameter(0);
|
||||
if (info.gp() != param_reg) {
|
||||
__ Move(param_reg, info.gp(), LiftoffAssembler::kWasmIntPtr);
|
||||
}
|
||||
|
||||
source_position_table_builder_.AddPosition(__ pc_offset(),
|
||||
SourcePosition(position), false);
|
||||
|
||||
Register args[] = {info.gp()};
|
||||
GenerateRuntimeCall(Runtime::kWasmTraceMemory, arraysize(args), args);
|
||||
__ DeallocateStackSlot(sizeof(MemoryTracingInfo));
|
||||
}
|
||||
|
||||
void GenerateRuntimeCall(Runtime::FunctionId runtime_function, int num_args,
|
||||
Register* args) {
|
||||
// Currently, only one argument is supported. More arguments require some
|
||||
// caution for the parallel register moves (reuse StackTransferRecipe).
|
||||
DCHECK_EQ(1, num_args);
|
||||
#ifdef DEBUG
|
||||
auto call_descriptor = compiler::Linkage::GetRuntimeCallDescriptor(
|
||||
compilation_zone_, runtime_function, num_args,
|
||||
compiler::Operator::kNoProperties, compiler::CallDescriptor::kNoFlags);
|
||||
constexpr size_t kInputShift = 1; // Input 0 is the call target.
|
||||
compiler::LinkageLocation param_loc =
|
||||
call_descriptor->GetInputLocation(kInputShift);
|
||||
// Runtime calls take their arguments on the stack.
|
||||
DCHECK(param_loc.IsCallerFrameSlot());
|
||||
#endif
|
||||
LiftoffStackSlots stack_slots(&asm_);
|
||||
stack_slots.Add(LiftoffAssembler::VarState(LiftoffAssembler::kWasmIntPtr,
|
||||
LiftoffRegister(args[0])));
|
||||
stack_slots.Construct();
|
||||
|
||||
// Set context to "no context" for the runtime call.
|
||||
__ TurboAssembler::Move(kContextRegister,
|
||||
Smi::FromInt(Context::kNoContext));
|
||||
Register centry = kJavaScriptCallCodeStartRegister;
|
||||
LOAD_INSTANCE_FIELD(centry, IsolateRoot, kSystemPointerSize);
|
||||
// All cache registers are spilled and there are no register arguments.
|
||||
LiftoffRegList pinned;
|
||||
auto centry_id =
|
||||
Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit;
|
||||
__ LoadTaggedPointer(centry, centry, no_reg,
|
||||
IsolateData::builtin_slot_offset(centry_id), pinned);
|
||||
__ CallRuntimeWithCEntry(runtime_function, centry);
|
||||
__ CallRuntimeStub(WasmCode::kWasmTraceMemory);
|
||||
safepoint_table_builder_.DefineSafepoint(&asm_, Safepoint::kNoLazyDeopt);
|
||||
|
||||
__ DeallocateStackSlot(sizeof(MemoryTracingInfo));
|
||||
}
|
||||
|
||||
Register AddMemoryMasking(Register index, uint32_t* offset,
|
||||
|
Loading…
Reference in New Issue
Block a user