Reviewers: jochen,

https://codereview.chromium.org/1209403005/diff/1/src/global-handles.cc
File src/global-handles.cc (right):

https://codereview.chromium.org/1209403005/diff/1/src/global-handles.cc#newcode525
src/global-handles.cc:525: };
On 2015/07/03 at 12:42:27, jochen wrote:
nit. DISALLOW_COPY_AND_ASSIGN(PendingPhantomCallbacksSecondPassTask)

Done.

Description:
Let the second pass phantom callbacks run in a separate task on the foreground
thread.

[email protected]
LOG=y
BUG=

Please review this at https://codereview.chromium.org/1209403005/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+61, -8 lines):
  M src/global-handles.h
  M src/global-handles.cc
  M src/list.h
  M src/list-inl.h
  M test/cctest/cctest.h
  M test/cctest/cctest.cc
  M test/cctest/test-api.cc


Index: src/global-handles.cc
diff --git a/src/global-handles.cc b/src/global-handles.cc
index aa6542baee922f8f4e517cd6764f8b8ed71290ee..af1aa7e48e3b478cd2db3b520ffd65fb394c50dd 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -495,6 +495,37 @@ class GlobalHandles::NodeIterator {
   DISALLOW_COPY_AND_ASSIGN(NodeIterator);
 };

+class GlobalHandles::PendingPhantomCallbacksSecondPassTask : public v8::Task {
+ public:
+ // Takes ownership of the contents of pending_phantom_callbacks, leaving it in
+  // the same state it would be after a call to Clear().
+  PendingPhantomCallbacksSecondPassTask(
+ List<PendingPhantomCallback>* pending_phantom_callbacks, Isolate* isolate)
+      : isolate_(isolate) {
+    pending_phantom_callbacks_.Swap(pending_phantom_callbacks);
+  }
+
+  ~PendingPhantomCallbacksSecondPassTask() override {}
+
+  void Run() override {
+    while (pending_phantom_callbacks_.length() != 0) {
+      auto callback = pending_phantom_callbacks_.RemoveLast();
+      DCHECK(callback.node() == nullptr);
+      // No second pass callback required.
+      if (callback.callback() == nullptr) continue;
+      // Fire second pass callback
+      callback.Invoke(isolate_);
+    }
+    pending_phantom_callbacks_.Clear();
+  }
+
+ private:
+  List<PendingPhantomCallback> pending_phantom_callbacks_;
+  Isolate* isolate_;
+
+  DISALLOW_COPY_AND_ASSIGN(PendingPhantomCallbacksSecondPassTask);
+};
+

 GlobalHandles::GlobalHandles(Isolate* isolate)
     : isolate_(isolate),
@@ -804,14 +835,11 @@ int GlobalHandles::DispatchPendingPhantomCallbacks() {
       freed_nodes++;
     }
   }
-  // The second pass empties the list.
-  while (pending_phantom_callbacks_.length() != 0) {
-    auto callback = pending_phantom_callbacks_.RemoveLast();
-    DCHECK(callback.node() == nullptr);
-    // No second pass callback required.
-    if (callback.callback() == nullptr) continue;
-    // Fire second pass callback.
-    callback.Invoke(isolate());
+  if (pending_phantom_callbacks_.length() > 0) {
+    auto* task = new PendingPhantomCallbacksSecondPassTask(
+        &pending_phantom_callbacks_, isolate());
+    V8::GetCurrentPlatform()->CallOnForegroundThread(
+        reinterpret_cast<v8::Isolate*>(isolate()), task);
   }
   pending_phantom_callbacks_.Clear();
   return freed_nodes;
Index: src/global-handles.h
diff --git a/src/global-handles.h b/src/global-handles.h
index 6724847303d4188ffdab4fb31c859a9b85d2a410..a620e2366441dfc2356dd5136c1007909a44e23d 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -298,6 +298,7 @@ class GlobalHandles {
   class NodeBlock;
   class NodeIterator;
   class PendingPhantomCallback;
+  class PendingPhantomCallbacksSecondPassTask;

   Isolate* isolate_;

Index: src/list-inl.h
diff --git a/src/list-inl.h b/src/list-inl.h
index 98f0343fa57f0b84aff9254bf6c1bed7b482e56a..47653ef145bdc0ae2b53a2a2004d4c96506672ee 100644
--- a/src/list-inl.h
+++ b/src/list-inl.h
@@ -125,6 +125,12 @@ bool List<T, P>::RemoveElement(const T& elm) {
   return false;
 }

+template <typename T, class P>
+void List<T, P>::Swap(List<T, P>* list) {
+  std::swap(data_, list->data_);
+  std::swap(length_, list->length_);
+  std::swap(capacity_, list->capacity_);
+}

 template<typename T, class P>
 void List<T, P>::Allocate(int length, P allocator) {
Index: src/list.h
diff --git a/src/list.h b/src/list.h
index b636449c423b9d9ea7a184de78a3580a49c5780e..8021a9fbed1e5d955cbf910107f1c26d948ab5f6 100644
--- a/src/list.h
+++ b/src/list.h
@@ -5,6 +5,8 @@
 #ifndef V8_LIST_H_
 #define V8_LIST_H_

+#include <algorithm>
+
 #include "src/checks.h"
 #include "src/utils.h"

@@ -137,6 +139,9 @@ class List {
   // Drop the last 'count' elements from the list.
   INLINE(void RewindBy(int count)) { Rewind(length_ - count); }

+  // Swaps the contents of the two lists.
+  INLINE(void Swap(List<T, AllocationPolicy>* list));
+
   // Halve the capacity if fill level is less than a quarter.
   INLINE(void Trim(AllocationPolicy allocator = AllocationPolicy()));

Index: test/cctest/cctest.cc
diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc
index b5771ff6550681526cda8cd6a9a3c36411645482..e722d37153134c18fa7d81dcd7155e30429db12e 100644
--- a/test/cctest/cctest.cc
+++ b/test/cctest/cctest.cc
@@ -97,6 +97,7 @@ void CcTest::Run() {
   }
   callback_();
   if (initialize_) {
+    EmptyMessageLoop(isolate_);
     isolate_->Exit();
   }
 }
Index: test/cctest/cctest.h
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index cc9edc801f5e268b17476178cea243b51cb2495b..d8288f8d1942c50f1e1ff02b02c1848b6940bab3 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -28,6 +28,7 @@
 #ifndef CCTEST_H_
 #define CCTEST_H_

+#include "include/libplatform/libplatform.h"
 #include "src/v8.h"

 #ifndef TEST
@@ -594,6 +595,13 @@ static inline void EnableDebugger() {
static inline void DisableDebugger() { v8::Debug::SetDebugEventListener(NULL); }


+static inline void EmptyMessageLoop(v8::Isolate* isolate) {
+ while (v8::platform::PumpMessageLoop(v8::internal::V8::GetCurrentPlatform(),
+                                       isolate))
+    ;
+}
+
+
 // Helper class for new allocations tracking and checking.
 // To use checking of JS allocations tracking in a test,
 // just create an instance of this class.
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1433b7bed6b86a6a1a664818e34bb47c786618de..a5131787e3dd324cde56f831105b170d03115196 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -3275,6 +3275,7 @@ TEST(TwoPassPhantomCallbacks) {
   }
   CHECK_EQ(static_cast<int>(kLength), instance_counter);
   CcTest::heap()->CollectAllGarbage();
+  EmptyMessageLoop(isolate);
   CHECK_EQ(0, instance_counter);
 }

@@ -3293,6 +3294,7 @@ TEST(TwoPassPhantomCallbacksNestedGc) {
   array[15]->MarkTriggerGc();
   CHECK_EQ(static_cast<int>(kLength), instance_counter);
   CcTest::heap()->CollectAllGarbage();
+  EmptyMessageLoop(isolate);
   CHECK_EQ(0, instance_counter);
 }

@@ -6806,6 +6808,7 @@ THREADED_TEST(GCFromWeakCallbacks) {
                             v8::WeakCallbackType::kParameter);
       object.handle.MarkIndependent();
       invoke_gc[outer_gc]();
+      EmptyMessageLoop(isolate);
       CHECK(object.flag);
     }
   }
@@ -11818,6 +11821,7 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
   handle3.SetWeak(&handle3, HandleCreatingCallback1,
                   v8::WeakCallbackType::kParameter);
   CcTest::heap()->CollectAllGarbage();
+  EmptyMessageLoop(isolate);
 }




--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to