Commit 593fbb69 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[liftoff] Push the instance as part of frame construction

Currently we first construct the frame (via
{TurboAssembler::EnterFrame}), then we spill the instance to the
respective slot (via {LiftoffAssembler::SpillInstance}). Instead, we
should already spill the instance as part of frame construction. That
allows for a more compact instruction to be used ("push" instead of
"mov" on Intel), and on arm64 even allows to merge pushing into an
existing instruction (where we currently push the zero register x31
instead).

This makes the prologue more similar to what TurboFan generates in
{TurboAssembler::AssembleConstructFrame} (which does not use
{TurboAssembler::EnterFrame}).

R=ahaas@chromium.org

Bug: v8:12017
Change-Id: Ibb4a38d2049cff66fec9450db4f7f375d006beac
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3055302Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75938}
parent b86db139
......@@ -1370,6 +1370,9 @@ void TurboAssembler::EnterFrame(StackFrame::Type type,
mov(scratch, Operand(StackFrame::TypeToMarker(type)));
}
PushCommonFrame(scratch);
#if V8_ENABLE_WEBASSEMBLY
if (type == StackFrame::WASM) Push(kWasmInstanceRegister);
#endif // V8_ENABLE_WEBASSEMBLY
}
int TurboAssembler::LeaveFrame(StackFrame::Type type) {
......
......@@ -2603,11 +2603,11 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) {
Mov(type_reg, StackFrame::TypeToMarker(type));
Push<TurboAssembler::kSignLR>(lr, fp);
Mov(fp, sp);
Push(type_reg, padreg);
Push(type_reg, kWasmInstanceRegister);
// sp[3] : lr
// sp[2] : fp
// sp[1] : type
// sp[0] : for alignment
// sp[0] : wasm instance
#endif // V8_ENABLE_WEBASSEMBLY
} else if (type == StackFrame::CONSTRUCT) {
Register type_reg = temps.AcquireX();
......
......@@ -1164,6 +1164,9 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) {
if (!StackFrame::IsJavaScript(type)) {
Push(Immediate(StackFrame::TypeToMarker(type)));
}
#if V8_ENABLE_WEBASSEMBLY
if (type == StackFrame::WASM) Push(kWasmInstanceRegister);
#endif // V8_ENABLE_WEBASSEMBLY
}
void TurboAssembler::LeaveFrame(StackFrame::Type type) {
......
......@@ -3159,6 +3159,9 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) {
if (!StackFrame::IsJavaScript(type)) {
Push(Immediate(StackFrame::TypeToMarker(type)));
}
#if V8_ENABLE_WEBASSEMBLY
if (type == StackFrame::WASM) Push(kWasmInstanceRegister);
#endif // V8_ENABLE_WEBASSEMBLY
}
void TurboAssembler::LeaveFrame(StackFrame::Type type) {
......
......@@ -481,10 +481,10 @@ void LiftoffAssembler::AlignFrameSize() {}
void LiftoffAssembler::PatchPrepareStackFrame(
int offset, SafepointTableBuilder* safepoint_table_builder) {
// The frame_size includes the frame marker. The frame marker has already been
// pushed on the stack though, so we don't need to allocate memory for it
// anymore.
int frame_size = GetTotalFrameSize() - kSystemPointerSize;
// The frame_size includes the frame marker and the instance slot. Both are
// pushed as part of frame construction, so we don't need to allocate memory
// for them anymore.
int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
PatchingAssembler patching_assembler(AssemblerOptions{},
buffer_start_ + offset,
......@@ -531,9 +531,6 @@ void LiftoffAssembler::PatchPrepareStackFrame(
b(cs /* higher or same */, &continuation);
}
// The instance has not been written to the frame yet (because no frame space
// has been allocated), but the runtime call expects it. Hence push it now.
Push(kWasmInstanceRegister);
Call(wasm::WasmCode::kWasmStackOverflow, RelocInfo::WASM_STUB_CALL);
// The call will not return; just define an empty safepoint.
safepoint_table_builder->DefineSafepoint(this);
......
......@@ -306,9 +306,9 @@ void LiftoffAssembler::AlignFrameSize() {
void LiftoffAssembler::PatchPrepareStackFrame(
int offset, SafepointTableBuilder* safepoint_table_builder) {
// The frame_size includes the frame marker. The frame marker has already been
// pushed on the stack though, so we don't need to allocate memory for it
// anymore.
// The frame_size includes the frame marker and the instance slot. Both are
// pushed as part of frame construction, so we don't need to allocate memory
// for them anymore.
int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
// The stack pointer is required to be quadword aligned.
......@@ -361,7 +361,6 @@ void LiftoffAssembler::PatchPrepareStackFrame(
// The instance was not written to the frame yet, but the slot was already
// reserved in {EnterFrame}. The runtime call expects it, thus spill it now.
SpillInstance(kWasmInstanceRegister);
Call(wasm::WasmCode::kWasmStackOverflow, RelocInfo::WASM_STUB_CALL);
// The call will not return; just define an empty safepoint.
safepoint_table_builder->DefineSafepoint(this);
......
......@@ -222,10 +222,10 @@ void LiftoffAssembler::AlignFrameSize() {}
void LiftoffAssembler::PatchPrepareStackFrame(int offset,
SafepointTableBuilder*) {
// The frame_size includes the frame marker. The frame marker has already been
// pushed on the stack though, so we don't need to allocate memory for it
// anymore.
int frame_size = GetTotalFrameSize() - kSystemPointerSize;
// The frame_size includes the frame marker and the instance slot. Both are
// pushed as part of frame construction, so we don't need to allocate memory
// for them anymore.
int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
DCHECK_EQ(frame_size % kSystemPointerSize, 0);
// We can't run out of space, just pass anything big enough to not cause the
// assembler to try to grow the buffer.
......
......@@ -741,8 +741,6 @@ class LiftoffCompiler {
Register::from_code(
descriptor_->GetInputLocation(kInstanceParameterIndex)
.AsRegister()));
// Store the instance parameter to a special stack slot.
__ SpillInstance(kWasmInstanceRegister);
__ cache_state()->SetInstanceCacheRegister(kWasmInstanceRegister);
if (for_debugging_) __ ResetOSRTarget();
......
......@@ -208,10 +208,11 @@ void LiftoffAssembler::AlignFrameSize() {
void LiftoffAssembler::PatchPrepareStackFrame(int offset,
SafepointTableBuilder*) {
// The frame_size includes the frame marker. The frame marker has already been
// pushed on the stack though, so we don't need to allocate memory for it
// anymore.
int frame_size = GetTotalFrameSize() - kSystemPointerSize;
// The frame_size includes the frame marker and the instance slot. Both are
// pushed as part of frame construction, so we don't need to allocate memory
// for them anymore.
int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
// Need to align sp to system pointer size.
DCHECK_EQ(frame_size, RoundUp(frame_size, kSystemPointerSize));
// We can't run out of space, just pass anything big enough to not cause the
......
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