[api] Make microtask callbacks consistent across policies

When running microtasks, the auto policy currently only invokes
MicrotasksCompletedCallbacks when the microtask queue is non-empty,
while all other policies unconditionally invokes the callbacks. Make the
auto mode also unconditionally invoke the callbacks.

Bug: v8:10213
Change-Id: I2f608459960b84e6f506646712ac935130646b9e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2057813
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Sathya Gunasekaran  <gsathya@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66320}
This commit is contained in:
Shu-yu Guo 2020-02-14 16:11:29 -08:00 committed by Commit Bot
parent af76dd6e7e
commit 215f22dcae
2 changed files with 18 additions and 17 deletions

View File

@ -3926,18 +3926,15 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) { void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) {
if (!thread_local_top()->CallDepthIsZero()) return; if (!thread_local_top()->CallDepthIsZero()) return;
bool run_microtasks = bool perform_checkpoint =
microtask_queue && microtask_queue->size() && microtask_queue &&
!microtask_queue->HasMicrotasksSuppressions() &&
microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kAuto; microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kAuto;
if (run_microtasks) { v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this);
microtask_queue->RunMicrotasks(this); if (perform_checkpoint) microtask_queue->PerformCheckpoint(isolate);
}
if (call_completed_callbacks_.empty()) return; if (call_completed_callbacks_.empty()) return;
// Fire callbacks. Increase call depth to prevent recursive callbacks. // Fire callbacks. Increase call depth to prevent recursive callbacks.
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this);
v8::Isolate::SuppressMicrotaskExecutionScope suppress(isolate); v8::Isolate::SuppressMicrotaskExecutionScope suppress(isolate);
std::vector<CallCompletedCallback> callbacks(call_completed_callbacks_); std::vector<CallCompletedCallback> callbacks(call_completed_callbacks_);
for (auto& callback : callbacks) { for (auto& callback : callbacks) {

View File

@ -19928,21 +19928,25 @@ TEST(SetAutorunMicrotasks) {
v8::HandleScope scope(env->GetIsolate()); v8::HandleScope scope(env->GetIsolate());
env->GetIsolate()->AddMicrotasksCompletedCallback( env->GetIsolate()->AddMicrotasksCompletedCallback(
&MicrotasksCompletedCallback); &MicrotasksCompletedCallback);
// If the policy is auto, there's a microtask checkpoint at the end of every
// zero-depth API call.
CompileRun( CompileRun(
"var ext1Calls = 0;" "var ext1Calls = 0;"
"var ext2Calls = 0;"); "var ext2Calls = 0;");
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(0, CompileRun("ext2Calls")->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( env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskOne).ToLocalChecked()); Function::New(env.local(), MicrotaskOne).ToLocalChecked());
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(0, CompileRun("ext2Calls")->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()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
env->GetIsolate()->EnqueueMicrotask( env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskOne).ToLocalChecked()); Function::New(env.local(), MicrotaskOne).ToLocalChecked());
@ -19951,24 +19955,24 @@ TEST(SetAutorunMicrotasks) {
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(0, CompileRun("ext2Calls")->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(); env->GetIsolate()->RunMicrotasks();
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(1, CompileRun("ext2Calls")->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( env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(1, CompileRun("ext2Calls")->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(); env->GetIsolate()->RunMicrotasks();
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(2, CompileRun("ext2Calls")->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()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
env->GetIsolate()->EnqueueMicrotask( env->GetIsolate()->EnqueueMicrotask(
@ -19976,7 +19980,7 @@ TEST(SetAutorunMicrotasks) {
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(3, CompileRun("ext2Calls")->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( env->GetIsolate()->EnqueueMicrotask(
Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
@ -19985,13 +19989,13 @@ TEST(SetAutorunMicrotasks) {
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(3, CompileRun("ext2Calls")->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;"); CompileRun("1+1;");
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(4, CompileRun("ext2Calls")->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( env->GetIsolate()->RemoveMicrotasksCompletedCallback(
&MicrotasksCompletedCallback); &MicrotasksCompletedCallback);
@ -20000,7 +20004,7 @@ TEST(SetAutorunMicrotasks) {
CompileRun("1+1;"); CompileRun("1+1;");
CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
CHECK_EQ(4, CompileRun("ext2Calls")->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);
} }