Commit 8a7adb0b authored by tzik's avatar tzik Committed by Commit Bot

Use MicrotaskQueue class as the default microtask storage

This CL introduces the global default microtask queue as the replacement
of Heap::microtask_queue and Isolate::pending_microtask_count.

Bug: v8:8124
Change-Id: I0a6a7618a1a6ca7ceaf370dc15917a6b3690542c
Reviewed-on: https://chromium-review.googlesource.com/1226760Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56012}
parent 9b50b3b0
......@@ -623,11 +623,14 @@ class InternalBuiltinsAssembler : public CodeStubAssembler {
explicit InternalBuiltinsAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
TNode<IntPtrT> GetPendingMicrotaskCount();
void SetPendingMicrotaskCount(TNode<IntPtrT> count);
TNode<FixedArray> GetMicrotaskQueue();
void SetMicrotaskQueue(TNode<FixedArray> queue);
TNode<MicrotaskQueue> GetDefaultMicrotaskQueue();
TNode<IntPtrT> GetPendingMicrotaskCount(
TNode<MicrotaskQueue> microtask_queue);
void SetPendingMicrotaskCount(TNode<MicrotaskQueue> microtask_queue,
TNode<IntPtrT> new_num_tasks);
TNode<FixedArray> GetQueuedMicrotasks(TNode<MicrotaskQueue> microtask_queue);
void SetQueuedMicrotasks(TNode<MicrotaskQueue> microtask_queue,
TNode<FixedArray> new_queue);
TNode<Context> GetCurrentContext();
void SetCurrentContext(TNode<Context> context);
......@@ -714,37 +717,34 @@ TF_BUILTIN(AdaptorWithBuiltinExitFrame, InternalBuiltinsAssembler) {
GenerateAdaptorWithExitFrameType<Descriptor>(Builtins::BUILTIN_EXIT);
}
TNode<IntPtrT> InternalBuiltinsAssembler::GetPendingMicrotaskCount() {
auto ref = ExternalReference::pending_microtask_count_address(isolate());
if (kIntSize == 8) {
return TNode<IntPtrT>::UncheckedCast(
Load(MachineType::Int64(), ExternalConstant(ref)));
} else {
Node* const value = Load(MachineType::Int32(), ExternalConstant(ref));
return ChangeInt32ToIntPtr(value);
}
TNode<MicrotaskQueue> InternalBuiltinsAssembler::GetDefaultMicrotaskQueue() {
return TNode<MicrotaskQueue>::UncheckedCast(
LoadRoot(Heap::kDefaultMicrotaskQueueRootIndex));
}
void InternalBuiltinsAssembler::SetPendingMicrotaskCount(TNode<IntPtrT> count) {
auto ref = ExternalReference::pending_microtask_count_address(isolate());
auto rep = kIntSize == 8 ? MachineRepresentation::kWord64
: MachineRepresentation::kWord32;
if (kIntSize == 4 && kPointerSize == 8) {
Node* const truncated_count =
TruncateInt64ToInt32(TNode<Int64T>::UncheckedCast(count));
StoreNoWriteBarrier(rep, ExternalConstant(ref), truncated_count);
} else {
StoreNoWriteBarrier(rep, ExternalConstant(ref), count);
}
TNode<IntPtrT> InternalBuiltinsAssembler::GetPendingMicrotaskCount(
TNode<MicrotaskQueue> microtask_queue) {
TNode<IntPtrT> result = LoadAndUntagObjectField(
microtask_queue, MicrotaskQueue::kPendingMicrotaskCountOffset);
return result;
}
void InternalBuiltinsAssembler::SetPendingMicrotaskCount(
TNode<MicrotaskQueue> microtask_queue, TNode<IntPtrT> new_num_tasks) {
StoreObjectField(microtask_queue,
MicrotaskQueue::kPendingMicrotaskCountOffset,
SmiFromIntPtr(new_num_tasks));
}
TNode<FixedArray> InternalBuiltinsAssembler::GetMicrotaskQueue() {
return TNode<FixedArray>::UncheckedCast(
LoadRoot(Heap::kMicrotaskQueueRootIndex));
TNode<FixedArray> InternalBuiltinsAssembler::GetQueuedMicrotasks(
TNode<MicrotaskQueue> microtask_queue) {
return LoadObjectField<FixedArray>(microtask_queue,
MicrotaskQueue::kQueueOffset);
}
void InternalBuiltinsAssembler::SetMicrotaskQueue(TNode<FixedArray> queue) {
StoreRoot(Heap::kMicrotaskQueueRootIndex, queue);
void InternalBuiltinsAssembler::SetQueuedMicrotasks(
TNode<MicrotaskQueue> microtask_queue, TNode<FixedArray> new_queue) {
StoreObjectField(microtask_queue, MicrotaskQueue::kQueueOffset, new_queue);
}
TNode<Context> InternalBuiltinsAssembler::GetCurrentContext() {
......@@ -833,9 +833,10 @@ void InternalBuiltinsAssembler::RunPromiseHook(
TF_BUILTIN(EnqueueMicrotask, InternalBuiltinsAssembler) {
Node* microtask = Parameter(Descriptor::kMicrotask);
TNode<IntPtrT> num_tasks = GetPendingMicrotaskCount();
TNode<MicrotaskQueue> microtask_queue = GetDefaultMicrotaskQueue();
TNode<IntPtrT> num_tasks = GetPendingMicrotaskCount(microtask_queue);
TNode<IntPtrT> new_num_tasks = IntPtrAdd(num_tasks, IntPtrConstant(1));
TNode<FixedArray> queue = GetMicrotaskQueue();
TNode<FixedArray> queue = GetQueuedMicrotasks(microtask_queue);
TNode<IntPtrT> queue_length = LoadAndUntagFixedArrayBaseLength(queue);
Label if_append(this), if_grow(this), done(this);
......@@ -866,7 +867,7 @@ TF_BUILTIN(EnqueueMicrotask, InternalBuiltinsAssembler) {
SKIP_WRITE_BARRIER);
FillFixedArrayWithValue(PACKED_ELEMENTS, new_queue, new_num_tasks,
new_queue_length, Heap::kUndefinedValueRootIndex);
SetMicrotaskQueue(new_queue);
SetQueuedMicrotasks(microtask_queue, new_queue);
Goto(&done);
}
......@@ -880,7 +881,7 @@ TF_BUILTIN(EnqueueMicrotask, InternalBuiltinsAssembler) {
StoreFixedArrayElement(new_queue, num_tasks, microtask);
FillFixedArrayWithValue(PACKED_ELEMENTS, new_queue, new_num_tasks,
new_queue_length, Heap::kUndefinedValueRootIndex);
SetMicrotaskQueue(new_queue);
SetQueuedMicrotasks(microtask_queue, new_queue);
Goto(&done);
}
}
......@@ -892,13 +893,14 @@ TF_BUILTIN(EnqueueMicrotask, InternalBuiltinsAssembler) {
}
BIND(&done);
SetPendingMicrotaskCount(new_num_tasks);
SetPendingMicrotaskCount(microtask_queue, new_num_tasks);
Return(UndefinedConstant());
}
TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Load the current context from the isolate.
TNode<Context> current_context = GetCurrentContext();
TNode<MicrotaskQueue> microtask_queue = GetDefaultMicrotaskQueue();
Label init_queue_loop(this);
Goto(&init_queue_loop);
......@@ -907,17 +909,17 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
TVARIABLE(IntPtrT, index, IntPtrConstant(0));
Label loop(this, &index), loop_next(this);
TNode<IntPtrT> num_tasks = GetPendingMicrotaskCount();
TNode<IntPtrT> num_tasks = GetPendingMicrotaskCount(microtask_queue);
ReturnIf(IntPtrEqual(num_tasks, IntPtrConstant(0)), UndefinedConstant());
TNode<FixedArray> queue = GetMicrotaskQueue();
TNode<FixedArray> queue = GetQueuedMicrotasks(microtask_queue);
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(
LoadAndUntagFixedArrayBaseLength(queue), num_tasks));
CSA_ASSERT(this, IntPtrGreaterThan(num_tasks, IntPtrConstant(0)));
SetPendingMicrotaskCount(IntPtrConstant(0));
SetMicrotaskQueue(EmptyFixedArrayConstant());
SetQueuedMicrotasks(microtask_queue, EmptyFixedArrayConstant());
SetPendingMicrotaskCount(microtask_queue, IntPtrConstant(0));
Goto(&loop);
BIND(&loop);
......
......@@ -134,11 +134,6 @@ ExternalReference ExternalReference::handle_scope_implementer_address(
return ExternalReference(isolate->handle_scope_implementer_address());
}
ExternalReference ExternalReference::pending_microtask_count_address(
Isolate* isolate) {
return ExternalReference(isolate->pending_microtask_count_address());
}
ExternalReference ExternalReference::interpreter_dispatch_table_address(
Isolate* isolate) {
return ExternalReference(isolate->interpreter()->dispatch_table_address());
......
......@@ -27,8 +27,6 @@ class StatsCounter;
V(builtins_address, "builtins") \
V(handle_scope_implementer_address, \
"Isolate::handle_scope_implementer_address") \
V(pending_microtask_count_address, \
"Isolate::pending_microtask_count_address()") \
V(interpreter_dispatch_counters, "Interpreter::dispatch_counters") \
V(interpreter_dispatch_table_address, "Interpreter::dispatch_table_address") \
V(date_cache_stamp, "date_cache_stamp") \
......
......@@ -29,6 +29,7 @@
#include "src/objects/api-callbacks-inl.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/literal-objects.h"
#include "src/objects/microtask-queue-inl.h"
#include "src/objects/scope-info.h"
#include "src/objects/script-inl.h"
#include "src/profiler/heap-profiler.h"
......
......@@ -2691,7 +2691,6 @@ bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
case kCodeStubsRootIndex:
case kScriptListRootIndex:
case kMaterializedObjectsRootIndex:
case kMicrotaskQueueRootIndex:
case kDetachedContextsRootIndex:
case kRetainedMapsRootIndex:
case kRetainingPathTargetsRootIndex:
......
......@@ -755,9 +755,7 @@ void Heap::CreateInitialObjects() {
factory->NewManyClosuresCell(factory->undefined_value());
set_many_closures_cell(*many_closures_cell);
// Microtask queue uses the empty fixed array as a sentinel for "empty".
// Number of queued microtasks stored in Isolate::pending_microtask_count().
set_microtask_queue(roots.empty_fixed_array());
set_default_microtask_queue(*factory->NewMicrotaskQueue());
{
Handle<FixedArray> empty_sloppy_arguments_elements =
......
......@@ -3725,7 +3725,7 @@ void Isolate::FireCallCompletedCallback() {
if (!handle_scope_implementer()->CallDepthIsZero()) return;
bool run_microtasks =
pending_microtask_count() &&
heap()->default_microtask_queue()->pending_microtask_count() &&
!handle_scope_implementer()->HasMicrotasksSuppressions() &&
handle_scope_implementer()->microtasks_policy() ==
v8::MicrotasksPolicy::kAuto;
......@@ -3968,18 +3968,9 @@ void Isolate::ReportPromiseReject(Handle<JSPromise> promise,
}
void Isolate::EnqueueMicrotask(Handle<Microtask> microtask) {
Handle<FixedArray> queue(heap()->microtask_queue(), this);
int num_tasks = pending_microtask_count();
DCHECK_LE(num_tasks, queue->length());
if (num_tasks == queue->length()) {
queue = factory()->CopyFixedArrayAndGrow(queue, std::max(num_tasks, 8));
heap()->set_microtask_queue(*queue);
}
DCHECK_LE(8, queue->length());
DCHECK_LT(num_tasks, queue->length());
DCHECK(queue->get(num_tasks)->IsUndefined(this));
queue->set(num_tasks, *microtask);
set_pending_microtask_count(num_tasks + 1);
Handle<MicrotaskQueue> microtask_queue(heap()->default_microtask_queue(),
this);
MicrotaskQueue::EnqueueMicrotask(this, microtask_queue, microtask);
}
......@@ -3987,25 +3978,27 @@ void Isolate::RunMicrotasks() {
// Increase call depth to prevent recursive callbacks.
v8::Isolate::SuppressMicrotaskExecutionScope suppress(
reinterpret_cast<v8::Isolate*>(this));
if (pending_microtask_count()) {
HandleScope scope(this);
Handle<MicrotaskQueue> microtask_queue(heap()->default_microtask_queue(),
this);
if (microtask_queue->pending_microtask_count()) {
is_running_microtasks_ = true;
TRACE_EVENT0("v8.execute", "RunMicrotasks");
TRACE_EVENT_CALL_STATS_SCOPED(this, "v8", "V8.RunMicrotasks");
HandleScope scope(this);
MaybeHandle<Object> maybe_exception;
MaybeHandle<Object> maybe_result = Execution::RunMicrotasks(
this, Execution::MessageHandling::kReport, &maybe_exception);
// If execution is terminating, bail out, clean up, and propagate to
// TryCatch scope.
if (maybe_result.is_null() && maybe_exception.is_null()) {
heap()->set_microtask_queue(ReadOnlyRoots(heap()).empty_fixed_array());
set_pending_microtask_count(0);
microtask_queue->set_queue(ReadOnlyRoots(heap()).empty_fixed_array());
microtask_queue->set_pending_microtask_count(0);
handle_scope_implementer()->LeaveMicrotaskContext();
SetTerminationOnExternalTryCatch();
}
CHECK_EQ(0, pending_microtask_count());
CHECK_EQ(0, heap()->microtask_queue()->length());
CHECK_EQ(0, microtask_queue->pending_microtask_count());
CHECK_EQ(0, microtask_queue->queue()->length());
is_running_microtasks_ = false;
}
FireMicrotasksCompletedCallback();
......
......@@ -528,7 +528,6 @@ typedef std::vector<HeapObject*> DebugObjectCache;
V(const intptr_t*, api_external_references, nullptr) \
V(AddressToIndexHashMap*, external_reference_map, nullptr) \
V(HeapObjectToIndexHashMap*, root_index_map, nullptr) \
V(int, pending_microtask_count, 0) \
V(CompilationStatistics*, turbo_statistics, nullptr) \
V(CodeTracer*, code_tracer, nullptr) \
V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu) \
......@@ -1394,10 +1393,6 @@ class Isolate : private HiddenFactory {
return reinterpret_cast<Address>(&promise_hook_or_async_event_delegate_);
}
Address pending_microtask_count_address() {
return reinterpret_cast<Address>(&pending_microtask_count_);
}
Address handle_scope_implementer_address() {
return reinterpret_cast<Address>(&handle_scope_implementer_);
}
......
......@@ -236,7 +236,7 @@ namespace internal {
V(WeakArrayList, script_list, ScriptList) \
V(SimpleNumberDictionary, code_stubs, CodeStubs) \
V(FixedArray, materialized_objects, MaterializedObjects) \
V(FixedArray, microtask_queue, MicrotaskQueue) \
V(MicrotaskQueue, default_microtask_queue, DefaultMicrotaskQueue) \
V(WeakArrayList, detached_contexts, DetachedContexts) \
V(WeakArrayList, retaining_path_targets, RetainingPathTargets) \
V(WeakArrayList, retained_maps, RetainedMaps) \
......
......@@ -82,7 +82,6 @@ bool IsInitiallyMutable(Factory* factory, Address object_address) {
V(detached_contexts) \
V(feedback_vectors_for_profiling_tools) \
V(materialized_objects) \
V(microtask_queue) \
V(noscript_shared_function_infos) \
V(retained_maps) \
V(retaining_path_targets) \
......
......@@ -35,7 +35,7 @@ TEST_F(MicrotaskQueueTest, EnqueueMicrotask) {
std::vector<Handle<Microtask>> microtasks;
microtasks.push_back(microtask);
// Queue microtasks until the reallocation.
// Queue microtasks until the reallocation happens.
int queue_capacity = microtask_queue->queue()->length();
for (int i = 0; i < queue_capacity; ++i) {
microtask = NewMicrotask();
......
......@@ -289,31 +289,31 @@ KNOWN_MAPS = {
("RO_SPACE", 0x047b1): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x04aa1): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x04b91): (169, "ScriptMap"),
("RO_SPACE", 0x08cf1): (154, "AccessorInfoMap"),
("RO_SPACE", 0x08d41): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x08d91): (155, "AccessorPairMap"),
("RO_SPACE", 0x08de1): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x08e31): (157, "AllocationMementoMap"),
("RO_SPACE", 0x08e81): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x08ed1): (159, "DebugInfoMap"),
("RO_SPACE", 0x08f21): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x08f71): (162, "InterpreterDataMap"),
("RO_SPACE", 0x08fc1): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x09011): (164, "ModuleMap"),
("RO_SPACE", 0x09061): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x090b1): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x09101): (167, "PromiseReactionMap"),
("RO_SPACE", 0x09151): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x091a1): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x091f1): (172, "Tuple3Map"),
("RO_SPACE", 0x09241): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x09291): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x092e1): (176, "CallableTaskMap"),
("RO_SPACE", 0x09331): (177, "CallbackTaskMap"),
("RO_SPACE", 0x09381): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x093d1): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x09421): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x09471): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x04c59): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x08d41): (154, "AccessorInfoMap"),
("RO_SPACE", 0x08d91): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x08de1): (155, "AccessorPairMap"),
("RO_SPACE", 0x08e31): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x08e81): (157, "AllocationMementoMap"),
("RO_SPACE", 0x08ed1): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x08f21): (159, "DebugInfoMap"),
("RO_SPACE", 0x08f71): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x08fc1): (162, "InterpreterDataMap"),
("RO_SPACE", 0x09011): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x09061): (164, "ModuleMap"),
("RO_SPACE", 0x090b1): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x09101): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x09151): (167, "PromiseReactionMap"),
("RO_SPACE", 0x091a1): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x091f1): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x09241): (172, "Tuple3Map"),
("RO_SPACE", 0x09291): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x092e1): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x09331): (176, "CallableTaskMap"),
("RO_SPACE", 0x09381): (177, "CallbackTaskMap"),
("RO_SPACE", 0x093d1): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x09421): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x09471): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x094c1): (182, "AllocationSiteMap"),
("RO_SPACE", 0x09511): (182, "AllocationSiteMap"),
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
......
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