[heap] Remove DeferredHandles instrumentation

Now that we are using PersistentHandles, we don't need it anymore.

Bug: v8:7790
Change-Id: Id0b9d555191c00fb08dc2bb9099746076c5ad1b7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2332161
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: Dominik Inf├╝hr <dinfuehr@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69278}
diff --git a/include/v8.h b/include/v8.h
index f0f6472..4dec3c5 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -127,7 +127,6 @@
 class Arguments;
 template <typename T>
 class CustomArguments;
-class DeferredHandles;
 class FunctionCallbackArguments;
 class GlobalHandles;
 class Heap;
diff --git a/src/api/api.cc b/src/api/api.cc
index 0ce029a2..2ea9498 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -11153,33 +11153,6 @@
   return storage + ArchiveSpacePerThread();
 }
 
-std::unique_ptr<DeferredHandles> HandleScopeImplementer::Detach(
-    Address* prev_limit) {
-  std::unique_ptr<DeferredHandles> deferred(
-      new DeferredHandles(isolate()->handle_scope_data()->next, isolate()));
-  DCHECK_NOT_NULL(prev_limit);
-
-  while (!blocks_.empty()) {
-    Address* block_start = blocks_.back();
-    Address* block_limit = &block_start[kHandleBlockSize];
-    // We should not need to check for SealHandleScope here. Assert this.
-    DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
-                   prev_limit == block_limit);
-    if (prev_limit == block_limit) break;
-    deferred->blocks_.push_back(blocks_.back());
-    blocks_.pop_back();
-  }
-
-  // deferred->blocks_ now contains the blocks installed on the
-  // HandleScope stack since BeginDeferredScope was called, but in
-  // reverse order.
-  DCHECK(!blocks_.empty() && !deferred->blocks_.empty());
-
-  DCHECK_NOT_NULL(last_handle_before_deferred_block_);
-  last_handle_before_deferred_block_ = nullptr;
-  return deferred;
-}
-
 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
     Address* prev_limit) {
   std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
@@ -11222,40 +11195,6 @@
   last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
 }
 
-DeferredHandles::~DeferredHandles() {
-  isolate_->UnlinkDeferredHandles(this);
-
-  for (size_t i = 0; i < blocks_.size(); i++) {
-#ifdef ENABLE_HANDLE_ZAPPING
-    HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
-#endif
-    isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
-  }
-}
-
-void DeferredHandles::Iterate(RootVisitor* v) {
-  DCHECK(!blocks_.empty());
-
-  // Comparing pointers that do not point into the same array is undefined
-  // behavior, which means if we didn't cast everything to plain Address
-  // before comparing, the compiler would be allowed to assume that all
-  // comparisons evaluate to true and drop the entire check.
-  DCHECK((reinterpret_cast<Address>(first_block_limit_) >=
-          reinterpret_cast<Address>(blocks_.front())) &&
-         (reinterpret_cast<Address>(first_block_limit_) <=
-          reinterpret_cast<Address>(&(blocks_.front())[kHandleBlockSize])));
-
-  v->VisitRootPointers(Root::kHandleScope, nullptr,
-                       FullObjectSlot(blocks_.front()),
-                       FullObjectSlot(first_block_limit_));
-
-  for (size_t i = 1; i < blocks_.size(); i++) {
-    v->VisitRootPointers(Root::kHandleScope, nullptr,
-                         FullObjectSlot(blocks_[i]),
-                         FullObjectSlot(&blocks_[i][kHandleBlockSize]));
-  }
-}
-
 void InvokeAccessorGetterCallback(
     v8::Local<v8::Name> property,
     const v8::PropertyCallbackInfo<v8::Value>& info,
diff --git a/src/api/api.h b/src/api/api.h
index 8f0daaf..6c0ea8f 100644
--- a/src/api/api.h
+++ b/src/api/api.h
@@ -304,31 +304,6 @@
 
 class PersistentHandles;
 
-class V8_EXPORT_PRIVATE DeferredHandles {
- public:
-  ~DeferredHandles();
-
- private:
-  DeferredHandles(Address* first_block_limit, Isolate* isolate)
-      : next_(nullptr),
-        previous_(nullptr),
-        first_block_limit_(first_block_limit),
-        isolate_(isolate) {
-    isolate->LinkDeferredHandles(this);
-  }
-
-  void Iterate(RootVisitor* v);
-
-  std::vector<Address*> blocks_;
-  DeferredHandles* next_;
-  DeferredHandles* previous_;
-  Address* first_block_limit_;
-  Isolate* isolate_;
-
-  friend class HandleScopeImplementer;
-  friend class Isolate;
-};
-
 // This class is here in order to be able to declare it a friend of
 // HandleScope.  Moving these methods to be members of HandleScope would be
 // neat in some ways, but it would expose internal implementation details in
@@ -433,7 +408,6 @@
   }
 
   void BeginDeferredScope();
-  std::unique_ptr<DeferredHandles> Detach(Address* prev_limit);
   std::unique_ptr<PersistentHandles> DetachPersistent(Address* prev_limit);
 
   Isolate* isolate_;
@@ -458,8 +432,6 @@
   char* RestoreThreadHelper(char* from);
   char* ArchiveThreadHelper(char* to);
 
-  friend class DeferredHandles;
-  friend class DeferredHandleScope;
   friend class HandleScopeImplementerOffsets;
   friend class PersistentHandlesScope;
 
diff --git a/src/codegen/optimized-compilation-info.h b/src/codegen/optimized-compilation-info.h
index 02f016f..4d289d9 100644
--- a/src/codegen/optimized-compilation-info.h
+++ b/src/codegen/optimized-compilation-info.h
@@ -27,7 +27,6 @@
 
 namespace internal {
 
-class DeferredHandles;
 class FunctionLiteral;
 class Isolate;
 class JavaScriptFrame;
diff --git a/src/compiler-dispatcher/compiler-dispatcher.h b/src/compiler-dispatcher/compiler-dispatcher.h
index 108e3cc..21c7b8a 100644
--- a/src/compiler-dispatcher/compiler-dispatcher.h
+++ b/src/compiler-dispatcher/compiler-dispatcher.h
@@ -35,7 +35,6 @@
 class CancelableTaskManager;
 class UnoptimizedCompileJob;
 class CompilerDispatcherTracer;
-class DeferredHandles;
 class FunctionLiteral;
 class Isolate;
 class ParseInfo;
diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc
index 8862cc7..4e7f21f 100644
--- a/src/execution/isolate.cc
+++ b/src/execution/isolate.cc
@@ -517,40 +517,6 @@
   Iterate(v, current_t);
 }
 
-void Isolate::IterateDeferredHandles(RootVisitor* visitor) {
-  for (DeferredHandles* deferred = deferred_handles_head_; deferred != nullptr;
-       deferred = deferred->next_) {
-    deferred->Iterate(visitor);
-  }
-}
-
-#ifdef DEBUG
-bool Isolate::IsDeferredHandle(Address* handle) {
-  // Comparing unrelated pointers (not from the same array) is undefined
-  // behavior, so cast to Address before making arbitrary comparisons.
-  Address handle_as_address = reinterpret_cast<Address>(handle);
-  // Each DeferredHandles instance keeps the handles to one job in the
-  // concurrent recompilation queue, containing a list of blocks.  Each block
-  // contains kHandleBlockSize handles except for the first block, which may
-  // not be fully filled.
-  // We iterate through all the blocks to see whether the argument handle
-  // belongs to one of the blocks.  If so, it is deferred.
-  for (DeferredHandles* deferred = deferred_handles_head_; deferred != nullptr;
-       deferred = deferred->next_) {
-    std::vector<Address*>* blocks = &deferred->blocks_;
-    for (size_t i = 0; i < blocks->size(); i++) {
-      Address* block_limit = (i == 0) ? deferred->first_block_limit_
-                                      : blocks->at(i) + kHandleBlockSize;
-      if (reinterpret_cast<Address>(blocks->at(i)) <= handle_as_address &&
-          handle_as_address < reinterpret_cast<Address>(block_limit)) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-#endif  // DEBUG
-
 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
   thread_local_top()->try_catch_handler_ = that;
 }
@@ -3775,34 +3741,6 @@
   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
 }
 
-void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
-  deferred->next_ = deferred_handles_head_;
-  if (deferred_handles_head_ != nullptr) {
-    deferred_handles_head_->previous_ = deferred;
-  }
-  deferred_handles_head_ = deferred;
-}
-
-void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
-#ifdef DEBUG
-  // In debug mode assert that the linked list is well-formed.
-  DeferredHandles* deferred_iterator = deferred;
-  while (deferred_iterator->previous_ != nullptr) {
-    deferred_iterator = deferred_iterator->previous_;
-  }
-  DCHECK(deferred_handles_head_ == deferred_iterator);
-#endif
-  if (deferred_handles_head_ == deferred) {
-    deferred_handles_head_ = deferred_handles_head_->next_;
-  }
-  if (deferred->next_ != nullptr) {
-    deferred->next_->previous_ = deferred->previous_;
-  }
-  if (deferred->previous_ != nullptr) {
-    deferred->previous_->next_ = deferred->next_;
-  }
-}
-
 std::unique_ptr<PersistentHandles> Isolate::NewPersistentHandles() {
   return std::make_unique<PersistentHandles>(this);
 }
diff --git a/src/execution/isolate.h b/src/execution/isolate.h
index 57b519f..d4ea999 100644
--- a/src/execution/isolate.h
+++ b/src/execution/isolate.h
@@ -1224,10 +1224,6 @@
   // Returns true if array is the initial array prototype in any native context.
   bool IsAnyInitialArrayPrototype(Handle<JSArray> array);
 
-  void IterateDeferredHandles(RootVisitor* visitor);
-  void LinkDeferredHandles(DeferredHandles* deferred_handles);
-  void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
-
   std::unique_ptr<PersistentHandles> NewPersistentHandles();
 
   PersistentHandlesList* persistent_handles_list() {
@@ -1802,7 +1798,6 @@
 #undef ISOLATE_FIELD_OFFSET
 #endif
 
-  DeferredHandles* deferred_handles_head_ = nullptr;
   OptimizingCompileDispatcher* optimizing_compile_dispatcher_ = nullptr;
 
   std::unique_ptr<PersistentHandlesList> persistent_handles_list_;
diff --git a/src/handles/handles.cc b/src/handles/handles.cc
index af82c8f..e584995 100644
--- a/src/handles/handles.cc
+++ b/src/handles/handles.cc
@@ -169,45 +169,5 @@
   return *entry;
 }
 
-DeferredHandleScope::DeferredHandleScope(Isolate* isolate)
-    : impl_(isolate->handle_scope_implementer()) {
-  impl_->BeginDeferredScope();
-  HandleScopeData* data = impl_->isolate()->handle_scope_data();
-  Address* new_next = impl_->GetSpareOrNewBlock();
-  Address* new_limit = &new_next[kHandleBlockSize];
-  // Check that at least one HandleScope with at least one Handle in it exists,
-  // see the class description.
-  DCHECK(!impl_->blocks()->empty());
-  // Check that we are not in a SealHandleScope.
-  DCHECK(data->limit == &impl_->blocks()->back()[kHandleBlockSize]);
-  impl_->blocks()->push_back(new_next);
-
-#ifdef DEBUG
-  prev_level_ = data->level;
-#endif
-  data->level++;
-  prev_limit_ = data->limit;
-  prev_next_ = data->next;
-  data->next = new_next;
-  data->limit = new_limit;
-}
-
-DeferredHandleScope::~DeferredHandleScope() {
-  DCHECK(handles_detached_);
-  impl_->isolate()->handle_scope_data()->level--;
-  DCHECK_EQ(impl_->isolate()->handle_scope_data()->level, prev_level_);
-}
-
-std::unique_ptr<DeferredHandles> DeferredHandleScope::Detach() {
-  std::unique_ptr<DeferredHandles> deferred = impl_->Detach(prev_limit_);
-  HandleScopeData* data = impl_->isolate()->handle_scope_data();
-  data->next = prev_next_;
-  data->limit = prev_limit_;
-#ifdef DEBUG
-  handles_detached_ = true;
-#endif
-  return deferred;
-}
-
 }  // namespace internal
 }  // namespace v8
diff --git a/src/handles/handles.h b/src/handles/handles.h
index a84eba1..c21a86d 100644
--- a/src/handles/handles.h
+++ b/src/handles/handles.h
@@ -18,7 +18,6 @@
 namespace internal {
 
 // Forward declarations.
-class DeferredHandles;
 class HandleScopeImplementer;
 class Isolate;
 class LocalHeap;
@@ -260,8 +259,6 @@
 #endif
 
   friend class v8::HandleScope;
-  friend class DeferredHandles;
-  friend class DeferredHandleScope;
   friend class HandleScopeImplementer;
   friend class Isolate;
   friend class LocalHandles;
@@ -300,48 +297,6 @@
   friend class HandleScope;
 };
 
-// A DeferredHandleScope is a HandleScope in which handles are not destroyed
-// when the DeferredHandleScope is left. Instead the DeferredHandleScope has to
-// be detached with {Detach}, and the result of {Detach} has to be destroyed
-// explicitly. A DeferredHandleScope should only be used with the following
-// design pattern:
-// 1) Open a HandleScope (not a DeferredHandleScope).
-//    HandleScope scope(isolate_);
-// 2) Create handles.
-//    Handle<Object> h1 = handle(object1, isolate);
-//    Handle<Object> h2 = handle(object2, isolate);
-// 3) Open a DeferredHandleScope.
-//    DeferredHandleScope deferred_scope(isolate);
-// 4) Reopen handles which should be in the DeferredHandleScope, e.g only h1.
-//    h1 = handle(*h1, isolate);
-// 5) Detach the DeferredHandleScope.
-//    DeferredHandles* deferred_handles = deferred_scope.Detach();
-// 6) Destroy the deferred handles.
-//    delete deferred_handles;
-//
-// Note: A DeferredHandleScope must not be opened within a DeferredHandleScope.
-class V8_EXPORT_PRIVATE DeferredHandleScope final {
- public:
-  explicit DeferredHandleScope(Isolate* isolate);
-  // The DeferredHandles object returned stores the Handles created
-  // since the creation of this DeferredHandleScope.  The Handles are
-  // alive as long as the DeferredHandles object is alive.
-  std::unique_ptr<DeferredHandles> Detach();
-  ~DeferredHandleScope();
-
- private:
-  Address* prev_limit_;
-  Address* prev_next_;
-  HandleScopeImplementer* impl_;
-
-#ifdef DEBUG
-  bool handles_detached_ = false;
-  int prev_level_;
-#endif
-
-  friend class HandleScopeImplementer;
-};
-
 // Seal off the current HandleScope so that new handles can only be created
 // if a new HandleScope is entered.
 class SealHandleScope final {
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 63068ca..a096614 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -4582,10 +4582,6 @@
     isolate_->persistent_handles_list()->Iterate(&left_trim_visitor, isolate_);
     isolate_->persistent_handles_list()->Iterate(v, isolate_);
 
-    // TODO(solanes): Delete these two iterations once we delete all
-    // DeferredHandle uses.
-    isolate_->IterateDeferredHandles(&left_trim_visitor);
-    isolate_->IterateDeferredHandles(v);
     v->Synchronize(VisitorSynchronization::kHandleScope);
 
     if (options.contains(SkipRoot::kOldGeneration)) {
diff --git a/src/heap/off-thread-heap.cc b/src/heap/off-thread-heap.cc
index 584fe34..545150b 100644
--- a/src/heap/off-thread-heap.cc
+++ b/src/heap/off-thread-heap.cc
@@ -153,7 +153,7 @@
   //
   // TODO(leszeks): We might be able to create a HandleScope-compatible
   // structure off-thread and merge it into the current handle scope all in
-  // one go (DeferredHandles maybe?).
+  // one go (PersistentHandles maybe?).
   std::vector<std::pair<Handle<HeapObject>, Handle<Map>>> heap_object_handles;
   std::vector<Handle<Script>> script_handles;
   {
diff --git a/test/cctest/heap/test-heap.cc b/test/cctest/heap/test-heap.cc
index e769b7c..4d1dbd9 100644
--- a/test/cctest/heap/test-heap.cc
+++ b/test/cctest/heap/test-heap.cc
@@ -3747,8 +3747,7 @@
                          FullObjectSlot start, FullObjectSlot end) override {}
 };
 
-
-TEST(DeferredHandles) {
+TEST(PersistentHandles) {
   CcTest::InitializeVM();
   Isolate* isolate = CcTest::i_isolate();
   Heap* heap = isolate->heap();
@@ -3762,13 +3761,13 @@
   // Next handle would require a new block.
   CHECK(data->next == data->limit);
 
-  DeferredHandleScope deferred(isolate);
+  PersistentHandlesScope persistent(isolate);
   DummyVisitor visitor;
   isolate->handle_scope_implementer()->Iterate(&visitor);
-  deferred.Detach();
+  persistent.Detach();
 }
 
-static void TestFillersFromDeferredHandles(bool promote) {
+static void TestFillersFromPersistentHandles(bool promote) {
   // We assume that the fillers can only arise when left-trimming arrays.
   Isolate* isolate = CcTest::i_isolate();
   Heap* heap = isolate->heap();
@@ -3783,10 +3782,10 @@
   }
   CHECK(Heap::InYoungGeneration(*array));
 
-  DeferredHandleScope deferred_scope(isolate);
+  PersistentHandlesScope persistent_scope(isolate);
 
   // Trim the array three times to different sizes so all kinds of fillers are
-  // created and tracked by the deferred handles.
+  // created and tracked by the persistent handles.
   Handle<FixedArrayBase> filler_1 = Handle<FixedArrayBase>(*array, isolate);
   Handle<FixedArrayBase> filler_2 =
       Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_1, 1), isolate);
@@ -3795,7 +3794,8 @@
   Handle<FixedArrayBase> tail =
       Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_3, 3), isolate);
 
-  std::unique_ptr<DeferredHandles> deferred_handles(deferred_scope.Detach());
+  std::unique_ptr<PersistentHandles> persistent_handles(
+      persistent_scope.Detach());
 
   // GC should retain the trimmed array but drop all of the three fillers.
   CcTest::CollectGarbage(NEW_SPACE);
@@ -3810,14 +3810,14 @@
   CHECK(!filler_3->IsHeapObject());
 }
 
-TEST(DoNotEvacuateFillersFromDeferredHandles) {
+TEST(DoNotEvacuateFillersFromPersistentHandles) {
   if (FLAG_single_generation) return;
-  TestFillersFromDeferredHandles(false /*promote*/);
+  TestFillersFromPersistentHandles(false /*promote*/);
 }
 
-TEST(DoNotPromoteFillersFromDeferredHandles) {
+TEST(DoNotPromoteFillersFromPersistentHandles) {
   if (FLAG_single_generation) return;
-  TestFillersFromDeferredHandles(true /*promote*/);
+  TestFillersFromPersistentHandles(true /*promote*/);
 }
 
 TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {