1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2013 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_MALLOC_SPACE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "space.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include <iosfwd> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include "base/memory_tool.h" 25*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h" 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 28*795d594fSAndroid Build Coastguard Worker namespace gc { 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace collector { 31*795d594fSAndroid Build Coastguard Worker class MarkSweep; 32*795d594fSAndroid Build Coastguard Worker } // namespace collector 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker namespace space { 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker class ZygoteSpace; 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker // A common parent of DlMallocSpace and RosAllocSpace. 39*795d594fSAndroid Build Coastguard Worker class MallocSpace : public ContinuousMemMapAllocSpace { 40*795d594fSAndroid Build Coastguard Worker public: 41*795d594fSAndroid Build Coastguard Worker using WalkCallback = void (*)(void *start, void *end, size_t num_bytes, void* callback_arg); 42*795d594fSAndroid Build Coastguard Worker GetType()43*795d594fSAndroid Build Coastguard Worker SpaceType GetType() const override { 44*795d594fSAndroid Build Coastguard Worker return kSpaceTypeMallocSpace; 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker // Allocate num_bytes allowing the underlying space to grow. 48*795d594fSAndroid Build Coastguard Worker virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, 49*795d594fSAndroid Build Coastguard Worker size_t* bytes_allocated, size_t* usable_size, 50*795d594fSAndroid Build Coastguard Worker size_t* bytes_tl_bulk_allocated) = 0; 51*795d594fSAndroid Build Coastguard Worker // Allocate num_bytes without allowing the underlying space to grow. 52*795d594fSAndroid Build Coastguard Worker mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 53*795d594fSAndroid Build Coastguard Worker size_t* usable_size, size_t* bytes_tl_bulk_allocated) override = 0; 54*795d594fSAndroid Build Coastguard Worker // Return the storage space required by obj. If usable_size isn't null then it is set to the 55*795d594fSAndroid Build Coastguard Worker // amount of the storage space that may be used by obj. 56*795d594fSAndroid Build Coastguard Worker size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override = 0; 57*795d594fSAndroid Build Coastguard Worker size_t Free(Thread* self, mirror::Object* ptr) override 58*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 59*795d594fSAndroid Build Coastguard Worker size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) override 60*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker // Returns the maximum bytes that could be allocated for the given 63*795d594fSAndroid Build Coastguard Worker // size in bulk, that is the maximum value for the 64*795d594fSAndroid Build Coastguard Worker // bytes_allocated_bulk out param returned by MallocSpace::Alloc(). 65*795d594fSAndroid Build Coastguard Worker virtual size_t MaxBytesBulkAllocatedFor(size_t num_bytes) = 0; 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker #ifndef NDEBUG CheckMoreCoreForPrecondition()68*795d594fSAndroid Build Coastguard Worker virtual void CheckMoreCoreForPrecondition() {} // to be overridden in the debug build. 69*795d594fSAndroid Build Coastguard Worker #else CheckMoreCoreForPrecondition()70*795d594fSAndroid Build Coastguard Worker void CheckMoreCoreForPrecondition() {} // no-op in the non-debug build. 71*795d594fSAndroid Build Coastguard Worker #endif 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker void* MoreCore(intptr_t increment); 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker // Hands unused pages back to the system. 76*795d594fSAndroid Build Coastguard Worker virtual size_t Trim() = 0; 77*795d594fSAndroid Build Coastguard Worker 78*795d594fSAndroid Build Coastguard Worker // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be 79*795d594fSAndroid Build Coastguard Worker // in use, indicated by num_bytes equaling zero. 80*795d594fSAndroid Build Coastguard Worker virtual void Walk(WalkCallback callback, void* arg) = 0; 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker // Returns the number of bytes that the space has currently obtained from the system. This is 83*795d594fSAndroid Build Coastguard Worker // greater or equal to the amount of live data in the space. 84*795d594fSAndroid Build Coastguard Worker virtual size_t GetFootprint() = 0; 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore. 87*795d594fSAndroid Build Coastguard Worker virtual size_t GetFootprintLimit() = 0; 88*795d594fSAndroid Build Coastguard Worker 89*795d594fSAndroid Build Coastguard Worker // Set the maximum number of bytes that the heap is allowed to obtain from the system via 90*795d594fSAndroid Build Coastguard Worker // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When 91*795d594fSAndroid Build Coastguard Worker // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow. 92*795d594fSAndroid Build Coastguard Worker virtual void SetFootprintLimit(size_t limit) = 0; 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker // Removes the fork time growth limit on capacity, allowing the application to allocate up to the 95*795d594fSAndroid Build Coastguard Worker // maximum reserved size of the heap. ClearGrowthLimit()96*795d594fSAndroid Build Coastguard Worker void ClearGrowthLimit() { 97*795d594fSAndroid Build Coastguard Worker growth_limit_ = NonGrowthLimitCapacity(); 98*795d594fSAndroid Build Coastguard Worker } 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker // Override capacity so that we only return the possibly limited capacity Capacity()101*795d594fSAndroid Build Coastguard Worker size_t Capacity() const override { 102*795d594fSAndroid Build Coastguard Worker return growth_limit_; 103*795d594fSAndroid Build Coastguard Worker } 104*795d594fSAndroid Build Coastguard Worker 105*795d594fSAndroid Build Coastguard Worker // The total amount of memory reserved for the alloc space. NonGrowthLimitCapacity()106*795d594fSAndroid Build Coastguard Worker size_t NonGrowthLimitCapacity() const override { 107*795d594fSAndroid Build Coastguard Worker return GetMemMap()->Size(); 108*795d594fSAndroid Build Coastguard Worker } 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker // Change the non growth limit capacity by shrinking or expanding the map. Currently, only 111*795d594fSAndroid Build Coastguard Worker // shrinking is supported. 112*795d594fSAndroid Build Coastguard Worker void ClampGrowthLimit(); 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os) const override; 115*795d594fSAndroid Build Coastguard Worker 116*795d594fSAndroid Build Coastguard Worker void SetGrowthLimit(size_t growth_limit); 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker virtual MallocSpace* CreateInstance(MemMap&& mem_map, 119*795d594fSAndroid Build Coastguard Worker const std::string& name, 120*795d594fSAndroid Build Coastguard Worker void* allocator, 121*795d594fSAndroid Build Coastguard Worker uint8_t* begin, 122*795d594fSAndroid Build Coastguard Worker uint8_t* end, 123*795d594fSAndroid Build Coastguard Worker uint8_t* limit, 124*795d594fSAndroid Build Coastguard Worker size_t growth_limit, 125*795d594fSAndroid Build Coastguard Worker bool can_move_objects) = 0; 126*795d594fSAndroid Build Coastguard Worker 127*795d594fSAndroid Build Coastguard Worker // Splits ourself into a zygote space and new malloc space which has our unused memory. When true, 128*795d594fSAndroid Build Coastguard Worker // the low memory mode argument specifies that the heap wishes the created space to be more 129*795d594fSAndroid Build Coastguard Worker // aggressive in releasing unused pages. Invalidates the space its called on. 130*795d594fSAndroid Build Coastguard Worker ZygoteSpace* CreateZygoteSpace(const char* alloc_space_name, bool low_memory_mode, 131*795d594fSAndroid Build Coastguard Worker MallocSpace** out_malloc_space) NO_THREAD_SAFETY_ANALYSIS; 132*795d594fSAndroid Build Coastguard Worker uint64_t GetBytesAllocated() override = 0; 133*795d594fSAndroid Build Coastguard Worker uint64_t GetObjectsAllocated() override = 0; 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker // Returns the class of a recently freed object. 136*795d594fSAndroid Build Coastguard Worker mirror::Class* FindRecentFreedObject(const mirror::Object* obj); 137*795d594fSAndroid Build Coastguard Worker CanMoveObjects()138*795d594fSAndroid Build Coastguard Worker bool CanMoveObjects() const override { 139*795d594fSAndroid Build Coastguard Worker return can_move_objects_; 140*795d594fSAndroid Build Coastguard Worker } 141*795d594fSAndroid Build Coastguard Worker DisableMovingObjects()142*795d594fSAndroid Build Coastguard Worker void DisableMovingObjects() { 143*795d594fSAndroid Build Coastguard Worker can_move_objects_ = false; 144*795d594fSAndroid Build Coastguard Worker } 145*795d594fSAndroid Build Coastguard Worker 146*795d594fSAndroid Build Coastguard Worker protected: 147*795d594fSAndroid Build Coastguard Worker MallocSpace(const std::string& name, 148*795d594fSAndroid Build Coastguard Worker MemMap&& mem_map, 149*795d594fSAndroid Build Coastguard Worker uint8_t* begin, 150*795d594fSAndroid Build Coastguard Worker uint8_t* end, 151*795d594fSAndroid Build Coastguard Worker uint8_t* limit, 152*795d594fSAndroid Build Coastguard Worker size_t growth_limit, 153*795d594fSAndroid Build Coastguard Worker bool create_bitmaps, 154*795d594fSAndroid Build Coastguard Worker bool can_move_objects, 155*795d594fSAndroid Build Coastguard Worker size_t starting_size, 156*795d594fSAndroid Build Coastguard Worker size_t initial_size); 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker static MemMap CreateMemMap(const std::string& name, 159*795d594fSAndroid Build Coastguard Worker size_t starting_size, 160*795d594fSAndroid Build Coastguard Worker size_t* initial_size, 161*795d594fSAndroid Build Coastguard Worker size_t* growth_limit, 162*795d594fSAndroid Build Coastguard Worker size_t* capacity); 163*795d594fSAndroid Build Coastguard Worker 164*795d594fSAndroid Build Coastguard Worker // When true the low memory mode argument specifies that the heap wishes the created allocator to 165*795d594fSAndroid Build Coastguard Worker // be more aggressive in releasing unused pages. 166*795d594fSAndroid Build Coastguard Worker virtual void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size, 167*795d594fSAndroid Build Coastguard Worker size_t maximum_size, bool low_memory_mode) = 0; 168*795d594fSAndroid Build Coastguard Worker 169*795d594fSAndroid Build Coastguard Worker virtual void RegisterRecentFree(mirror::Object* ptr) 170*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) 171*795d594fSAndroid Build Coastguard Worker REQUIRES(lock_); 172*795d594fSAndroid Build Coastguard Worker GetSweepCallback()173*795d594fSAndroid Build Coastguard Worker accounting::ContinuousSpaceBitmap::SweepCallback* GetSweepCallback() override { 174*795d594fSAndroid Build Coastguard Worker return &SweepCallback; 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker // Recent allocation buffer. 178*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRecentFreeCount = kDebugSpaces ? (1 << 16) : 0; 179*795d594fSAndroid Build Coastguard Worker static constexpr size_t kRecentFreeMask = kRecentFreeCount - 1; 180*795d594fSAndroid Build Coastguard Worker std::pair<const mirror::Object*, mirror::Class*> recent_freed_objects_[kRecentFreeCount]; 181*795d594fSAndroid Build Coastguard Worker size_t recent_free_pos_; 182*795d594fSAndroid Build Coastguard Worker 183*795d594fSAndroid Build Coastguard Worker static size_t bitmap_index_; 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker // Used to ensure mutual exclusion when the allocation spaces data structures are being modified. 186*795d594fSAndroid Build Coastguard Worker Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker // The capacity of the alloc space until such time that ClearGrowthLimit is called. 189*795d594fSAndroid Build Coastguard Worker // The underlying mem_map_ controls the maximum size we allow the heap to grow to. The growth 190*795d594fSAndroid Build Coastguard Worker // limit is a value <= to the mem_map_ capacity used for ergonomic reasons because of the zygote. 191*795d594fSAndroid Build Coastguard Worker // Prior to forking the zygote the heap will have a maximally sized mem_map_ but the growth_limit_ 192*795d594fSAndroid Build Coastguard Worker // will be set to a lower value. The growth_limit_ is used as the capacity of the alloc_space_, 193*795d594fSAndroid Build Coastguard Worker // however, capacity normally can't vary. In the case of the growth_limit_ it can be cleared 194*795d594fSAndroid Build Coastguard Worker // one time by a call to ClearGrowthLimit. 195*795d594fSAndroid Build Coastguard Worker size_t growth_limit_; 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker // True if objects in the space are movable. 198*795d594fSAndroid Build Coastguard Worker bool can_move_objects_; 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker // Starting and initial sized, used when you reset the space. 201*795d594fSAndroid Build Coastguard Worker const size_t starting_size_; 202*795d594fSAndroid Build Coastguard Worker const size_t initial_size_; 203*795d594fSAndroid Build Coastguard Worker 204*795d594fSAndroid Build Coastguard Worker private: 205*795d594fSAndroid Build Coastguard Worker static void SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg) 206*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 207*795d594fSAndroid Build Coastguard Worker 208*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(MallocSpace); 209*795d594fSAndroid Build Coastguard Worker }; 210*795d594fSAndroid Build Coastguard Worker 211*795d594fSAndroid Build Coastguard Worker } // namespace space 212*795d594fSAndroid Build Coastguard Worker } // namespace gc 213*795d594fSAndroid Build Coastguard Worker } // namespace art 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_ 216