1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 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_DLMALLOC_SPACE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "malloc_space.h" 21*795d594fSAndroid Build Coastguard Worker #include "space.h" 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 24*795d594fSAndroid Build Coastguard Worker namespace gc { 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace collector { 27*795d594fSAndroid Build Coastguard Worker class MarkSweep; 28*795d594fSAndroid Build Coastguard Worker } // namespace collector 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace space { 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker // An alloc space is a space where objects may be allocated and garbage collected. Not final as may 33*795d594fSAndroid Build Coastguard Worker // be overridden by a MemoryToolMallocSpace. 34*795d594fSAndroid Build Coastguard Worker class DlMallocSpace : public MallocSpace { 35*795d594fSAndroid Build Coastguard Worker public: 36*795d594fSAndroid Build Coastguard Worker // Create a DlMallocSpace from an existing mem_map. 37*795d594fSAndroid Build Coastguard Worker static DlMallocSpace* CreateFromMemMap(MemMap&& mem_map, 38*795d594fSAndroid Build Coastguard Worker const std::string& name, 39*795d594fSAndroid Build Coastguard Worker size_t starting_size, 40*795d594fSAndroid Build Coastguard Worker size_t initial_size, 41*795d594fSAndroid Build Coastguard Worker size_t growth_limit, 42*795d594fSAndroid Build Coastguard Worker size_t capacity, 43*795d594fSAndroid Build Coastguard Worker bool can_move_objects); 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker // Create a DlMallocSpace with the requested sizes. The requested 46*795d594fSAndroid Build Coastguard Worker // base address is not guaranteed to be granted, if it is required, 47*795d594fSAndroid Build Coastguard Worker // the caller should call Begin on the returned space to confirm the 48*795d594fSAndroid Build Coastguard Worker // request was granted. 49*795d594fSAndroid Build Coastguard Worker static DlMallocSpace* Create(const std::string& name, 50*795d594fSAndroid Build Coastguard Worker size_t initial_size, 51*795d594fSAndroid Build Coastguard Worker size_t growth_limit, 52*795d594fSAndroid Build Coastguard Worker size_t capacity, 53*795d594fSAndroid Build Coastguard Worker bool can_move_objects); 54*795d594fSAndroid Build Coastguard Worker 55*795d594fSAndroid Build Coastguard Worker // Virtual to allow MemoryToolMallocSpace to intercept. 56*795d594fSAndroid Build Coastguard Worker mirror::Object* AllocWithGrowth(Thread* self, 57*795d594fSAndroid Build Coastguard Worker size_t num_bytes, 58*795d594fSAndroid Build Coastguard Worker size_t* bytes_allocated, 59*795d594fSAndroid Build Coastguard Worker size_t* usable_size, 60*795d594fSAndroid Build Coastguard Worker size_t* bytes_tl_bulk_allocated) override REQUIRES(!lock_); 61*795d594fSAndroid Build Coastguard Worker // Virtual to allow MemoryToolMallocSpace to intercept. Alloc(Thread * self,size_t num_bytes,size_t * bytes_allocated,size_t * usable_size,size_t * bytes_tl_bulk_allocated)62*795d594fSAndroid Build Coastguard Worker mirror::Object* Alloc(Thread* self, 63*795d594fSAndroid Build Coastguard Worker size_t num_bytes, 64*795d594fSAndroid Build Coastguard Worker size_t* bytes_allocated, 65*795d594fSAndroid Build Coastguard Worker size_t* usable_size, 66*795d594fSAndroid Build Coastguard Worker size_t* bytes_tl_bulk_allocated) override REQUIRES(!lock_) { 67*795d594fSAndroid Build Coastguard Worker return AllocNonvirtual(self, num_bytes, bytes_allocated, usable_size, 68*795d594fSAndroid Build Coastguard Worker bytes_tl_bulk_allocated); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker // Virtual to allow MemoryToolMallocSpace to intercept. AllocationSize(mirror::Object * obj,size_t * usable_size)71*795d594fSAndroid Build Coastguard Worker size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override { 72*795d594fSAndroid Build Coastguard Worker return AllocationSizeNonvirtual(obj, usable_size); 73*795d594fSAndroid Build Coastguard Worker } 74*795d594fSAndroid Build Coastguard Worker // Virtual to allow MemoryToolMallocSpace to intercept. 75*795d594fSAndroid Build Coastguard Worker size_t Free(Thread* self, mirror::Object* ptr) override 76*795d594fSAndroid Build Coastguard Worker REQUIRES(!lock_) 77*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 78*795d594fSAndroid Build Coastguard Worker // Virtual to allow MemoryToolMallocSpace to intercept. 79*795d594fSAndroid Build Coastguard Worker size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) override 80*795d594fSAndroid Build Coastguard Worker REQUIRES(!lock_) 81*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 82*795d594fSAndroid Build Coastguard Worker MaxBytesBulkAllocatedFor(size_t num_bytes)83*795d594fSAndroid Build Coastguard Worker size_t MaxBytesBulkAllocatedFor(size_t num_bytes) override { 84*795d594fSAndroid Build Coastguard Worker return num_bytes; 85*795d594fSAndroid Build Coastguard Worker } 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker // DlMallocSpaces don't have thread local state. RevokeThreadLocalBuffers(art::Thread *)88*795d594fSAndroid Build Coastguard Worker size_t RevokeThreadLocalBuffers(art::Thread*) override { 89*795d594fSAndroid Build Coastguard Worker return 0U; 90*795d594fSAndroid Build Coastguard Worker } RevokeAllThreadLocalBuffers()91*795d594fSAndroid Build Coastguard Worker size_t RevokeAllThreadLocalBuffers() override { 92*795d594fSAndroid Build Coastguard Worker return 0U; 93*795d594fSAndroid Build Coastguard Worker } 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker // Faster non-virtual allocation path. 96*795d594fSAndroid Build Coastguard Worker mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated, 97*795d594fSAndroid Build Coastguard Worker size_t* usable_size, size_t* bytes_tl_bulk_allocated) 98*795d594fSAndroid Build Coastguard Worker REQUIRES(!lock_); 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker // Faster non-virtual allocation size path. 101*795d594fSAndroid Build Coastguard Worker size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size); 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker #ifndef NDEBUG 104*795d594fSAndroid Build Coastguard Worker // Override only in the debug build. 105*795d594fSAndroid Build Coastguard Worker void CheckMoreCoreForPrecondition() override; 106*795d594fSAndroid Build Coastguard Worker #endif 107*795d594fSAndroid Build Coastguard Worker GetMspace()108*795d594fSAndroid Build Coastguard Worker void* GetMspace() const { 109*795d594fSAndroid Build Coastguard Worker return mspace_; 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker size_t Trim() override; 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be 115*795d594fSAndroid Build Coastguard Worker // in use, indicated by num_bytes equaling zero. 116*795d594fSAndroid Build Coastguard Worker void Walk(WalkCallback callback, void* arg) override REQUIRES(!lock_); 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker // Returns the number of bytes that the space has currently obtained from the system. This is 119*795d594fSAndroid Build Coastguard Worker // greater or equal to the amount of live data in the space. 120*795d594fSAndroid Build Coastguard Worker size_t GetFootprint() override; 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore. 123*795d594fSAndroid Build Coastguard Worker size_t GetFootprintLimit() override; 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker // Set the maximum number of bytes that the heap is allowed to obtain from the system via 126*795d594fSAndroid Build Coastguard Worker // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When 127*795d594fSAndroid Build Coastguard Worker // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow. 128*795d594fSAndroid Build Coastguard Worker void SetFootprintLimit(size_t limit) override; 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker MallocSpace* CreateInstance(MemMap&& mem_map, 131*795d594fSAndroid Build Coastguard Worker const std::string& name, 132*795d594fSAndroid Build Coastguard Worker void* allocator, 133*795d594fSAndroid Build Coastguard Worker uint8_t* begin, 134*795d594fSAndroid Build Coastguard Worker uint8_t* end, 135*795d594fSAndroid Build Coastguard Worker uint8_t* limit, 136*795d594fSAndroid Build Coastguard Worker size_t growth_limit, 137*795d594fSAndroid Build Coastguard Worker bool can_move_objects) override; 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker uint64_t GetBytesAllocated() override; 140*795d594fSAndroid Build Coastguard Worker uint64_t GetObjectsAllocated() override; 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker void Clear() override; 143*795d594fSAndroid Build Coastguard Worker IsDlMallocSpace()144*795d594fSAndroid Build Coastguard Worker bool IsDlMallocSpace() const override { 145*795d594fSAndroid Build Coastguard Worker return true; 146*795d594fSAndroid Build Coastguard Worker } 147*795d594fSAndroid Build Coastguard Worker AsDlMallocSpace()148*795d594fSAndroid Build Coastguard Worker DlMallocSpace* AsDlMallocSpace() override { 149*795d594fSAndroid Build Coastguard Worker return this; 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker bool LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) override 153*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker protected: 156*795d594fSAndroid Build Coastguard Worker DlMallocSpace(MemMap&& mem_map, 157*795d594fSAndroid Build Coastguard Worker size_t initial_size, 158*795d594fSAndroid Build Coastguard Worker const std::string& name, 159*795d594fSAndroid Build Coastguard Worker void* mspace, 160*795d594fSAndroid Build Coastguard Worker uint8_t* begin, 161*795d594fSAndroid Build Coastguard Worker uint8_t* end, 162*795d594fSAndroid Build Coastguard Worker uint8_t* limit, 163*795d594fSAndroid Build Coastguard Worker size_t growth_limit, 164*795d594fSAndroid Build Coastguard Worker bool can_move_objects, 165*795d594fSAndroid Build Coastguard Worker size_t starting_size); 166*795d594fSAndroid Build Coastguard Worker 167*795d594fSAndroid Build Coastguard Worker private: 168*795d594fSAndroid Build Coastguard Worker mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated, 169*795d594fSAndroid Build Coastguard Worker size_t* usable_size, 170*795d594fSAndroid Build Coastguard Worker size_t* bytes_tl_bulk_allocated) 171*795d594fSAndroid Build Coastguard Worker REQUIRES(lock_); 172*795d594fSAndroid Build Coastguard Worker CreateAllocator(void * base,size_t morecore_start,size_t initial_size,size_t,bool)173*795d594fSAndroid Build Coastguard Worker void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size, 174*795d594fSAndroid Build Coastguard Worker size_t /*maximum_size*/, bool /*low_memory_mode*/) override { 175*795d594fSAndroid Build Coastguard Worker return CreateMspace(base, morecore_start, initial_size); 176*795d594fSAndroid Build Coastguard Worker } 177*795d594fSAndroid Build Coastguard Worker static void* CreateMspace(void* base, size_t morecore_start, size_t initial_size); 178*795d594fSAndroid Build Coastguard Worker 179*795d594fSAndroid Build Coastguard Worker // The boundary tag overhead. 180*795d594fSAndroid Build Coastguard Worker static const size_t kChunkOverhead = sizeof(intptr_t); 181*795d594fSAndroid Build Coastguard Worker 182*795d594fSAndroid Build Coastguard Worker // Underlying malloc space. 183*795d594fSAndroid Build Coastguard Worker void* mspace_; 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker friend class collector::MarkSweep; 186*795d594fSAndroid Build Coastguard Worker 187*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(DlMallocSpace); 188*795d594fSAndroid Build Coastguard Worker }; 189*795d594fSAndroid Build Coastguard Worker 190*795d594fSAndroid Build Coastguard Worker } // namespace space 191*795d594fSAndroid Build Coastguard Worker 192*795d594fSAndroid Build Coastguard Worker namespace allocator { 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker // Callback from dlmalloc when it needs to increase the footprint. 195*795d594fSAndroid Build Coastguard Worker // Must be implemented outside of art-dlmalloc.cc. 196*795d594fSAndroid Build Coastguard Worker void* ArtDlMallocMoreCore(void* mspace, intptr_t increment); 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker } // namespace allocator 199*795d594fSAndroid Build Coastguard Worker } // namespace gc 200*795d594fSAndroid Build Coastguard Worker } // namespace art 201*795d594fSAndroid Build Coastguard Worker 202*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ 203