v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
sweeper.h
Go to the documentation of this file.
1// Copyright 2017 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_SWEEPER_H_
6#define V8_HEAP_SWEEPER_H_
7
8#include <limits>
9#include <map>
10#include <type_traits>
11#include <unordered_map>
12#include <unordered_set>
13#include <utility>
14#include <vector>
15
17#include "src/common/globals.h"
18#include "src/flags/flags.h"
19#include "src/heap/gc-tracer.h"
22#include "src/heap/slot-set.h"
24
25namespace v8 {
26namespace internal {
27
28class MutablePageMetadata;
29class NonAtomicMarkingState;
30class PageMetadata;
31class LargePageMetadata;
32class PagedSpaceBase;
33class Space;
34
36
37class Sweeper {
38 public:
39 // When the scope is entered, the concurrent sweeping tasks
40 // are preempted and are not looking at the heap objects, concurrent sweeping
41 // is resumed when the scope is exited.
43 public:
44 explicit PauseMajorSweepingScope(Sweeper* sweeper);
46
47 private:
49 const bool resume_on_exit_;
50 };
51
52 using SweepingList = std::vector<PageMetadata*>;
53 using SweptList = std::vector<PageMetadata*>;
54
56
57 // LocalSweeper holds local data structures required for sweeping and is used
58 // to initiate sweeping and promoted page iteration on multiple threads. Each
59 // thread should holds its own LocalSweeper. Once sweeping is done, all
60 // LocalSweepers should be finalized on the main thread.
61 //
62 // LocalSweeper is not thread-safe and should not be concurrently by several
63 // threads. The exceptions to this rule are allocations during parallel
64 // evacuation and from concurrent allocators. In practice the data structures
65 // in LocalSweeper are only actively used for new space sweeping. Since
66 // parallel evacuators and concurrent allocators never try to allocate in new
67 // space, they will never contribute to new space sweeping and thus can use
68 // the main thread's local sweeper without risk of data races.
69 class LocalSweeper final {
70 public:
71 explicit LocalSweeper(Sweeper* sweeper) : sweeper_(sweeper) {
73 }
74 ~LocalSweeper() = default;
75
76 // Returns true if any swept pages can be allocated on.
78 AllocationSpace identity, SweepingMode sweeping_mode,
79 uint32_t max_pages = std::numeric_limits<uint32_t>::max());
80 // Intended to be called either with a JobDelegate from a job. Returns true
81 // if iteration is finished.
84
85 private:
87 SweepingMode sweeping_mode);
88
92
93 template <typename ShouldYieldCallback>
95 ShouldYieldCallback should_yield_callback);
96 template <typename ShouldYieldCallback>
98 ShouldYieldCallback should_yield_callback);
99
101
102 friend class Sweeper;
103 };
104
105 explicit Sweeper(Heap* heap);
107
118 if (space == NEW_SPACE) return minor_sweeping_in_progress();
120 }
121
122 void TearDown();
123
124 void AddPage(AllocationSpace space, PageMetadata* page);
125 void AddNewSpacePage(PageMetadata* page);
127
128 // Returns true if any swept pages can be allocated on.
130 AllocationSpace identity, SweepingMode sweeping_mode,
131 uint32_t max_pages = std::numeric_limits<uint32_t>::max());
132
135
136 // After calling this function sweeping is considered to be in progress
137 // and the main thread can sweep lazily, but the background sweeper tasks
138 // are not running yet.
139 void StartMajorSweeping();
140 void StartMinorSweeping();
145
146 // Finishes all major sweeping tasks/work without changing the sweeping state.
147 void FinishMajorJobs();
148 // Finishes all major sweeping tasks/work and resets sweeping state to NOT in
149 // progress.
151
152 // Finishes all minor sweeping tasks/work without changing the sweeping state.
153 void FinishMinorJobs();
154 // Finishes all minor sweeping tasks/work and resets sweeping state to NOT in
155 // progress.
157
158 bool AreMinorSweeperTasksRunning() const;
159 bool AreMajorSweeperTasksRunning() const;
160
161 bool UsingMajorSweeperTasks() const;
162
165
166 bool IsSweepingDoneForSpace(AllocationSpace space) const;
167
169 bool is_joining_thread);
170
171 bool IsIteratingPromotedPages() const;
173
175
177
178 uint64_t GetTraceIdForFlowEvent(GCTracer::Scope::ScopeId scope_id) const;
179
180#if DEBUG
181 // Can only be called on the main thread when no tasks are running.
182 bool HasUnsweptPagesForMajorSweeping() const;
183#endif // DEBUG
184
185 // Computes OS page boundaries for unused memory.
186 V8_EXPORT_PRIVATE static std::optional<base::AddressRegion>
188
189 private:
191
192 void RawSweep(PageMetadata* p,
193 FreeSpaceTreatmentMode free_space_treatment_mode,
194 SweepingMode sweeping_mode, bool should_reduce_memory);
195
196 void ZeroOrDiscardUnusedMemory(PageMetadata* page, Address addr, size_t size);
197
198 void AddPageImpl(AllocationSpace space, PageMetadata* page);
199
200 class ConcurrentMajorSweeper;
201 class ConcurrentMinorSweeper;
202
203 class MajorSweeperJob;
204 class MinorSweeperJob;
205
206 static constexpr int kNumberOfSweepingSpaces =
208
209 template <typename Callback>
220
221 // Helper function for RawSweep. Depending on the FreeListRebuildingMode and
222 // FreeSpaceTreatmentMode this function may add the free memory to a free
223 // list, make the memory iterable, clear it, and return the free memory to
224 // the operating system.
226 Address free_start, Address free_end, PageMetadata* page, Space* space,
227 FreeSpaceTreatmentMode free_space_treatment_mode,
228 bool should_reduce_memory);
229
230 // Helper function for RawSweep. Handle remembered set entries in the freed
231 // memory which require clearing.
233 Address free_start, Address free_end, PageMetadata* page,
234 bool record_free_ranges, TypedSlotSet::FreeRangesMap* free_ranges_map,
235 SweepingMode sweeping_mode);
236
237 // Helper function for RawSweep. Clears invalid typed slots in the given free
238 // ranges.
240 PageMetadata* page, const TypedSlotSet::FreeRangesMap& free_ranges_map,
241 SweepingMode sweeping_mode);
242
243 // Helper function for RawSweep. Clears the mark bits and ensures consistency
244 // of live bytes.
246 size_t live_bytes);
247
250
255
258
260 return space >= FIRST_SWEEPABLE_SPACE && space <= LAST_SWEEPABLE_SPACE;
261 }
262
265 return space - FIRST_SWEEPABLE_SPACE;
266 }
267
270
271 void AddSweptPage(PageMetadata* page, AllocationSpace identity);
272
273 enum class SweepingScope { kMinor, kMajor };
274 template <SweepingScope scope>
277 typename std::conditional<scope == SweepingScope::kMinor,
281 typename std::conditional<scope == SweepingScope::kMinor,
283
284 public:
285 explicit SweepingState(Sweeper* sweeper);
287
288 void InitializeSweeping();
289 void StartSweeping();
292 void FinishSweeping();
293 void JoinSweeping();
294
295 bool HasValidJob() const;
296 bool HasActiveJob() const;
297
298 bool in_progress() const { return in_progress_; }
300 std::vector<ConcurrentSweeper>& concurrent_sweepers() {
302 }
303
304 void Pause();
305 void Resume();
306
307 uint64_t trace_id() const { return trace_id_; }
308 uint64_t background_trace_id() const { return background_trace_id_; }
309
310 private:
312 // Main thread can finalize sweeping, while background threads allocation
313 // slow path checks this flag to see whether it could support concurrent
314 // sweeping.
315 std::atomic<bool> in_progress_{false};
316 std::unique_ptr<JobHandle> job_handle_;
317 std::vector<ConcurrentSweeper> concurrent_sweepers_;
318 uint64_t trace_id_ = 0;
321 };
322
323 Heap* const heap_;
330 std::atomic<bool> has_swept_pages_[kNumberOfSweepingSpaces]{false};
331 std::vector<MutablePageMetadata*> sweeping_list_for_promoted_page_iteration_;
335
336 // The following fields are used for maintaining an order between iterating
337 // promoted pages and sweeping array buffer extensions.
339 std::atomic<size_t> iterated_promoted_pages_count_{0};
342 std::atomic<bool> promoted_page_iteration_in_progress_{false};
343};
344
345template <typename ShouldYieldCallback>
347 ShouldYieldCallback should_yield_callback) {
348 if (!sweeper_->sweeping_in_progress()) return true;
349 if (!sweeper_->IsIteratingPromotedPages()) return true;
350 if (!ParallelIteratePromotedPagesImpl(should_yield_callback)) return false;
351 base::MutexGuard guard(
353 // Check again that iteration is not yet finished.
354 if (!sweeper_->IsIteratingPromotedPages()) return true;
355 if (should_yield_callback()) {
356 return false;
357 }
360 return true;
361}
362
363template <typename ShouldYieldCallback>
365 ShouldYieldCallback should_yield_callback) {
366 while (!should_yield_callback()) {
367 MutablePageMetadata* chunk = sweeper_->GetPromotedPageSafe();
368 if (chunk == nullptr) return true;
369 ParallelIteratePromotedPage(chunk);
370 }
371 return false;
372}
373
374} // namespace internal
375} // namespace v8
376
377#endif // V8_HEAP_SWEEPER_H_
bool ParallelIteratePromotedPagesImpl(ShouldYieldCallback should_yield_callback)
Definition sweeper.h:364
bool ContributeAndWaitForPromotedPagesIterationImpl(ShouldYieldCallback should_yield_callback)
Definition sweeper.h:346
void ParallelSweepPage(PageMetadata *page, AllocationSpace identity, SweepingMode sweeping_mode)
Definition sweeper.cc:376
bool ParallelSweepSpace(AllocationSpace identity, SweepingMode sweeping_mode, uint32_t max_pages=std::numeric_limits< uint32_t >::max())
Definition sweeper.cc:347
LocalSweeper(Sweeper *sweeper)
Definition sweeper.h:71
void ParallelIteratePromotedPage(MutablePageMetadata *page)
Definition sweeper.cc:620
std::atomic< bool > in_progress_
Definition sweeper.h:315
uint64_t background_trace_id() const
Definition sweeper.h:308
std::vector< ConcurrentSweeper > & concurrent_sweepers()
Definition sweeper.h:300
std::vector< ConcurrentSweeper > concurrent_sweepers_
Definition sweeper.h:317
std::unique_ptr< JobHandle > job_handle_
Definition sweeper.h:316
typename std::conditional< scope==SweepingScope::kMinor, ConcurrentMinorSweeper, ConcurrentMajorSweeper >::type ConcurrentSweeper
Definition sweeper.h:276
typename std::conditional< scope==SweepingScope::kMinor, MinorSweeperJob, MajorSweeperJob >::type SweeperJob
Definition sweeper.h:280
bool sweeping_in_progress() const
Definition sweeper.h:114
bool sweeping_in_progress_for_space(AllocationSpace space) const
Definition sweeper.h:117
void EnsureMajorCompleted()
Definition sweeper.cc:830
void InitializeMinorSweeping()
Definition sweeper.cc:669
static int GetSweepSpaceIndex(AllocationSpace space)
Definition sweeper.h:263
bool AreMajorSweeperTasksRunning() const
Definition sweeper.cc:903
SweptList GetAllSweptPagesSafe(PagedSpaceBase *space)
Definition sweeper.cc:800
V8_EXPORT_PRIVATE void StartMajorSweeperTasks()
Definition sweeper.cc:738
static constexpr int kNumberOfSweepingSpaces
Definition sweeper.h:206
PageMetadata * GetSweptPageSafe(PagedSpaceBase *space)
Definition sweeper.cc:785
bool ShouldRefillFreelistForSpace(AllocationSpace space) const
Definition sweeper.cc:1470
bool TryRemovePromotedPageSafe(MutablePageMetadata *chunk)
Definition sweeper.cc:1300
base::ConditionVariable cv_page_swept_
Definition sweeper.h:326
base::Mutex mutex_
Definition sweeper.h:325
static V8_EXPORT_PRIVATE std::optional< base::AddressRegion > ComputeDiscardMemoryArea(Address start, Address end)
Definition sweeper.cc:940
static bool IsValidSweepingSpace(AllocationSpace space)
Definition sweeper.h:259
MutablePageMetadata * GetPromotedPageSafe()
Definition sweeper.cc:1435
void PrepareToBeSweptPage(AllocationSpace space, PageMetadata *page)
Definition sweeper.cc:1382
void CleanupRememberedSetEntriesForFreedMemory(Address free_start, Address free_end, PageMetadata *page, bool record_free_ranges, TypedSlotSet::FreeRangesMap *free_ranges_map, SweepingMode sweeping_mode)
Definition sweeper.cc:1006
void ContributeAndWaitForPromotedPagesIteration()
Definition sweeper.cc:1183
void AddNewSpacePage(PageMetadata *page)
Definition sweeper.cc:1316
uint64_t GetTraceIdForFlowEvent(GCTracer::Scope::ScopeId scope_id) const
Definition sweeper.cc:1541
size_t promoted_pages_for_iteration_count_
Definition sweeper.h:338
base::ConditionVariable promoted_pages_iteration_notification_variable_
Definition sweeper.h:341
bool major_sweeping_in_progress() const
Definition sweeper.h:108
Sweeper(Heap *heap)
Definition sweeper.cc:653
void ZeroOrDiscardUnusedMemory(PageMetadata *page, Address addr, size_t size)
Definition sweeper.cc:953
bool minor_sweeping_in_progress() const
Definition sweeper.h:111
void NotifyPromotedPagesIterationFinished()
Definition sweeper.cc:1197
void InitializeMajorSweeping()
Definition sweeper.cc:665
size_t ConcurrentMinorSweepingPageCount()
Definition sweeper.cc:1205
NonAtomicMarkingState *const marking_state_
Definition sweeper.h:324
void ClearMarkBitsAndHandleLivenessStatistics(PageMetadata *page, size_t live_bytes)
Definition sweeper.cc:1074
bool TryRemoveSweepingPageSafe(AllocationSpace space, PageMetadata *page)
Definition sweeper.cc:1283
SweepingState< SweepingScope::kMajor > major_sweeping_state_
Definition sweeper.h:333
bool IsSweepingDoneForSpace(AllocationSpace space) const
Definition sweeper.cc:1455
bool ParallelSweepSpace(AllocationSpace identity, SweepingMode sweeping_mode, uint32_t max_pages=std::numeric_limits< uint32_t >::max())
Definition sweeper.cc:1223
size_t ConcurrentMajorSweepingPageCount()
Definition sweeper.cc:1212
std::atomic< bool > has_swept_pages_[kNumberOfSweepingSpaces]
Definition sweeper.h:330
void EnsurePageIsSwept(PageMetadata *page)
Definition sweeper.cc:1231
NonAtomicMarkingState * marking_state() const
Definition sweeper.h:190
std::atomic< size_t > iterated_promoted_pages_count_
Definition sweeper.h:339
std::atomic< bool > promoted_page_iteration_in_progress_
Definition sweeper.h:342
PageMetadata * GetSweepingPageSafe(AllocationSpace space)
Definition sweeper.cc:1418
V8_EXPORT_PRIVATE void StartMinorSweeperTasks()
Definition sweeper.cc:764
void ForAllSweepingSpaces(Callback callback) const
Definition sweeper.h:210
void CleanupTypedSlotsInFreeMemory(PageMetadata *page, const TypedSlotSet::FreeRangesMap &free_ranges_map, SweepingMode sweeping_mode)
Definition sweeper.cc:1048
Heap *const heap_
Definition sweeper.h:323
bool AreMinorSweeperTasksRunning() const
Definition sweeper.cc:899
SweepingState< SweepingScope::kMinor > minor_sweeping_state_
Definition sweeper.h:334
std::vector< MutablePageMetadata * > sweeping_list_for_promoted_page_iteration_
Definition sweeper.h:331
size_t FreeAndProcessFreedMemory(Address free_start, Address free_end, PageMetadata *page, Space *space, FreeSpaceTreatmentMode free_space_treatment_mode, bool should_reduce_memory)
Definition sweeper.cc:911
void AddSweptPage(PageMetadata *page, AllocationSpace identity)
Definition sweeper.cc:1460
bool IsIteratingPromotedPages() const
Definition sweeper.cc:1179
void SweepEmptyNewSpacePage(PageMetadata *page)
Definition sweeper.cc:1476
SweptList swept_list_[kNumberOfSweepingSpaces]
Definition sweeper.h:327
void NotifyPromotedPageIterationFinished(MutablePageMetadata *chunk)
Definition sweeper.cc:1187
void AddPageImpl(AllocationSpace space, PageMetadata *page)
Definition sweeper.cc:1326
void WaitForPageToBeSwept(PageMetadata *page)
Definition sweeper.cc:1273
void AddPromotedPage(MutablePageMetadata *chunk)
Definition sweeper.cc:1343
base::Mutex promoted_pages_iteration_notification_mutex_
Definition sweeper.h:340
std::atomic< bool > has_sweeping_work_[kNumberOfSweepingSpaces]
Definition sweeper.h:329
void RawSweep(PageMetadata *p, FreeSpaceTreatmentMode free_space_treatment_mode, SweepingMode sweeping_mode, bool should_reduce_memory)
Definition sweeper.cc:1085
SweepingList sweeping_list_[kNumberOfSweepingSpaces]
Definition sweeper.h:328
void PrepareToBeIteratedPromotedPage(PageMetadata *page)
Definition sweeper.cc:1402
std::vector< PageMetadata * > SweepingList
Definition sweeper.h:52
bool UsingMajorSweeperTasks() const
Definition sweeper.cc:907
LocalSweeper main_thread_local_sweeper_
Definition sweeper.h:332
void EnsureMinorCompleted()
Definition sweeper.cc:888
GCTracer::Scope::ScopeId GetTracingScope(AllocationSpace space, bool is_joining_thread)
Definition sweeper.cc:1445
std::vector< PageMetadata * > SweptList
Definition sweeper.h:53
void AddPage(AllocationSpace space, PageMetadata *page)
Definition sweeper.cc:1311
std::map< uint32_t, uint32_t > FreeRangesMap
Definition slot-set.h:306
int start
int end
TNode< Object > callback
FreeSpaceTreatmentMode
Definition sweeper.h:35
@ FIRST_SWEEPABLE_SPACE
Definition globals.h:1328
@ SHARED_TRUSTED_SPACE
Definition globals.h:1314
@ LAST_SWEEPABLE_SPACE
Definition globals.h:1329
V8_EXPORT_PRIVATE FlagValues v8_flags
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_NODISCARD
Definition v8config.h:693
wasm::ValueType type