Skip to content

Commit 7a88ff3

Browse files
mlippautzCommit bot
authored andcommitted
[heap] Filter out stale left-trimmed handles for scavenges
The missing part from https://codereview.chromium.org/2078403002/ [email protected] BUG=chromium:621869 LOG=N Review-Url: https://codereview.chromium.org/2077353004 Cr-Commit-Position: refs/heads/master@{#37184}
1 parent d4d4703 commit 7a88ff3

7 files changed

Lines changed: 55 additions & 28 deletions

File tree

src/heap/heap-inl.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,31 @@ void Heap::CopyBlock(Address dst, Address src, int byte_size) {
476476
static_cast<size_t>(byte_size / kPointerSize));
477477
}
478478

479+
bool Heap::PurgeLeftTrimmedObject(Object** object) {
480+
HeapObject* current = reinterpret_cast<HeapObject*>(*object);
481+
const MapWord map_word = current->map_word();
482+
if (current->IsFiller() && !map_word.IsForwardingAddress()) {
483+
#ifdef DEBUG
484+
// We need to find a FixedArrayBase map after walking the fillers.
485+
while (current->IsFiller()) {
486+
Address next = reinterpret_cast<Address>(current);
487+
if (current->map() == one_pointer_filler_map()) {
488+
next += kPointerSize;
489+
} else if (current->map() == two_pointer_filler_map()) {
490+
next += 2 * kPointerSize;
491+
} else {
492+
next += current->Size();
493+
}
494+
current = reinterpret_cast<HeapObject*>(next);
495+
}
496+
DCHECK(current->IsFixedArrayBase());
497+
#endif // DEBUG
498+
*object = nullptr;
499+
return true;
500+
}
501+
return false;
502+
}
503+
479504
template <Heap::FindMementoMode mode>
480505
AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) {
481506
// Check if there is potentially a memento behind the object. If

src/heap/heap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,12 @@ class Heap {
626626
// stored on the map to facilitate fast dispatch for {StaticVisitorBase}.
627627
static int GetStaticVisitorIdForMap(Map* map);
628628

629+
// We cannot avoid stale handles to left-trimmed objects, but can only make
630+
// sure all handles still needed are updated. Filter out a stale pointer
631+
// and clear the slot to allow post processing of handles (needed because
632+
// the sweeper might actually free the underlying page).
633+
inline bool PurgeLeftTrimmedObject(Object** object);
634+
629635
// Notifies the heap that is ok to start marking or other activities that
630636
// should not happen during deserialization.
631637
void NotifyDeserializationComplete();

src/heap/mark-compact.cc

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,31 +1435,7 @@ class RootMarkingVisitor : public ObjectVisitor {
14351435

14361436
HeapObject* object = HeapObject::cast(*p);
14371437

1438-
// We cannot avoid stale handles to left-trimmed objects, but can only make
1439-
// sure all handles still needed are updated. Filter out any stale pointers
1440-
// and clear the slot to allow post processing of handles (needed because
1441-
// the sweeper might actually free the underlying page).
1442-
if (object->IsFiller()) {
1443-
#ifdef DEBUG
1444-
// We need to find a FixedArrayBase map after walking the fillers.
1445-
Heap* heap = collector_->heap();
1446-
HeapObject* current = object;
1447-
while (current->IsFiller()) {
1448-
Address next = reinterpret_cast<Address>(current);
1449-
if (current->map() == heap->one_pointer_filler_map()) {
1450-
next += kPointerSize;
1451-
} else if (current->map() == heap->two_pointer_filler_map()) {
1452-
next += 2 * kPointerSize;
1453-
} else {
1454-
next += current->Size();
1455-
}
1456-
current = reinterpret_cast<HeapObject*>(next);
1457-
}
1458-
DCHECK(current->IsFixedArrayBase());
1459-
#endif // DEBUG
1460-
*p = nullptr;
1461-
return;
1462-
}
1438+
if (collector_->heap()->PurgeLeftTrimmedObject(p)) return;
14631439

14641440
MarkBit mark_bit = Marking::MarkBitFrom(object);
14651441
if (Marking::IsBlackOrGrey(mark_bit)) return;

src/heap/scavenger.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ void ScavengeVisitor::VisitPointers(Object** start, Object** end) {
444444
void ScavengeVisitor::ScavengePointer(Object** p) {
445445
Object* object = *p;
446446
if (!heap_->InNewSpace(object)) return;
447+
448+
if (heap_->PurgeLeftTrimmedObject(p)) return;
449+
447450
Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p),
448451
reinterpret_cast<HeapObject*>(object));
449452
}

src/objects-inl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,8 +1274,7 @@ Map* MapWord::ToMap() {
12741274
return reinterpret_cast<Map*>(value_);
12751275
}
12761276

1277-
1278-
bool MapWord::IsForwardingAddress() {
1277+
bool MapWord::IsForwardingAddress() const {
12791278
return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
12801279
}
12811280

src/objects.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,7 @@ class MapWord BASE_EMBEDDED {
14901490
// True if this map word is a forwarding address for a scavenge
14911491
// collection. Only valid during a scavenge collection (specifically,
14921492
// when all map words are heap object pointers, i.e. not during a full GC).
1493-
inline bool IsForwardingAddress();
1493+
inline bool IsForwardingAddress() const;
14941494

14951495
// Create a map word from a forwarding address.
14961496
static inline MapWord FromForwardingAddress(HeapObject* object);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --expose-gc
6+
7+
var o0 = [];
8+
var o1 = [];
9+
var cnt = 0;
10+
var only_scavenge = true;
11+
o1.__defineGetter__(0, function() {
12+
if (cnt++ > 2) return;
13+
o0.shift();
14+
gc(only_scavenge);
15+
o0.push((64));
16+
o0.concat(o1);
17+
});
18+
o1[0];

0 commit comments

Comments
 (0)