Index: src/ia32/macro-assembler-ia32.cc |
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc |
index fae15251ec2e8a33345da7f05badf2d8e3eae618..de0ef8ece9b27c84f0eab2b5d08fb80dbcde1ae1 100644 |
--- a/src/ia32/macro-assembler-ia32.cc |
+++ b/src/ia32/macro-assembler-ia32.cc |
@@ -146,43 +146,30 @@ void MacroAssembler::RecordWrite(Register object, int offset, |
// for the remembered set bits. |
Label done; |
- // This optimization cannot survive serialization and deserialization, |
- // so we disable as long as serialization can take place. |
- int32_t new_space_start = |
- reinterpret_cast<int32_t>(ExternalReference::new_space_start().address()); |
- if (Serializer::enabled() || new_space_start < 0) { |
- // Cannot do smart bit-twiddling. Need to do two consecutive checks. |
- // Check for Smi first. |
- 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. |
+ // Skip barrier if writing a smi. |
+ ASSERT_EQ(0, kSmiTag); |
+ test(value, Immediate(kSmiTagMask)); |
+ j(zero, &done); |
+ |
+ if (Serializer::enabled()) { |
+ // Can't do arithmetic on external references if it might get serialized. |
mov(value, Operand(object)); |
and_(value, Heap::NewSpaceMask()); |
cmp(Operand(value), Immediate(ExternalReference::new_space_start())); |
j(equal, &done); |
} else { |
- // move the value SmiTag into the sign bit |
- shl(value, 31); |
- // combine the object with value SmiTag |
- or_(value, Operand(object)); |
- // remove the uninteresing bits inside the page |
- 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); |
+ int32_t new_space_start = reinterpret_cast<int32_t>( |
+ ExternalReference::new_space_start().address()); |
+ lea(value, Operand(object, -new_space_start)); |
+ and_(value, Heap::NewSpaceMask()); |
+ j(equal, &done); |
} |
if ((offset > 0) && (offset < Page::kMaxHeapObjectSize)) { |
// 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); |
- add(Operand(value), Immediate(offset)); |
- shr(value, kObjectAlignmentBits); |
+ shr(value, kPointerSizeLog2); |
// Compute the page address from the heap object pointer, leave it in |
// 'object'. |
@@ -192,7 +179,7 @@ void MacroAssembler::RecordWrite(Register object, int offset, |
// to limit code size. We should probably evaluate this decision by |
// measuring the performance of an equivalent implementation using |
// "simpler" instructions |
- bts(Operand(object, 0), value); |
+ bts(Operand(object, Page::kRSetOffset), value); |
} else { |
Register dst = scratch; |
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 |
// KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset |
// 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)); |
} |
// If we are already generating a shared stub, not inlining the |