if (instr->hydrogen()->has_transition()) {
Handle<Map> transition = instr->hydrogen()->transition_map();
AddDeprecationDependency(transition);
- if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
- __ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
- } else {
+ __ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
+ if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
Register temp = ToRegister(instr->temp());
Register temp_map = ToRegister(instr->temp_map());
__ mov(temp_map, transition);
__ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
// Update the write barrier for the map field.
- __ RecordWriteField(object,
- HeapObject::kMapOffset,
- temp_map,
- temp,
- OMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
+ __ RecordWriteForMap(object, transition, temp_map, temp);
}
}
value,
temp,
EMIT_REMEMBERED_SET,
- instr->hydrogen()->SmiCheckForWriteBarrier());
+ instr->hydrogen()->SmiCheckForWriteBarrier(),
+ instr->hydrogen()->PointersToHereCheckForValue());
}
}
key,
value,
EMIT_REMEMBERED_SET,
- check_needed);
+ check_needed,
+ instr->hydrogen()->PointersToHereCheckForValue());
}
}
}
-void MacroAssembler::RecordWriteArray(Register object,
- Register value,
- Register index,
- RememberedSetAction remembered_set_action,
- SmiCheck smi_check) {
+void MacroAssembler::RecordWriteArray(
+ Register object,
+ Register value,
+ Register index,
+ 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;
lea(dst, Operand(object, index, times_half_pointer_size,
FixedArray::kHeaderSize - kHeapObjectTag));
- RecordWrite(
- object, dst, value, remembered_set_action, OMIT_SMI_CHECK);
+ RecordWrite(object, dst, value, remembered_set_action, OMIT_SMI_CHECK,
+ pointers_to_here_check_for_value);
bind(&done);
Register value,
Register dst,
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;
bind(&ok);
}
- RecordWrite(
- object, dst, value, remembered_set_action, OMIT_SMI_CHECK);
+ RecordWrite(object, dst, value, remembered_set_action, OMIT_SMI_CHECK,
+ pointers_to_here_check_for_value);
bind(&done);
return;
}
+ // Compute the address.
+ lea(address, 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);
&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 values 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(isolate(), object, value, address, OMIT_REMEMBERED_SET);
CallStub(&stub);
}
-void MacroAssembler::RecordWrite(Register object,
- Register address,
- Register value,
- RememberedSetAction remembered_set_action,
- SmiCheck smi_check) {
+void MacroAssembler::RecordWrite(
+ Register object,
+ Register address,
+ Register value,
+ 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));
JumpIfSmi(value, &done, Label::kNear);
}
- 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.
MemoryChunk::kPointersFromHereAreInterestingMask,
enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
+enum PointersToHereCheck {
+ kPointersToHereMaybeInteresting,
+ kPointersToHereAreAlwaysInteresting
+};
enum RegisterValueType {
Register value,
Register scratch,
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
- SmiCheck smi_check = INLINE_SMI_CHECK);
+ SmiCheck smi_check = INLINE_SMI_CHECK,
+ PointersToHereCheck pointers_to_here_check_for_value =
+ kPointersToHereMaybeInteresting);
// As above, but the offset has the tag presubtracted. For use with
// Operand(reg, off).
Register value,
Register scratch,
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
- SmiCheck smi_check = INLINE_SMI_CHECK) {
+ SmiCheck smi_check = INLINE_SMI_CHECK,
+ PointersToHereCheck pointers_to_here_check_for_value =
+ kPointersToHereMaybeInteresting) {
RecordWriteField(context,
offset + kHeapObjectTag,
value,
scratch,
remembered_set_action,
- smi_check);
+ smi_check,
+ pointers_to_here_check_for_value);
}
// Notify the garbage collector that we wrote a pointer into a fixed array.
Register value,
Register index,
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
- SmiCheck smi_check = INLINE_SMI_CHECK);
+ SmiCheck smi_check = INLINE_SMI_CHECK,
+ PointersToHereCheck pointers_to_here_check_for_value =
+ kPointersToHereMaybeInteresting);
// For page containing |object| mark region covering |address|
// dirty. |object| is the object being stored into, |value| is the
Register address,
Register value,
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
- SmiCheck smi_check = INLINE_SMI_CHECK);
+ SmiCheck smi_check = INLINE_SMI_CHECK,
+ PointersToHereCheck pointers_to_here_check_for_value =
+ kPointersToHereMaybeInteresting);
// For page containing |object| mark the region covering the object's map
// dirty. |object| is the object being stored into, |map| is the Map object