Index: src/mark-compact.cc |
diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
index f04a8bcb9a64105a496b8e4926cc833d06b7bc3a..04c36f7f3039e9371fc641d0646963fcf3223215 100644 |
--- a/src/mark-compact.cc |
+++ b/src/mark-compact.cc |
@@ -2988,25 +2988,30 @@ class PointersUpdatingVisitor: public ObjectVisitor { |
}; |
-static void UpdatePointer(HeapObject** p, HeapObject* object) { |
- ASSERT(*p == object); |
- |
- Address old_addr = object->address(); |
- |
- Address new_addr = Memory::Address_at(old_addr); |
+static void UpdatePointer(HeapObject** address, HeapObject* object) { |
+ Address new_addr = Memory::Address_at(object->address()); |
// The new space sweep will overwrite the map word of dead objects |
// with NULL. In this case we do not need to transfer this entry to |
// the store buffer which we are rebuilding. |
+ // We perform the pointer update with a no barrier compare-and-swap. The |
+ // compare and swap may fail in the case where the pointer update tries to |
+ // update garbage memory which was concurrently accessed by the sweeper. |
if (new_addr != NULL) { |
- *p = HeapObject::FromAddress(new_addr); |
+ NoBarrier_CompareAndSwap( |
+ reinterpret_cast<AtomicWord*>(address), |
+ reinterpret_cast<AtomicWord>(object), |
+ reinterpret_cast<AtomicWord>(HeapObject::FromAddress(new_addr))); |
} else { |
// We have to zap this pointer, because the store buffer may overflow later, |
// and then we have to scan the entire heap and we don't want to find |
// spurious newspace pointers in the old space. |
// TODO(mstarzinger): This was changed to a sentinel value to track down |
// rare crashes, change it back to Smi::FromInt(0) later. |
- *p = reinterpret_cast<HeapObject*>(Smi::FromInt(0x0f100d00 >> 1)); // flood |
+ NoBarrier_CompareAndSwap( |
+ reinterpret_cast<AtomicWord*>(address), |
+ reinterpret_cast<AtomicWord>(object), |
+ reinterpret_cast<AtomicWord>(Smi::FromInt(0x0f100d00 >> 1))); |
} |
} |