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