diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc index 45d001ae74..f2b8dd9baa 100644 --- a/src/execution/isolate.cc +++ b/src/execution/isolate.cc @@ -3926,18 +3926,15 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) { void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) { if (!thread_local_top()->CallDepthIsZero()) return; - bool run_microtasks = - microtask_queue && microtask_queue->size() && - !microtask_queue->HasMicrotasksSuppressions() && + bool perform_checkpoint = + microtask_queue && microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kAuto; - if (run_microtasks) { - microtask_queue->RunMicrotasks(this); - } + v8::Isolate* isolate = reinterpret_cast(this); + if (perform_checkpoint) microtask_queue->PerformCheckpoint(isolate); if (call_completed_callbacks_.empty()) return; // Fire callbacks. Increase call depth to prevent recursive callbacks. - v8::Isolate* isolate = reinterpret_cast(this); v8::Isolate::SuppressMicrotaskExecutionScope suppress(isolate); std::vector callbacks(call_completed_callbacks_); for (auto& callback : callbacks) { diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 4cbb9eb6ec..8fb1a49d0e 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -19928,21 +19928,25 @@ TEST(SetAutorunMicrotasks) { v8::HandleScope scope(env->GetIsolate()); env->GetIsolate()->AddMicrotasksCompletedCallback( &MicrotasksCompletedCallback); + + // If the policy is auto, there's a microtask checkpoint at the end of every + // zero-depth API call. CompileRun( "var ext1Calls = 0;" "var ext2Calls = 0;"); CompileRun("1+1;"); CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(0u, microtasks_completed_callback_count); + CHECK_EQ(4u, microtasks_completed_callback_count); env->GetIsolate()->EnqueueMicrotask( Function::New(env.local(), MicrotaskOne).ToLocalChecked()); CompileRun("1+1;"); CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(1u, microtasks_completed_callback_count); + CHECK_EQ(7u, microtasks_completed_callback_count); + // If the policy is explicit, microtask checkpoints are explicitly invoked. env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); env->GetIsolate()->EnqueueMicrotask( Function::New(env.local(), MicrotaskOne).ToLocalChecked()); @@ -19951,24 +19955,24 @@ TEST(SetAutorunMicrotasks) { CompileRun("1+1;"); CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(1u, microtasks_completed_callback_count); + CHECK_EQ(7u, microtasks_completed_callback_count); env->GetIsolate()->RunMicrotasks(); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(2u, microtasks_completed_callback_count); + CHECK_EQ(8u, microtasks_completed_callback_count); env->GetIsolate()->EnqueueMicrotask( Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(2u, microtasks_completed_callback_count); + CHECK_EQ(8u, microtasks_completed_callback_count); env->GetIsolate()->RunMicrotasks(); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(3u, microtasks_completed_callback_count); + CHECK_EQ(9u, microtasks_completed_callback_count); env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto); env->GetIsolate()->EnqueueMicrotask( @@ -19976,7 +19980,7 @@ TEST(SetAutorunMicrotasks) { CompileRun("1+1;"); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(4u, microtasks_completed_callback_count); + CHECK_EQ(12u, microtasks_completed_callback_count); env->GetIsolate()->EnqueueMicrotask( Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); @@ -19985,13 +19989,13 @@ TEST(SetAutorunMicrotasks) { CompileRun("1+1;"); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(4u, microtasks_completed_callback_count); + CHECK_EQ(12u, microtasks_completed_callback_count); } CompileRun("1+1;"); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(5u, microtasks_completed_callback_count); + CHECK_EQ(15u, microtasks_completed_callback_count); env->GetIsolate()->RemoveMicrotasksCompletedCallback( &MicrotasksCompletedCallback); @@ -20000,7 +20004,7 @@ TEST(SetAutorunMicrotasks) { CompileRun("1+1;"); CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); - CHECK_EQ(5u, microtasks_completed_callback_count); + CHECK_EQ(15u, microtasks_completed_callback_count); }