@@ -194,18 +194,34 @@ void MacroAssembler::PreCheckSkippedWriteBarrier(Register object,
194194 bind (¬_ok);
195195}
196196
197+ void MacroAssembler::MaybeJumpIfReadOnlyOrSmallSmi (Register value,
198+ Label* dest) {
199+ #if V8_STATIC_ROOTS_BOOL
200+ // Quick check for Read-only and small Smi values.
201+ static_assert (StaticReadOnlyRoot::kLastAllocatedRoot < kRegularPageSize );
202+ JumpIfUnsignedLessThan (value, kRegularPageSize , dest);
203+ #endif // V8_STATIC_ROOTS_BOOL
204+ }
205+
197206// Clobbers object, dst, value, and ra, if (ra_status == kRAHasBeenSaved)
198207// The register 'object' contains a heap object pointer. The heap object
199208// tag is shifted away.
200209void MacroAssembler::RecordWriteField (Register object, int offset,
201210 Register value, RAStatus ra_status,
202211 SaveFPRegsMode save_fp,
203- SmiCheck smi_check, SlotDescriptor slot) {
212+ SmiCheck smi_check,
213+ ReadOnlyCheck ro_check,
214+ SlotDescriptor slot) {
204215 ASM_CODE_COMMENT (this );
216+ DCHECK (!AreAliased (object, value));
205217 // First, check if a write barrier is even needed. The tests below
206- // catch stores of Smis.
218+ // catch stores of Smis and read-only objects .
207219 Label done;
208220
221+ if (ro_check == ReadOnlyCheck::kInline ) {
222+ MaybeJumpIfReadOnlyOrSmallSmi (value, &done);
223+ }
224+
209225 // Skip barrier if writing a smi.
210226 if (smi_check == SmiCheck::kInline ) {
211227 JumpIfSmi (value, &done);
@@ -228,7 +244,7 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
228244 }
229245
230246 RecordWrite (object, Operand (offset - kHeapObjectTag ), value, ra_status,
231- save_fp, SmiCheck::kOmit , slot);
247+ save_fp, SmiCheck::kOmit , ReadOnlyCheck:: kOmit , slot);
232248
233249 bind (&done);
234250}
@@ -703,7 +719,7 @@ void MacroAssembler::MoveObjectAndSlot(Register dst_object, Register dst_slot,
703719void MacroAssembler::RecordWrite (Register object, Operand offset,
704720 Register value, RAStatus ra_status,
705721 SaveFPRegsMode fp_mode, SmiCheck smi_check,
706- SlotDescriptor slot) {
722+ ReadOnlyCheck ro_check, SlotDescriptor slot) {
707723 DCHECK (!AreAliased (object, value));
708724
709725 if (v8_flags.slow_debug_code ) {
@@ -726,9 +742,14 @@ void MacroAssembler::RecordWrite(Register object, Operand offset,
726742 }
727743
728744 // First, check if a write barrier is even needed. The tests below
729- // catch stores of smis and stores into the young generation.
745+ // catch stores of smis and read-only objects, as well as stores into the
746+ // young generation.
730747 Label done;
731748
749+ if (ro_check == ReadOnlyCheck::kInline ) {
750+ MaybeJumpIfReadOnlyOrSmallSmi (value, &done);
751+ }
752+
732753 if (smi_check == SmiCheck::kInline ) {
733754 DCHECK_EQ (0 , kSmiTag );
734755 JumpIfSmi (value, &done);
@@ -5312,7 +5333,7 @@ void MacroAssembler::ReplaceClosureCodeWithOptimizedCode(
53125333 FieldMemOperand (closure, JSFunction::kCodeOffset ));
53135334 RecordWriteField (closure, JSFunction::kCodeOffset , optimized_code,
53145335 kRAHasNotBeenSaved , SaveFPRegsMode::kIgnore , SmiCheck::kOmit ,
5315- SlotDescriptor::ForCodePointerSlot ());
5336+ ReadOnlyCheck:: kOmit , SlotDescriptor::ForCodePointerSlot ());
53165337}
53175338
53185339// Read off the flags in the feedback vector and check if there
0 commit comments