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 {
TNode<IntPtrT> index);
void RunSingleMicrotask(TNode<Context> current_context,
TNode<Microtask> microtask);
void IncrementFinishedMicrotaskCount(TNode<RawPtrT> microtask_queue);
TNode<Context> GetCurrentContext();
void SetCurrentContext(TNode<Context> context);
......@@ -311,6 +312,17 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask(
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() {
auto ref = ExternalReference::Create(kContextAddress, isolate());
return TNode<Context>::UncheckedCast(
......@@ -531,6 +543,7 @@ TF_BUILTIN(RunMicrotasks, MicrotaskQueueBuiltinsAssembler) {
SetMicrotaskQueueStart(microtask_queue, new_start);
RunSingleMicrotask(current_context, microtask);
IncrementFinishedMicrotaskCount(microtask_queue);
Goto(&loop);
BIND(&done);
......
......@@ -25,6 +25,8 @@ const size_t MicrotaskQueue::kCapacityOffset =
OFFSET_OF(MicrotaskQueue, capacity_);
const size_t MicrotaskQueue::kSizeOffset = OFFSET_OF(MicrotaskQueue, size_);
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;
......@@ -114,20 +116,27 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
return 0;
}
intptr_t base_count = finished_microtask_count_;
HandleScope handle_scope(isolate);
MaybeHandle<Object> maybe_exception;
MaybeHandle<Object> maybe_result;
int processed_microtask_count;
{
SetIsRunningMicrotasks scope(&is_running_microtasks_);
v8::Isolate::SuppressMicrotaskExecutionScope suppress(
reinterpret_cast<v8::Isolate*>(isolate));
HandleScopeImplementer::EnteredContextRewindScope rewind_scope(
isolate->handle_scope_implementer());
TRACE_EVENT0("v8.execute", "RunMicrotasks");
TRACE_EVENT_BEGIN0("v8.execute", "RunMicrotasks");
TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.RunMicrotasks");
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.
......@@ -144,8 +153,7 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
DCHECK_EQ(0, size());
OnCompleted(isolate);
// TODO(tzik): Return the number of microtasks run in this round.
return 0;
return processed_microtask_count;
}
void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) {
......
......@@ -37,9 +37,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
void EnqueueMicrotask(Microtask microtask);
// Returns -1 if the execution is terminating, otherwise, returns 0.
// TODO(tzik): Update the implementation to return the number of processed
// microtasks.
// Runs all queued Microtasks.
// Returns -1 if the execution is terminating, otherwise, returns the number
// of microtasks that ran in this round.
int RunMicrotasks(Isolate* isolate);
// Iterate all pending Microtasks in this queue as strong roots, so that
......@@ -86,6 +86,7 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
static const size_t kCapacityOffset;
static const size_t kSizeOffset;
static const size_t kStartOffset;
static const size_t kFinishedMicrotaskCountOffset;
static const intptr_t kMinimumCapacity;
......@@ -103,6 +104,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
intptr_t start_ = 0;
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
// instances are reachable through |next_|.
MicrotaskQueue* next_ = nullptr;
......
......@@ -88,7 +88,7 @@ TEST_F(MicrotaskQueueTest, EnqueueAndRun) {
}));
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity, microtask_queue()->capacity());
EXPECT_EQ(1, microtask_queue()->size());
microtask_queue()->RunMicrotasks(isolate());
EXPECT_EQ(1, microtask_queue()->RunMicrotasks(isolate()));
EXPECT_TRUE(ran);
EXPECT_EQ(0, microtask_queue()->size());
}
......@@ -100,7 +100,7 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) {
// Enqueue and flush the queue first to have non-zero |start_|.
microtask_queue()->EnqueueMicrotask(
*NewMicrotask([&count] { EXPECT_EQ(0, count++); }));
microtask_queue()->RunMicrotasks(isolate());
EXPECT_EQ(1, microtask_queue()->RunMicrotasks(isolate()));
EXPECT_LT(0, microtask_queue()->capacity());
EXPECT_EQ(0, microtask_queue()->size());
......@@ -122,7 +122,8 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) {
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 1, microtask_queue()->size());
// 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);
}
......@@ -163,7 +164,8 @@ TEST_F(MicrotaskQueueTest, VisitRoot) {
for (int i = 0; i < MicrotaskQueue::kMinimumCapacity / 2 + 1; ++i) {
microtask_queue()->EnqueueMicrotask(*NewMicrotask([] {}));
}
microtask_queue()->RunMicrotasks(isolate());
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity / 2 + 1,
microtask_queue()->RunMicrotasks(isolate()));
std::vector<Object> expected;
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