Reviewers: Jakob,
Description:
Filter out slot buffer slots, that point to SMIs in dead objects.
The following situation may happen which reproduces this bug:
(1) We allocate JSObject A on an evacuation candidate.
(2) We allocate JSObject B on a non-evacuation candidate.
(3) Incremental marking starts and marks object A and B.
(4) We create a reference from B.field = A; which records the slot B.field
since
A is on an evacuation candidate.
(5) After that we write a SMI into B.field.
(6) After that B goes into dictionary mode and shrinks its original size.
B.field is now outside of the JSOBject, i.e B.field is in memory that will
be
freed by the sweeper threads.
(7) GC is triggered.
(8) BUG: Slots buffer filtering walks over the slots buffer, SMIs are not
filtered out because we assumed that SMIs are just ignored when the slots
get
updated later. However, recorded SMI slots of dead objects may be
overwritten by
double values at evacuation time.
(9) During evacuation, a heap number that looks like a valid pointer is
moved
over B.field.
(10) The slots buffer is scanned for updates, follows B.field since it looks
like a pointer (the double value looks like a pointer), and crashes.
BUG=chromium:519577,chromium:454297
Please review this at https://codereview.chromium.org/1286343004/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+4, -6 lines):
M src/heap/mark-compact.cc
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index
e34dbfd2337cc0bec932e2729d51ae1aeb5d1787..61db9d88320171d1961818068ffc83b8512472e3
100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -4504,12 +4504,10 @@ void SlotsBuffer::RemoveInvalidSlots(Heap* heap,
SlotsBuffer* buffer) {
ObjectSlot slot = slots[slot_idx];
if (!IsTypedSlot(slot)) {
Object* object = *slot;
- if (object->IsHeapObject()) {
- if (heap->InNewSpace(object) ||
- !heap->mark_compact_collector()->IsSlotInLiveObject(
- reinterpret_cast<Address>(slot))) {
- slots[slot_idx] = kRemovedEntry;
- }
+ if ((object->IsHeapObject() && heap->InNewSpace(object)) ||
+ !heap->mark_compact_collector()->IsSlotInLiveObject(
+ reinterpret_cast<Address>(slot))) {
+ slots[slot_idx] = kRemovedEntry;
}
} else {
++slot_idx;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.