xref: /aosp_15_r20/art/runtime/gc/space/malloc_space.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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