Revision: 12134
Author:   [email protected]
Date:     Wed Jul 18 07:15:02 2012
Log:      The deferred handes list belongs to the Isolate and not to the
HandleScopeImplementer (since it isn't something specific to a
particular thread executing on an Isolate). This patch ensures correct
traversal of the handles when when multiple compilations are queued
up.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10778036
http://code.google.com/p/v8/source/detail?r=12134

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/api.h
 /branches/bleeding_edge/src/handles.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h

=======================================
--- /branches/bleeding_edge/src/api.cc  Tue Jul 17 08:18:15 2012
+++ /branches/bleeding_edge/src/api.cc  Wed Jul 18 07:15:02 2012
@@ -6422,12 +6422,6 @@
     Object** start = reinterpret_cast<Object**>(&saved_contexts_.first());
     v->VisitPointers(start, start + saved_contexts_.length());
   }
-
-  for (DeferredHandles* deferred = deferred_handles_head_;
-       deferred != NULL;
-       deferred = deferred->next_) {
-    deferred->Iterate(v);
-  }
 }


@@ -6448,8 +6442,8 @@


 DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
-  DeferredHandles* deferred = new DeferredHandles(
-      deferred_handles_head_, isolate()->handle_scope_data()->next, this);
+  DeferredHandles* deferred =
+      new DeferredHandles(isolate()->handle_scope_data()->next, isolate());

   while (!blocks_.is_empty()) {
     Object** block_start = blocks_.last();
@@ -6470,39 +6464,10 @@
   ASSERT(prev_limit == NULL || !blocks_.is_empty());

   ASSERT(!blocks_.is_empty() && prev_limit != NULL);
-  deferred_handles_head_ = deferred;
   ASSERT(last_handle_before_deferred_block_ != NULL);
   last_handle_before_deferred_block_ = NULL;
   return deferred;
 }
-
-
-void HandleScopeImplementer::DestroyDeferredHandles(DeferredHandles* deferred) {
-#ifdef DEBUG
-  DeferredHandles* deferred_iterator = deferred;
-  while (deferred_iterator->previous_ != NULL) {
-    deferred_iterator = deferred_iterator->previous_;
-  }
-  ASSERT(deferred_handles_head_ == deferred_iterator);
-#endif
-  if (deferred_handles_head_ == deferred) {
-    deferred_handles_head_ = deferred_handles_head_->next_;
-  }
-  if (deferred->next_ != NULL) {
-    deferred->next_->previous_ = deferred->previous_;
-  }
-  if (deferred->previous_ != NULL) {
-    deferred->previous_->next_ = deferred->next_;
-  }
-  for (int i = 0; i < deferred->blocks_.length(); i++) {
-#ifdef DEBUG
-    HandleScope::ZapRange(deferred->blocks_[i],
-                          &deferred->blocks_[i][kHandleBlockSize]);
-#endif
-    if (spare_ != NULL) DeleteArray(spare_);
-    spare_ = deferred->blocks_[i];
-  }
-}


 void HandleScopeImplementer::BeginDeferredScope() {
@@ -6512,7 +6477,14 @@


 DeferredHandles::~DeferredHandles() {
-  impl_->DestroyDeferredHandles(this);
+  isolate_->UnlinkDeferredHandles(this);
+
+  for (int i = 0; i < blocks_.length(); i++) {
+#ifdef DEBUG
+    HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
+#endif
+    isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
+  }
 }


=======================================
--- /branches/bleeding_edge/src/api.h   Thu Jul 12 00:59:41 2012
+++ /branches/bleeding_edge/src/api.h   Wed Jul 18 07:15:02 2012
@@ -397,13 +397,12 @@
   ~DeferredHandles();

  private:
-  DeferredHandles(DeferredHandles* next, Object** first_block_limit,
-                  HandleScopeImplementer* impl)
-      : next_(next),
+  DeferredHandles(Object** first_block_limit, Isolate* isolate)
+      : next_(NULL),
         previous_(NULL),
         first_block_limit_(first_block_limit),
-        impl_(impl) {
-    if (next != NULL) next->previous_ = this;
+        isolate_(isolate) {
+    isolate->LinkDeferredHandles(this);
   }

   void Iterate(ObjectVisitor* v);
@@ -412,9 +411,10 @@
   DeferredHandles* next_;
   DeferredHandles* previous_;
   Object** first_block_limit_;
-  HandleScopeImplementer* impl_;
+  Isolate* isolate_;

   friend class HandleScopeImplementer;
+  friend class Isolate;
 };


@@ -436,8 +436,7 @@
         saved_contexts_(0),
         spare_(NULL),
         call_depth_(0),
-        last_handle_before_deferred_block_(NULL),
-        deferred_handles_head_(NULL) { }
+        last_handle_before_deferred_block_(NULL) { }

   ~HandleScopeImplementer() {
     DeleteArray(spare_);
@@ -474,6 +473,12 @@

   inline List<internal::Object**>* blocks() { return &blocks_; }
   Isolate* isolate() const { return isolate_; }
+
+  void ReturnBlock(Object** block) {
+    ASSERT(block != NULL);
+    if (spare_ != NULL) DeleteArray(spare_);
+    spare_ = block;
+  }

  private:
   void ResetAfterArchive() {
@@ -481,7 +486,6 @@
     entered_contexts_.Initialize(0);
     saved_contexts_.Initialize(0);
     spare_ = NULL;
-    deferred_handles_head_ = NULL;
     last_handle_before_deferred_block_ = NULL;
     call_depth_ = 0;
   }
@@ -490,7 +494,6 @@
     ASSERT(blocks_.length() == 0);
     ASSERT(entered_contexts_.length() == 0);
     ASSERT(saved_contexts_.length() == 0);
-    ASSERT(deferred_handles_head_ == NULL);
     blocks_.Free();
     entered_contexts_.Free();
     saved_contexts_.Free();
@@ -503,7 +506,6 @@

   void BeginDeferredScope();
   DeferredHandles* Detach(Object** prev_limit);
-  void DestroyDeferredHandles(DeferredHandles* handles);

   Isolate* isolate_;
   List<internal::Object**> blocks_;
@@ -514,7 +516,6 @@
   Object** spare_;
   int call_depth_;
   Object** last_handle_before_deferred_block_;
-  DeferredHandles* deferred_handles_head_;
   // This is only used for threading support.
   v8::ImplementationUtilities::HandleScopeData handle_scope_data_;

=======================================
--- /branches/bleeding_edge/src/handles.h       Tue Jul 10 04:04:38 2012
+++ /branches/bleeding_edge/src/handles.h       Wed Jul 18 07:15:02 2012
@@ -95,6 +95,7 @@
 };


+class DeferredHandles;
 class HandleScopeImplementer;


@@ -159,9 +160,11 @@
   // Zaps the handles in the half-open interval [start, end).
   static void ZapRange(internal::Object** start, internal::Object** end);

+  friend class v8::internal::DeferredHandles;
   friend class v8::HandleScope;
   friend class v8::internal::HandleScopeImplementer;
   friend class v8::ImplementationUtilities;
+  friend class v8::internal::Isolate;
 };


=======================================
--- /branches/bleeding_edge/src/heap.cc Tue Jul 17 07:04:41 2012
+++ /branches/bleeding_edge/src/heap.cc Wed Jul 18 07:15:02 2012
@@ -5698,6 +5698,7 @@

   // Iterate over local handles in handle scopes.
   isolate_->handle_scope_implementer()->Iterate(v);
+  isolate_->IterateDeferredHandles(v);
   v->Synchronize(VisitorSynchronization::kHandleScope);

   // Iterate over the builtin code objects and code stubs in the
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Fri Jul 13 00:22:11 2012
+++ /branches/bleeding_edge/src/isolate.cc      Wed Jul 18 07:15:02 2012
@@ -477,6 +477,14 @@
   Iterate(v, current_t);
 }

+void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) {
+  for (DeferredHandles* deferred = deferred_handles_head_;
+       deferred != NULL;
+       deferred = deferred->next_) {
+    deferred->Iterate(visitor);
+  }
+}
+

 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
   // The ARM simulator has a separate JS stack.  We therefore register
@@ -1484,7 +1492,8 @@
       string_tracker_(NULL),
       regexp_stack_(NULL),
       date_cache_(NULL),
-      context_exit_happened_(false) {
+      context_exit_happened_(false),
+      deferred_handles_head_(NULL) {
   TRACE_ISOLATE(constructor);

   memset(isolate_addresses_, 0,
@@ -1987,6 +1996,36 @@
// Reinit the current thread for the isolate it was running before this one.
   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
 }
+
+
+void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
+  deferred->next_ = deferred_handles_head_;
+  if (deferred_handles_head_ != NULL) {
+    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_ != NULL) {
+    deferred_iterator = deferred_iterator->previous_;
+  }
+  ASSERT(deferred_handles_head_ == deferred_iterator);
+#endif
+  if (deferred_handles_head_ == deferred) {
+    deferred_handles_head_ = deferred_handles_head_->next_;
+  }
+  if (deferred->next_ != NULL) {
+    deferred->next_->previous_ = deferred->previous_;
+  }
+  if (deferred->previous_ != NULL) {
+    deferred->previous_->next_ = deferred->next_;
+  }
+}


 #ifdef DEBUG
=======================================
--- /branches/bleeding_edge/src/isolate.h       Thu Jul 12 08:01:39 2012
+++ /branches/bleeding_edge/src/isolate.h       Wed Jul 18 07:15:02 2012
@@ -1054,6 +1054,10 @@
     }
     date_cache_ = date_cache;
   }
+
+  void IterateDeferredHandles(ObjectVisitor* visitor);
+  void LinkDeferredHandles(DeferredHandles* deferred_handles);
+  void UnlinkDeferredHandles(DeferredHandles* deferred_handles);

  private:
   Isolate();
@@ -1278,6 +1282,8 @@
 #undef ISOLATE_FIELD_OFFSET
 #endif

+  DeferredHandles* deferred_handles_head_;
+
   friend class ExecutionAccess;
   friend class IsolateInitializer;
   friend class ThreadManager;

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to