| Index: src/x64/macro-assembler-x64.cc
|
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
|
| index af4f7b59cef3a8692458f345dcd47bd454b34e8b..8ff6e63f07a2cd75c008482930315fb369320f01 100644
|
| --- a/src/x64/macro-assembler-x64.cc
|
| +++ b/src/x64/macro-assembler-x64.cc
|
| @@ -292,7 +292,8 @@ void MacroAssembler::RecordWriteField(
|
| Register dst,
|
| SaveFPRegsMode save_fp,
|
| RememberedSetAction remembered_set_action,
|
| - SmiCheck smi_check) {
|
| + SmiCheck smi_check,
|
| + PointersToHereCheck pointers_to_here_check_for_value) {
|
| // First, check if a write barrier is even needed. The tests below
|
| // catch stores of Smis.
|
| Label done;
|
| @@ -315,8 +316,8 @@ void MacroAssembler::RecordWriteField(
|
| bind(&ok);
|
| }
|
|
|
| - RecordWrite(
|
| - object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK);
|
| + RecordWrite(object, dst, value, save_fp, remembered_set_action,
|
| + OMIT_SMI_CHECK, pointers_to_here_check_for_value);
|
|
|
| bind(&done);
|
|
|
| @@ -329,12 +330,14 @@ void MacroAssembler::RecordWriteField(
|
| }
|
|
|
|
|
| -void MacroAssembler::RecordWriteArray(Register object,
|
| - Register value,
|
| - Register index,
|
| - SaveFPRegsMode save_fp,
|
| - RememberedSetAction remembered_set_action,
|
| - SmiCheck smi_check) {
|
| +void MacroAssembler::RecordWriteArray(
|
| + Register object,
|
| + Register value,
|
| + Register index,
|
| + SaveFPRegsMode save_fp,
|
| + RememberedSetAction remembered_set_action,
|
| + SmiCheck smi_check,
|
| + PointersToHereCheck pointers_to_here_check_for_value) {
|
| // First, check if a write barrier is even needed. The tests below
|
| // catch stores of Smis.
|
| Label done;
|
| @@ -349,8 +352,8 @@ void MacroAssembler::RecordWriteArray(Register object,
|
| leap(dst, Operand(object, index, times_pointer_size,
|
| FixedArray::kHeaderSize - kHeapObjectTag));
|
|
|
| - RecordWrite(
|
| - object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK);
|
| + RecordWrite(object, dst, value, save_fp, remembered_set_action,
|
| + OMIT_SMI_CHECK, pointers_to_here_check_for_value);
|
|
|
| bind(&done);
|
|
|
| @@ -363,12 +366,85 @@ void MacroAssembler::RecordWriteArray(Register object,
|
| }
|
|
|
|
|
| -void MacroAssembler::RecordWrite(Register object,
|
| - Register address,
|
| - Register value,
|
| - SaveFPRegsMode fp_mode,
|
| - RememberedSetAction remembered_set_action,
|
| - SmiCheck smi_check) {
|
| +void MacroAssembler::RecordWriteForMap(Register object,
|
| + Register map,
|
| + Register dst,
|
| + SaveFPRegsMode fp_mode) {
|
| + ASSERT(!object.is(kScratchRegister));
|
| + ASSERT(!object.is(map));
|
| + ASSERT(!object.is(dst));
|
| + ASSERT(!map.is(dst));
|
| + AssertNotSmi(object);
|
| +
|
| + if (emit_debug_code()) {
|
| + Label ok;
|
| + if (map.is(kScratchRegister)) pushq(map);
|
| + CompareMap(map, isolate()->factory()->meta_map());
|
| + if (map.is(kScratchRegister)) popq(map);
|
| + j(equal, &ok, Label::kNear);
|
| + int3();
|
| + bind(&ok);
|
| + }
|
| +
|
| + if (!FLAG_incremental_marking) {
|
| + return;
|
| + }
|
| +
|
| + if (emit_debug_code()) {
|
| + Label ok;
|
| + if (map.is(kScratchRegister)) pushq(map);
|
| + cmpp(map, FieldOperand(object, HeapObject::kMapOffset));
|
| + if (map.is(kScratchRegister)) popq(map);
|
| + j(equal, &ok, Label::kNear);
|
| + int3();
|
| + bind(&ok);
|
| + }
|
| +
|
| + // Compute the address.
|
| + leap(dst, FieldOperand(object, HeapObject::kMapOffset));
|
| +
|
| + // Count number of write barriers in generated code.
|
| + isolate()->counters()->write_barriers_static()->Increment();
|
| + IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
|
| +
|
| + // First, check if a write barrier is even needed. The tests below
|
| + // catch stores of smis and stores into the young generation.
|
| + 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,
|
| + zero,
|
| + &done,
|
| + Label::kNear);
|
| +
|
| + RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
|
| + fp_mode);
|
| + CallStub(&stub);
|
| +
|
| + bind(&done);
|
| +
|
| + // Clobber clobbered registers when running with the debug-code flag
|
| + // turned on to provoke errors.
|
| + if (emit_debug_code()) {
|
| + Move(dst, kZapValue, Assembler::RelocInfoNone());
|
| + Move(map, kZapValue, Assembler::RelocInfoNone());
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::RecordWrite(
|
| + Register object,
|
| + Register address,
|
| + Register value,
|
| + SaveFPRegsMode fp_mode,
|
| + RememberedSetAction remembered_set_action,
|
| + SmiCheck smi_check,
|
| + PointersToHereCheck pointers_to_here_check_for_value) {
|
| ASSERT(!object.is(value));
|
| ASSERT(!object.is(address));
|
| ASSERT(!value.is(address));
|
| @@ -400,12 +476,14 @@ void MacroAssembler::RecordWrite(Register object,
|
| JumpIfSmi(value, &done);
|
| }
|
|
|
| - CheckPageFlag(value,
|
| - value, // Used as scratch.
|
| - MemoryChunk::kPointersToHereAreInterestingMask,
|
| - zero,
|
| - &done,
|
| - Label::kNear);
|
| + if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
|
| + CheckPageFlag(value,
|
| + value, // Used as scratch.
|
| + MemoryChunk::kPointersToHereAreInterestingMask,
|
| + zero,
|
| + &done,
|
| + Label::kNear);
|
| + }
|
|
|
| CheckPageFlag(object,
|
| value, // Used as scratch.
|
|
|