1 /* 2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_GC_COLLECTOR_MARK_COMPACT_H_ 18 #define ART_RUNTIME_GC_COLLECTOR_MARK_COMPACT_H_ 19 20 #include <signal.h> 21 22 #include <map> 23 #include <memory> 24 #include <unordered_set> 25 26 #include "barrier.h" 27 #include "base/atomic.h" 28 #include "base/bit_vector.h" 29 #include "base/gc_visited_arena_pool.h" 30 #include "base/macros.h" 31 #include "base/mutex.h" 32 #include "garbage_collector.h" 33 #include "gc/accounting/atomic_stack.h" 34 #include "gc/accounting/bitmap-inl.h" 35 #include "gc/accounting/heap_bitmap.h" 36 #include "gc_root.h" 37 #include "immune_spaces.h" 38 #include "offsets.h" 39 40 namespace art HIDDEN { 41 42 EXPORT bool KernelSupportsUffd(); 43 44 namespace mirror { 45 class DexCache; 46 } // namespace mirror 47 48 namespace gc { 49 50 class Heap; 51 52 namespace space { 53 class BumpPointerSpace; 54 } // namespace space 55 56 namespace collector { 57 class MarkCompact; 58 59 // The actual young GC code is also implemented in MarkCompact class. However, 60 // using this class saves us from creating duplicate data-structures, which 61 // would have happened with two instances of MarkCompact. 62 class YoungMarkCompact final : public GarbageCollector { 63 public: 64 YoungMarkCompact(Heap* heap, MarkCompact* main); 65 66 void RunPhases() override REQUIRES(!Locks::mutator_lock_); 67 GetGcType()68 GcType GetGcType() const override { return kGcTypeSticky; } 69 GetCollectorType()70 CollectorType GetCollectorType() const override { return kCollectorTypeCMC; } 71 72 // None of the following methods are ever called as actual GC is performed by MarkCompact. 73 MarkObject(mirror::Object * obj)74 mirror::Object* MarkObject([[maybe_unused]] mirror::Object* obj) override { 75 UNIMPLEMENTED(FATAL); 76 UNREACHABLE(); 77 } MarkHeapReference(mirror::HeapReference<mirror::Object> * obj,bool do_atomic_update)78 void MarkHeapReference([[maybe_unused]] mirror::HeapReference<mirror::Object>* obj, 79 [[maybe_unused]] bool do_atomic_update) override { 80 UNIMPLEMENTED(FATAL); 81 } VisitRoots(mirror::Object *** roots,size_t count,const RootInfo & info)82 void VisitRoots([[maybe_unused]] mirror::Object*** roots, 83 [[maybe_unused]] size_t count, 84 [[maybe_unused]] const RootInfo& info) override { 85 UNIMPLEMENTED(FATAL); 86 } VisitRoots(mirror::CompressedReference<mirror::Object> ** roots,size_t count,const RootInfo & info)87 void VisitRoots([[maybe_unused]] mirror::CompressedReference<mirror::Object>** roots, 88 [[maybe_unused]] size_t count, 89 [[maybe_unused]] const RootInfo& info) override { 90 UNIMPLEMENTED(FATAL); 91 } IsNullOrMarkedHeapReference(mirror::HeapReference<mirror::Object> * obj,bool do_atomic_update)92 bool IsNullOrMarkedHeapReference([[maybe_unused]] mirror::HeapReference<mirror::Object>* obj, 93 [[maybe_unused]] bool do_atomic_update) override { 94 UNIMPLEMENTED(FATAL); 95 UNREACHABLE(); 96 } RevokeAllThreadLocalBuffers()97 void RevokeAllThreadLocalBuffers() override { UNIMPLEMENTED(FATAL); } 98 DelayReferenceReferent(ObjPtr<mirror::Class> klass,ObjPtr<mirror::Reference> reference)99 void DelayReferenceReferent([[maybe_unused]] ObjPtr<mirror::Class> klass, 100 [[maybe_unused]] ObjPtr<mirror::Reference> reference) override { 101 UNIMPLEMENTED(FATAL); 102 } IsMarked(mirror::Object * obj)103 mirror::Object* IsMarked([[maybe_unused]] mirror::Object* obj) override { 104 UNIMPLEMENTED(FATAL); 105 UNREACHABLE(); 106 } ProcessMarkStack()107 void ProcessMarkStack() override { UNIMPLEMENTED(FATAL); } 108 109 private: 110 MarkCompact* const main_collector_; 111 112 DISALLOW_IMPLICIT_CONSTRUCTORS(YoungMarkCompact); 113 }; 114 115 class MarkCompact final : public GarbageCollector { 116 public: 117 using SigbusCounterType = uint32_t; 118 119 static constexpr size_t kAlignment = kObjectAlignment; 120 static constexpr int kCopyMode = -1; 121 // Fake file descriptor for fall back mode (when uffd isn't available) 122 static constexpr int kFallbackMode = -3; 123 static constexpr int kFdUnused = -2; 124 125 // Bitmask for the compaction-done bit in the sigbus_in_progress_count_. 126 static constexpr SigbusCounterType kSigbusCounterCompactionDoneMask = 127 1u << (BitSizeOf<SigbusCounterType>() - 1); 128 129 explicit MarkCompact(Heap* heap); 130 ~MarkCompact()131 ~MarkCompact() {} 132 133 void RunPhases() override REQUIRES(!Locks::mutator_lock_, !lock_); 134 135 void ClampGrowthLimit(size_t new_capacity) REQUIRES(Locks::heap_bitmap_lock_); 136 // Updated before (or in) pre-compaction pause and is accessed only in the 137 // pause or during concurrent compaction. The flag is reset in next GC cycle's 138 // InitializePhase(). Therefore, it's safe to update without any memory ordering. IsCompacting()139 bool IsCompacting() const { return compacting_; } 140 141 // Called by SIGBUS handler. NO_THREAD_SAFETY_ANALYSIS for mutator-lock, which 142 // is asserted in the function. 143 bool SigbusHandler(siginfo_t* info) REQUIRES(!lock_) NO_THREAD_SAFETY_ANALYSIS; 144 GetGcType()145 GcType GetGcType() const override { return kGcTypePartial; } 146 GetCollectorType()147 CollectorType GetCollectorType() const override { 148 return kCollectorTypeCMC; 149 } 150 GetBarrier()151 Barrier& GetBarrier() { 152 return gc_barrier_; 153 } 154 155 mirror::Object* MarkObject(mirror::Object* obj) override 156 REQUIRES_SHARED(Locks::mutator_lock_) 157 REQUIRES(Locks::heap_bitmap_lock_); 158 159 void MarkHeapReference(mirror::HeapReference<mirror::Object>* obj, 160 bool do_atomic_update) override 161 REQUIRES_SHARED(Locks::mutator_lock_) 162 REQUIRES(Locks::heap_bitmap_lock_); 163 164 void VisitRoots(mirror::Object*** roots, 165 size_t count, 166 const RootInfo& info) override 167 REQUIRES_SHARED(Locks::mutator_lock_) 168 REQUIRES(Locks::heap_bitmap_lock_); 169 void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, 170 size_t count, 171 const RootInfo& info) override 172 REQUIRES_SHARED(Locks::mutator_lock_) 173 REQUIRES(Locks::heap_bitmap_lock_); 174 175 bool IsNullOrMarkedHeapReference(mirror::HeapReference<mirror::Object>* obj, 176 bool do_atomic_update) override 177 REQUIRES_SHARED(Locks::mutator_lock_) 178 REQUIRES(Locks::heap_bitmap_lock_); 179 180 void RevokeAllThreadLocalBuffers() override; 181 182 void DelayReferenceReferent(ObjPtr<mirror::Class> klass, 183 ObjPtr<mirror::Reference> reference) override 184 REQUIRES_SHARED(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 185 186 mirror::Object* IsMarked(mirror::Object* obj) override 187 REQUIRES_SHARED(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 188 GetFromSpaceAddrFromBarrier(mirror::Object * old_ref)189 mirror::Object* GetFromSpaceAddrFromBarrier(mirror::Object* old_ref) { 190 CHECK(compacting_); 191 if (HasAddress(old_ref)) { 192 return GetFromSpaceAddr(old_ref); 193 } 194 return old_ref; 195 } 196 // Called from Heap::PostForkChildAction() for non-zygote processes and from 197 // PrepareForCompaction() for zygote processes. Returns true if uffd was 198 // created or was already done. 199 bool CreateUserfaultfd(bool post_fork); 200 201 // Returns a pair indicating if userfaultfd itself is available (first) and if 202 // so then whether its minor-fault feature is available or not (second). 203 static std::pair<bool, bool> GetUffdAndMinorFault(); 204 205 // Add linear-alloc space data when a new space is added to 206 // GcVisitedArenaPool, which mostly happens only once. 207 void AddLinearAllocSpaceData(uint8_t* begin, size_t len); 208 209 // Called by Heap::PreZygoteFork() to reset generational heap pointers and 210 // other data structures as the moving space gets completely evicted into new 211 // zygote-space. 212 void ResetGenerationalState(); 213 214 // In copy-mode of userfaultfd, we don't need to reach a 'processed' state as 215 // it's given that processing thread also copies the page, thereby mapping it. 216 // The order is important as we may treat them as integers. Also 217 // 'kUnprocessed' should be set to 0 as we rely on madvise(dontneed) to return 218 // us zero'ed pages, which implicitly makes page-status initialized to 'kUnprocessed'. 219 enum class PageState : uint8_t { 220 kUnprocessed = 0, // Not processed yet. 221 kProcessing = 1, // Being processed by GC thread and will not be mapped 222 kProcessed = 2, // Processed but not mapped 223 kProcessingAndMapping = 3, // Being processed by GC or mutator and will be mapped 224 kMutatorProcessing = 4, // Being processed by mutator thread 225 kProcessedAndMapping = 5, // Processed and will be mapped 226 kProcessedAndMapped = 6 // Processed and mapped. For SIGBUS. 227 }; 228 229 // Different heap clamping states. 230 enum class ClampInfoStatus : uint8_t { 231 kClampInfoNotDone, 232 kClampInfoPending, 233 kClampInfoFinished 234 }; 235 236 friend void YoungMarkCompact::RunPhases(); 237 238 private: 239 using ObjReference = mirror::CompressedReference<mirror::Object>; 240 static constexpr uint32_t kPageStateMask = (1 << BitSizeOf<uint8_t>()) - 1; 241 // Number of bits (live-words) covered by a single chunk-info (below) 242 // entry/word. 243 // TODO: Since popcount is performed usomg SIMD instructions, we should 244 // consider using 128-bit in order to halve the chunk-info size. 245 static constexpr uint32_t kBitsPerVectorWord = kBitsPerIntPtrT; 246 static constexpr uint32_t kOffsetChunkSize = kBitsPerVectorWord * kAlignment; 247 static_assert(kOffsetChunkSize < kMinPageSize); 248 // Bitmap with bits corresponding to every live word set. For an object 249 // which is 4 words in size will have the corresponding 4 bits set. This is 250 // required for efficient computation of new-address (post-compaction) from 251 // the given old-address (pre-compaction). 252 template <size_t kAlignment> 253 class LiveWordsBitmap : private accounting::MemoryRangeBitmap<kAlignment> { 254 using Bitmap = accounting::Bitmap; 255 using MemRangeBitmap = accounting::MemoryRangeBitmap<kAlignment>; 256 257 public: 258 static_assert(IsPowerOfTwo(kBitsPerVectorWord)); 259 static_assert(IsPowerOfTwo(Bitmap::kBitsPerBitmapWord)); 260 static_assert(kBitsPerVectorWord >= Bitmap::kBitsPerBitmapWord); 261 static constexpr uint32_t kBitmapWordsPerVectorWord = 262 kBitsPerVectorWord / Bitmap::kBitsPerBitmapWord; 263 static_assert(IsPowerOfTwo(kBitmapWordsPerVectorWord)); 264 using MemRangeBitmap::SetBitmapSize; 265 static LiveWordsBitmap* Create(uintptr_t begin, uintptr_t end); 266 267 // Return offset (within the indexed chunk-info) of the nth live word. 268 uint32_t FindNthLiveWordOffset(size_t chunk_idx, uint32_t n) const; 269 // Sets all bits in the bitmap corresponding to the given range. Also 270 // returns the bit-index of the first word. 271 ALWAYS_INLINE uintptr_t SetLiveWords(uintptr_t begin, size_t size); 272 // Count number of live words upto the given bit-index. This is to be used 273 // to compute the post-compact address of an old reference. 274 ALWAYS_INLINE size_t CountLiveWordsUpto(size_t bit_idx) const; 275 // Call 'visitor' for every stride of contiguous marked bits in the live-words 276 // bitmap, starting from begin_bit_idx. Only visit 'bytes' live bytes or 277 // until 'end', whichever comes first. 278 // Visitor is called with index of the first marked bit in the stride, 279 // stride size and whether it's the last stride in the given range or not. 280 template <typename Visitor> 281 ALWAYS_INLINE void VisitLiveStrides(uintptr_t begin_bit_idx, 282 uint8_t* end, 283 const size_t bytes, 284 Visitor&& visitor) const 285 REQUIRES_SHARED(Locks::mutator_lock_); 286 // Count the number of live bytes in the given vector entry. 287 size_t LiveBytesInBitmapWord(size_t chunk_idx) const; ClearBitmap()288 void ClearBitmap() { Bitmap::Clear(); } Begin()289 ALWAYS_INLINE uintptr_t Begin() const { return MemRangeBitmap::CoverBegin(); } HasAddress(mirror::Object * obj)290 ALWAYS_INLINE bool HasAddress(mirror::Object* obj) const { 291 return MemRangeBitmap::HasAddress(reinterpret_cast<uintptr_t>(obj)); 292 } Test(uintptr_t bit_index)293 ALWAYS_INLINE bool Test(uintptr_t bit_index) const { 294 return Bitmap::TestBit(bit_index); 295 } Test(mirror::Object * obj)296 ALWAYS_INLINE bool Test(mirror::Object* obj) const { 297 return MemRangeBitmap::Test(reinterpret_cast<uintptr_t>(obj)); 298 } GetWord(size_t index)299 ALWAYS_INLINE uintptr_t GetWord(size_t index) const { 300 static_assert(kBitmapWordsPerVectorWord == 1); 301 return Bitmap::Begin()[index * kBitmapWordsPerVectorWord]; 302 } 303 }; 304 HasAddress(mirror::Object * obj,uint8_t * begin,uint8_t * end)305 static bool HasAddress(mirror::Object* obj, uint8_t* begin, uint8_t* end) { 306 uint8_t* ptr = reinterpret_cast<uint8_t*>(obj); 307 return ptr >= begin && ptr < end; 308 } 309 HasAddress(mirror::Object * obj)310 bool HasAddress(mirror::Object* obj) const { 311 return HasAddress(obj, moving_space_begin_, moving_space_end_); 312 } 313 // For a given object address in pre-compact space, return the corresponding 314 // address in the from-space, where heap pages are relocated in the compaction 315 // pause. GetFromSpaceAddr(mirror::Object * obj)316 mirror::Object* GetFromSpaceAddr(mirror::Object* obj) const { 317 DCHECK(HasAddress(obj)) << " obj=" << obj; 318 return reinterpret_cast<mirror::Object*>(reinterpret_cast<uintptr_t>(obj) 319 + from_space_slide_diff_); 320 } 321 322 inline bool IsOnAllocStack(mirror::Object* ref) 323 REQUIRES_SHARED(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 324 // Verifies that that given object reference refers to a valid object. 325 // Otherwise fataly dumps logs, including those from callback. 326 template <typename Callback> 327 void VerifyObject(mirror::Object* ref, Callback& callback) const 328 REQUIRES_SHARED(Locks::mutator_lock_); 329 // Check if the obj is within heap and has a klass which is likely to be valid 330 // mirror::Class. 331 bool IsValidObject(mirror::Object* obj) const REQUIRES_SHARED(Locks::mutator_lock_); 332 void InitializePhase(); 333 void FinishPhase(bool performed_compaction) 334 REQUIRES(!Locks::mutator_lock_, !Locks::heap_bitmap_lock_, !lock_); 335 void MarkingPhase() REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::heap_bitmap_lock_); 336 void CompactionPhase() REQUIRES_SHARED(Locks::mutator_lock_); 337 338 void SweepSystemWeaks(Thread* self, Runtime* runtime, const bool paused) 339 REQUIRES_SHARED(Locks::mutator_lock_) 340 REQUIRES(!Locks::heap_bitmap_lock_); 341 // Update the reference at 'offset' in 'obj' with post-compact address, and 342 // return the new address. [begin, end) is a range in which compaction is 343 // happening. So post-compact address needs to be computed only for 344 // pre-compact references in this range. 345 ALWAYS_INLINE mirror::Object* UpdateRef(mirror::Object* obj, 346 MemberOffset offset, 347 uint8_t* begin, 348 uint8_t* end) REQUIRES_SHARED(Locks::mutator_lock_); 349 350 // Verify that the gc-root is updated only once. Returns false if the update 351 // shouldn't be done. 352 ALWAYS_INLINE bool VerifyRootSingleUpdate(void* root, 353 mirror::Object* old_ref, 354 const RootInfo& info) 355 REQUIRES_SHARED(Locks::mutator_lock_); 356 // Update the given root with post-compact address and return the new address. [begin, end) 357 // is a range in which compaction is happening. So post-compact address needs to be computed 358 // only for pre-compact references in this range. 359 ALWAYS_INLINE mirror::Object* UpdateRoot(mirror::CompressedReference<mirror::Object>* root, 360 uint8_t* begin, 361 uint8_t* end, 362 const RootInfo& info = RootInfo(RootType::kRootUnknown)) 363 REQUIRES_SHARED(Locks::mutator_lock_); 364 ALWAYS_INLINE mirror::Object* UpdateRoot(mirror::Object** root, 365 uint8_t* begin, 366 uint8_t* end, 367 const RootInfo& info = RootInfo(RootType::kRootUnknown)) 368 REQUIRES_SHARED(Locks::mutator_lock_); 369 // If the given pre-compact address (old_ref) is in [begin, end) range of moving-space, 370 // then the function returns the computed post-compact address. Otherwise, 'old_ref' is 371 // returned. 372 ALWAYS_INLINE mirror::Object* PostCompactAddress(mirror::Object* old_ref, 373 uint8_t* begin, 374 uint8_t* end) const 375 REQUIRES_SHARED(Locks::mutator_lock_); 376 // Compute post-compact address of an object in moving space. This function 377 // assumes that old_ref is in moving space. 378 ALWAYS_INLINE mirror::Object* PostCompactAddressUnchecked(mirror::Object* old_ref) const 379 REQUIRES_SHARED(Locks::mutator_lock_); 380 // Compute the new address for an object which was allocated prior to starting 381 // this GC cycle. 382 ALWAYS_INLINE mirror::Object* PostCompactOldObjAddr(mirror::Object* old_ref) const 383 REQUIRES_SHARED(Locks::mutator_lock_); 384 // Compute the new address for an object which was black allocated during this 385 // GC cycle. 386 ALWAYS_INLINE mirror::Object* PostCompactBlackObjAddr(mirror::Object* old_ref) const 387 REQUIRES_SHARED(Locks::mutator_lock_); 388 // Clears (for alloc spaces in the beginning of marking phase) or ages the 389 // card table. Also, identifies immune spaces and mark bitmap. 390 void PrepareForMarking(bool pre_marking) REQUIRES_SHARED(Locks::mutator_lock_) 391 REQUIRES(Locks::heap_bitmap_lock_); 392 393 // Perform one last round of marking, identifying roots from dirty cards 394 // during a stop-the-world (STW) pause. 395 void MarkingPause() REQUIRES(Locks::mutator_lock_, !Locks::heap_bitmap_lock_); 396 // Perform stop-the-world pause prior to concurrent compaction. 397 // Updates GC-roots and protects heap so that during the concurrent 398 // compaction phase we can receive faults and compact the corresponding pages 399 // on the fly. 400 void CompactionPause() REQUIRES(Locks::mutator_lock_); 401 // Compute offsets (in chunk_info_vec_) and other data structures required 402 // during concurrent compaction. Also determines a black-dense region at the 403 // beginning of the moving space which is not compacted. Returns false if 404 // performing compaction isn't required. 405 bool PrepareForCompaction() REQUIRES_SHARED(Locks::mutator_lock_) 406 REQUIRES(!Locks::heap_bitmap_lock_); 407 408 // Copy gPageSize live bytes starting from 'offset' (within the moving space), 409 // which must be within 'obj', into the gPageSize sized memory pointed by 'addr'. 410 // Then update the references within the copied objects. The boundary objects are 411 // partially updated such that only the references that lie in the page are updated. 412 // This is necessary to avoid cascading userfaults. 413 template <bool kSetupForGenerational> 414 void CompactPage(mirror::Object* obj, 415 uint32_t offset, 416 uint8_t* addr, 417 uint8_t* to_space_addr, 418 bool needs_memset_zero) REQUIRES_SHARED(Locks::mutator_lock_); 419 // Compact the bump-pointer space. Pass page that should be used as buffer for 420 // userfaultfd. 421 template <int kMode> 422 void CompactMovingSpace(uint8_t* page) REQUIRES_SHARED(Locks::mutator_lock_); 423 424 // Compact the given page as per func and change its state. Also map/copy the 425 // page, if required. Returns true if the page was compacted, else false. 426 template <int kMode, typename CompactionFn> 427 ALWAYS_INLINE bool DoPageCompactionWithStateChange(size_t page_idx, 428 uint8_t* to_space_page, 429 uint8_t* page, 430 bool map_immediately, 431 CompactionFn func) 432 REQUIRES_SHARED(Locks::mutator_lock_); 433 434 // Update all the objects in the given non-moving page. 'first' object 435 // could have started in some preceding page. 436 template <bool kSetupForGenerational> 437 void UpdateNonMovingPage(mirror::Object* first, 438 uint8_t* page, 439 ptrdiff_t from_space_diff, 440 accounting::ContinuousSpaceBitmap* bitmap) 441 REQUIRES_SHARED(Locks::mutator_lock_); 442 // Update all the references in the non-moving space. 443 void UpdateNonMovingSpace() REQUIRES_SHARED(Locks::mutator_lock_); 444 445 // For all the pages in non-moving space, find the first object that overlaps 446 // with the pages' start address, and store in first_objs_non_moving_space_ array. 447 size_t InitNonMovingFirstObjects(uintptr_t begin, 448 uintptr_t end, 449 accounting::ContinuousSpaceBitmap* bitmap, 450 ObjReference* first_objs_arr) 451 REQUIRES_SHARED(Locks::mutator_lock_); 452 // In addition to the first-objects for every post-compact moving space page, 453 // also find offsets within those objects from where the contents should be 454 // copied to the page. The offsets are relative to the moving-space's 455 // beginning. Store the computed first-object and offset in first_objs_moving_space_ 456 // and pre_compact_offset_moving_space_ respectively. 457 void InitMovingSpaceFirstObjects(size_t vec_len, size_t to_space_page_idx) 458 REQUIRES_SHARED(Locks::mutator_lock_); 459 460 // Gather the info related to black allocations from bump-pointer space to 461 // enable concurrent sliding of these pages. 462 void UpdateMovingSpaceBlackAllocations() REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 463 // Update first-object info from allocation-stack for non-moving space black 464 // allocations. 465 void UpdateNonMovingSpaceBlackAllocations() REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 466 467 // Slides (retain the empty holes, which are usually part of some in-use TLAB) 468 // black page in the moving space. 'first_obj' is the object that overlaps with 469 // the first byte of the page being slid. pre_compact_page is the pre-compact 470 // address of the page being slid. 'dest' is the gPageSize sized memory where 471 // the contents would be copied. 472 void SlideBlackPage(mirror::Object* first_obj, 473 mirror::Object* next_page_first_obj, 474 uint32_t first_chunk_size, 475 uint8_t* const pre_compact_page, 476 uint8_t* dest, 477 bool needs_memset_zero) REQUIRES_SHARED(Locks::mutator_lock_); 478 479 // Perform reference-processing and the likes before sweeping the non-movable 480 // spaces. 481 void ReclaimPhase() REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::heap_bitmap_lock_); 482 483 // Mark GC-roots (except from immune spaces and thread-stacks) during a STW pause. 484 void ReMarkRoots(Runtime* runtime) REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 485 // Concurrently mark GC-roots, except from immune spaces. 486 void MarkRoots(VisitRootFlags flags) REQUIRES_SHARED(Locks::mutator_lock_) 487 REQUIRES(Locks::heap_bitmap_lock_); 488 // Collect thread stack roots via a checkpoint. 489 void MarkRootsCheckpoint(Thread* self, Runtime* runtime) REQUIRES_SHARED(Locks::mutator_lock_) 490 REQUIRES(Locks::heap_bitmap_lock_); 491 // Second round of concurrent marking. Mark all gray objects that got dirtied 492 // since the first round. 493 void PreCleanCards() REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_); 494 495 void MarkNonThreadRoots(Runtime* runtime) REQUIRES_SHARED(Locks::mutator_lock_) 496 REQUIRES(Locks::heap_bitmap_lock_); 497 void MarkConcurrentRoots(VisitRootFlags flags, Runtime* runtime) 498 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_); 499 500 // Traverse through the reachable objects and mark them. 501 void MarkReachableObjects() REQUIRES_SHARED(Locks::mutator_lock_) 502 REQUIRES(Locks::heap_bitmap_lock_); 503 // Scan (only) immune spaces looking for references into the garbage collected 504 // spaces. 505 void UpdateAndMarkModUnion() REQUIRES_SHARED(Locks::mutator_lock_) 506 REQUIRES(Locks::heap_bitmap_lock_); 507 // Scan mod-union and card tables, covering all the spaces, to identify dirty objects. 508 // These are in 'minimum age' cards, which is 'kCardAged' in case of concurrent (second round) 509 // marking and kCardDirty during the STW pause. 510 void ScanDirtyObjects(bool paused, uint8_t minimum_age) REQUIRES_SHARED(Locks::mutator_lock_) 511 REQUIRES(Locks::heap_bitmap_lock_); 512 // Recursively mark dirty objects. Invoked both concurrently as well in a STW 513 // pause in PausePhase(). 514 void RecursiveMarkDirtyObjects(bool paused, uint8_t minimum_age) 515 REQUIRES_SHARED(Locks::mutator_lock_) 516 REQUIRES(Locks::heap_bitmap_lock_); 517 // Go through all the objects in the mark-stack until it's empty. 518 void ProcessMarkStack() override REQUIRES_SHARED(Locks::mutator_lock_) 519 REQUIRES(Locks::heap_bitmap_lock_); 520 void ExpandMarkStack() REQUIRES_SHARED(Locks::mutator_lock_) 521 REQUIRES(Locks::heap_bitmap_lock_); 522 523 // Scan object for references. If kUpdateLivewords is true then set bits in 524 // the live-words bitmap and add size to chunk-info. 525 template <bool kUpdateLiveWords> 526 void ScanObject(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) 527 REQUIRES(Locks::heap_bitmap_lock_); 528 // Push objects to the mark-stack right after successfully marking objects. 529 void PushOnMarkStack(mirror::Object* obj) 530 REQUIRES_SHARED(Locks::mutator_lock_) 531 REQUIRES(Locks::heap_bitmap_lock_); 532 533 // Update the live-words bitmap as well as add the object size to the 534 // chunk-info vector. Both are required for computation of post-compact addresses. 535 // Also updates freed_objects_ counter. 536 void UpdateLivenessInfo(mirror::Object* obj, size_t obj_size) 537 REQUIRES_SHARED(Locks::mutator_lock_); 538 539 void ProcessReferences(Thread* self) 540 REQUIRES_SHARED(Locks::mutator_lock_) 541 REQUIRES(!Locks::heap_bitmap_lock_); 542 543 void MarkObjectNonNull(mirror::Object* obj, 544 mirror::Object* holder = nullptr, 545 MemberOffset offset = MemberOffset(0)) 546 REQUIRES_SHARED(Locks::mutator_lock_) 547 REQUIRES(Locks::heap_bitmap_lock_); 548 549 void MarkObject(mirror::Object* obj, mirror::Object* holder, MemberOffset offset) 550 REQUIRES_SHARED(Locks::mutator_lock_) 551 REQUIRES(Locks::heap_bitmap_lock_); 552 553 template <bool kParallel> 554 bool MarkObjectNonNullNoPush(mirror::Object* obj, 555 mirror::Object* holder = nullptr, 556 MemberOffset offset = MemberOffset(0)) 557 REQUIRES(Locks::heap_bitmap_lock_) 558 REQUIRES_SHARED(Locks::mutator_lock_); 559 560 void Sweep(bool swap_bitmaps) REQUIRES_SHARED(Locks::mutator_lock_) 561 REQUIRES(Locks::heap_bitmap_lock_); 562 void SweepLargeObjects(bool swap_bitmaps) REQUIRES_SHARED(Locks::mutator_lock_) 563 REQUIRES(Locks::heap_bitmap_lock_); 564 565 // Perform all kernel operations required for concurrent compaction. Includes 566 // mremap to move pre-compact pages to from-space, followed by userfaultfd 567 // registration on the moving space and linear-alloc. 568 void KernelPreparation(); 569 // Called by KernelPreparation() for every memory range being prepared for 570 // userfaultfd registration. 571 void KernelPrepareRangeForUffd(uint8_t* to_addr, uint8_t* from_addr, size_t map_size); 572 573 void RegisterUffd(void* addr, size_t size); 574 void UnregisterUffd(uint8_t* start, size_t len); 575 576 // Called by SIGBUS handler to compact and copy/map the fault page in moving space. 577 void ConcurrentlyProcessMovingPage(uint8_t* fault_page, 578 uint8_t* buf, 579 size_t nr_moving_space_used_pages, 580 bool tolerate_enoent) REQUIRES_SHARED(Locks::mutator_lock_); 581 // Called by SIGBUS handler to process and copy/map the fault page in linear-alloc. 582 void ConcurrentlyProcessLinearAllocPage(uint8_t* fault_page, bool tolerate_enoent) 583 REQUIRES_SHARED(Locks::mutator_lock_); 584 585 // Process concurrently all the pages in linear-alloc. Called by gc-thread. 586 void ProcessLinearAlloc() REQUIRES_SHARED(Locks::mutator_lock_); 587 588 // Does the following: 589 // 1. Checks the status of to-space pages in [cur_page_idx, 590 // last_checked_reclaim_page_idx_) range to see whether the corresponding 591 // from-space pages can be reused. 592 // 2. Taking into consideration classes which are allocated after their 593 // objects (in address order), computes the page (in from-space) from which 594 // actual reclamation can be done. 595 // 3. Map the pages in [cur_page_idx, end_idx_for_mapping) range. 596 // 4. Madvise the pages in [page from (2), last_reclaimed_page_) 597 bool FreeFromSpacePages(size_t cur_page_idx, int mode, size_t end_idx_for_mapping) 598 REQUIRES_SHARED(Locks::mutator_lock_); 599 600 // Maps moving space pages in [start_idx, arr_len) range. It fetches the page 601 // address containing the compacted content from moving_pages_status_ array. 602 // 'from_fault' is true when called from userfault (sigbus handler). 603 // 'return_on_contention' is set to true by gc-thread while it is compacting 604 // pages. In the end it calls the function with `return_on_contention=false` 605 // to ensure all pages are mapped. Returns number of pages that are mapped. 606 size_t MapMovingSpacePages(size_t start_idx, 607 size_t arr_len, 608 bool from_fault, 609 bool return_on_contention, 610 bool tolerate_enoent) REQUIRES_SHARED(Locks::mutator_lock_); 611 IsValidFd(int fd)612 bool IsValidFd(int fd) const { return fd >= 0; } 613 GetPageStateFromWord(uint32_t page_word)614 PageState GetPageStateFromWord(uint32_t page_word) { 615 return static_cast<PageState>(static_cast<uint8_t>(page_word)); 616 } 617 GetMovingPageState(size_t idx)618 PageState GetMovingPageState(size_t idx) { 619 return GetPageStateFromWord(moving_pages_status_[idx].load(std::memory_order_acquire)); 620 } 621 622 // Add/update <class, obj> pair if class > obj and obj is the lowest address 623 // object of class. 624 ALWAYS_INLINE void UpdateClassAfterObjectMap(mirror::Object* obj) 625 REQUIRES_SHARED(Locks::mutator_lock_); 626 627 void MarkZygoteLargeObjects() REQUIRES_SHARED(Locks::mutator_lock_) 628 REQUIRES(Locks::heap_bitmap_lock_); 629 630 // Map zero-pages in the given range. 'tolerate_eexist' and 'tolerate_enoent' 631 // help us decide if we should expect EEXIST or ENOENT back from the ioctl 632 // respectively. It may return after mapping fewer pages than requested. 633 // found to be contended, then we delay the operations based on thread's 634 // Returns number of bytes (multiple of page-size) now known to be mapped. 635 size_t ZeropageIoctl(void* addr, size_t length, bool tolerate_eexist, bool tolerate_enoent); 636 // Map 'buffer' to 'dst', both being 'length' bytes using at most one ioctl 637 // call. 'return_on_contention' indicates that the function should return 638 // as soon as mmap_lock contention is detected. Like ZeropageIoctl(), this 639 // function also uses thread's priority to decide how long we delay before 640 // forcing the ioctl operation. If ioctl returns EEXIST, then also function 641 // returns. Returns number of bytes (multiple of page-size) mapped. 642 size_t CopyIoctl( 643 void* dst, void* buffer, size_t length, bool return_on_contention, bool tolerate_enoent); 644 645 // Called after updating linear-alloc page(s) to map the page. It first 646 // updates the state of the pages to kProcessedAndMapping and after ioctl to 647 // kProcessedAndMapped. Returns true if at least the first page is now mapped. 648 // If 'free_pages' is true then also frees shadow pages. If 'single_ioctl' 649 // is true, then stops after first ioctl. 650 bool MapUpdatedLinearAllocPages(uint8_t* start_page, 651 uint8_t* start_shadow_page, 652 Atomic<PageState>* state, 653 size_t length, 654 bool free_pages, 655 bool single_ioctl, 656 bool tolerate_enoent); 657 // Called for clamping of 'info_map_' and other GC data structures, which are 658 // small and/or in >4GB address space. There is no real benefit of clamping 659 // them synchronously during app forking. It clamps only if clamp_info_map_status_ 660 // is set to kClampInfoPending, which is done by ClampGrowthLimit(). 661 void MaybeClampGcStructures() REQUIRES(Locks::heap_bitmap_lock_); 662 663 size_t ComputeInfoMapSize(); 664 // Initialize all the info-map related fields of this GC. Returns total size 665 // of all the structures in info-map. 666 size_t InitializeInfoMap(uint8_t* p, size_t moving_space_sz); 667 // Update class-table classes in compaction pause if we are running in debuggable 668 // mode. Only visit class-table in image spaces if 'immune_class_table_only' 669 // is true. 670 void UpdateClassTableClasses(Runtime* runtime, bool immune_class_table_only) 671 REQUIRES_SHARED(Locks::mutator_lock_); 672 673 void SweepArray(accounting::ObjectStack* obj_arr, bool swap_bitmaps) 674 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_); 675 676 // Set bit corresponding to 'obj' in 'mid_to_old_promo_bit_vec_' bit-vector. 677 // 'obj' is the post-compacted object in mid-gen, which will get promoted to 678 // old-gen and hence 'mid_to_old_promo_bit_vec_' is copied into mark-bitmap at 679 // the end of GC for next GC cycle. 680 void SetBitForMidToOldPromotion(uint8_t* obj); 681 // Scan old-gen for young GCs by looking for cards that are at least 'aged' in 682 // the card-table corresponding to moving and non-moving spaces. 683 void ScanOldGenObjects() REQUIRES(Locks::heap_bitmap_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 684 685 // Verify that cards corresponding to objects containing references to 686 // young-gen are dirty. 687 void VerifyNoMissingCardMarks() REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_); 688 // Verify that post-GC objects (all objects except the ones allocated after 689 // marking pause) are valid with valid references in them. Bitmap corresponding 690 // to [moving_space_begin_, mark_bitmap_clear_end) was retained. This is used in 691 // case compaction is skipped. 692 void VerifyPostGCObjects(bool performed_compaction, uint8_t* mark_bitmap_clear_end) 693 REQUIRES(Locks::heap_bitmap_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 694 695 // For checkpoints 696 Barrier gc_barrier_; 697 // Required only when mark-stack is accessed in shared mode, which happens 698 // when collecting thread-stack roots using checkpoint. Otherwise, we use it 699 // to synchronize on updated_roots_ in debug-builds. 700 Mutex lock_; 701 // Counters to synchronize mutator threads and gc-thread at the end of 702 // compaction. Counter 0 represents the number of mutators still working on 703 // moving space pages which started before gc-thread finished compacting pages, 704 // whereas the counter 1 represents those which started afterwards but 705 // before unregistering the space from uffd. Once counter 1 reaches 0, the 706 // gc-thread madvises spaces and data structures like page-status array. 707 // Both the counters are set to 0 before compaction begins. They are or'ed 708 // with kSigbusCounterCompactionDoneMask one-by-one by gc-thread after 709 // compaction to communicate the status to future mutators. 710 std::atomic<SigbusCounterType> sigbus_in_progress_count_[2]; 711 MemMap from_space_map_; 712 // Any array of live-bytes in logical chunks of kOffsetChunkSize size 713 // in the 'to-be-compacted' space. 714 MemMap info_map_; 715 // Set of page-sized buffers used for compaction. The first page is used by 716 // the GC thread. Subdequent pages are used by mutator threads in case of 717 // SIGBUS feature, and by uffd-worker threads otherwise. In the latter case 718 // the first page is also used for termination of concurrent compaction by 719 // making worker threads terminate the userfaultfd read loop. 720 MemMap compaction_buffers_map_; 721 722 class LessByArenaAddr { 723 public: operator()724 bool operator()(const TrackedArena* a, const TrackedArena* b) const { 725 return std::less<uint8_t*>{}(a->Begin(), b->Begin()); 726 } 727 }; 728 729 // Map of arenas allocated in LinearAlloc arena-pool and last non-zero page, 730 // captured during compaction pause for concurrent updates. 731 std::map<const TrackedArena*, uint8_t*, LessByArenaAddr> linear_alloc_arenas_; 732 // Set of PageStatus arrays, one per arena-pool space. It's extremely rare to 733 // have more than one, but this is to be ready for the worst case. 734 class LinearAllocSpaceData { 735 public: LinearAllocSpaceData(MemMap && shadow,MemMap && page_status_map,uint8_t * begin,uint8_t * end)736 LinearAllocSpaceData(MemMap&& shadow, MemMap&& page_status_map, uint8_t* begin, uint8_t* end) 737 : shadow_(std::move(shadow)), 738 page_status_map_(std::move(page_status_map)), 739 begin_(begin), 740 end_(end) {} 741 742 MemMap shadow_; 743 MemMap page_status_map_; 744 uint8_t* begin_; 745 uint8_t* end_; 746 }; 747 std::vector<LinearAllocSpaceData> linear_alloc_spaces_data_; 748 749 class LessByObjReference { 750 public: operator()751 bool operator()(const ObjReference& a, const ObjReference& b) const { 752 return std::less<mirror::Object*>{}(a.AsMirrorPtr(), b.AsMirrorPtr()); 753 } 754 }; 755 using ClassAfterObjectMap = std::map<ObjReference, ObjReference, LessByObjReference>; 756 // map of <K, V> such that the class K (in moving space) is after its 757 // objects, and its object V is the lowest object (in moving space). 758 ClassAfterObjectMap class_after_obj_map_; 759 // Since the compaction is done in reverse, we use a reverse iterator. It is maintained 760 // either at the pair whose class is lower than the first page to be freed, or at the 761 // pair whose object is not yet compacted. 762 ClassAfterObjectMap::const_reverse_iterator class_after_obj_iter_; 763 // Every object inside the immune spaces is assumed to be marked. 764 ImmuneSpaces immune_spaces_; 765 // Bit-vector to store bits for objects which are promoted from mid-gen to 766 // old-gen during compaction. Later in FinishPhase() it's copied into 767 // mark-bitmap of moving-space. 768 std::unique_ptr<BitVector> mid_to_old_promo_bit_vec_; 769 770 // List of objects found to have native gc-roots into young-gen during 771 // marking. Cards corresponding to these objects are dirtied at the end of GC. 772 // These have to be captured during marking phase as we don't update 773 // native-roots during compaction. 774 std::vector<mirror::Object*> dirty_cards_later_vec_; 775 space::ContinuousSpace* non_moving_space_; 776 space::BumpPointerSpace* const bump_pointer_space_; 777 Thread* thread_running_gc_; 778 // Length of 'chunk_info_vec_' vector (defined below). 779 size_t vector_length_; 780 size_t live_stack_freeze_size_; 781 size_t non_moving_first_objs_count_; 782 // Length of first_objs_moving_space_ and pre_compact_offset_moving_space_ 783 // arrays. Also the number of pages which are to be compacted. 784 size_t moving_first_objs_count_; 785 // Number of pages containing black-allocated objects, indicating number of 786 // pages to be slid. 787 size_t black_page_count_; 788 // Used by FreeFromSpacePages() for maintaining markers in the moving space for 789 // how far the pages have been reclaimed (madvised) and checked. 790 // 791 // Pages from this index to the end of to-space have been checked (via page_status) 792 // and their corresponding from-space pages are reclaimable. 793 size_t last_checked_reclaim_page_idx_; 794 // All from-space pages in [last_reclaimed_page_, from_space->End()) are 795 // reclaimed (madvised). Pages in [from-space page corresponding to 796 // last_checked_reclaim_page_idx_, last_reclaimed_page_) are not reclaimed as 797 // they may contain classes required for class hierarchy traversal for 798 // visiting references during compaction. 799 uint8_t* last_reclaimed_page_; 800 // All the pages in [last_reclaimable_page_, last_reclaimed_page_) in 801 // from-space are available to store compacted contents for batching until the 802 // next time madvise is called. 803 uint8_t* last_reclaimable_page_; 804 // [cur_reclaimable_page_, last_reclaimed_page_) have been used to store 805 // compacted contents for batching. 806 uint8_t* cur_reclaimable_page_; 807 808 // Mark bits for non-moving space 809 accounting::ContinuousSpaceBitmap* non_moving_space_bitmap_; 810 // Array of moving-space's pages' compaction status, which is stored in the 811 // least-significant byte. kProcessed entries also contain the from-space 812 // offset of the page which contains the compacted contents of the ith 813 // to-space page. 814 Atomic<uint32_t>* moving_pages_status_; 815 // For pages before black allocations, pre_compact_offset_moving_space_[i] 816 // holds offset within the space from where the objects need to be copied in 817 // the ith post-compact page. 818 // Otherwise, black_alloc_pages_first_chunk_size_[i] holds the size of first 819 // non-empty chunk in the ith black-allocations page. 820 union { 821 uint32_t* pre_compact_offset_moving_space_; 822 uint32_t* black_alloc_pages_first_chunk_size_; 823 }; 824 // first_objs_moving_space_[i] is the pre-compact address of the object which 825 // would overlap with the starting boundary of the ith post-compact page. 826 ObjReference* first_objs_moving_space_; 827 // First object for every page. It could be greater than the page's start 828 // address, or null if the page is empty. 829 ObjReference* first_objs_non_moving_space_; 830 831 // Cache (from_space_begin_ - bump_pointer_space_->Begin()) so that we can 832 // compute from-space address of a given pre-comapct address efficiently. 833 ptrdiff_t from_space_slide_diff_; 834 uint8_t* from_space_begin_; 835 836 // The moving space markers are ordered as follows: 837 // [moving_space_begin_, black_dense_end_, mid_gen_end_, post_compact_end_, moving_space_end_) 838 839 // End of compacted space. Used for computing post-compact address of black 840 // allocated objects. Aligned up to page size. 841 uint8_t* post_compact_end_; 842 843 // BEGIN HOT FIELDS: accessed per object 844 845 accounting::ObjectStack* mark_stack_; 846 uint64_t bytes_scanned_; 847 // Number of objects freed during this GC in moving space. It is decremented 848 // every time an object is discovered. And total-object count is added to it 849 // in MarkingPause(). It reaches the correct count only once the marking phase 850 // is completed. 851 int32_t freed_objects_; 852 // Set to true when doing young gen collection. 853 bool young_gen_; 854 const bool use_generational_; 855 // True while compacting. 856 bool compacting_; 857 // Mark bits for main space 858 accounting::ContinuousSpaceBitmap* const moving_space_bitmap_; 859 // Cached values of moving-space range to optimize checking if reference 860 // belongs to moving-space or not. May get updated if and when heap is clamped. 861 uint8_t* const moving_space_begin_; 862 uint8_t* moving_space_end_; 863 // In generational-mode, we maintain 3 generations: young, mid, and old. 864 // Mid generation is collected during young collections. This means objects 865 // need to survive two GCs before they get promoted to old-gen. This helps 866 // in avoiding pre-mature promotion of objects which are allocated just 867 // prior to a young collection but are short-lived. 868 869 // Set to moving_space_begin_ if compacting the entire moving space. 870 // Otherwise, set to a page-aligned address such that [moving_space_begin_, 871 // black_dense_end_) is considered to be densely populated with reachable 872 // objects and hence is not compacted. In generational mode, old-gen is 873 // treated just like black-dense region. 874 union { 875 uint8_t* black_dense_end_; 876 uint8_t* old_gen_end_; 877 }; 878 // Prior to compaction, 'mid_gen_end_' represents end of 'pre-compacted' 879 // mid-gen. During compaction, it represents 'post-compacted' end of mid-gen. 880 // This is done in PrepareForCompaction(). At the end of GC, in FinishPhase(), 881 // mid-gen gets consumed/promoted to old-gen, and young-gen becomes mid-gen, 882 // in preparation for the next GC cycle. 883 uint8_t* mid_gen_end_; 884 885 // BEGIN HOT FIELDS: accessed per reference update 886 887 // Special bitmap wherein all the bits corresponding to an object are set. 888 // TODO: make LiveWordsBitmap encapsulated in this class rather than a 889 // pointer. We tend to access its members in performance-sensitive 890 // code-path. Also, use a single MemMap for all the GC's data structures, 891 // which we will clear in the end. This would help in limiting the number of 892 // VMAs that get created in the kernel. 893 std::unique_ptr<LiveWordsBitmap<kAlignment>> live_words_bitmap_; 894 // For every page in the to-space (post-compact heap) we need to know the 895 // first object from which we must compact and/or update references. This is 896 // for both non-moving and moving space. Additionally, for the moving-space, 897 // we also need the offset within the object from where we need to start 898 // copying. 899 // chunk_info_vec_ holds live bytes for chunks during marking phase. After 900 // marking we perform an exclusive scan to compute offset for every chunk. 901 uint32_t* chunk_info_vec_; 902 // moving-space's end pointer at the marking pause. All allocations beyond 903 // this will be considered black in the current GC cycle. Aligned up to page 904 // size. 905 uint8_t* black_allocations_begin_; 906 // Cache (black_allocations_begin_ - post_compact_end_) for post-compact 907 // address computations. 908 ptrdiff_t black_objs_slide_diff_; 909 910 // END HOT FIELDS: accessed per reference update 911 // END HOT FIELDS: accessed per object 912 913 uint8_t* conc_compaction_termination_page_; 914 PointerSize pointer_size_; 915 // Userfault file descriptor, accessed only by the GC itself. 916 // kFallbackMode value indicates that we are in the fallback mode. 917 int uffd_; 918 // When using SIGBUS feature, this counter is used by mutators to claim a page 919 // out of compaction buffers to be used for the entire compaction cycle. 920 std::atomic<uint16_t> compaction_buffer_counter_; 921 // Set to true in MarkingPause() to indicate when allocation_stack_ should be 922 // checked in IsMarked() for black allocations. 923 bool marking_done_; 924 // Flag indicating whether one-time uffd initialization has been done. It will 925 // be false on the first GC for non-zygote processes, and always for zygote. 926 // Its purpose is to minimize the userfaultfd overhead to the minimal in 927 // Heap::PostForkChildAction() as it's invoked in app startup path. With 928 // this, we register the compaction-termination page on the first GC. 929 bool uffd_initialized_; 930 // Clamping statue of `info_map_`. Initialized with 'NotDone'. Once heap is 931 // clamped but info_map_ is delayed, we set it to 'Pending'. Once 'info_map_' 932 // is also clamped, then we set it to 'Finished'. 933 ClampInfoStatus clamp_info_map_status_; 934 935 // Track GC-roots updated so far in a GC-cycle. This is to confirm that no 936 // GC-root is updated twice. 937 // TODO: Must be replaced with an efficient mechanism eventually. Or ensure 938 // that double updation doesn't happen in the first place. 939 std::unique_ptr<std::unordered_set<void*>> updated_roots_ GUARDED_BY(lock_); 940 // TODO: Remove once an efficient mechanism to deal with double root updation 941 // is incorporated. 942 void* stack_high_addr_; 943 void* stack_low_addr_; 944 // Following values for logging purposes 945 void* prev_post_compact_end_; 946 void* prev_black_dense_end_; 947 void* prev_black_allocations_begin_; 948 bool prev_gc_young_; 949 bool prev_gc_performed_compaction_; 950 // Timestamp when the read-barrier is enabled 951 uint64_t app_slow_path_start_time_; 952 953 class FlipCallback; 954 class ThreadFlipVisitor; 955 class VerifyRootMarkedVisitor; 956 class ScanObjectVisitor; 957 class CheckpointMarkThreadRoots; 958 template <size_t kBufferSize> 959 class ThreadRootsVisitor; 960 class RefFieldsVisitor; 961 template <bool kCheckBegin, bool kCheckEnd, bool kDirtyOldToMid = false> 962 class RefsUpdateVisitor; 963 class ArenaPoolPageUpdater; 964 class ClassLoaderRootsUpdater; 965 class LinearAllocPageUpdater; 966 class ImmuneSpaceUpdateObjVisitor; 967 template <typename Visitor> 968 class VisitReferencesVisitor; 969 970 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkCompact); 971 }; 972 973 std::ostream& operator<<(std::ostream& os, MarkCompact::PageState value); 974 std::ostream& operator<<(std::ostream& os, MarkCompact::ClampInfoStatus value); 975 976 } // namespace collector 977 } // namespace gc 978 } // namespace art 979 980 #endif // ART_RUNTIME_GC_COLLECTOR_MARK_COMPACT_H_ 981