xref: /aosp_15_r20/art/runtime/gc/accounting/space_bitmap.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2008 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <limits.h>
21*795d594fSAndroid Build Coastguard Worker #include <stdint.h>
22*795d594fSAndroid Build Coastguard Worker #include <memory>
23*795d594fSAndroid Build Coastguard Worker #include <set>
24*795d594fSAndroid Build Coastguard Worker #include <vector>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/mem_map.h"
28*795d594fSAndroid Build Coastguard Worker #include "runtime_globals.h"
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker namespace mirror {
33*795d594fSAndroid Build Coastguard Worker class Class;
34*795d594fSAndroid Build Coastguard Worker class Object;
35*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker namespace gc {
38*795d594fSAndroid Build Coastguard Worker namespace accounting {
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker template<size_t kAlignment>
41*795d594fSAndroid Build Coastguard Worker class SpaceBitmap {
42*795d594fSAndroid Build Coastguard Worker  public:
43*795d594fSAndroid Build Coastguard Worker   using ScanCallback = void(mirror::Object* obj, void* finger, void* arg);
44*795d594fSAndroid Build Coastguard Worker   using SweepCallback = void(size_t ptr_count, mirror::Object** ptrs, void* arg);
45*795d594fSAndroid Build Coastguard Worker 
46*795d594fSAndroid Build Coastguard Worker   // Initialize a space bitmap so that it points to a bitmap large enough to cover a heap at
47*795d594fSAndroid Build Coastguard Worker   // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
48*795d594fSAndroid Build Coastguard Worker   EXPORT static SpaceBitmap Create(const std::string& name,
49*795d594fSAndroid Build Coastguard Worker                                    uint8_t* heap_begin,
50*795d594fSAndroid Build Coastguard Worker                                    size_t heap_capacity);
51*795d594fSAndroid Build Coastguard Worker 
52*795d594fSAndroid Build Coastguard Worker   // Initialize a space bitmap using the provided mem_map as the live bits. Takes ownership of the
53*795d594fSAndroid Build Coastguard Worker   // mem map. The address range covered starts at heap_begin and is of size equal to heap_capacity.
54*795d594fSAndroid Build Coastguard Worker   // Objects are kAlignement-aligned.
55*795d594fSAndroid Build Coastguard Worker   static SpaceBitmap CreateFromMemMap(const std::string& name,
56*795d594fSAndroid Build Coastguard Worker                                       MemMap&& mem_map,
57*795d594fSAndroid Build Coastguard Worker                                       uint8_t* heap_begin,
58*795d594fSAndroid Build Coastguard Worker                                       size_t heap_capacity);
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker   EXPORT ~SpaceBitmap();
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker   // Return the bitmap word index corresponding to memory offset (relative to
63*795d594fSAndroid Build Coastguard Worker   // `HeapBegin()`) `offset`.
64*795d594fSAndroid Build Coastguard Worker   // See also SpaceBitmap::OffsetBitIndex.
65*795d594fSAndroid Build Coastguard Worker   //
66*795d594fSAndroid Build Coastguard Worker   // <offset> is the difference from .base to a pointer address.
67*795d594fSAndroid Build Coastguard Worker   // <index> is the index of .bits that contains the bit representing
68*795d594fSAndroid Build Coastguard Worker   //         <offset>.
OffsetToIndex(size_t offset)69*795d594fSAndroid Build Coastguard Worker   static constexpr size_t OffsetToIndex(size_t offset) {
70*795d594fSAndroid Build Coastguard Worker     return offset / kAlignment / kBitsPerIntPtrT;
71*795d594fSAndroid Build Coastguard Worker   }
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker   // Return the memory offset (relative to `HeapBegin()`) corresponding to
74*795d594fSAndroid Build Coastguard Worker   // bitmap word index `index`.
75*795d594fSAndroid Build Coastguard Worker   template<typename T>
IndexToOffset(T index)76*795d594fSAndroid Build Coastguard Worker   static constexpr T IndexToOffset(T index) {
77*795d594fSAndroid Build Coastguard Worker     return static_cast<T>(index * kAlignment * kBitsPerIntPtrT);
78*795d594fSAndroid Build Coastguard Worker   }
79*795d594fSAndroid Build Coastguard Worker 
80*795d594fSAndroid Build Coastguard Worker   // Return the bit within the bitmap word index corresponding to
81*795d594fSAndroid Build Coastguard Worker   // memory offset (relative to `HeapBegin()`) `offset`.
82*795d594fSAndroid Build Coastguard Worker   // See also SpaceBitmap::OffsetToIndex.
OffsetBitIndex(uintptr_t offset)83*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE static constexpr uintptr_t OffsetBitIndex(uintptr_t offset) {
84*795d594fSAndroid Build Coastguard Worker     return (offset / kAlignment) % kBitsPerIntPtrT;
85*795d594fSAndroid Build Coastguard Worker   }
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker   // Return the word-wide bit mask corresponding to `OffsetBitIndex(offset)`.
88*795d594fSAndroid Build Coastguard Worker   // Bits are packed in the obvious way.
OffsetToMask(uintptr_t offset)89*795d594fSAndroid Build Coastguard Worker   static constexpr uintptr_t OffsetToMask(uintptr_t offset) {
90*795d594fSAndroid Build Coastguard Worker     return static_cast<size_t>(1) << OffsetBitIndex(offset);
91*795d594fSAndroid Build Coastguard Worker   }
92*795d594fSAndroid Build Coastguard Worker 
93*795d594fSAndroid Build Coastguard Worker   // Set the bit corresponding to `obj` in the bitmap and return the previous value of that bit.
Set(const mirror::Object * obj)94*795d594fSAndroid Build Coastguard Worker   bool Set(const mirror::Object* obj) ALWAYS_INLINE {
95*795d594fSAndroid Build Coastguard Worker     return Modify<true>(obj);
96*795d594fSAndroid Build Coastguard Worker   }
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker   // Clear the bit corresponding to `obj` in the bitmap and return the previous value of that bit.
Clear(const mirror::Object * obj)99*795d594fSAndroid Build Coastguard Worker   bool Clear(const mirror::Object* obj) ALWAYS_INLINE {
100*795d594fSAndroid Build Coastguard Worker     return Modify<false>(obj);
101*795d594fSAndroid Build Coastguard Worker   }
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   // Returns true if the object was previously marked.
104*795d594fSAndroid Build Coastguard Worker   bool AtomicTestAndSet(const mirror::Object* obj);
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker   // Fill the bitmap with zeroes.  Returns the bitmap's memory to the system as a side-effect.
107*795d594fSAndroid Build Coastguard Worker   // If `release_eagerly` is true, this method will also try to give back the
108*795d594fSAndroid Build Coastguard Worker   // memory to the OS eagerly.
109*795d594fSAndroid Build Coastguard Worker   void Clear(bool release_eagerly = true);
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker   // Clear a range covered by the bitmap using madvise if possible.
112*795d594fSAndroid Build Coastguard Worker   void ClearRange(const mirror::Object* begin, const mirror::Object* end);
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker   // Test whether `obj` is part of the bitmap (i.e. return whether the bit
115*795d594fSAndroid Build Coastguard Worker   // corresponding to `obj` has been set in the bitmap).
116*795d594fSAndroid Build Coastguard Worker   //
117*795d594fSAndroid Build Coastguard Worker   // Precondition: `obj` is within the range of pointers that this bitmap could
118*795d594fSAndroid Build Coastguard Worker   // potentially cover (i.e. `this->HasAddress(obj)` is true)
119*795d594fSAndroid Build Coastguard Worker   bool Test(const mirror::Object* obj) const;
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker   // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
122*795d594fSAndroid Build Coastguard Worker   // even if a bit has not been set for it.
HasAddress(const void * obj)123*795d594fSAndroid Build Coastguard Worker   bool HasAddress(const void* obj) const {
124*795d594fSAndroid Build Coastguard Worker     // If obj < heap_begin_ then offset underflows to some very large value past the end of the
125*795d594fSAndroid Build Coastguard Worker     // bitmap.
126*795d594fSAndroid Build Coastguard Worker     const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_;
127*795d594fSAndroid Build Coastguard Worker     const size_t index = OffsetToIndex(offset);
128*795d594fSAndroid Build Coastguard Worker     return index < bitmap_size_ / sizeof(intptr_t);
129*795d594fSAndroid Build Coastguard Worker   }
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
VisitRange(uintptr_t visit_begin,uintptr_t visit_end,const Visitor & visitor)132*795d594fSAndroid Build Coastguard Worker   void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
133*795d594fSAndroid Build Coastguard Worker     for (; visit_begin < visit_end; visit_begin += kAlignment) {
134*795d594fSAndroid Build Coastguard Worker       visitor(reinterpret_cast<mirror::Object*>(visit_begin));
135*795d594fSAndroid Build Coastguard Worker     }
136*795d594fSAndroid Build Coastguard Worker   }
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // Find first object while scanning bitmap backwards from visit_begin -> visit_end.
139*795d594fSAndroid Build Coastguard Worker   // Covers [visit_end, visit_begin] range.
140*795d594fSAndroid Build Coastguard Worker   mirror::Object* FindPrecedingObject(uintptr_t visit_begin, uintptr_t visit_end = 0) const;
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker   // Visit the live objects in the range [visit_begin, visit_end). If kVisitOnce
143*795d594fSAndroid Build Coastguard Worker   // is true, then only the first live object will be visited.
144*795d594fSAndroid Build Coastguard Worker   // TODO: Use lock annotations when clang is fixed.
145*795d594fSAndroid Build Coastguard Worker   // REQUIRES(Locks::heap_bitmap_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
146*795d594fSAndroid Build Coastguard Worker   template <bool kVisitOnce = false, typename Visitor>
147*795d594fSAndroid Build Coastguard Worker   void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end, Visitor&& visitor) const
148*795d594fSAndroid Build Coastguard Worker       NO_THREAD_SAFETY_ANALYSIS;
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker   // Visit all of the set bits in HeapBegin(), HeapLimit().
151*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
VisitAllMarked(Visitor && visitor)152*795d594fSAndroid Build Coastguard Worker   void VisitAllMarked(Visitor&& visitor) const {
153*795d594fSAndroid Build Coastguard Worker     VisitMarkedRange(HeapBegin(), HeapLimit(), visitor);
154*795d594fSAndroid Build Coastguard Worker   }
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker   // Visits set bits in address order.  The callback is not permitted to change the bitmap bits or
157*795d594fSAndroid Build Coastguard Worker   // max during the traversal.
158*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
159*795d594fSAndroid Build Coastguard Worker   void Walk(Visitor&& visitor)
160*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   // Walk through the bitmaps in increasing address order, and find the object pointers that
163*795d594fSAndroid Build Coastguard Worker   // correspond to garbage objects.  Call <callback> zero or more times with lists of these object
164*795d594fSAndroid Build Coastguard Worker   // pointers. The callback is not permitted to increase the max of either bitmap.
165*795d594fSAndroid Build Coastguard Worker   static void SweepWalk(const SpaceBitmap& live, const SpaceBitmap& mark, uintptr_t base,
166*795d594fSAndroid Build Coastguard Worker                         uintptr_t max, SweepCallback* thunk, void* arg);
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   void CopyFrom(SpaceBitmap* source_bitmap);
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker   // Starting address of our internal storage.
Begin()171*795d594fSAndroid Build Coastguard Worker   Atomic<uintptr_t>* Begin() const {
172*795d594fSAndroid Build Coastguard Worker     return bitmap_begin_;
173*795d594fSAndroid Build Coastguard Worker   }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker   // Size of our internal storage
Size()176*795d594fSAndroid Build Coastguard Worker   size_t Size() const {
177*795d594fSAndroid Build Coastguard Worker     return bitmap_size_;
178*795d594fSAndroid Build Coastguard Worker   }
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker   // Size in bytes of the memory that the bitmaps spans.
HeapSize()181*795d594fSAndroid Build Coastguard Worker   uint64_t HeapSize() const {
182*795d594fSAndroid Build Coastguard Worker     return IndexToOffset<uint64_t>(Size() / sizeof(intptr_t));
183*795d594fSAndroid Build Coastguard Worker   }
184*795d594fSAndroid Build Coastguard Worker 
SetHeapSize(size_t bytes)185*795d594fSAndroid Build Coastguard Worker   void SetHeapSize(size_t bytes) {
186*795d594fSAndroid Build Coastguard Worker     heap_limit_ = heap_begin_ + bytes;
187*795d594fSAndroid Build Coastguard Worker     bitmap_size_ = ComputeBitmapSize(bytes);
188*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(HeapSize(), bytes);
189*795d594fSAndroid Build Coastguard Worker     if (mem_map_.IsValid()) {
190*795d594fSAndroid Build Coastguard Worker       mem_map_.SetSize(bitmap_size_);
191*795d594fSAndroid Build Coastguard Worker     }
192*795d594fSAndroid Build Coastguard Worker   }
193*795d594fSAndroid Build Coastguard Worker 
HeapBegin()194*795d594fSAndroid Build Coastguard Worker   uintptr_t HeapBegin() const {
195*795d594fSAndroid Build Coastguard Worker     return heap_begin_;
196*795d594fSAndroid Build Coastguard Worker   }
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker   // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()).
HeapLimit()199*795d594fSAndroid Build Coastguard Worker   uint64_t HeapLimit() const {
200*795d594fSAndroid Build Coastguard Worker     return heap_limit_;
201*795d594fSAndroid Build Coastguard Worker   }
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker   // Set the max address which can covered by the bitmap.
204*795d594fSAndroid Build Coastguard Worker   void SetHeapLimit(uintptr_t new_end);
205*795d594fSAndroid Build Coastguard Worker 
GetName()206*795d594fSAndroid Build Coastguard Worker   std::string GetName() const {
207*795d594fSAndroid Build Coastguard Worker     return name_;
208*795d594fSAndroid Build Coastguard Worker   }
209*795d594fSAndroid Build Coastguard Worker 
SetName(const std::string & name)210*795d594fSAndroid Build Coastguard Worker   void SetName(const std::string& name) {
211*795d594fSAndroid Build Coastguard Worker     name_ = name;
212*795d594fSAndroid Build Coastguard Worker   }
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker   std::string Dump() const;
215*795d594fSAndroid Build Coastguard Worker 
216*795d594fSAndroid Build Coastguard Worker   // Dump three bitmap words around obj.
217*795d594fSAndroid Build Coastguard Worker   std::string DumpMemAround(mirror::Object* obj) const;
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   // Helper function for computing bitmap size based on a 64 bit capacity.
220*795d594fSAndroid Build Coastguard Worker   static size_t ComputeBitmapSize(uint64_t capacity);
221*795d594fSAndroid Build Coastguard Worker   static size_t ComputeHeapSize(uint64_t bitmap_bytes);
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker   // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
224*795d594fSAndroid Build Coastguard Worker   // however, we document that this is expected on heap_end_
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker   SpaceBitmap() = default;
227*795d594fSAndroid Build Coastguard Worker   SpaceBitmap(SpaceBitmap&&) noexcept = default;
228*795d594fSAndroid Build Coastguard Worker   SpaceBitmap& operator=(SpaceBitmap&&) noexcept = default;
229*795d594fSAndroid Build Coastguard Worker 
IsValid()230*795d594fSAndroid Build Coastguard Worker   bool IsValid() const {
231*795d594fSAndroid Build Coastguard Worker     return bitmap_begin_ != nullptr;
232*795d594fSAndroid Build Coastguard Worker   }
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   // Copy a view of the other bitmap without taking ownership of the underlying data.
CopyView(SpaceBitmap & other)235*795d594fSAndroid Build Coastguard Worker   void CopyView(SpaceBitmap& other) {
236*795d594fSAndroid Build Coastguard Worker     bitmap_begin_ = other.bitmap_begin_;
237*795d594fSAndroid Build Coastguard Worker     bitmap_size_ = other.bitmap_size_;
238*795d594fSAndroid Build Coastguard Worker     heap_begin_ = other.heap_begin_;
239*795d594fSAndroid Build Coastguard Worker     heap_limit_ = other.heap_limit_;
240*795d594fSAndroid Build Coastguard Worker     name_ = other.name_;
241*795d594fSAndroid Build Coastguard Worker   }
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker  private:
244*795d594fSAndroid Build Coastguard Worker   // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
245*795d594fSAndroid Build Coastguard Worker   // however, we document that this is expected on heap_end_
246*795d594fSAndroid Build Coastguard Worker   SpaceBitmap(const std::string& name,
247*795d594fSAndroid Build Coastguard Worker               MemMap&& mem_map,
248*795d594fSAndroid Build Coastguard Worker               uintptr_t* bitmap_begin,
249*795d594fSAndroid Build Coastguard Worker               size_t bitmap_size,
250*795d594fSAndroid Build Coastguard Worker               const void* heap_begin,
251*795d594fSAndroid Build Coastguard Worker               size_t heap_capacity);
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker   // Change the value of the bit corresponding to `obj` in the bitmap
254*795d594fSAndroid Build Coastguard Worker   // to `kSetBit` and return the previous value of that bit.
255*795d594fSAndroid Build Coastguard Worker   template<bool kSetBit>
256*795d594fSAndroid Build Coastguard Worker   bool Modify(const mirror::Object* obj);
257*795d594fSAndroid Build Coastguard Worker 
258*795d594fSAndroid Build Coastguard Worker   // Backing storage for bitmap.
259*795d594fSAndroid Build Coastguard Worker   MemMap mem_map_;
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker   // This bitmap itself, word sized for efficiency in scanning.
262*795d594fSAndroid Build Coastguard Worker   Atomic<uintptr_t>* bitmap_begin_ = nullptr;
263*795d594fSAndroid Build Coastguard Worker 
264*795d594fSAndroid Build Coastguard Worker   // Size of this bitmap.
265*795d594fSAndroid Build Coastguard Worker   size_t bitmap_size_ = 0u;
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker   // The start address of the memory covered by the bitmap, which corresponds to the word
268*795d594fSAndroid Build Coastguard Worker   // containing the first bit in the bitmap.
269*795d594fSAndroid Build Coastguard Worker   uintptr_t heap_begin_ = 0u;
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker   // The end address of the memory covered by the bitmap. This may not be on a word boundary.
272*795d594fSAndroid Build Coastguard Worker   uintptr_t heap_limit_ = 0u;
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   // Name of this bitmap.
275*795d594fSAndroid Build Coastguard Worker   std::string name_;
276*795d594fSAndroid Build Coastguard Worker };
277*795d594fSAndroid Build Coastguard Worker 
278*795d594fSAndroid Build Coastguard Worker using ContinuousSpaceBitmap = SpaceBitmap<kObjectAlignment>;
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker // We pick the lowest supported page size to ensure that it's a constexpr, so
281*795d594fSAndroid Build Coastguard Worker // that we can keep bitmap accesses optimized. However, this means that when the
282*795d594fSAndroid Build Coastguard Worker // large-object alignment is higher than kMinPageSize, then not all bits in the
283*795d594fSAndroid Build Coastguard Worker // bitmap are actually in use.
284*795d594fSAndroid Build Coastguard Worker // In practice, this happens when running with a kernel that uses 16kB as the
285*795d594fSAndroid Build Coastguard Worker // page size, where 1 out of every 4 bits of the bitmap is used.
286*795d594fSAndroid Build Coastguard Worker 
287*795d594fSAndroid Build Coastguard Worker // TODO: In the future, we should consider alternative fixed alignments for
288*795d594fSAndroid Build Coastguard Worker // large objects, disassociated from the page size. This would allow us to keep
289*795d594fSAndroid Build Coastguard Worker // accesses optimized, while also packing the bitmap efficiently, and reducing
290*795d594fSAndroid Build Coastguard Worker // its size enough that it would no longer make sense to allocate it with
291*795d594fSAndroid Build Coastguard Worker // mmap().
292*795d594fSAndroid Build Coastguard Worker using LargeObjectBitmap = SpaceBitmap<kMinPageSize>;
293*795d594fSAndroid Build Coastguard Worker 
294*795d594fSAndroid Build Coastguard Worker template<size_t kAlignment>
295*795d594fSAndroid Build Coastguard Worker std::ostream& operator << (std::ostream& stream, const SpaceBitmap<kAlignment>& bitmap);
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker }  // namespace accounting
298*795d594fSAndroid Build Coastguard Worker }  // namespace gc
299*795d594fSAndroid Build Coastguard Worker }  // namespace art
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
302