1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 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_SPACE_LARGE_OBJECT_SPACE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_SPACE_LARGE_OBJECT_SPACE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "base/allocator.h" 21*795d594fSAndroid Build Coastguard Worker #include "base/safe_map.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/tracking_safe_map.h" 23*795d594fSAndroid Build Coastguard Worker #include "dlmalloc_space.h" 24*795d594fSAndroid Build Coastguard Worker #include "space.h" 25*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h" 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker #include <set> 28*795d594fSAndroid Build Coastguard Worker #include <vector> 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 31*795d594fSAndroid Build Coastguard Worker namespace gc { 32*795d594fSAndroid Build Coastguard Worker namespace space { 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker class AllocationInfo; 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker enum class LargeObjectSpaceType { 37*795d594fSAndroid Build Coastguard Worker kDisabled, 38*795d594fSAndroid Build Coastguard Worker kMap, 39*795d594fSAndroid Build Coastguard Worker kFreeList, 40*795d594fSAndroid Build Coastguard Worker }; 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker // Abstraction implemented by all large object spaces. 43*795d594fSAndroid Build Coastguard Worker class LargeObjectSpace : public DiscontinuousSpace, public AllocSpace { 44*795d594fSAndroid Build Coastguard Worker public: GetType()45*795d594fSAndroid Build Coastguard Worker SpaceType GetType() const override { 46*795d594fSAndroid Build Coastguard Worker return kSpaceTypeLargeObjectSpace; 47*795d594fSAndroid Build Coastguard Worker } 48*795d594fSAndroid Build Coastguard Worker void SwapBitmaps(); 49*795d594fSAndroid Build Coastguard Worker void CopyLiveToMarked(); 50*795d594fSAndroid Build Coastguard Worker virtual void Walk(DlMallocSpace::WalkCallback, void* arg) = 0; ~LargeObjectSpace()51*795d594fSAndroid Build Coastguard Worker virtual ~LargeObjectSpace() {} 52*795d594fSAndroid Build Coastguard Worker GetBytesAllocated()53*795d594fSAndroid Build Coastguard Worker uint64_t GetBytesAllocated() override { 54*795d594fSAndroid Build Coastguard Worker MutexLock mu(Thread::Current(), lock_); 55*795d594fSAndroid Build Coastguard Worker return num_bytes_allocated_; 56*795d594fSAndroid Build Coastguard Worker } GetObjectsAllocated()57*795d594fSAndroid Build Coastguard Worker uint64_t GetObjectsAllocated() override { 58*795d594fSAndroid Build Coastguard Worker MutexLock mu(Thread::Current(), lock_); 59*795d594fSAndroid Build Coastguard Worker return num_objects_allocated_; 60*795d594fSAndroid Build Coastguard Worker } GetTotalBytesAllocated()61*795d594fSAndroid Build Coastguard Worker uint64_t GetTotalBytesAllocated() const { 62*795d594fSAndroid Build Coastguard Worker MutexLock mu(Thread::Current(), lock_); 63*795d594fSAndroid Build Coastguard Worker return total_bytes_allocated_; 64*795d594fSAndroid Build Coastguard Worker } GetTotalObjectsAllocated()65*795d594fSAndroid Build Coastguard Worker uint64_t GetTotalObjectsAllocated() const { 66*795d594fSAndroid Build Coastguard Worker MutexLock mu(Thread::Current(), lock_); 67*795d594fSAndroid Build Coastguard Worker return total_objects_allocated_; 68*795d594fSAndroid Build Coastguard Worker } 69*795d594fSAndroid Build Coastguard Worker size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) override; 70*795d594fSAndroid Build Coastguard Worker // LargeObjectSpaces don't have thread local state. RevokeThreadLocalBuffers(art::Thread *)71*795d594fSAndroid Build Coastguard Worker size_t RevokeThreadLocalBuffers(art::Thread*) override { 72*795d594fSAndroid Build Coastguard Worker return 0U; 73*795d594fSAndroid Build Coastguard Worker } RevokeAllThreadLocalBuffers()74*795d594fSAndroid Build Coastguard Worker size_t RevokeAllThreadLocalBuffers() override { 75*795d594fSAndroid Build Coastguard Worker return 0U; 76*795d594fSAndroid Build Coastguard Worker } IsAllocSpace()77*795d594fSAndroid Build Coastguard Worker bool IsAllocSpace() const override { 78*795d594fSAndroid Build Coastguard Worker return true; 79*795d594fSAndroid Build Coastguard Worker } AsAllocSpace()80*795d594fSAndroid Build Coastguard Worker AllocSpace* AsAllocSpace() override { 81*795d594fSAndroid Build Coastguard Worker return this; 82*795d594fSAndroid Build Coastguard Worker } 83*795d594fSAndroid Build Coastguard Worker collector::ObjectBytePair Sweep(bool swap_bitmaps); CanMoveObjects()84*795d594fSAndroid Build Coastguard Worker bool CanMoveObjects() const override { 85*795d594fSAndroid Build Coastguard Worker return false; 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker // Current address at which the space begins, which may vary as the space is filled. Begin()88*795d594fSAndroid Build Coastguard Worker uint8_t* Begin() const { 89*795d594fSAndroid Build Coastguard Worker return begin_; 90*795d594fSAndroid Build Coastguard Worker } 91*795d594fSAndroid Build Coastguard Worker // Current address at which the space ends, which may vary as the space is filled. End()92*795d594fSAndroid Build Coastguard Worker uint8_t* End() const { 93*795d594fSAndroid Build Coastguard Worker return end_; 94*795d594fSAndroid Build Coastguard Worker } 95*795d594fSAndroid Build Coastguard Worker // Current size of space Size()96*795d594fSAndroid Build Coastguard Worker size_t Size() const { 97*795d594fSAndroid Build Coastguard Worker return End() - Begin(); 98*795d594fSAndroid Build Coastguard Worker } 99*795d594fSAndroid Build Coastguard Worker // Return true if we contain the specified address. Contains(const mirror::Object * obj)100*795d594fSAndroid Build Coastguard Worker bool Contains(const mirror::Object* obj) const override { 101*795d594fSAndroid Build Coastguard Worker const uint8_t* byte_obj = reinterpret_cast<const uint8_t*>(obj); 102*795d594fSAndroid Build Coastguard Worker return Begin() <= byte_obj && byte_obj < End(); 103*795d594fSAndroid Build Coastguard Worker } 104*795d594fSAndroid Build Coastguard Worker bool LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) override 105*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker // Return true if the large object is a zygote large object. Potentially slow. 108*795d594fSAndroid Build Coastguard Worker virtual bool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const = 0; 109*795d594fSAndroid Build Coastguard Worker // Called when we create the zygote space, mark all existing large objects as zygote large 110*795d594fSAndroid Build Coastguard Worker // objects. Set mark-bit if called from PreZygoteFork() for ConcurrentCopying 111*795d594fSAndroid Build Coastguard Worker // GC to avoid dirtying the first page. 112*795d594fSAndroid Build Coastguard Worker virtual void SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) = 0; 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker virtual void ForEachMemMap(std::function<void(const MemMap&)> func) const = 0; 115*795d594fSAndroid Build Coastguard Worker // GetRangeAtomic returns Begin() and End() atomically, that is, it never returns Begin() and 116*795d594fSAndroid Build Coastguard Worker // End() from different allocations. 117*795d594fSAndroid Build Coastguard Worker virtual std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const = 0; 118*795d594fSAndroid Build Coastguard Worker // Clamp the space size to the given capacity. 119*795d594fSAndroid Build Coastguard Worker virtual void ClampGrowthLimit(size_t capacity) = 0; 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker // The way large object spaces are implemented, the object alignment has to be 122*795d594fSAndroid Build Coastguard Worker // the same as the *runtime* OS page size. However, in the future this may 123*795d594fSAndroid Build Coastguard Worker // change so it is important to use LargeObjectSpace::ObjectAlignment() rather 124*795d594fSAndroid Build Coastguard Worker // than gPageSize when appropriate. 125*795d594fSAndroid Build Coastguard Worker #if defined(ART_PAGE_SIZE_AGNOSTIC) ObjectAlignment()126*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE size_t ObjectAlignment() { return gPageSize; } 127*795d594fSAndroid Build Coastguard Worker #else ObjectAlignment()128*795d594fSAndroid Build Coastguard Worker static constexpr size_t ObjectAlignment() { return kMinPageSize; } 129*795d594fSAndroid Build Coastguard Worker #endif 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker protected: 132*795d594fSAndroid Build Coastguard Worker explicit LargeObjectSpace(const std::string& name, uint8_t* begin, uint8_t* end, 133*795d594fSAndroid Build Coastguard Worker const char* lock_name); 134*795d594fSAndroid Build Coastguard Worker static void SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg); 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker // Used to ensure mutual exclusion when the allocation spaces data structures, 137*795d594fSAndroid Build Coastguard Worker // including the allocation counters below, are being modified. 138*795d594fSAndroid Build Coastguard Worker mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker // Number of bytes which have been allocated into the space and not yet freed. The count is also 141*795d594fSAndroid Build Coastguard Worker // included in the identically named field in Heap. Counts actual allocated (after rounding), 142*795d594fSAndroid Build Coastguard Worker // not requested, sizes. TODO: It would be cheaper to just maintain total allocated and total 143*795d594fSAndroid Build Coastguard Worker // free counts. 144*795d594fSAndroid Build Coastguard Worker uint64_t num_bytes_allocated_ GUARDED_BY(lock_); 145*795d594fSAndroid Build Coastguard Worker uint64_t num_objects_allocated_ GUARDED_BY(lock_); 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker // Totals for large objects ever allocated, including those that have since been deallocated. 148*795d594fSAndroid Build Coastguard Worker // Never decremented. 149*795d594fSAndroid Build Coastguard Worker uint64_t total_bytes_allocated_ GUARDED_BY(lock_); 150*795d594fSAndroid Build Coastguard Worker uint64_t total_objects_allocated_ GUARDED_BY(lock_); 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker // Begin and end, may change as more large objects are allocated. 153*795d594fSAndroid Build Coastguard Worker uint8_t* begin_; 154*795d594fSAndroid Build Coastguard Worker uint8_t* end_; 155*795d594fSAndroid Build Coastguard Worker 156*795d594fSAndroid Build Coastguard Worker friend class Space; 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker private: 159*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(LargeObjectSpace); 160*795d594fSAndroid Build Coastguard Worker }; 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker // A discontinuous large object space implemented by individual mmap/munmap calls. 163*795d594fSAndroid Build Coastguard Worker class LargeObjectMapSpace : public LargeObjectSpace { 164*795d594fSAndroid Build Coastguard Worker public: 165*795d594fSAndroid Build Coastguard Worker // Creates a large object space. Allocations into the large object space use memory maps instead 166*795d594fSAndroid Build Coastguard Worker // of malloc. 167*795d594fSAndroid Build Coastguard Worker static LargeObjectMapSpace* Create(const std::string& name); 168*795d594fSAndroid Build Coastguard Worker // Return the storage space required by obj. 169*795d594fSAndroid Build Coastguard Worker size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override REQUIRES(!lock_); 170*795d594fSAndroid Build Coastguard Worker mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 171*795d594fSAndroid Build Coastguard Worker size_t* usable_size, size_t* bytes_tl_bulk_allocated) override 172*795d594fSAndroid Build Coastguard Worker REQUIRES(!lock_); 173*795d594fSAndroid Build Coastguard Worker size_t Free(Thread* self, mirror::Object* ptr) override REQUIRES(!lock_); 174*795d594fSAndroid Build Coastguard Worker void Walk(DlMallocSpace::WalkCallback, void* arg) override REQUIRES(!lock_); 175*795d594fSAndroid Build Coastguard Worker // TODO: disabling thread safety analysis as this may be called when we already hold lock_. 176*795d594fSAndroid Build Coastguard Worker bool Contains(const mirror::Object* obj) const override NO_THREAD_SAFETY_ANALYSIS; 177*795d594fSAndroid Build Coastguard Worker void ForEachMemMap(std::function<void(const MemMap&)> func) const override REQUIRES(!lock_); 178*795d594fSAndroid Build Coastguard Worker std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const override REQUIRES(!lock_); ClampGrowthLimit(size_t capacity ATTRIBUTE_UNUSED)179*795d594fSAndroid Build Coastguard Worker void ClampGrowthLimit(size_t capacity ATTRIBUTE_UNUSED) override {} 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker protected: 182*795d594fSAndroid Build Coastguard Worker struct LargeObject { 183*795d594fSAndroid Build Coastguard Worker MemMap mem_map; 184*795d594fSAndroid Build Coastguard Worker bool is_zygote; 185*795d594fSAndroid Build Coastguard Worker }; 186*795d594fSAndroid Build Coastguard Worker explicit LargeObjectMapSpace(const std::string& name); ~LargeObjectMapSpace()187*795d594fSAndroid Build Coastguard Worker virtual ~LargeObjectMapSpace() {} 188*795d594fSAndroid Build Coastguard Worker 189*795d594fSAndroid Build Coastguard Worker bool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const override REQUIRES(!lock_); 190*795d594fSAndroid Build Coastguard Worker void SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) override 191*795d594fSAndroid Build Coastguard Worker REQUIRES(!lock_) 192*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker AllocationTrackingSafeMap<mirror::Object*, LargeObject, kAllocatorTagLOSMaps> large_objects_ 195*795d594fSAndroid Build Coastguard Worker GUARDED_BY(lock_); 196*795d594fSAndroid Build Coastguard Worker }; 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker // A continuous large object space with a free-list to handle holes. 199*795d594fSAndroid Build Coastguard Worker class FreeListSpace final : public LargeObjectSpace { 200*795d594fSAndroid Build Coastguard Worker public: 201*795d594fSAndroid Build Coastguard Worker virtual ~FreeListSpace(); 202*795d594fSAndroid Build Coastguard Worker static FreeListSpace* Create(const std::string& name, size_t capacity); 203*795d594fSAndroid Build Coastguard Worker size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override 204*795d594fSAndroid Build Coastguard Worker REQUIRES(lock_); 205*795d594fSAndroid Build Coastguard Worker mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 206*795d594fSAndroid Build Coastguard Worker size_t* usable_size, size_t* bytes_tl_bulk_allocated) 207*795d594fSAndroid Build Coastguard Worker override REQUIRES(!lock_); 208*795d594fSAndroid Build Coastguard Worker size_t Free(Thread* self, mirror::Object* obj) override REQUIRES(!lock_); 209*795d594fSAndroid Build Coastguard Worker void Walk(DlMallocSpace::WalkCallback callback, void* arg) override REQUIRES(!lock_); 210*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os) const override REQUIRES(!lock_); 211*795d594fSAndroid Build Coastguard Worker void ForEachMemMap(std::function<void(const MemMap&)> func) const override REQUIRES(!lock_); 212*795d594fSAndroid Build Coastguard Worker std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const override REQUIRES(!lock_); 213*795d594fSAndroid Build Coastguard Worker void ClampGrowthLimit(size_t capacity) override REQUIRES(!lock_); 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker protected: 216*795d594fSAndroid Build Coastguard Worker FreeListSpace(const std::string& name, MemMap&& mem_map, uint8_t* begin, uint8_t* end); GetSlotIndexForAddress(uintptr_t address)217*795d594fSAndroid Build Coastguard Worker size_t GetSlotIndexForAddress(uintptr_t address) const { 218*795d594fSAndroid Build Coastguard Worker DCHECK(Contains(reinterpret_cast<mirror::Object*>(address))); 219*795d594fSAndroid Build Coastguard Worker return (address - reinterpret_cast<uintptr_t>(Begin())) / ObjectAlignment(); 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker size_t GetSlotIndexForAllocationInfo(const AllocationInfo* info) const; 222*795d594fSAndroid Build Coastguard Worker AllocationInfo* GetAllocationInfoForAddress(uintptr_t address); 223*795d594fSAndroid Build Coastguard Worker const AllocationInfo* GetAllocationInfoForAddress(uintptr_t address) const; GetAllocationAddressForSlot(size_t slot)224*795d594fSAndroid Build Coastguard Worker uintptr_t GetAllocationAddressForSlot(size_t slot) const { 225*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<uintptr_t>(Begin()) + slot * ObjectAlignment(); 226*795d594fSAndroid Build Coastguard Worker } GetAddressForAllocationInfo(const AllocationInfo * info)227*795d594fSAndroid Build Coastguard Worker uintptr_t GetAddressForAllocationInfo(const AllocationInfo* info) const { 228*795d594fSAndroid Build Coastguard Worker return GetAllocationAddressForSlot(GetSlotIndexForAllocationInfo(info)); 229*795d594fSAndroid Build Coastguard Worker } 230*795d594fSAndroid Build Coastguard Worker // Removes header from the free blocks set by finding the corresponding iterator and erasing it. 231*795d594fSAndroid Build Coastguard Worker void RemoveFreePrev(AllocationInfo* info) REQUIRES(lock_); 232*795d594fSAndroid Build Coastguard Worker bool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const override; 233*795d594fSAndroid Build Coastguard Worker void SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) override 234*795d594fSAndroid Build Coastguard Worker REQUIRES(!lock_) 235*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 236*795d594fSAndroid Build Coastguard Worker 237*795d594fSAndroid Build Coastguard Worker class SortByPrevFree { 238*795d594fSAndroid Build Coastguard Worker public: 239*795d594fSAndroid Build Coastguard Worker bool operator()(const AllocationInfo* a, const AllocationInfo* b) const; 240*795d594fSAndroid Build Coastguard Worker }; 241*795d594fSAndroid Build Coastguard Worker using FreeBlocks = std::set<AllocationInfo*, 242*795d594fSAndroid Build Coastguard Worker SortByPrevFree, 243*795d594fSAndroid Build Coastguard Worker TrackingAllocator<AllocationInfo*, kAllocatorTagLOSFreeList>>; 244*795d594fSAndroid Build Coastguard Worker 245*795d594fSAndroid Build Coastguard Worker // There is not footer for any allocations at the end of the space, so we keep track of how much 246*795d594fSAndroid Build Coastguard Worker // free space there is at the end manually. 247*795d594fSAndroid Build Coastguard Worker MemMap mem_map_; 248*795d594fSAndroid Build Coastguard Worker // Side table for allocation info, one per page. 249*795d594fSAndroid Build Coastguard Worker MemMap allocation_info_map_; 250*795d594fSAndroid Build Coastguard Worker AllocationInfo* allocation_info_; 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker // Free bytes at the end of the space. 253*795d594fSAndroid Build Coastguard Worker size_t free_end_ GUARDED_BY(lock_); 254*795d594fSAndroid Build Coastguard Worker FreeBlocks free_blocks_ GUARDED_BY(lock_); 255*795d594fSAndroid Build Coastguard Worker }; 256*795d594fSAndroid Build Coastguard Worker 257*795d594fSAndroid Build Coastguard Worker } // namespace space 258*795d594fSAndroid Build Coastguard Worker } // namespace gc 259*795d594fSAndroid Build Coastguard Worker } // namespace art 260*795d594fSAndroid Build Coastguard Worker 261*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_GC_SPACE_LARGE_OBJECT_SPACE_H_ 262