Index: src/arm64/macro-assembler-arm64.cc |
diff --git a/src/arm64/macro-assembler-arm64.cc b/src/arm64/macro-assembler-arm64.cc |
index 7052dac540397ba47848486ff4e7a8bdfba8915d..b7c622bdb918aa79e24a5a52e89105a2325cbf33 100644 |
--- a/src/arm64/macro-assembler-arm64.cc |
+++ b/src/arm64/macro-assembler-arm64.cc |
@@ -4272,7 +4272,8 @@ void MacroAssembler::RecordWriteField( |
LinkRegisterStatus lr_status, |
SaveFPRegsMode save_fp, |
RememberedSetAction remembered_set_action, |
- SmiCheck smi_check) { |
+ SmiCheck smi_check, |
+ PointersToHereCheck pointers_to_here_check_for_value) { |
// First, check if a write barrier is even needed. The tests below |
// catch stores of Smis. |
Label done; |
@@ -4301,7 +4302,8 @@ void MacroAssembler::RecordWriteField( |
lr_status, |
save_fp, |
remembered_set_action, |
- OMIT_SMI_CHECK); |
+ OMIT_SMI_CHECK, |
+ pointers_to_here_check_for_value); |
Bind(&done); |
@@ -4314,18 +4316,91 @@ void MacroAssembler::RecordWriteField( |
} |
+// Will clobber: object, map, dst. |
+// If lr_status is kLRHasBeenSaved, lr will also be clobbered. |
+void MacroAssembler::RecordWriteForMap(Register object, |
+ Register map, |
+ Register dst, |
+ LinkRegisterStatus lr_status, |
+ SaveFPRegsMode fp_mode) { |
+ ASM_LOCATION("MacroAssembler::RecordWrite"); |
+ ASSERT(!AreAliased(object, map)); |
+ |
+ if (emit_debug_code()) { |
+ UseScratchRegisterScope temps(this); |
+ Register temp = temps.AcquireX(); |
+ |
+ CompareMap(map, temp, isolate()->factory()->meta_map()); |
+ Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
+ } |
+ |
+ if (!FLAG_incremental_marking) { |
+ return; |
+ } |
+ |
+ if (emit_debug_code()) { |
+ UseScratchRegisterScope temps(this); |
+ Register temp = temps.AcquireX(); |
+ |
+ Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); |
+ Cmp(temp, map); |
+ Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
+ } |
+ |
+ // Count number of write barriers in generated code. |
+ isolate()->counters()->write_barriers_static()->Increment(); |
+ // TODO(mstarzinger): Dynamic counter missing. |
+ |
+ // First, check if a write barrier is even needed. The tests below |
+ // catch stores of smis and stores into the young generation. |
+ Label done; |
+ |
+ // A single check of the map's pages interesting flag suffices, since it is |
+ // only set during incremental collection, and then it's also guaranteed that |
+ // the from object's page's interesting flag is also set. This optimization |
+ // relies on the fact that maps can never be in new space. |
+ CheckPageFlagClear(map, |
+ map, // Used as scratch. |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ &done); |
+ |
+ // Record the actual write. |
+ if (lr_status == kLRHasNotBeenSaved) { |
+ Push(lr); |
+ } |
+ Add(dst, object, HeapObject::kMapOffset - kHeapObjectTag); |
+ RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, |
+ fp_mode); |
+ CallStub(&stub); |
+ if (lr_status == kLRHasNotBeenSaved) { |
+ Pop(lr); |
+ } |
+ |
+ Bind(&done); |
+ |
+ // Clobber clobbered registers when running with the debug-code flag |
+ // turned on to provoke errors. |
+ if (emit_debug_code()) { |
+ Mov(dst, Operand(BitCast<int64_t>(kZapValue + 12))); |
+ Mov(map, Operand(BitCast<int64_t>(kZapValue + 16))); |
+ } |
+} |
+ |
+ |
// Will clobber: object, address, value. |
// If lr_status is kLRHasBeenSaved, lr will also be clobbered. |
// |
// The register 'object' contains a heap object pointer. The heap object tag is |
// shifted away. |
-void MacroAssembler::RecordWrite(Register object, |
- Register address, |
- Register value, |
- LinkRegisterStatus lr_status, |
- SaveFPRegsMode fp_mode, |
- RememberedSetAction remembered_set_action, |
- SmiCheck smi_check) { |
+void MacroAssembler::RecordWrite( |
+ Register object, |
+ Register address, |
+ Register value, |
+ LinkRegisterStatus lr_status, |
+ SaveFPRegsMode fp_mode, |
+ RememberedSetAction remembered_set_action, |
+ SmiCheck smi_check, |
+ PointersToHereCheck pointers_to_here_check_for_value) { |
ASM_LOCATION("MacroAssembler::RecordWrite"); |
ASSERT(!AreAliased(object, value)); |
@@ -4351,10 +4426,12 @@ void MacroAssembler::RecordWrite(Register object, |
JumpIfSmi(value, &done); |
} |
- CheckPageFlagClear(value, |
- value, // Used as scratch. |
- MemoryChunk::kPointersToHereAreInterestingMask, |
- &done); |
+ if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { |
+ CheckPageFlagClear(value, |
+ value, // Used as scratch. |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ &done); |
+ } |
CheckPageFlagClear(object, |
value, // Used as scratch. |
MemoryChunk::kPointersFromHereAreInterestingMask, |