Skip to content

Commit 6a8fa0d

Browse files
mlippautzV8 LUCI CQ
authored andcommitted
[compiler] Add bottleneck for static roots check in MacroAssembler
The patch adds a `MaybeJumpIfReadOnlyOrSmallSmi()` helper utility to all the 64-bit MacroAssembler's to allow write barriers to bail out on certain read-only objects and Smis. This bottleneck can later be easily extended for contiguous RO space to cover a larger region. Drive-by: - Call the bottleneck from TS which missed this optimization. - Also speed up skipped write barrier elimination which doesn't need to be called on RO values. Change-Id: Ibddea166fccb0671fac1641420a1cdba7ce6bc76 Bug: 429538831, 443678572 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6976228 Commit-Queue: Michael Lippautz <[email protected]> Reviewed-by: Leszek Swirski <[email protected]> Cr-Commit-Position: refs/heads/main@{#102727}
1 parent d3326e5 commit 6a8fa0d

11 files changed

Lines changed: 55 additions & 31 deletions

src/codegen/arm/macro-assembler-arm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
773773
// ---------------------------------------------------------------------------
774774
// GC Support
775775

776+
void MaybeJumpIfReadOnlyOrSmallSmi(Register, Label*) {}
777+
776778
// Notify the garbage collector that we wrote a pointer into an object.
777779
// |object| is the object being stored into, |value| is the object being
778780
// stored.

src/codegen/arm64/macro-assembler-arm64.cc

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3974,6 +3974,15 @@ void MacroAssembler::PreCheckSkippedWriteBarrier(Register object,
39743974
bind(&not_ok);
39753975
}
39763976

3977+
void MacroAssembler::MaybeJumpIfReadOnlyOrSmallSmi(Register value,
3978+
Label* dest) {
3979+
#if V8_STATIC_ROOTS_BOOL
3980+
// Quick check for Read-only and small Smi values.
3981+
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
3982+
JumpIfUnsignedLessThan(value, kRegularPageSize, dest);
3983+
#endif // V8_STATIC_ROOTS_BOOL
3984+
}
3985+
39773986
void MacroAssembler::RecordWriteField(
39783987
Register object, int offset, Register value, LinkRegisterStatus lr_status,
39793988
SaveFPRegsMode save_fp, SmiCheck smi_check, ReadOnlyCheck ro_check,
@@ -3984,13 +3993,9 @@ void MacroAssembler::RecordWriteField(
39843993
// catch stores of Smis and read-only objects.
39853994
Label done;
39863995

3987-
#if V8_STATIC_ROOTS_BOOL
39883996
if (ro_check == ReadOnlyCheck::kInline) {
3989-
// Quick check for Read-only and small Smi values.
3990-
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
3991-
JumpIfUnsignedLessThan(value, kRegularPageSize, &done);
3997+
MaybeJumpIfReadOnlyOrSmallSmi(value, &done);
39923998
}
3993-
#endif // V8_STATIC_ROOTS_BOOL
39943999

39954000
// Skip the barrier if writing a smi.
39964001
if (smi_check == SmiCheck::kInline) {
@@ -4581,13 +4586,9 @@ void MacroAssembler::RecordWrite(Register object, Operand offset,
45814586
// young generation.
45824587
Label done;
45834588

4584-
#if V8_STATIC_ROOTS_BOOL
45854589
if (ro_check == ReadOnlyCheck::kInline) {
4586-
// Quick check for Read-only and small Smi values.
4587-
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
4588-
JumpIfUnsignedLessThan(value, kRegularPageSize, &done);
4590+
MaybeJumpIfReadOnlyOrSmallSmi(value, &done);
45894591
}
4590-
#endif // V8_STATIC_ROOTS_BOOL
45914592

45924593
if (smi_check == SmiCheck::kInline) {
45934594
DCHECK_EQ(0, kSmiTag);

src/codegen/arm64/macro-assembler-arm64.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,6 +2373,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
23732373
// ---------------------------------------------------------------------------
23742374
// Garbage collector support (GC).
23752375

2376+
// Performs a fast check for whether `value` is a read-only object or a small
2377+
// Smi. Only enabled in some configurations.
2378+
void MaybeJumpIfReadOnlyOrSmallSmi(Register value, Label* dest);
2379+
23762380
// Notify the garbage collector that we wrote a pointer into an object.
23772381
// |object| is the object being stored into, |value| is the object being
23782382
// stored.

src/codegen/riscv/macro-assembler-riscv.cc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,15 @@ void MacroAssembler::CallVerifySkippedWriteBarrierStub(Register object,
863863
SetIsolateDataSlots::kNo);
864864
}
865865

866+
void MacroAssembler::MaybeJumpIfReadOnlyOrSmallSmi(Register value,
867+
Label* dest) {
868+
#if V8_STATIC_ROOTS_BOOL
869+
// Quick check for Read-only and small Smi values.
870+
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
871+
JumpIfUnsignedLessThan(value, kRegularPageSize, dest);
872+
#endif // V8_STATIC_ROOTS_BOOL
873+
}
874+
866875
// Clobbers object, address, value, and ra, if (ra_status == kRAHasBeenSaved)
867876
// The register 'object' contains a heap object pointer. The heap object
868877
// tag is shifted away.
@@ -897,16 +906,13 @@ void MacroAssembler::RecordWrite(Register object, Operand offset,
897906
}
898907

899908
// First, check if a write barrier is even needed. The tests below
900-
// catch stores of smisand read-only objects, as well as stores into the
909+
// catch stores of smis and read-only objects, as well as stores into the
901910
// young generation.
902911
Label done;
903-
#if V8_STATIC_ROOTS_BOOL
912+
904913
if (ro_check == ReadOnlyCheck::kInline) {
905-
// Quick check for read-only and small Smi values.
906-
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
907-
JumpIfUnsignedLessThan(value, kRegularPageSize, &done);
914+
MaybeJumpIfReadOnlyOrSmallSmi(value, &done);
908915
}
909-
#endif
910916

911917
if (smi_check == SmiCheck::kInline) {
912918
DCHECK_EQ(0, kSmiTag);

src/codegen/riscv/macro-assembler-riscv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
16031603
// ---------------------------------------------------------------------------
16041604
// GC Support
16051605

1606+
// Performs a fast check for whether `value` is a read-only object or a small
1607+
// Smi. Only enabled in some configurations.
1608+
void MaybeJumpIfReadOnlyOrSmallSmi(Register value, Label* dest);
1609+
16061610
// Notify the garbage collector that we wrote a pointer into an object.
16071611
// |object| is the object being stored into, |value| is the object being
16081612
// stored. value and scratch registers are clobbered by the operation.

src/codegen/x64/macro-assembler-x64.cc

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -464,13 +464,9 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
464464
// catch stores of Smis and read-only objects.
465465
Label done;
466466

467-
#if V8_STATIC_ROOTS_BOOL
468467
if (ro_check == ReadOnlyCheck::kInline) {
469-
// Quick check for Read-only and small Smi values.
470-
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
471-
JumpIfUnsignedLessThan(value, kRegularPageSize, &done);
468+
MaybeJumpIfReadOnlyOrSmallSmi(value, &done);
472469
}
473-
#endif // V8_STATIC_ROOTS_BOOL
474470

475471
// Skip barrier if writing a smi.
476472
if (smi_check == SmiCheck::kInline) {
@@ -1222,6 +1218,15 @@ void MacroAssembler::CallTSANRelaxedLoadStub(Register address,
12221218
}
12231219
#endif // V8_IS_TSAN
12241220

1221+
void MacroAssembler::MaybeJumpIfReadOnlyOrSmallSmi(Register value,
1222+
Label* dest) {
1223+
#if V8_STATIC_ROOTS_BOOL
1224+
// Quick check for Read-only and small Smi values.
1225+
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
1226+
JumpIfUnsignedLessThan(value, kRegularPageSize, dest);
1227+
#endif // V8_STATIC_ROOTS_BOOL
1228+
}
1229+
12251230
void MacroAssembler::RecordWrite(Register object, Register slot_address,
12261231
Register value, SaveFPRegsMode fp_mode,
12271232
SmiCheck smi_check, ReadOnlyCheck ro_check,
@@ -1262,13 +1267,9 @@ void MacroAssembler::RecordWrite(Register object, Register slot_address,
12621267
// young generation.
12631268
Label done;
12641269

1265-
#if V8_STATIC_ROOTS_BOOL
12661270
if (ro_check == ReadOnlyCheck::kInline) {
1267-
// Quick check for Read-only and small Smi values.
1268-
static_assert(StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize);
1269-
JumpIfUnsignedLessThan(value, kRegularPageSize, &done);
1271+
MaybeJumpIfReadOnlyOrSmallSmi(value, &done);
12701272
}
1271-
#endif // V8_STATIC_ROOTS_BOOL
12721273

12731274
if (smi_check == SmiCheck::kInline) {
12741275
// Skip barrier if writing a smi.

src/codegen/x64/macro-assembler-x64.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,10 @@ class V8_EXPORT_PRIVATE MacroAssembler
972972
// ---------------------------------------------------------------------------
973973
// GC Support
974974

975+
// Performs a fast check for whether `value` is a read-only object or a small
976+
// Smi. Only enabled in some configurations.
977+
void MaybeJumpIfReadOnlyOrSmallSmi(Register value, Label* dest);
978+
975979
// Notify the garbage collector that we wrote a pointer into an object.
976980
// |object| is the object being stored into, |value| is the object being
977981
// stored. value and scratch registers are clobbered by the operation.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
13691369
Register scratch = i.TempRegister(0);
13701370
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
13711371
this, object, value, scratch, &unwinding_info_writer_);
1372+
__ MaybeJumpIfReadOnlyOrSmallSmi(value, ool->exit());
13721373
__ JumpIfNotSmi(value, ool->entry());
13731374
__ bind(ool->exit());
13741375

@@ -1419,6 +1420,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
14191420
Register scratch = i.TempRegister(1);
14201421
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
14211422
this, object, value, scratch, &unwinding_info_writer_);
1423+
__ MaybeJumpIfReadOnlyOrSmallSmi(value, ool->exit());
14221424
__ JumpIfNotSmi(value, ool->entry());
14231425
__ bind(ool->exit());
14241426

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
11291129
if (v8_flags.verify_write_barriers) {
11301130
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
11311131
this, object, value, kScratchReg);
1132+
__ MaybeJumpIfReadOnlyOrSmallSmi(value, ool->exit());
11321133
__ JumpIfNotSmi(value, ool->entry());
11331134
__ bind(ool->exit());
11341135
}
@@ -1175,6 +1176,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
11751176
if (v8_flags.verify_write_barriers) {
11761177
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
11771178
this, object, value, kScratchReg);
1179+
__ MaybeJumpIfReadOnlyOrSmallSmi(value, ool->exit());
11781180
__ JumpIfNotSmi(value, ool->entry());
11791181
__ bind(ool->exit());
11801182
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
19251925
MachineRepresentation::kTagged, instr);
19261926
}
19271927
if (mode > RecordWriteMode::kValueIsPointer) {
1928+
__ MaybeJumpIfReadOnlyOrSmallSmi(value, ool->exit());
19281929
__ JumpIfSmi(value, ool->exit());
19291930
}
19301931
#if V8_ENABLE_STICKY_MARK_BITS_BOOL
@@ -1952,6 +1953,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
19521953
DCHECK(v8_flags.verify_write_barriers);
19531954
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
19541955
this, object, value, i.TempRegister(0));
1956+
__ MaybeJumpIfReadOnlyOrSmallSmi(value, ool->exit());
19551957
__ JumpIfNotSmi(value, ool->entry());
19561958
__ bind(ool->exit());
19571959

0 commit comments

Comments
 (0)