Revision: 21128
Author:   [email protected]
Date:     Fri May  2 19:30:54 2014 UTC
Log: Introduce a microtask suppression scope and move microtask methods to isolate

BUG=369503
[email protected]
LOG=y
TEST=cctest/test-api/SetAutorunMicrotasks

Review URL: https://codereview.chromium.org/263933002
http://code.google.com/p/v8/source/detail?r=21128

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/v8.cc
 /branches/bleeding_edge/src/v8.h
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/cctest/test-microtask-delivery.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Tue Apr 29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/include/v8.h        Fri May  2 19:30:54 2014 UTC
@@ -4112,6 +4112,24 @@
         const AllowJavascriptExecutionScope&);
   };

+  /**
+ * Do not run microtasks while this scope is active, even if microtasks are
+   * automatically executed otherwise.
+   */
+  class V8_EXPORT SuppressMicrotaskExecutionScope {
+   public:
+    explicit SuppressMicrotaskExecutionScope(Isolate* isolate);
+    ~SuppressMicrotaskExecutionScope();
+
+   private:
+    internal::Isolate* isolate_;
+
+    // Prevent copying of Scope objects.
+ SuppressMicrotaskExecutionScope(const SuppressMicrotaskExecutionScope&);
+    SuppressMicrotaskExecutionScope& operator=(
+        const SuppressMicrotaskExecutionScope&);
+  };
+
   /**
    * Types of garbage collections that can be requested via
    * RequestGarbageCollectionForTesting.
@@ -4361,6 +4379,22 @@
    */
   void RemoveCallCompletedCallback(CallCompletedCallback callback);

+  /**
+   * Experimental: Runs the Microtask Work Queue until empty
+   */
+  void RunMicrotasks();
+
+  /**
+   * Experimental: Enqueues the callback to the Microtask Work Queue
+   */
+  void EnqueueMicrotask(Handle<Function> microtask);
+
+   /**
+ * Experimental: Controls whether the Microtask Work Queue is automatically
+   * run when the script call depth decrements to zero.
+   */
+  void SetAutorunMicrotasks(bool autorun);
+
  private:
   template<class K, class V, class Traits> friend class PersistentValueMap;

@@ -4724,17 +4758,23 @@

   /**
    * Experimental: Runs the Microtask Work Queue until empty
+   *
+   * Deprecated: Use methods on Isolate instead.
    */
   static void RunMicrotasks(Isolate* isolate);

   /**
    * Experimental: Enqueues the callback to the Microtask Work Queue
+   *
+   * Deprecated: Use methods on Isolate instead.
    */
static void EnqueueMicrotask(Isolate* isolate, Handle<Function> microtask);

    /**
* Experimental: Controls whether the Microtask Work Queue is automatically
    * run when the script call depth decrements to zero.
+   *
+   * Deprecated: Use methods on Isolate instead.
    */
   static void SetAutorunMicrotasks(Isolate *source, bool autorun);

=======================================
--- /branches/bleeding_edge/src/api.cc  Fri May  2 13:55:11 2014 UTC
+++ /branches/bleeding_edge/src/api.cc  Fri May  2 19:30:54 2014 UTC
@@ -6455,21 +6455,17 @@


 void V8::RunMicrotasks(Isolate* isolate) {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  i::HandleScope scope(i_isolate);
-  i::V8::RunMicrotasks(i_isolate);
+  isolate->RunMicrotasks();
 }


 void V8::EnqueueMicrotask(Isolate* isolate, Handle<Function> microtask) {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  ENTER_V8(i_isolate);
-  i::Execution::EnqueueMicrotask(i_isolate, Utils::OpenHandle(*microtask));
+  isolate->EnqueueMicrotask(microtask);
 }


 void V8::SetAutorunMicrotasks(Isolate* isolate, bool autorun) {
-  reinterpret_cast<i::Isolate*>(isolate)->set_autorun_microtasks(autorun);
+  isolate->SetAutorunMicrotasks(autorun);
 }


@@ -6591,6 +6587,18 @@
   delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
 }
+
+
+Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
+    Isolate* isolate)
+    : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
+  isolate_->handle_scope_implementer()->IncrementCallDepth();
+}
+
+
+Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
+  isolate_->handle_scope_implementer()->DecrementCallDepth();
+}


 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
@@ -6630,6 +6638,25 @@
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   isolate->RemoveCallCompletedCallback(callback);
 }
+
+
+void Isolate::RunMicrotasks() {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
+  i::HandleScope scope(i_isolate);
+  i_isolate->RunMicrotasks();
+}
+
+
+void Isolate::EnqueueMicrotask(Handle<Function> microtask) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
+  ENTER_V8(i_isolate);
+  i::Execution::EnqueueMicrotask(i_isolate, Utils::OpenHandle(*microtask));
+}
+
+
+void Isolate::SetAutorunMicrotasks(bool autorun) {
+  reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
+}


 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Wed Apr 30 15:17:51 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc      Fri May  2 19:30:54 2014 UTC
@@ -2250,6 +2250,19 @@
   }
   handle_scope_implementer()->DecrementCallDepth();
 }
+
+
+void Isolate::RunMicrotasks() {
+  if (!microtask_pending())
+    return;
+
+  ASSERT(handle_scope_implementer()->CallDepthIsZero());
+
+  // Increase call depth to prevent recursive callbacks.
+  handle_scope_implementer()->IncrementCallDepth();
+  Execution::RunMicrotasks(this);
+  handle_scope_implementer()->DecrementCallDepth();
+}


 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/isolate.h       Wed Apr 30 12:25:18 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h       Fri May  2 19:30:54 2014 UTC
@@ -1077,6 +1077,8 @@
   void RemoveCallCompletedCallback(CallCompletedCallback callback);
   void FireCallCompletedCallback();

+  void RunMicrotasks();
+
  private:
   Isolate();

=======================================
--- /branches/bleeding_edge/src/v8.cc   Fri May  2 10:14:37 2014 UTC
+++ /branches/bleeding_edge/src/v8.cc   Fri May  2 19:30:54 2014 UTC
@@ -85,21 +85,6 @@
       ReturnAddressLocationResolver resolver) {
   StackFrame::SetReturnAddressLocationResolver(resolver);
 }
-
-
-void V8::RunMicrotasks(Isolate* isolate) {
-  if (!isolate->microtask_pending())
-    return;
-
-  HandleScopeImplementer* handle_scope_implementer =
-      isolate->handle_scope_implementer();
-  ASSERT(handle_scope_implementer->CallDepthIsZero());
-
-  // Increase call depth to prevent recursive callbacks.
-  handle_scope_implementer->IncrementCallDepth();
-  Execution::RunMicrotasks(isolate);
-  handle_scope_implementer->DecrementCallDepth();
-}


 void V8::InitializeOncePerProcessImpl() {
=======================================
--- /branches/bleeding_edge/src/v8.h    Tue Apr 29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/v8.h    Fri May  2 19:30:54 2014 UTC
@@ -75,8 +75,6 @@
   // Support for entry hooking JITed code.
   static void SetFunctionEntryHook(FunctionEntryHook entry_hook);

-  static void RunMicrotasks(Isolate* isolate);
-
   static v8::ArrayBuffer::Allocator* ArrayBufferAllocator() {
     return array_buffer_allocator_;
   }
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Mon Apr 28 13:42:03 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Fri May 2 19:30:54 2014 UTC
@@ -20717,22 +20717,22 @@
   CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());

-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskOne));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskOne));
   CompileRun("1+1;");
   CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());

-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskOne));
-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskTwo));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskOne));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskTwo));
   CompileRun("1+1;");
   CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());

-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskTwo));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskTwo));
   CompileRun("1+1;");
   CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
@@ -20753,41 +20753,54 @@
   CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());

-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskOne));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskOne));
   CompileRun("1+1;");
   CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());

-  V8::SetAutorunMicrotasks(env->GetIsolate(), false);
-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskOne));
-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskTwo));
+  env->GetIsolate()->SetAutorunMicrotasks(false);
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskOne));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskTwo));
   CompileRun("1+1;");
   CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());

-  V8::RunMicrotasks(env->GetIsolate());
+  env->GetIsolate()->RunMicrotasks();
   CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());

-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskTwo));
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskTwo));
   CompileRun("1+1;");
   CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());

-  V8::RunMicrotasks(env->GetIsolate());
+  env->GetIsolate()->RunMicrotasks();
   CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());

-  V8::SetAutorunMicrotasks(env->GetIsolate(), true);
-  v8::V8::EnqueueMicrotask(env->GetIsolate(),
-                           Function::New(env->GetIsolate(), MicrotaskTwo));
+  env->GetIsolate()->SetAutorunMicrotasks(true);
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskTwo));
   CompileRun("1+1;");
   CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
   CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+
+  env->GetIsolate()->EnqueueMicrotask(
+      Function::New(env->GetIsolate(), MicrotaskTwo));
+  {
+    v8::Isolate::SuppressMicrotaskExecutionScope scope(env->GetIsolate());
+    CompileRun("1+1;");
+    CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+    CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+  }
+
+  CompileRun("1+1;");
+  CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+  CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value());
 }


@@ -22342,20 +22355,20 @@

   p->Chain(f1);
   CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());

   p->Catch(f2);
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());

   r->Catch(f2);
   CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(2, global->Get(v8_str("x2"))->Int32Value());

   r->Chain(f1);
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());

   // Chaining pending promises.
@@ -22365,7 +22378,7 @@

   pr->GetPromise()->Chain(f1);
   rr->GetPromise()->Catch(f2);
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());

@@ -22374,7 +22387,7 @@
   CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());

-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(2, global->Get(v8_str("x2"))->Int32Value());

@@ -22385,7 +22398,7 @@
   pr->Resolve(v8::Integer::New(isolate, 3));
   CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());

@@ -22395,7 +22408,7 @@
   rr->Reject(v8::Integer::New(isolate, 3));
   CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
-  V8::RunMicrotasks(isolate);
+  isolate->RunMicrotasks();
   CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
 }
=======================================
--- /branches/bleeding_edge/test/cctest/test-microtask-delivery.cc Tue Apr 22 10:45:43 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-microtask-delivery.cc Fri May 2 19:30:54 2014 UTC
@@ -96,7 +96,7 @@
   HarmonyIsolate isolate;
   HandleScope scope(isolate.GetIsolate());
   LocalContext context1(isolate.GetIsolate());
-  V8::SetAutorunMicrotasks(isolate.GetIsolate(), false);
+  isolate.GetIsolate()->SetAutorunMicrotasks(false);
   CompileRun(
       "var obj = { calls: 0 };");
   Handle<Value> obj = CompileRun("obj");
@@ -130,7 +130,7 @@
     LocalContext context4(isolate.GetIsolate());
context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
                             obj);
-    V8::RunMicrotasks(isolate.GetIsolate());
+    isolate.GetIsolate()->RunMicrotasks();
     CHECK_EQ(2, CompileRun("obj.calls")->Int32Value());
   }
 }

--
--
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