X87: Improve write barriers in optimized code.

Port r21630 (a21ff10)

Original commit message:
Use a cheaper RecordWriteForMap() to update the
write barrier for maps. And skip the value check
in RecordWriteField() when we statically know that
the value is in new space (and therefore has "pointers
to here are interesting" flag set).

BUG=
R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/314983002

Patch from Chunyang Dai <chunyang.dai@intel.com>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21668 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
weiliang.lin@intel.com 2014-06-04 09:27:16 +00:00
parent a75a788928
commit eac091277f
3 changed files with 56 additions and 43 deletions

View File

@ -3904,20 +3904,14 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
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);
}
}
@ -3957,7 +3951,8 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
value,
temp,
EMIT_REMEMBERED_SET,
instr->hydrogen()->SmiCheckForWriteBarrier());
instr->hydrogen()->SmiCheckForWriteBarrier(),
instr->hydrogen()->PointersToHereCheckForValue());
}
}
@ -4155,7 +4150,8 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
key,
value,
EMIT_REMEMBERED_SET,
check_needed);
check_needed,
instr->hydrogen()->PointersToHereCheckForValue());
}
}

View File

@ -315,11 +315,13 @@ void MacroAssembler::LoadUint32NoSSE2(Register src) {
}
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;
@ -338,8 +340,8 @@ void MacroAssembler::RecordWriteArray(Register object,
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);
@ -358,7 +360,8 @@ void MacroAssembler::RecordWriteField(
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;
@ -381,8 +384,8 @@ void MacroAssembler::RecordWriteField(
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);
@ -422,6 +425,9 @@ void MacroAssembler::RecordWriteForMap(
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);
@ -437,12 +443,6 @@ void MacroAssembler::RecordWriteForMap(
&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);
@ -458,11 +458,13 @@ void MacroAssembler::RecordWriteForMap(
}
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));
@ -494,12 +496,14 @@ void MacroAssembler::RecordWrite(Register object,
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,

View File

@ -18,6 +18,10 @@ typedef Operand MemOperand;
enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
enum PointersToHereCheck {
kPointersToHereMaybeInteresting,
kPointersToHereAreAlwaysInteresting
};
enum RegisterValueType {
@ -138,7 +142,9 @@ class MacroAssembler: public Assembler {
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).
@ -148,13 +154,16 @@ class MacroAssembler: public Assembler {
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.
@ -168,7 +177,9 @@ class MacroAssembler: public Assembler {
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
@ -180,7 +191,9 @@ class MacroAssembler: public Assembler {
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