Chromium Code Reviews| 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, |