Skip to content

Commit cc26a34

Browse files
Dominik InführV8 LUCI CQ
authored andcommitted
[compiler] Save link register in write barrier verification
On ARM the write barrier verification calls can clobber the link register when that block doesn't have a frame. Like OutOfLineRecordWrite we need to save the link register manually. Bug: 437096305 Change-Id: I51cff5dd2f3106a7420a6d35e36ebfd2ffd8e74f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6939392 Commit-Queue: Dominik Inführ <[email protected]> Reviewed-by: Darius Mercadier <[email protected]> Cr-Commit-Position: refs/heads/main@{#102435}
1 parent 16d8eb8 commit cc26a34

2 files changed

Lines changed: 57 additions & 11 deletions

File tree

src/compiler/backend/arm/code-generator-arm.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,24 +233,38 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
233233
class OutOfLineVerifySkippedWriteBarrier final : public OutOfLineCode {
234234
public:
235235
OutOfLineVerifySkippedWriteBarrier(CodeGenerator* gen, Register object,
236-
Register value)
236+
Register value,
237+
UnwindingInfoWriter* unwinding_info_writer)
237238
: OutOfLineCode(gen),
238239
object_(object),
239240
value_(value),
241+
must_save_lr_(!gen->frame_access_state()->has_frame()),
242+
unwinding_info_writer_(unwinding_info_writer),
240243
zone_(gen->zone()) {}
241244

242245
void Generate() final {
243246
SaveFPRegsMode const save_fp_mode = frame()->DidAllocateDoubleRegisters()
244247
? SaveFPRegsMode::kSave
245248
: SaveFPRegsMode::kIgnore;
246249

250+
if (must_save_lr_) {
251+
// We need to save and restore lr if the frame was elided.
252+
__ Push(lr);
253+
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset());
254+
}
247255
__ CallVerifySkippedWriteBarrierStubSaveRegisters(object_, value_,
248256
save_fp_mode);
257+
if (must_save_lr_) {
258+
__ Pop(lr);
259+
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
260+
}
249261
}
250262

251263
private:
252264
Register const object_;
253265
Register const value_;
266+
const bool must_save_lr_;
267+
UnwindingInfoWriter* const unwinding_info_writer_;
254268
Zone* zone_;
255269
};
256270

@@ -1057,8 +1071,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
10571071
}
10581072

10591073
DCHECK(v8_flags.verify_write_barriers);
1060-
auto ool =
1061-
zone()->New<OutOfLineVerifySkippedWriteBarrier>(this, object, value);
1074+
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
1075+
this, object, value, &unwinding_info_writer_);
10621076
__ JumpIfNotSmi(value, ool->entry());
10631077
__ bind(ool->exit());
10641078

src/compiler/backend/arm64/code-generator-arm64.cc

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,22 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
386386
class OutOfLineVerifySkippedWriteBarrier final : public OutOfLineCode {
387387
public:
388388
OutOfLineVerifySkippedWriteBarrier(CodeGenerator* gen, Register object,
389-
Register value)
389+
Register value,
390+
UnwindingInfoWriter* unwinding_info_writer)
390391
: OutOfLineCode(gen),
391392
object_(object),
392393
value_(value),
394+
must_save_lr_(!gen->frame_access_state()->has_frame()),
395+
unwinding_info_writer_(unwinding_info_writer),
393396
zone_(gen->zone()) {}
394397

395398
void Generate() final {
399+
if (must_save_lr_) {
400+
// We need to save and restore lr if the frame was elided.
401+
__ Push<MacroAssembler::kSignLR>(lr, padreg);
402+
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset(), sp);
403+
}
404+
396405
if (COMPRESS_POINTERS_BOOL) {
397406
__ DecompressTagged(value_, value_);
398407
}
@@ -403,35 +412,58 @@ class OutOfLineVerifySkippedWriteBarrier final : public OutOfLineCode {
403412

404413
__ CallVerifySkippedWriteBarrierStubSaveRegisters(object_, value_,
405414
save_fp_mode);
415+
416+
if (must_save_lr_) {
417+
__ Pop<MacroAssembler::kAuthLR>(padreg, lr);
418+
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
419+
}
406420
}
407421

408422
private:
409423
Register const object_;
410424
Register const value_;
425+
const bool must_save_lr_;
426+
UnwindingInfoWriter* const unwinding_info_writer_;
411427
Zone* zone_;
412428
};
413429

414430
class OutOfLineVerifySkippedIndirectWriteBarrier final : public OutOfLineCode {
415431
public:
416-
OutOfLineVerifySkippedIndirectWriteBarrier(CodeGenerator* gen,
417-
Register object, Register value)
432+
OutOfLineVerifySkippedIndirectWriteBarrier(
433+
CodeGenerator* gen, Register object, Register value,
434+
UnwindingInfoWriter* unwinding_info_writer)
418435
: OutOfLineCode(gen),
419436
object_(object),
420437
value_(value),
438+
must_save_lr_(!gen->frame_access_state()->has_frame()),
439+
unwinding_info_writer_(unwinding_info_writer),
421440
zone_(gen->zone()) {}
422441

423442
void Generate() final {
443+
if (must_save_lr_) {
444+
// We need to save and restore lr if the frame was elided.
445+
__ Push<MacroAssembler::kSignLR>(lr, padreg);
446+
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset(), sp);
447+
}
448+
424449
SaveFPRegsMode const save_fp_mode = frame()->DidAllocateDoubleRegisters()
425450
? SaveFPRegsMode::kSave
426451
: SaveFPRegsMode::kIgnore;
427452

428453
__ CallVerifySkippedIndirectWriteBarrierStubSaveRegisters(object_, value_,
429454
save_fp_mode);
455+
456+
if (must_save_lr_) {
457+
__ Pop<MacroAssembler::kAuthLR>(padreg, lr);
458+
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
459+
}
430460
}
431461

432462
private:
433463
Register const object_;
434464
Register const value_;
465+
const bool must_save_lr_;
466+
UnwindingInfoWriter* const unwinding_info_writer_;
435467
Zone* zone_;
436468
};
437469

@@ -1330,8 +1362,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
13301362
}
13311363

13321364
DCHECK(v8_flags.verify_write_barriers);
1333-
auto ool =
1334-
zone()->New<OutOfLineVerifySkippedWriteBarrier>(this, object, value);
1365+
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
1366+
this, object, value, &unwinding_info_writer_);
13351367
__ JumpIfNotSmi(value, ool->entry());
13361368
__ bind(ool->exit());
13371369

@@ -1379,8 +1411,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
13791411
__ Add(temp, object, offset);
13801412

13811413
DCHECK(v8_flags.verify_write_barriers);
1382-
auto ool =
1383-
zone()->New<OutOfLineVerifySkippedWriteBarrier>(this, object, value);
1414+
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
1415+
this, object, value, &unwinding_info_writer_);
13841416
__ JumpIfNotSmi(value, ool->entry());
13851417
__ bind(ool->exit());
13861418

@@ -1438,7 +1470,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
14381470

14391471
DCHECK(v8_flags.verify_write_barriers);
14401472
auto ool = zone()->New<OutOfLineVerifySkippedIndirectWriteBarrier>(
1441-
this, object, value);
1473+
this, object, value, &unwinding_info_writer_);
14421474
__ jmp(ool->entry());
14431475
__ bind(ool->exit());
14441476

0 commit comments

Comments
 (0)