[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 <ishell@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81780}
This commit is contained in:
Leszek Swirski 2022-07-18 15:28:23 +02:00 committed by V8 LUCI CQ
parent c08756d0fd
commit 035982c6dd
2 changed files with 14 additions and 4 deletions

View File

@ -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<UnconditionalControlNode, NodeT>::value) {
EmitBlockEndGapMoves(node->template Cast<UnconditionalControlNode>(),

View File

@ -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 =