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