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