Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index bb6d298d32d9851069a5a4064e379db4c0caf30a..fd54221dec65a22f38b9ae5669bec559b0f66b5b 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -194,7 +194,8 @@ void MacroAssembler::RecordWriteField( |
RAStatus ra_status, |
SaveFPRegsMode save_fp, |
RememberedSetAction remembered_set_action, |
- SmiCheck smi_check) { |
+ SmiCheck smi_check, |
+ PointersToHereCheck pointers_to_here_check_for_value) { |
ASSERT(!AreAliased(value, dst, t8, object)); |
// First, check if a write barrier is even needed. The tests below |
// catch stores of Smis. |
@@ -224,7 +225,8 @@ void MacroAssembler::RecordWriteField( |
ra_status, |
save_fp, |
remembered_set_action, |
- OMIT_SMI_CHECK); |
+ OMIT_SMI_CHECK, |
+ pointers_to_here_check_for_value); |
bind(&done); |
@@ -237,16 +239,93 @@ 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, |
+ RAStatus ra_status, |
+ SaveFPRegsMode fp_mode) { |
+ if (emit_debug_code()) { |
+ ASSERT(!dst.is(at)); |
+ lw(dst, FieldMemOperand(map, HeapObject::kMapOffset)); |
+ Check(eq, |
+ kWrongAddressOrValuePassedToRecordWrite, |
+ dst, |
+ Operand(isolate()->factory()->meta_map())); |
+ } |
+ |
+ if (!FLAG_incremental_marking) { |
+ return; |
+ } |
+ |
+ // Count number of write barriers in generated code. |
+ isolate()->counters()->write_barriers_static()->Increment(); |
+ // TODO(mstarzinger): Dynamic counter missing. |
+ |
+ if (emit_debug_code()) { |
+ lw(at, FieldMemOperand(object, HeapObject::kMapOffset)); |
+ Check(eq, |
+ kWrongAddressOrValuePassedToRecordWrite, |
+ map, |
+ Operand(at)); |
+ } |
+ |
+ 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. |
+ CheckPageFlag(map, |
+ map, // Used as scratch. |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ eq, |
+ &done); |
+ |
+ Addu(dst, object, Operand(HeapObject::kMapOffset - kHeapObjectTag)); |
+ if (emit_debug_code()) { |
+ Label ok; |
+ And(at, dst, Operand((1 << kPointerSizeLog2) - 1)); |
+ Branch(&ok, eq, at, Operand(zero_reg)); |
+ stop("Unaligned cell in write barrier"); |
+ bind(&ok); |
+ } |
+ |
+ // Record the actual write. |
+ if (ra_status == kRAHasNotBeenSaved) { |
+ push(ra); |
+ } |
+ RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, |
+ fp_mode); |
+ CallStub(&stub); |
+ if (ra_status == kRAHasNotBeenSaved) { |
+ pop(ra); |
+ } |
+ |
+ bind(&done); |
+ |
+ // Clobber clobbered registers when running with the debug-code flag |
+ // turned on to provoke errors. |
+ if (emit_debug_code()) { |
+ li(dst, Operand(BitCast<int32_t>(kZapValue + 12))); |
+ li(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. |
-void MacroAssembler::RecordWrite(Register object, |
- Register address, |
- Register value, |
- RAStatus ra_status, |
- SaveFPRegsMode fp_mode, |
- RememberedSetAction remembered_set_action, |
- SmiCheck smi_check) { |
+void MacroAssembler::RecordWrite( |
+ Register object, |
+ Register address, |
+ Register value, |
+ RAStatus ra_status, |
+ SaveFPRegsMode fp_mode, |
+ RememberedSetAction remembered_set_action, |
+ SmiCheck smi_check, |
+ PointersToHereCheck pointers_to_here_check_for_value) { |
ASSERT(!AreAliased(object, address, value, t8)); |
ASSERT(!AreAliased(object, address, value, t9)); |
@@ -256,6 +335,11 @@ void MacroAssembler::RecordWrite(Register object, |
eq, kWrongAddressOrValuePassedToRecordWrite, at, Operand(value)); |
} |
+ if (remembered_set_action == OMIT_REMEMBERED_SET && |
+ !FLAG_incremental_marking) { |
+ return; |
+ } |
+ |
// Count number of write barriers in generated code. |
isolate()->counters()->write_barriers_static()->Increment(); |
// TODO(mstarzinger): Dynamic counter missing. |
@@ -269,11 +353,13 @@ void MacroAssembler::RecordWrite(Register object, |
JumpIfSmi(value, &done); |
} |
- CheckPageFlag(value, |
- value, // Used as scratch. |
- MemoryChunk::kPointersToHereAreInterestingMask, |
- eq, |
- &done); |
+ if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { |
+ CheckPageFlag(value, |
+ value, // Used as scratch. |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ eq, |
+ &done); |
+ } |
CheckPageFlag(object, |
value, // Used as scratch. |
MemoryChunk::kPointersFromHereAreInterestingMask, |