Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index 5b649e3fb423459a19add214af9444b7e50734f8..f0b09ad0c0a6b18971c4e814f8f6230e11ef31b6 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -453,7 +453,8 @@ void MacroAssembler::RecordWriteField( |
LinkRegisterStatus lr_status, |
SaveFPRegsMode save_fp, |
RememberedSetAction remembered_set_action, |
- SmiCheck smi_check) { |
+ SmiCheck smi_check, |
+ bool value_is_in_new_space) { |
// First, check if a write barrier is even needed. The tests below |
// catch stores of Smis. |
Label done; |
@@ -482,7 +483,8 @@ void MacroAssembler::RecordWriteField( |
lr_status, |
save_fp, |
remembered_set_action, |
- OMIT_SMI_CHECK); |
+ OMIT_SMI_CHECK, |
+ value_is_in_new_space); |
bind(&done); |
@@ -495,6 +497,72 @@ void MacroAssembler::RecordWriteField( |
} |
+// Will clobber 4 registers: object, map, dst, ip. The |
+// register 'object' contains a heap object pointer. |
+void MacroAssembler::RecordWriteForMap(Register object, |
+ Register map, |
+ Register dst, |
+ LinkRegisterStatus lr_status, |
+ SaveFPRegsMode fp_mode) { |
+ Label done; |
+ |
+ if (emit_debug_code()) { |
+ ldr(dst, FieldMemOperand(map, HeapObject::kMapOffset)); |
+ cmp(dst, Operand(isolate()->factory()->meta_map())); |
+ Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
+ } |
+ |
+ // Count number of write barriers in generated code. |
+ isolate()->counters()->write_barriers_static()->Increment(); |
+ // TODO(mstarzinger): Dynamic counter missing. |
Hannes Payer (out of office)
2014/06/03 05:51:48
why TODO?
Benedikt Meurer
2014/06/03 07:48:02
I just copied the TODO.
|
+ |
+ if (emit_debug_code()) { |
+ ldr(ip, FieldMemOperand(object, HeapObject::kMapOffset)); |
+ cmp(ip, map); |
+ Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
+ } |
+ |
+ // 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. |
+ CheckPageFlag(map, |
+ map, // Used as scratch. |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ eq, |
+ &done); |
+ |
+ add(dst, object, Operand(HeapObject::kMapOffset - kHeapObjectTag)); |
+ if (emit_debug_code()) { |
+ Label ok; |
+ tst(dst, Operand((1 << kPointerSizeLog2) - 1)); |
+ b(eq, &ok); |
+ stop("Unaligned cell in write barrier"); |
+ bind(&ok); |
+ } |
+ |
+ // Record the actual write. |
+ if (lr_status == kLRHasNotBeenSaved) { |
+ push(lr); |
+ } |
+ 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<int32_t>(kZapValue + 12))); |
+ mov(map, Operand(BitCast<int32_t>(kZapValue + 16))); |
+ } |
+} |
+ |
+ |
// Will clobber 4 registers: object, address, scratch, ip. The |
// register 'object' contains a heap object pointer. The heap object |
// tag is shifted away. |
@@ -504,7 +572,8 @@ void MacroAssembler::RecordWrite(Register object, |
LinkRegisterStatus lr_status, |
SaveFPRegsMode fp_mode, |
RememberedSetAction remembered_set_action, |
- SmiCheck smi_check) { |
+ SmiCheck smi_check, |
+ bool value_is_in_new_space) { |
ASSERT(!object.is(value)); |
if (emit_debug_code()) { |
ldr(ip, MemOperand(address)); |
@@ -524,11 +593,13 @@ void MacroAssembler::RecordWrite(Register object, |
JumpIfSmi(value, &done); |
} |
- CheckPageFlag(value, |
- value, // Used as scratch. |
- MemoryChunk::kPointersToHereAreInterestingMask, |
- eq, |
- &done); |
+ if (!value_is_in_new_space) { |
+ CheckPageFlag(value, |
+ value, // Used as scratch. |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ eq, |
+ &done); |
+ } |
CheckPageFlag(object, |
value, // Used as scratch. |
MemoryChunk::kPointersFromHereAreInterestingMask, |