Commit 0755c9b6 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Save new.target reg across stack check

Since the function entry stack check happens outside of the IR, the
standard register spilling mechanisms don't kick in and registers that
expect to be valid might be clobbered.

The only such case is, in fact, the new.target register, so make sure
it is preserved across the stack check.

R=jgruber@chromium.org

Bug: v8:7700
Change-Id: I530b6af882ca188b0e3c7da752f810506f3340a0
Fixed: v8:13226, chromium:1356082
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3852389
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82700}
parent d83346be
......@@ -1469,9 +1469,10 @@ void MaglevFrame::Iterate(RootVisitor* v) const {
// we've set up the frame header, but not the spill slots yet.
// DCHECK the frame setup under the above assumption. Include one extra slot
// for the single argument into StackGuardWithGap.
// for the single argument into StackGuardWithGap, and another for the saved
// new.target register.
DCHECK_EQ(actual_frame_size, StandardFrameConstants::kFixedFrameSizeFromFp +
kSystemPointerSize);
2 * kSystemPointerSize);
DCHECK_EQ(isolate()->c_function(),
Runtime::FunctionForId(Runtime::kStackGuardWithGap)->entry);
DCHECK_EQ(maglev_safepoint_entry.num_pushed_registers(), 0);
......
......@@ -551,13 +551,14 @@ class MaglevCodeGeneratingNodeProcessor {
__ int3();
__ bind(&deferred_call_stack_guard_);
ASM_CODE_COMMENT_STRING(masm(), "Stack/interrupt call");
// Save incoming new target or generator
// __ Push(new_target);
// Save any registers that can be referenced by RegisterInput.
// TODO(leszeks): Only push those that are used by the graph.
__ PushAll(RegisterInput::kAllowedRegisters);
// Push the frame size
__ Push(Immediate(
Smi::FromInt(code_gen_state_->stack_slots() * kSystemPointerSize)));
__ CallRuntime(Runtime::kStackGuardWithGap, 1);
//__ Pop(new_target);
__ PopAll(RegisterInput::kAllowedRegisters);
__ jmp(&deferred_call_stack_guard_return_);
}
......
......@@ -1998,8 +1998,13 @@ class RegisterInput : public FixedInputValueNodeT<0, RegisterInput> {
using Base = FixedInputValueNodeT<0, RegisterInput>;
public:
static constexpr RegList kAllowedRegisters = {
kJavaScriptCallNewTargetRegister};
explicit RegisterInput(uint64_t bitfield, Register input)
: Base(bitfield), input_(input) {}
: Base(bitfield), input_(input) {
DCHECK(kAllowedRegisters.has(input));
}
Register input() const { return input_; }
......
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