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