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