• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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