| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 1a768fbc920ec6116bda538e741d205ce41744ae..bf9e0b403e39a10b1064a726b799d3b3d53634c7 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -4755,6 +4755,49 @@ void Heap::IterateSmiRoots(ObjectVisitor* v) {
|
| v->Synchronize(VisitorSynchronization::kSmiRootList);
|
| }
|
|
|
| +// We cannot avoid stale handles to left-trimmed objects, but can only make
|
| +// sure all handles still needed are updated. Filter out a stale pointer
|
| +// and clear the slot to allow post processing of handles (needed because
|
| +// the sweeper might actually free the underlying page).
|
| +class FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor {
|
| + public:
|
| + explicit FixStaleLeftTrimmedHandlesVisitor(Heap* heap) : heap_(heap) {
|
| + USE(heap_);
|
| + }
|
| +
|
| + void VisitPointer(Object** p) override { FixHandle(p); }
|
| +
|
| + void VisitPointers(Object** start, Object** end) override {
|
| + for (Object** p = start; p < end; p++) FixHandle(p);
|
| + }
|
| +
|
| + private:
|
| + inline void FixHandle(Object** p) {
|
| + HeapObject* current = reinterpret_cast<HeapObject*>(*p);
|
| + if (!current->IsHeapObject()) return;
|
| + const MapWord map_word = current->map_word();
|
| + if (!map_word.IsForwardingAddress() && current->IsFiller()) {
|
| +#ifdef DEBUG
|
| + // We need to find a FixedArrayBase map after walking the fillers.
|
| + while (current->IsFiller()) {
|
| + Address next = reinterpret_cast<Address>(current);
|
| + if (current->map() == heap_->one_pointer_filler_map()) {
|
| + next += kPointerSize;
|
| + } else if (current->map() == heap_->two_pointer_filler_map()) {
|
| + next += 2 * kPointerSize;
|
| + } else {
|
| + next += current->Size();
|
| + }
|
| + current = reinterpret_cast<HeapObject*>(next);
|
| + }
|
| + DCHECK(current->IsFixedArrayBase());
|
| +#endif // DEBUG
|
| + *p = nullptr;
|
| + }
|
| + }
|
| +
|
| + Heap* heap_;
|
| +};
|
|
|
| void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
|
| v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
|
| @@ -4777,6 +4820,8 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
|
| v->Synchronize(VisitorSynchronization::kCompilationCache);
|
|
|
| // Iterate over local handles in handle scopes.
|
| + FixStaleLeftTrimmedHandlesVisitor left_trim_visitor(this);
|
| + isolate_->handle_scope_implementer()->Iterate(&left_trim_visitor);
|
| isolate_->handle_scope_implementer()->Iterate(v);
|
| isolate_->IterateDeferredHandles(v);
|
| v->Synchronize(VisitorSynchronization::kHandleScope);
|
|
|