v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
microtask-queue.h
Go to the documentation of this file.
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_EXECUTION_MICROTASK_QUEUE_H_
6#define V8_EXECUTION_MICROTASK_QUEUE_H_
7
8#include <stdint.h>
9
10#include <memory>
11#include <vector>
12
13#include "include/v8-internal.h" // For Address.
15#include "src/base/macros.h"
16
17namespace v8 {
18namespace internal {
19
20class Isolate;
21class Microtask;
22class Object;
23class RootVisitor;
24template <typename T>
25class Tagged;
26
28 public:
29 static void SetUpDefaultMicrotaskQueue(Isolate* isolate);
30 static std::unique_ptr<MicrotaskQueue> New(Isolate* isolate);
31
32 ~MicrotaskQueue() override;
33
34 // Uses raw Address values because it's called via ExternalReference.
35 // {raw_microtask} is a tagged Microtask pointer.
36 // Returns Smi::kZero due to CallCFunction.
37 static Address CallEnqueueMicrotask(Isolate* isolate,
38 intptr_t microtask_queue_pointer,
39 Address raw_microtask);
40
41 // v8::MicrotaskQueue implementations.
42 void EnqueueMicrotask(v8::Isolate* isolate,
43 v8::Local<Function> microtask) override;
44 void EnqueueMicrotask(v8::Isolate* isolate, v8::MicrotaskCallback callback,
45 void* data) override;
46 void PerformCheckpoint(v8::Isolate* isolate) override {
47 if (!ShouldPerfomCheckpoint()) return;
48 PerformCheckpointInternal(isolate);
49 }
50
52 return !IsRunningMicrotasks() && !GetMicrotasksScopeDepth() &&
53 !HasMicrotasksSuppressions();
54 }
55
56 void EnqueueMicrotask(Tagged<Microtask> microtask);
57 void AddMicrotasksCompletedCallback(
59 void RemoveMicrotasksCompletedCallback(
61 bool IsRunningMicrotasks() const override { return is_running_microtasks_; }
62
63 // Runs all queued Microtasks.
64 // Returns -1 if the execution is terminating, otherwise, returns the number
65 // of microtasks that ran in this round.
66 int RunMicrotasks(Isolate* isolate);
67
68 // Iterate all pending Microtasks in this queue as strong roots, so that
69 // builtins can update the queue directly without the write barrier.
70 void IterateMicrotasks(RootVisitor* visitor);
71
72 // Microtasks scope depth represents nested scopes controlling microtasks
73 // invocation, which happens when depth reaches zero.
74 void IncrementMicrotasksScopeDepth() { ++microtasks_depth_; }
75 void DecrementMicrotasksScopeDepth() { --microtasks_depth_; }
76 int GetMicrotasksScopeDepth() const override { return microtasks_depth_; }
77
78 // Possibly nested microtasks suppression scopes prevent microtasks
79 // from running.
80 void IncrementMicrotasksSuppressions() { ++microtasks_suppressions_; }
81 void DecrementMicrotasksSuppressions() { --microtasks_suppressions_; }
83 return microtasks_suppressions_ != 0;
84 }
85
86#ifdef DEBUG
87 // In debug we check that calls not intended to invoke microtasks are
88 // still correctly wrapped with microtask scopes.
89 void IncrementDebugMicrotasksScopeDepth() { ++debug_microtasks_depth_; }
90 void DecrementDebugMicrotasksScopeDepth() { --debug_microtasks_depth_; }
91 bool DebugMicrotasksScopeDepthIsZero() const {
92 return debug_microtasks_depth_ == 0;
93 }
94#endif
95
97 microtasks_policy_ = microtasks_policy;
98 }
99 v8::MicrotasksPolicy microtasks_policy() const { return microtasks_policy_; }
100
101 intptr_t capacity() const { return capacity_; }
102 intptr_t size() const { return size_; }
103 intptr_t start() const { return start_; }
104
105 Tagged<Microtask> get(intptr_t index) const;
106
107 MicrotaskQueue* next() const { return next_; }
108 MicrotaskQueue* prev() const { return prev_; }
109
110 static const size_t kRingBufferOffset;
111 static const size_t kCapacityOffset;
112 static const size_t kSizeOffset;
113 static const size_t kStartOffset;
114 static const size_t kFinishedMicrotaskCountOffset;
115
116 static const intptr_t kMinimumCapacity;
117
118 private:
119 void PerformCheckpointInternal(v8::Isolate* v8_isolate);
120
121 void OnCompleted(Isolate* isolate);
122
124 void ResizeBuffer(intptr_t new_capacity);
125
126 // A ring buffer to hold Microtask instances.
127 // ring_buffer_[(start_ + i) % capacity_] contains |i|th Microtask for each
128 // |i| in [0, size_).
129 intptr_t size_ = 0;
130 intptr_t capacity_ = 0;
131 intptr_t start_ = 0;
132 Address* ring_buffer_ = nullptr;
133
134 // The number of finished microtask.
135 intptr_t finished_microtask_count_ = 0;
136
137 // MicrotaskQueue instances form a doubly linked list loop, so that all
138 // instances are reachable through |next_|.
139 MicrotaskQueue* next_ = nullptr;
141
142 int microtasks_depth_ = 0;
143 int microtasks_suppressions_ = 0;
144#ifdef DEBUG
145 int debug_microtasks_depth_ = 0;
146#endif
147
149
150 bool is_running_microtasks_ = false;
151 bool is_running_completed_callbacks_ = false;
153 std::pair<MicrotasksCompletedCallbackWithData, void*>;
154 std::vector<CallbackWithData> microtasks_completed_callbacks_;
155 std::optional<std::vector<CallbackWithData>>
157};
158
159} // namespace internal
160} // namespace v8
161
162#endif // V8_EXECUTION_MICROTASK_QUEUE_H_
MicrotaskQueue * next() const
void set_microtasks_policy(v8::MicrotasksPolicy microtasks_policy)
v8::MicrotasksPolicy microtasks_policy() const
static const size_t kRingBufferOffset
static const size_t kSizeOffset
static const intptr_t kMinimumCapacity
MicrotaskQueue * prev() const
static const size_t kCapacityOffset
std::pair< MicrotasksCompletedCallbackWithData, void * > CallbackWithData
int GetMicrotasksScopeDepth() const override
bool IsRunningMicrotasks() const override
static const size_t kFinishedMicrotaskCountOffset
void PerformCheckpoint(v8::Isolate *isolate) override
std::vector< CallbackWithData > microtasks_completed_callbacks_
static const size_t kStartOffset
std::optional< std::vector< CallbackWithData > > microtasks_completed_callbacks_cow_
const int size_
Definition assembler.cc:132
uint8_t *const start_
Definition assembler.cc:131
TNode< Object > callback
Tagged(T object) -> Tagged< T >
MicrotasksPolicy
void(*)(void *data) MicrotaskCallback
void(*)(Isolate *, void *) MicrotasksCompletedCallbackWithData
Node * prev_
#define V8_EXPORT_PRIVATE
Definition macros.h:460