Commit 0e425400 authored by tzik's avatar tzik Committed by Commit Bot

Reland "Expose the number of microtasks from RunMicrotasks"

This is a reland of 516d9068

Original change's description:
> Expose the number of microtasks from RunMicrotasks
>
> This CL adds the number of processed microtasks to the tracing marker
> of RunMicrotasks, plus let RunMicrotasks return the number.
>
> Bug: v8:7804, v8:8124
> Change-Id: Ie584e22964121fbda3a822379d760e7518fc54a7
> Reviewed-on: https://chromium-review.googlesource.com/c/1425277
> Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#59017}

Bug: v8:7804, v8:8124
Change-Id: I4a57ba3e23973f6b46414c4502244091c42cf532
Reviewed-on: https://chromium-review.googlesource.com/c/1430399Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59148}
parent f6b787f2
...@@ -35,6 +35,7 @@ class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler { ...@@ -35,6 +35,7 @@ class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler {
TNode<IntPtrT> index); TNode<IntPtrT> index);
void RunSingleMicrotask(TNode<Context> current_context, void RunSingleMicrotask(TNode<Context> current_context,
TNode<Microtask> microtask); TNode<Microtask> microtask);
void IncrementFinishedMicrotaskCount(TNode<RawPtrT> microtask_queue);
TNode<Context> GetCurrentContext(); TNode<Context> GetCurrentContext();
void SetCurrentContext(TNode<Context> context); void SetCurrentContext(TNode<Context> context);
...@@ -311,6 +312,17 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( ...@@ -311,6 +312,17 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask(
BIND(&done); BIND(&done);
} }
void MicrotaskQueueBuiltinsAssembler::IncrementFinishedMicrotaskCount(
TNode<RawPtrT> microtask_queue) {
TNode<IntPtrT> count = UncheckedCast<IntPtrT>(
Load(MachineType::IntPtr(), microtask_queue,
IntPtrConstant(MicrotaskQueue::kFinishedMicrotaskCountOffset)));
TNode<IntPtrT> new_count = IntPtrAdd(count, IntPtrConstant(1));
StoreNoWriteBarrier(
MachineType::PointerRepresentation(), microtask_queue,
IntPtrConstant(MicrotaskQueue::kFinishedMicrotaskCountOffset), new_count);
}
TNode<Context> MicrotaskQueueBuiltinsAssembler::GetCurrentContext() { TNode<Context> MicrotaskQueueBuiltinsAssembler::GetCurrentContext() {
auto ref = ExternalReference::Create(kContextAddress, isolate()); auto ref = ExternalReference::Create(kContextAddress, isolate());
return TNode<Context>::UncheckedCast( return TNode<Context>::UncheckedCast(
...@@ -531,6 +543,7 @@ TF_BUILTIN(RunMicrotasks, MicrotaskQueueBuiltinsAssembler) { ...@@ -531,6 +543,7 @@ TF_BUILTIN(RunMicrotasks, MicrotaskQueueBuiltinsAssembler) {
SetMicrotaskQueueStart(microtask_queue, new_start); SetMicrotaskQueueStart(microtask_queue, new_start);
RunSingleMicrotask(current_context, microtask); RunSingleMicrotask(current_context, microtask);
IncrementFinishedMicrotaskCount(microtask_queue);
Goto(&loop); Goto(&loop);
BIND(&done); BIND(&done);
......
...@@ -25,6 +25,8 @@ const size_t MicrotaskQueue::kCapacityOffset = ...@@ -25,6 +25,8 @@ const size_t MicrotaskQueue::kCapacityOffset =
OFFSET_OF(MicrotaskQueue, capacity_); OFFSET_OF(MicrotaskQueue, capacity_);
const size_t MicrotaskQueue::kSizeOffset = OFFSET_OF(MicrotaskQueue, size_); const size_t MicrotaskQueue::kSizeOffset = OFFSET_OF(MicrotaskQueue, size_);
const size_t MicrotaskQueue::kStartOffset = OFFSET_OF(MicrotaskQueue, start_); const size_t MicrotaskQueue::kStartOffset = OFFSET_OF(MicrotaskQueue, start_);
const size_t MicrotaskQueue::kFinishedMicrotaskCountOffset =
OFFSET_OF(MicrotaskQueue, finished_microtask_count_);
const intptr_t MicrotaskQueue::kMinimumCapacity = 8; const intptr_t MicrotaskQueue::kMinimumCapacity = 8;
...@@ -114,20 +116,27 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) { ...@@ -114,20 +116,27 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
return 0; return 0;
} }
intptr_t base_count = finished_microtask_count_;
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
MaybeHandle<Object> maybe_exception; MaybeHandle<Object> maybe_exception;
MaybeHandle<Object> maybe_result; MaybeHandle<Object> maybe_result;
int processed_microtask_count;
{ {
SetIsRunningMicrotasks scope(&is_running_microtasks_); SetIsRunningMicrotasks scope(&is_running_microtasks_);
v8::Isolate::SuppressMicrotaskExecutionScope suppress( v8::Isolate::SuppressMicrotaskExecutionScope suppress(
reinterpret_cast<v8::Isolate*>(isolate)); reinterpret_cast<v8::Isolate*>(isolate));
HandleScopeImplementer::EnteredContextRewindScope rewind_scope( HandleScopeImplementer::EnteredContextRewindScope rewind_scope(
isolate->handle_scope_implementer()); isolate->handle_scope_implementer());
TRACE_EVENT0("v8.execute", "RunMicrotasks"); TRACE_EVENT_BEGIN0("v8.execute", "RunMicrotasks");
TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.RunMicrotasks"); TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.RunMicrotasks");
maybe_result = Execution::TryRunMicrotasks(isolate, this, &maybe_exception); maybe_result = Execution::TryRunMicrotasks(isolate, this, &maybe_exception);
processed_microtask_count =
static_cast<int>(finished_microtask_count_ - base_count);
TRACE_EVENT_END1("v8.execute", "RunMicrotasks", "microtask_count",
processed_microtask_count);
} }
// If execution is terminating, clean up and propagate that to TryCatch scope. // If execution is terminating, clean up and propagate that to TryCatch scope.
...@@ -144,8 +153,7 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) { ...@@ -144,8 +153,7 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
DCHECK_EQ(0, size()); DCHECK_EQ(0, size());
OnCompleted(isolate); OnCompleted(isolate);
// TODO(tzik): Return the number of microtasks run in this round. return processed_microtask_count;
return 0;
} }
void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) { void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) {
......
...@@ -37,9 +37,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue { ...@@ -37,9 +37,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
void EnqueueMicrotask(Microtask microtask); void EnqueueMicrotask(Microtask microtask);
// Returns -1 if the execution is terminating, otherwise, returns 0. // Runs all queued Microtasks.
// TODO(tzik): Update the implementation to return the number of processed // Returns -1 if the execution is terminating, otherwise, returns the number
// microtasks. // of microtasks that ran in this round.
int RunMicrotasks(Isolate* isolate); int RunMicrotasks(Isolate* isolate);
// Iterate all pending Microtasks in this queue as strong roots, so that // Iterate all pending Microtasks in this queue as strong roots, so that
...@@ -86,6 +86,7 @@ class V8_EXPORT_PRIVATE MicrotaskQueue { ...@@ -86,6 +86,7 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
static const size_t kCapacityOffset; static const size_t kCapacityOffset;
static const size_t kSizeOffset; static const size_t kSizeOffset;
static const size_t kStartOffset; static const size_t kStartOffset;
static const size_t kFinishedMicrotaskCountOffset;
static const intptr_t kMinimumCapacity; static const intptr_t kMinimumCapacity;
...@@ -103,6 +104,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue { ...@@ -103,6 +104,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
intptr_t start_ = 0; intptr_t start_ = 0;
Address* ring_buffer_ = nullptr; Address* ring_buffer_ = nullptr;
// The number of finished microtask.
intptr_t finished_microtask_count_ = 0;
// MicrotaskQueue instances form a doubly linked list loop, so that all // MicrotaskQueue instances form a doubly linked list loop, so that all
// instances are reachable through |next_|. // instances are reachable through |next_|.
MicrotaskQueue* next_ = nullptr; MicrotaskQueue* next_ = nullptr;
......
...@@ -88,7 +88,7 @@ TEST_F(MicrotaskQueueTest, EnqueueAndRun) { ...@@ -88,7 +88,7 @@ TEST_F(MicrotaskQueueTest, EnqueueAndRun) {
})); }));
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity, microtask_queue()->capacity()); EXPECT_EQ(MicrotaskQueue::kMinimumCapacity, microtask_queue()->capacity());
EXPECT_EQ(1, microtask_queue()->size()); EXPECT_EQ(1, microtask_queue()->size());
microtask_queue()->RunMicrotasks(isolate()); EXPECT_EQ(1, microtask_queue()->RunMicrotasks(isolate()));
EXPECT_TRUE(ran); EXPECT_TRUE(ran);
EXPECT_EQ(0, microtask_queue()->size()); EXPECT_EQ(0, microtask_queue()->size());
} }
...@@ -100,7 +100,7 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) { ...@@ -100,7 +100,7 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) {
// Enqueue and flush the queue first to have non-zero |start_|. // Enqueue and flush the queue first to have non-zero |start_|.
microtask_queue()->EnqueueMicrotask( microtask_queue()->EnqueueMicrotask(
*NewMicrotask([&count] { EXPECT_EQ(0, count++); })); *NewMicrotask([&count] { EXPECT_EQ(0, count++); }));
microtask_queue()->RunMicrotasks(isolate()); EXPECT_EQ(1, microtask_queue()->RunMicrotasks(isolate()));
EXPECT_LT(0, microtask_queue()->capacity()); EXPECT_LT(0, microtask_queue()->capacity());
EXPECT_EQ(0, microtask_queue()->size()); EXPECT_EQ(0, microtask_queue()->size());
...@@ -122,7 +122,8 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) { ...@@ -122,7 +122,8 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) {
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 1, microtask_queue()->size()); EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 1, microtask_queue()->size());
// Run all pending Microtasks to ensure they run in the proper order. // Run all pending Microtasks to ensure they run in the proper order.
microtask_queue()->RunMicrotasks(isolate()); EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 1,
microtask_queue()->RunMicrotasks(isolate()));
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 2, count); EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 2, count);
} }
...@@ -163,7 +164,8 @@ TEST_F(MicrotaskQueueTest, VisitRoot) { ...@@ -163,7 +164,8 @@ TEST_F(MicrotaskQueueTest, VisitRoot) {
for (int i = 0; i < MicrotaskQueue::kMinimumCapacity / 2 + 1; ++i) { for (int i = 0; i < MicrotaskQueue::kMinimumCapacity / 2 + 1; ++i) {
microtask_queue()->EnqueueMicrotask(*NewMicrotask([] {})); microtask_queue()->EnqueueMicrotask(*NewMicrotask([] {}));
} }
microtask_queue()->RunMicrotasks(isolate()); EXPECT_EQ(MicrotaskQueue::kMinimumCapacity / 2 + 1,
microtask_queue()->RunMicrotasks(isolate()));
std::vector<Object> expected; std::vector<Object> expected;
for (int i = 0; i < MicrotaskQueue::kMinimumCapacity / 2 + 1; ++i) { for (int i = 0; i < MicrotaskQueue::kMinimumCapacity / 2 + 1; ++i) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment