@@ -3117,10 +3117,6 @@ FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
31173117 DCHECK (!lo_space ()->Contains (object));
31183118 DCHECK (object->map () != fixed_cow_array_map ());
31193119
3120- // Ensure that the no handle-scope has more than one pointer to the same
3121- // backing-store.
3122- SLOW_DCHECK (CountHandlesForObject (object) <= 1 );
3123-
31243120 STATIC_ASSERT (FixedArrayBase::kMapOffset == 0 );
31253121 STATIC_ASSERT (FixedArrayBase::kLengthOffset == kPointerSize );
31263122 STATIC_ASSERT (FixedArrayBase::kHeaderSize == 2 * kPointerSize );
@@ -4763,6 +4759,49 @@ void Heap::IterateSmiRoots(ObjectVisitor* v) {
47634759 v->Synchronize (VisitorSynchronization::kSmiRootList );
47644760}
47654761
4762+ // We cannot avoid stale handles to left-trimmed objects, but can only make
4763+ // sure all handles still needed are updated. Filter out a stale pointer
4764+ // and clear the slot to allow post processing of handles (needed because
4765+ // the sweeper might actually free the underlying page).
4766+ class FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor {
4767+ public:
4768+ explicit FixStaleLeftTrimmedHandlesVisitor (Heap* heap) : heap_(heap) {
4769+ USE (heap_);
4770+ }
4771+
4772+ void VisitPointer (Object** p) override { FixHandle (p); }
4773+
4774+ void VisitPointers (Object** start, Object** end) override {
4775+ for (Object** p = start; p < end; p++) FixHandle (p);
4776+ }
4777+
4778+ private:
4779+ inline void FixHandle (Object** p) {
4780+ HeapObject* current = reinterpret_cast <HeapObject*>(*p);
4781+ if (!current->IsHeapObject ()) return ;
4782+ const MapWord map_word = current->map_word ();
4783+ if (!map_word.IsForwardingAddress () && current->IsFiller ()) {
4784+ #ifdef DEBUG
4785+ // We need to find a FixedArrayBase map after walking the fillers.
4786+ while (current->IsFiller ()) {
4787+ Address next = reinterpret_cast <Address>(current);
4788+ if (current->map () == heap_->one_pointer_filler_map ()) {
4789+ next += kPointerSize ;
4790+ } else if (current->map () == heap_->two_pointer_filler_map ()) {
4791+ next += 2 * kPointerSize ;
4792+ } else {
4793+ next += current->Size ();
4794+ }
4795+ current = reinterpret_cast <HeapObject*>(next);
4796+ }
4797+ DCHECK (current->IsFixedArrayBase ());
4798+ #endif // DEBUG
4799+ *p = nullptr ;
4800+ }
4801+ }
4802+
4803+ Heap* heap_;
4804+ };
47664805
47674806void Heap::IterateStrongRoots (ObjectVisitor* v, VisitMode mode) {
47684807 v->VisitPointers (&roots_[0 ], &roots_[kStrongRootListLength ]);
@@ -4783,6 +4822,8 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
47834822 v->Synchronize (VisitorSynchronization::kCompilationCache );
47844823
47854824 // Iterate over local handles in handle scopes.
4825+ FixStaleLeftTrimmedHandlesVisitor left_trim_visitor (this );
4826+ isolate_->handle_scope_implementer ()->Iterate (&left_trim_visitor);
47864827 isolate_->handle_scope_implementer ()->Iterate (v);
47874828 isolate_->IterateDeferredHandles (v);
47884829 v->Synchronize (VisitorSynchronization::kHandleScope );
@@ -5632,32 +5673,6 @@ void Heap::PrintHandles() {
56325673
56335674#endif
56345675
5635- #ifdef ENABLE_SLOW_DCHECKS
5636-
5637- class CountHandleVisitor : public ObjectVisitor {
5638- public:
5639- explicit CountHandleVisitor (Object* object) : object_(object) {}
5640-
5641- void VisitPointers (Object** start, Object** end) override {
5642- for (Object** p = start; p < end; p++) {
5643- if (object_ == reinterpret_cast <Object*>(*p)) count_++;
5644- }
5645- }
5646-
5647- int count () { return count_; }
5648-
5649- private:
5650- Object* object_;
5651- int count_ = 0 ;
5652- };
5653-
5654- int Heap::CountHandlesForObject (Object* object) {
5655- CountHandleVisitor v (object);
5656- isolate_->handle_scope_implementer ()->Iterate (&v);
5657- return v.count ();
5658- }
5659- #endif
5660-
56615676class CheckHandleCountVisitor : public ObjectVisitor {
56625677 public:
56635678 CheckHandleCountVisitor () : handle_count_(0 ) {}
0 commit comments