Removed unsafe optimization in RecordWrite.
Optimization was only unsafe if new-space was in the low half of memory and an object could be located in the top half at an addressed that only differ from a new-space address by the high bit. Review URL: http://codereview.chromium.org/159784 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2608 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fd8b376989
commit
0e11fbcd79
@ -226,7 +226,9 @@ enum ScaleFactor {
|
|||||||
times_1 = 0,
|
times_1 = 0,
|
||||||
times_2 = 1,
|
times_2 = 1,
|
||||||
times_4 = 2,
|
times_4 = 2,
|
||||||
times_8 = 3
|
times_8 = 3,
|
||||||
|
times_pointer_size = times_4,
|
||||||
|
times_half_pointer_size = times_2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,43 +146,30 @@ void MacroAssembler::RecordWrite(Register object, int offset,
|
|||||||
// for the remembered set bits.
|
// for the remembered set bits.
|
||||||
Label done;
|
Label done;
|
||||||
|
|
||||||
// This optimization cannot survive serialization and deserialization,
|
// Skip barrier if writing a smi.
|
||||||
// so we disable as long as serialization can take place.
|
ASSERT_EQ(0, kSmiTag);
|
||||||
int32_t new_space_start =
|
test(value, Immediate(kSmiTagMask));
|
||||||
reinterpret_cast<int32_t>(ExternalReference::new_space_start().address());
|
j(zero, &done);
|
||||||
if (Serializer::enabled() || new_space_start < 0) {
|
|
||||||
// Cannot do smart bit-twiddling. Need to do two consecutive checks.
|
if (Serializer::enabled()) {
|
||||||
// Check for Smi first.
|
// Can't do arithmetic on external references if it might get serialized.
|
||||||
test(value, Immediate(kSmiTagMask));
|
|
||||||
j(zero, &done);
|
|
||||||
// Test that the object address is not in the new space. We cannot
|
|
||||||
// set remembered set bits in the new space.
|
|
||||||
mov(value, Operand(object));
|
mov(value, Operand(object));
|
||||||
and_(value, Heap::NewSpaceMask());
|
and_(value, Heap::NewSpaceMask());
|
||||||
cmp(Operand(value), Immediate(ExternalReference::new_space_start()));
|
cmp(Operand(value), Immediate(ExternalReference::new_space_start()));
|
||||||
j(equal, &done);
|
j(equal, &done);
|
||||||
} else {
|
} else {
|
||||||
// move the value SmiTag into the sign bit
|
int32_t new_space_start = reinterpret_cast<int32_t>(
|
||||||
shl(value, 31);
|
ExternalReference::new_space_start().address());
|
||||||
// combine the object with value SmiTag
|
lea(value, Operand(object, -new_space_start));
|
||||||
or_(value, Operand(object));
|
and_(value, Heap::NewSpaceMask());
|
||||||
// remove the uninteresing bits inside the page
|
j(equal, &done);
|
||||||
and_(value, Heap::NewSpaceMask() | (1 << 31));
|
|
||||||
// xor has two effects:
|
|
||||||
// - if the value was a smi, then the result will be negative
|
|
||||||
// - if the object is pointing into new space area the page bits will
|
|
||||||
// all be zero
|
|
||||||
xor_(value, new_space_start | (1 << 31));
|
|
||||||
// Check for both conditions in one branch
|
|
||||||
j(less_equal, &done);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) {
|
if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) {
|
||||||
// Compute the bit offset in the remembered set, leave it in 'value'.
|
// Compute the bit offset in the remembered set, leave it in 'value'.
|
||||||
mov(value, Operand(object));
|
lea(value, Operand(object, offset));
|
||||||
and_(value, Page::kPageAlignmentMask);
|
and_(value, Page::kPageAlignmentMask);
|
||||||
add(Operand(value), Immediate(offset));
|
shr(value, kPointerSizeLog2);
|
||||||
shr(value, kObjectAlignmentBits);
|
|
||||||
|
|
||||||
// Compute the page address from the heap object pointer, leave it in
|
// Compute the page address from the heap object pointer, leave it in
|
||||||
// 'object'.
|
// 'object'.
|
||||||
@ -192,7 +179,7 @@ void MacroAssembler::RecordWrite(Register object, int offset,
|
|||||||
// to limit code size. We should probably evaluate this decision by
|
// to limit code size. We should probably evaluate this decision by
|
||||||
// measuring the performance of an equivalent implementation using
|
// measuring the performance of an equivalent implementation using
|
||||||
// "simpler" instructions
|
// "simpler" instructions
|
||||||
bts(Operand(object, 0), value);
|
bts(Operand(object, Page::kRSetOffset), value);
|
||||||
} else {
|
} else {
|
||||||
Register dst = scratch;
|
Register dst = scratch;
|
||||||
if (offset != 0) {
|
if (offset != 0) {
|
||||||
@ -201,7 +188,9 @@ void MacroAssembler::RecordWrite(Register object, int offset,
|
|||||||
// array access: calculate the destination address in the same manner as
|
// array access: calculate the destination address in the same manner as
|
||||||
// KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
|
// KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
|
||||||
// into an array of words.
|
// into an array of words.
|
||||||
lea(dst, Operand(object, dst, times_2,
|
ASSERT_EQ(1, kSmiTagSize);
|
||||||
|
ASSERT_EQ(0, kSmiTag);
|
||||||
|
lea(dst, Operand(object, dst, times_half_pointer_size,
|
||||||
FixedArray::kHeaderSize - kHeapObjectTag));
|
FixedArray::kHeaderSize - kHeapObjectTag));
|
||||||
}
|
}
|
||||||
// If we are already generating a shared stub, not inlining the
|
// If we are already generating a shared stub, not inlining the
|
||||||
|
Loading…
Reference in New Issue
Block a user