@@ -4755,6 +4755,49 @@ void Heap::IterateSmiRoots(ObjectVisitor* v) {
47554755 v->Synchronize (VisitorSynchronization::kSmiRootList );
47564756}
47574757
4758+ // We cannot avoid stale handles to left-trimmed objects, but can only make
4759+ // sure all handles still needed are updated. Filter out a stale pointer
4760+ // and clear the slot to allow post processing of handles (needed because
4761+ // the sweeper might actually free the underlying page).
4762+ class FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor {
4763+ public:
4764+ explicit FixStaleLeftTrimmedHandlesVisitor (Heap* heap) : heap_(heap) {
4765+ USE (heap_);
4766+ }
4767+
4768+ void VisitPointer (Object** p) override { FixHandle (p); }
4769+
4770+ void VisitPointers (Object** start, Object** end) override {
4771+ for (Object** p = start; p < end; p++) FixHandle (p);
4772+ }
4773+
4774+ private:
4775+ inline void FixHandle (Object** p) {
4776+ HeapObject* current = reinterpret_cast <HeapObject*>(*p);
4777+ if (!current->IsHeapObject ()) return ;
4778+ const MapWord map_word = current->map_word ();
4779+ if (!map_word.IsForwardingAddress () && current->IsFiller ()) {
4780+ #ifdef DEBUG
4781+ // We need to find a FixedArrayBase map after walking the fillers.
4782+ while (current->IsFiller ()) {
4783+ Address next = reinterpret_cast <Address>(current);
4784+ if (current->map () == heap_->one_pointer_filler_map ()) {
4785+ next += kPointerSize ;
4786+ } else if (current->map () == heap_->two_pointer_filler_map ()) {
4787+ next += 2 * kPointerSize ;
4788+ } else {
4789+ next += current->Size ();
4790+ }
4791+ current = reinterpret_cast <HeapObject*>(next);
4792+ }
4793+ DCHECK (current->IsFixedArrayBase ());
4794+ #endif // DEBUG
4795+ *p = nullptr ;
4796+ }
4797+ }
4798+
4799+ Heap* heap_;
4800+ };
47584801
47594802void Heap::IterateStrongRoots (ObjectVisitor* v, VisitMode mode) {
47604803 v->VisitPointers (&roots_[0 ], &roots_[kStrongRootListLength ]);
@@ -4777,6 +4820,8 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
47774820 v->Synchronize (VisitorSynchronization::kCompilationCache );
47784821
47794822 // Iterate over local handles in handle scopes.
4823+ FixStaleLeftTrimmedHandlesVisitor left_trim_visitor (this );
4824+ isolate_->handle_scope_implementer ()->Iterate (&left_trim_visitor);
47804825 isolate_->handle_scope_implementer ()->Iterate (v);
47814826 isolate_->IterateDeferredHandles (v);
47824827 v->Synchronize (VisitorSynchronization::kHandleScope );
0 commit comments