Index: src/ia32/macro-assembler-ia32.cc |
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc |
index 1b614867cd4a1bfa29efda6623fd41cc5bece440..ee18a08845af111f719990e3d79a4b6d9366028c 100644 |
--- a/src/ia32/macro-assembler-ia32.cc |
+++ b/src/ia32/macro-assembler-ia32.cc |
@@ -237,6 +237,68 @@ void MacroAssembler::RecordWriteField( |
} |
+void MacroAssembler::RecordWriteForMap( |
+ Register object, |
+ Handle<Map> map, |
+ Register scratch1, |
+ Register scratch2, |
+ SaveFPRegsMode save_fp) { |
+ // First, check if a write barrier is even needed. The tests below |
+ // catch stores of Smis. |
Erik Corry
2012/06/06 11:04:26
Comment seems to be out of date.
|
+ Label done; |
+ |
+ Register address = scratch1; |
+ Register value = scratch2; |
+ if (emit_debug_code()) { |
+ Label ok; |
+ lea(address, FieldOperand(object, HeapObject::kMapOffset)); |
+ test_b(address, (1 << kPointerSizeLog2) - 1); |
+ j(zero, &ok, Label::kNear); |
+ int3(); |
+ bind(&ok); |
+ } |
+ |
+ ASSERT(!object.is(value)); |
+ ASSERT(!object.is(address)); |
+ ASSERT(!value.is(address)); |
+ if (emit_debug_code()) { |
+ AbortIfSmi(object); |
+ } |
+ |
+ if (!FLAG_incremental_marking) { |
+ return; |
+ } |
+ |
+ // A single check of the map's pages interesting flag suffices, since it is |
+ // only set during incremental collection, and it's guaranteed that the from |
+ // object's interesting flag is also set. |
Michael Starzinger
2012/06/06 09:41:17
Can we add to the comment that this relies on "map
danno
2012/06/06 10:58:28
Done.
|
+ CheckPageFlag(map, |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ zero, |
+ &done, |
+ Label::kNear); |
+ |
+ // Delay the initialization of |address| and |value| for the stub until it's |
+ // known that the will be needed. Up until this point their value are not |
+ // needed since they are embedded in the operands of instructions that need |
+ // them. |
+ lea(address, FieldOperand(object, HeapObject::kMapOffset)); |
+ mov(value, Immediate(map)); |
+ RecordWriteStub stub(object, value, address, OMIT_REMEMBERED_SET, save_fp); |
+ CallStub(&stub); |
+ |
+ bind(&done); |
+ |
+ // Clobber clobbered input registers when running with the debug-code flag |
+ // turned on to provoke errors. |
+ if (emit_debug_code()) { |
+ mov(value, Immediate(BitCast<int32_t>(kZapValue))); |
+ mov(scratch1, Immediate(BitCast<int32_t>(kZapValue))); |
+ mov(scratch2, Immediate(BitCast<int32_t>(kZapValue))); |
+ } |
+} |
+ |
+ |
void MacroAssembler::RecordWrite(Register object, |
Register address, |
Register value, |
@@ -2618,6 +2680,26 @@ void MacroAssembler::CheckPageFlag( |
} |
+void MacroAssembler::CheckPageFlag( |
+ Handle<Map> map, |
+ int mask, |
+ Condition cc, |
+ Label* condition_met, |
+ Label::Distance condition_met_distance) { |
+ ASSERT(cc == zero || cc == not_zero); |
+ uint32_t masked_address = reinterpret_cast<uint32_t>(*map) & |
+ ~Page::kPageAlignmentMask; |
+ Page* page = reinterpret_cast<Page*>(masked_address); |
Michael Starzinger
2012/06/06 09:41:17
Better use the following "Page* page = Page::FromA
danno
2012/06/06 10:58:28
Done.
|
+ ExternalReference reference(ExternalReference::page_flags(page)); |
+ if (mask < (1 << kBitsPerByte)) { |
+ test_b(Operand::StaticVariable(reference), static_cast<uint8_t>(mask)); |
+ } else { |
+ test(Operand::StaticVariable(reference), Immediate(mask)); |
+ } |
+ j(cc, condition_met, condition_met_distance); |
+} |
+ |
+ |
void MacroAssembler::JumpIfBlack(Register object, |
Register scratch0, |
Register scratch1, |