From 035982c6dd5f93815b15d2ce0c39b08069edfd1b Mon Sep 17 00:00:00 2001 From: Leszek Swirski Date: Mon, 18 Jul 2022 15:28:23 +0200 Subject: [PATCH] [maglev] Fix unbalanced push in deferred write barrier We check page flags in the deferred write barrier, and bail out early if pointers to that page are not interesting. Make sure that the slot register saving happens after that early bailout, to avoid unbalanced push/pop. To avoid bugs like this in the future, add a stack size check as a prefix to every node's code gen. Bug: v8:7700 Change-Id: I54a00fcbc843d473a1ca1e6cf3d852a0c60621c0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3769695 Reviewed-by: Igor Sheludko Auto-Submit: Leszek Swirski Commit-Queue: Igor Sheludko Cr-Commit-Position: refs/heads/main@{#81780} --- src/maglev/maglev-code-generator.cc | 9 +++++++++ src/maglev/maglev-ir.cc | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/maglev/maglev-code-generator.cc b/src/maglev/maglev-code-generator.cc index 004308fd6d..a76f03570c 100644 --- a/src/maglev/maglev-code-generator.cc +++ b/src/maglev/maglev-code-generator.cc @@ -131,6 +131,15 @@ class MaglevCodeGeneratingNodeProcessor { __ RecordComment(ss.str()); } + if (FLAG_debug_code) { + __ movq(kScratchRegister, rbp); + __ subq(kScratchRegister, rsp); + __ cmpq(kScratchRegister, + Immediate(code_gen_state_->stack_slots() * kSystemPointerSize + + StandardFrameConstants::kFixedFrameSizeFromFp)); + __ Assert(equal, AbortReason::kStackAccessBelowStackPointer); + } + // Emit Phi moves before visiting the control node. if (std::is_base_of::value) { EmitBlockEndGapMoves(node->template Cast(), diff --git a/src/maglev/maglev-ir.cc b/src/maglev/maglev-ir.cc index af1b45d8e9..f784bc8da3 100644 --- a/src/maglev/maglev-ir.cc +++ b/src/maglev/maglev-ir.cc @@ -1001,16 +1001,17 @@ void StoreTaggedFieldWithWriteBarrier::GenerateCode( StoreTaggedFieldWithWriteBarrier* node) { ASM_CODE_COMMENT_STRING(code_gen_state->masm(), "Write barrier slow path"); + __ CheckPageFlag(value, kScratchRegister, + MemoryChunk::kPointersToHereAreInterestingMask, zero, + return_label); + Register slot_reg = WriteBarrierDescriptor::SlotAddressRegister(); RegList saved; if (node->register_snapshot().live_registers.has(slot_reg)) { saved.set(slot_reg); } - __ PushAll(saved); - __ CheckPageFlag(value, kScratchRegister, - MemoryChunk::kPointersToHereAreInterestingMask, zero, - return_label); + __ PushAll(saved); __ leaq(slot_reg, FieldOperand(object, node->offset())); SaveFPRegsMode const save_fp_mode =