Index: src/heap/heap.cc |
diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
index 5c8cd4528ac86115c632826d15db5e36b2e2bdde..c4eed9ce25d3f7955c1e36634755fd20173d0081 100644 |
--- a/src/heap/heap.cc |
+++ b/src/heap/heap.cc |
@@ -2038,7 +2038,17 @@ class ScavengingVisitor : public StaticVisitorBase { |
// Order is important: slot might be inside of the target if target |
// was allocated over a dead object and slot comes from the store |
// buffer. |
- *slot = target; |
+ |
+ // Unfortunately, the allocation can also write over the slot if the slot |
+ // was in free space and the allocation wrote free list data (such as the |
+ // free list map or entry size) over the slot. We guard against this by |
+ // checking that the slot still points to the object being moved. This |
+ // should be sufficient because neither the free list map nor the free |
+ // list entry size should look like a new space pointer (the former is an |
+ // old space pointer, the latter is word-aligned). |
+ if (*slot == object) { |
+ *slot = target; |
+ } |
MigrateObject(heap, object, target, object_size); |
if (object_contents == POINTER_OBJECT) { |