v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
safepoint.h
Go to the documentation of this file.
1// Copyright 2020 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_HEAP_SAFEPOINT_H_
6#define V8_HEAP_SAFEPOINT_H_
7
8#include <optional>
9#include <vector>
10
13#include "src/common/globals.h"
15#include "src/heap/local-heap.h"
17
18namespace v8 {
19namespace internal {
20
21class Heap;
22class LocalHeap;
23class PerClientSafepointData;
24class RootVisitor;
25
26// Used to bring all threads with heap access in an isolate to a safepoint such
27// that e.g. a garbage collection can be performed.
28class IsolateSafepoint final {
29 public:
30 explicit IsolateSafepoint(Heap* heap);
31
32 // Iterate handles in local heaps
33 void Iterate(RootVisitor* visitor);
34
35 // Iterate local heaps
36 template <typename Callback>
37 void IterateLocalHeaps(Callback callback) {
39 for (LocalHeap* current = local_heaps_head_; current;
40 current = current->next_) {
41 callback(current);
42 }
43 }
44
46
48
49 private:
52#if V8_OS_DARWIN
53 pthread_override_t qos_override;
54#endif
55 };
56
58
59 class Barrier {
63 bool armed_;
64
65 size_t stopped_ = 0;
66
67 bool IsArmed() { return armed_; }
68
69 public:
70 Barrier() : armed_(false), stopped_(0) {}
71
72 void Arm();
73 void Disarm();
75 const IsolateSafepoint::RunningLocalHeaps& running_threads);
76
77 void WaitInSafepoint();
78 void WaitInUnpark();
79 void NotifyPark();
80 };
81
82 enum class IncludeMainThread { kYes, kNo };
83
84 // Wait until unpark operation is safe again.
85 void WaitInUnpark();
86
87 // Enter the safepoint from a running thread.
88 void WaitInSafepoint();
89
90 // Running thread reached a safepoint by parking itself.
91 void NotifyPark();
92
93 // Methods for entering/leaving local safepoint scopes.
96
97 // Methods for entering/leaving global safepoint scopes.
99 PerClientSafepointData* client_data);
101 PerClientSafepointData* client_data);
103 PerClientSafepointData* client_data);
104 void LeaveGlobalSafepointScope(Isolate* initiator);
105
106 // Blocks until all running threads reached a safepoint.
108 const PerClientSafepointData* client_data);
109
111
112 void LockMutex(LocalHeap* local_heap);
113
115 IncludeMainThread include_main_thread,
116 IsolateSafepoint::RunningLocalHeaps& running_local_heaps);
117 void ClearSafepointRequestedFlags(IncludeMainThread include_main_thread);
118
119 template <typename Callback>
120 void AddLocalHeap(LocalHeap* local_heap, Callback callback) {
121 // Safepoint holds this lock in order to stop threads from starting or
122 // stopping.
124
125 // Additional code protected from safepoint
126 callback();
127
128 // Add list to doubly-linked list
129 if (local_heaps_head_) local_heaps_head_->prev_ = local_heap;
130 local_heap->prev_ = nullptr;
131 local_heap->next_ = local_heaps_head_;
132 local_heaps_head_ = local_heap;
133 }
134
135 template <typename Callback>
136 void RemoveLocalHeap(LocalHeap* local_heap, Callback callback) {
138
139 // Additional code protected from safepoint
140 callback();
141
142 // Remove list from doubly-linked list
143 if (local_heap->next_) local_heap->next_->prev_ = local_heap->prev_;
144 if (local_heap->prev_)
145 local_heap->prev_->next_ = local_heap->next_;
146 else
147 local_heaps_head_ = local_heap->next_;
148 }
149
150 Isolate* isolate() const;
152
155
156 // Mutex is used both for safepointing and adding/removing threads. A
157 // RecursiveMutex is needed since we need to support nested SafepointScopes.
160
162
163 friend class GlobalSafepoint;
165 friend class Isolate;
167 friend class LocalHeap;
169};
170
179
180// Used for reaching a global safepoint, a safepoint across all client isolates
181// of the shared isolate.
182class GlobalSafepoint final {
183 public:
184 explicit GlobalSafepoint(Isolate* isolate);
185
186 void AppendClient(Isolate* client);
187 void RemoveClient(Isolate* client);
188
189 template <typename Callback>
191 AssertActive();
192 for (Isolate* current = clients_head_; current;
193 current = current->global_safepoint_next_client_isolate_) {
194 DCHECK(!current->is_shared_space_isolate());
195 callback(current);
196 }
197 }
198
199 template <typename Callback>
204
206
208
210
211 private:
212 void EnterGlobalSafepointScope(Isolate* initiator);
213 void LeaveGlobalSafepointScope(Isolate* initiator);
214
216 // RecursiveMutex is needed since we need to support nested
217 // GlobalSafepointScopes.
221
223 friend class Isolate;
224};
225
235
238
241
243 public:
244 V8_EXPORT_PRIVATE explicit SafepointScope(Isolate* initiator,
248
249 private:
250 std::optional<IsolateSafepointScope> isolate_safepoint_;
251 std::optional<GlobalSafepointScope> global_safepoint_;
252};
253
254} // namespace internal
255} // namespace v8
256
257#endif // V8_HEAP_SAFEPOINT_H_
Builtins::Kind kind
Definition builtins.cc:40
V8_INLINE void AssertHeld() const
Definition mutex.h:153
void IterateClientIsolates(Callback callback)
Definition safepoint.h:190
void IterateSharedSpaceAndClientIsolates(Callback callback)
Definition safepoint.h:200
void RemoveClient(Isolate *client)
Definition safepoint.cc:344
GlobalSafepoint(Isolate *isolate)
Definition safepoint.cc:324
base::RecursiveMutex clients_mutex_
Definition safepoint.h:218
void AppendClient(Isolate *client)
Definition safepoint.cc:327
V8_EXPORT_PRIVATE bool IsRequestedForTesting()
Definition safepoint.cc:430
void LeaveGlobalSafepointScope(Isolate *initiator)
Definition safepoint.cc:416
void EnterGlobalSafepointScope(Isolate *initiator)
Definition safepoint.cc:368
Isolate *const shared_space_isolate_
Definition safepoint.h:215
void WaitUntilRunningThreadsInSafepoint(const IsolateSafepoint::RunningLocalHeaps &running_threads)
Definition safepoint.cc:246
base::ConditionVariable cv_stopped_
Definition safepoint.h:62
base::ConditionVariable cv_resume_
Definition safepoint.h:61
Isolate * shared_space_isolate() const
Definition safepoint.cc:311
IncludeMainThread ShouldIncludeMainThread(Isolate *initiator)
Definition safepoint.cc:125
V8_EXPORT_PRIVATE void AssertMainThreadIsOnlyThread()
Definition safepoint.cc:304
void ClearSafepointRequestedFlags(IncludeMainThread include_main_thread)
Definition safepoint.cc:201
void InitiateGlobalSafepointScope(Isolate *initiator, PerClientSafepointData *client_data)
Definition safepoint.cc:74
void IterateLocalHeaps(Callback callback)
Definition safepoint.h:37
void TryInitiateGlobalSafepointScope(Isolate *initiator, PerClientSafepointData *client_data)
Definition safepoint.cc:81
void AddLocalHeap(LocalHeap *local_heap, Callback callback)
Definition safepoint.h:120
base::RecursiveMutex local_heaps_mutex_
Definition safepoint.h:158
void LeaveGlobalSafepointScope(Isolate *initiator)
Definition safepoint.cc:181
void InitiateGlobalSafepointScopeRaw(Isolate *initiator, PerClientSafepointData *client_data)
Definition safepoint.cc:105
void WaitUntilRunningThreadsInSafepoint(const PerClientSafepointData *client_data)
Definition safepoint.cc:226
void Iterate(RootVisitor *visitor)
Definition safepoint.cc:296
void RemoveLocalHeap(LocalHeap *local_heap, Callback callback)
Definition safepoint.h:136
void SetSafepointRequestedFlags(IncludeMainThread include_main_thread, IsolateSafepoint::RunningLocalHeaps &running_local_heaps)
Definition safepoint.cc:131
void LockMutex(LocalHeap *local_heap)
Definition safepoint.cc:172
Isolate * global_safepoint_next_client_isolate_
Definition isolate.h:2889
std::optional< IsolateSafepointScope > isolate_safepoint_
Definition safepoint.h:250
std::optional< GlobalSafepointScope > global_safepoint_
Definition safepoint.h:251
LineAndColumn current
TNode< Object > callback
static constexpr GlobalSafepointForSharedSpaceIsolateTag kGlobalSafepointForSharedSpaceIsolate
Definition safepoint.h:240
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_NODISCARD
Definition v8config.h:693