| 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,
|
|
|