xref: /aosp_15_r20/art/runtime/gc/space/rosalloc_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_ROSALLOC_SPACE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "gc/allocator/rosalloc.h"
21*795d594fSAndroid Build Coastguard Worker #include "malloc_space.h"
22*795d594fSAndroid Build Coastguard Worker #include "space.h"
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
25*795d594fSAndroid Build Coastguard Worker namespace gc {
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker namespace collector {
28*795d594fSAndroid Build Coastguard Worker class MarkSweep;
29*795d594fSAndroid Build Coastguard Worker }  // namespace collector
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker namespace space {
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker // An alloc space implemented using a runs-of-slots memory allocator. Not final as may be
34*795d594fSAndroid Build Coastguard Worker // overridden by a MemoryToolMallocSpace.
35*795d594fSAndroid Build Coastguard Worker class RosAllocSpace : public MallocSpace {
36*795d594fSAndroid Build Coastguard Worker  public:
37*795d594fSAndroid Build Coastguard Worker   // Create a RosAllocSpace with the requested sizes. The requested
38*795d594fSAndroid Build Coastguard Worker   // base address is not guaranteed to be granted, if it is required,
39*795d594fSAndroid Build Coastguard Worker   // the caller should call Begin on the returned space to confirm the
40*795d594fSAndroid Build Coastguard Worker   // request was granted.
41*795d594fSAndroid Build Coastguard Worker   static RosAllocSpace* Create(const std::string& name,
42*795d594fSAndroid Build Coastguard Worker                                size_t initial_size,
43*795d594fSAndroid Build Coastguard Worker                                size_t growth_limit,
44*795d594fSAndroid Build Coastguard Worker                                size_t capacity,
45*795d594fSAndroid Build Coastguard Worker                                bool low_memory_mode,
46*795d594fSAndroid Build Coastguard Worker                                bool can_move_objects);
47*795d594fSAndroid Build Coastguard Worker   static RosAllocSpace* CreateFromMemMap(MemMap&& mem_map,
48*795d594fSAndroid Build Coastguard Worker                                          const std::string& name,
49*795d594fSAndroid Build Coastguard Worker                                          size_t starting_size,
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 low_memory_mode,
54*795d594fSAndroid Build Coastguard Worker                                          bool can_move_objects);
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated,
57*795d594fSAndroid Build Coastguard Worker                                   size_t* usable_size, size_t* bytes_tl_bulk_allocated)
58*795d594fSAndroid Build Coastguard Worker       override REQUIRES(!lock_);
Alloc(Thread * self,size_t num_bytes,size_t * bytes_allocated,size_t * usable_size,size_t * bytes_tl_bulk_allocated)59*795d594fSAndroid Build Coastguard Worker   mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated,
60*795d594fSAndroid Build Coastguard Worker                         size_t* usable_size, size_t* bytes_tl_bulk_allocated) override {
61*795d594fSAndroid Build Coastguard Worker     return AllocNonvirtual(self, num_bytes, bytes_allocated, usable_size,
62*795d594fSAndroid Build Coastguard Worker                            bytes_tl_bulk_allocated);
63*795d594fSAndroid Build Coastguard Worker   }
AllocThreadUnsafe(Thread * self,size_t num_bytes,size_t * bytes_allocated,size_t * usable_size,size_t * bytes_tl_bulk_allocated)64*795d594fSAndroid Build Coastguard Worker   mirror::Object* AllocThreadUnsafe(Thread* self, size_t num_bytes, size_t* bytes_allocated,
65*795d594fSAndroid Build Coastguard Worker                                     size_t* usable_size, size_t* bytes_tl_bulk_allocated)
66*795d594fSAndroid Build Coastguard Worker       override REQUIRES(Locks::mutator_lock_) {
67*795d594fSAndroid Build Coastguard Worker     return AllocNonvirtualThreadUnsafe(self, num_bytes, bytes_allocated, usable_size,
68*795d594fSAndroid Build Coastguard Worker                                        bytes_tl_bulk_allocated);
69*795d594fSAndroid Build Coastguard Worker   }
AllocationSize(mirror::Object * obj,size_t * usable_size)70*795d594fSAndroid Build Coastguard Worker   size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override {
71*795d594fSAndroid Build Coastguard Worker     return AllocationSizeNonvirtual<true>(obj, usable_size);
72*795d594fSAndroid Build Coastguard Worker   }
73*795d594fSAndroid Build Coastguard Worker   size_t Free(Thread* self, mirror::Object* ptr) override
74*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
75*795d594fSAndroid Build Coastguard Worker   size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) override
76*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
77*795d594fSAndroid Build Coastguard Worker 
AllocNonvirtual(Thread * self,size_t num_bytes,size_t * bytes_allocated,size_t * usable_size,size_t * bytes_tl_bulk_allocated)78*795d594fSAndroid Build Coastguard Worker   mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated,
79*795d594fSAndroid Build Coastguard Worker                                   size_t* usable_size, size_t* bytes_tl_bulk_allocated) {
80*795d594fSAndroid Build Coastguard Worker     // RosAlloc zeroes memory internally.
81*795d594fSAndroid Build Coastguard Worker     return AllocCommon(self, num_bytes, bytes_allocated, usable_size,
82*795d594fSAndroid Build Coastguard Worker                        bytes_tl_bulk_allocated);
83*795d594fSAndroid Build Coastguard Worker   }
AllocNonvirtualThreadUnsafe(Thread * self,size_t num_bytes,size_t * bytes_allocated,size_t * usable_size,size_t * bytes_tl_bulk_allocated)84*795d594fSAndroid Build Coastguard Worker   mirror::Object* AllocNonvirtualThreadUnsafe(Thread* self, size_t num_bytes,
85*795d594fSAndroid Build Coastguard Worker                                               size_t* bytes_allocated, size_t* usable_size,
86*795d594fSAndroid Build Coastguard Worker                                               size_t* bytes_tl_bulk_allocated) {
87*795d594fSAndroid Build Coastguard Worker     // RosAlloc zeroes memory internally. Pass in false for thread unsafe.
88*795d594fSAndroid Build Coastguard Worker     return AllocCommon<false>(self, num_bytes, bytes_allocated, usable_size,
89*795d594fSAndroid Build Coastguard Worker                               bytes_tl_bulk_allocated);
90*795d594fSAndroid Build Coastguard Worker   }
91*795d594fSAndroid Build Coastguard Worker 
92*795d594fSAndroid Build Coastguard Worker   // Returns true if the given allocation request can be allocated in
93*795d594fSAndroid Build Coastguard Worker   // an existing thread local run without allocating a new run.
94*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool CanAllocThreadLocal(Thread* self, size_t num_bytes);
95*795d594fSAndroid Build Coastguard Worker   // Allocate the given allocation request in an existing thread local
96*795d594fSAndroid Build Coastguard Worker   // run without allocating a new run.
97*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE mirror::Object* AllocThreadLocal(Thread* self, size_t num_bytes,
98*795d594fSAndroid Build Coastguard Worker                                                  size_t* bytes_allocated);
MaxBytesBulkAllocatedFor(size_t num_bytes)99*795d594fSAndroid Build Coastguard Worker   size_t MaxBytesBulkAllocatedFor(size_t num_bytes) override {
100*795d594fSAndroid Build Coastguard Worker     return MaxBytesBulkAllocatedForNonvirtual(num_bytes);
101*795d594fSAndroid Build Coastguard Worker   }
102*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE size_t MaxBytesBulkAllocatedForNonvirtual(size_t num_bytes);
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   // TODO: NO_THREAD_SAFETY_ANALYSIS because SizeOf() requires that mutator_lock is held.
105*795d594fSAndroid Build Coastguard Worker   template<bool kMaybeIsRunningOnMemoryTool>
106*795d594fSAndroid Build Coastguard Worker   size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size)
107*795d594fSAndroid Build Coastguard Worker       NO_THREAD_SAFETY_ANALYSIS;
108*795d594fSAndroid Build Coastguard Worker 
GetRosAlloc()109*795d594fSAndroid Build Coastguard Worker   allocator::RosAlloc* GetRosAlloc() const {
110*795d594fSAndroid Build Coastguard Worker     return rosalloc_;
111*795d594fSAndroid Build Coastguard Worker   }
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker   size_t Trim() override;
114*795d594fSAndroid Build Coastguard Worker   void Walk(WalkCallback callback, void* arg) override REQUIRES(!lock_);
115*795d594fSAndroid Build Coastguard Worker   size_t GetFootprint() override;
116*795d594fSAndroid Build Coastguard Worker   size_t GetFootprintLimit() override;
117*795d594fSAndroid Build Coastguard Worker   void SetFootprintLimit(size_t limit) override;
118*795d594fSAndroid Build Coastguard Worker 
119*795d594fSAndroid Build Coastguard Worker   void Clear() override;
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker   MallocSpace* CreateInstance(MemMap&& mem_map,
122*795d594fSAndroid Build Coastguard Worker                               const std::string& name,
123*795d594fSAndroid Build Coastguard Worker                               void* allocator,
124*795d594fSAndroid Build Coastguard Worker                               uint8_t* begin,
125*795d594fSAndroid Build Coastguard Worker                               uint8_t* end,
126*795d594fSAndroid Build Coastguard Worker                               uint8_t* limit,
127*795d594fSAndroid Build Coastguard Worker                               size_t growth_limit,
128*795d594fSAndroid Build Coastguard Worker                               bool can_move_objects) override;
129*795d594fSAndroid Build Coastguard Worker 
130*795d594fSAndroid Build Coastguard Worker   uint64_t GetBytesAllocated() override;
131*795d594fSAndroid Build Coastguard Worker   uint64_t GetObjectsAllocated() override;
132*795d594fSAndroid Build Coastguard Worker 
133*795d594fSAndroid Build Coastguard Worker   size_t RevokeThreadLocalBuffers(Thread* thread) override;
134*795d594fSAndroid Build Coastguard Worker   size_t RevokeAllThreadLocalBuffers() override;
135*795d594fSAndroid Build Coastguard Worker   void AssertThreadLocalBuffersAreRevoked(Thread* thread);
136*795d594fSAndroid Build Coastguard Worker   void AssertAllThreadLocalBuffersAreRevoked();
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // Returns the class of a recently freed object.
139*795d594fSAndroid Build Coastguard Worker   mirror::Class* FindRecentFreedObject(const mirror::Object* obj);
140*795d594fSAndroid Build Coastguard Worker 
IsRosAllocSpace()141*795d594fSAndroid Build Coastguard Worker   bool IsRosAllocSpace() const override {
142*795d594fSAndroid Build Coastguard Worker     return true;
143*795d594fSAndroid Build Coastguard Worker   }
144*795d594fSAndroid Build Coastguard Worker 
AsRosAllocSpace()145*795d594fSAndroid Build Coastguard Worker   RosAllocSpace* AsRosAllocSpace() override {
146*795d594fSAndroid Build Coastguard Worker     return this;
147*795d594fSAndroid Build Coastguard Worker   }
148*795d594fSAndroid Build Coastguard Worker 
Verify()149*795d594fSAndroid Build Coastguard Worker   void Verify() REQUIRES(Locks::mutator_lock_) {
150*795d594fSAndroid Build Coastguard Worker     rosalloc_->Verify();
151*795d594fSAndroid Build Coastguard Worker   }
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker   virtual ~RosAllocSpace();
154*795d594fSAndroid Build Coastguard Worker 
LogFragmentationAllocFailure(std::ostream & os,size_t failed_alloc_bytes)155*795d594fSAndroid Build Coastguard Worker   bool LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) override {
156*795d594fSAndroid Build Coastguard Worker     return rosalloc_->LogFragmentationAllocFailure(os, failed_alloc_bytes);
157*795d594fSAndroid Build Coastguard Worker   }
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   void DumpStats(std::ostream& os);
160*795d594fSAndroid Build Coastguard Worker 
161*795d594fSAndroid Build Coastguard Worker  protected:
162*795d594fSAndroid Build Coastguard Worker   RosAllocSpace(MemMap&& mem_map,
163*795d594fSAndroid Build Coastguard Worker                 size_t initial_size,
164*795d594fSAndroid Build Coastguard Worker                 const std::string& name,
165*795d594fSAndroid Build Coastguard Worker                 allocator::RosAlloc* rosalloc,
166*795d594fSAndroid Build Coastguard Worker                 uint8_t* begin,
167*795d594fSAndroid Build Coastguard Worker                 uint8_t* end,
168*795d594fSAndroid Build Coastguard Worker                 uint8_t* limit,
169*795d594fSAndroid Build Coastguard Worker                 size_t growth_limit,
170*795d594fSAndroid Build Coastguard Worker                 bool can_move_objects,
171*795d594fSAndroid Build Coastguard Worker                 size_t starting_size,
172*795d594fSAndroid Build Coastguard Worker                 bool low_memory_mode);
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker  private:
175*795d594fSAndroid Build Coastguard Worker   template<bool kThreadSafe = true>
176*795d594fSAndroid Build Coastguard Worker   mirror::Object* AllocCommon(Thread* self, size_t num_bytes, size_t* bytes_allocated,
177*795d594fSAndroid Build Coastguard Worker                               size_t* usable_size, size_t* bytes_tl_bulk_allocated);
178*795d594fSAndroid Build Coastguard Worker 
CreateAllocator(void * base,size_t morecore_start,size_t initial_size,size_t maximum_size,bool low_memory_mode)179*795d594fSAndroid Build Coastguard Worker   void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size,
180*795d594fSAndroid Build Coastguard Worker                         size_t maximum_size, bool low_memory_mode) override {
181*795d594fSAndroid Build Coastguard Worker     return CreateRosAlloc(
182*795d594fSAndroid Build Coastguard Worker         base, morecore_start, initial_size, maximum_size, low_memory_mode, kRunningOnMemoryTool);
183*795d594fSAndroid Build Coastguard Worker   }
184*795d594fSAndroid Build Coastguard Worker   static allocator::RosAlloc* CreateRosAlloc(void* base, size_t morecore_start, size_t initial_size,
185*795d594fSAndroid Build Coastguard Worker                                              size_t maximum_size, bool low_memory_mode,
186*795d594fSAndroid Build Coastguard Worker                                              bool running_on_memory_tool);
187*795d594fSAndroid Build Coastguard Worker 
188*795d594fSAndroid Build Coastguard Worker   void InspectAllRosAlloc(void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
189*795d594fSAndroid Build Coastguard Worker                           void* arg, bool do_null_callback_at_end)
190*795d594fSAndroid Build Coastguard Worker       REQUIRES(!Locks::runtime_shutdown_lock_, !Locks::thread_list_lock_);
191*795d594fSAndroid Build Coastguard Worker   void InspectAllRosAllocWithSuspendAll(
192*795d594fSAndroid Build Coastguard Worker       void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
193*795d594fSAndroid Build Coastguard Worker       void* arg, bool do_null_callback_at_end)
194*795d594fSAndroid Build Coastguard Worker       REQUIRES(!Locks::runtime_shutdown_lock_, !Locks::thread_list_lock_);
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker   // Underlying rosalloc.
197*795d594fSAndroid Build Coastguard Worker   allocator::RosAlloc* rosalloc_;
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker   const bool low_memory_mode_;
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker   friend class collector::MarkSweep;
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(RosAllocSpace);
204*795d594fSAndroid Build Coastguard Worker };
205*795d594fSAndroid Build Coastguard Worker 
206*795d594fSAndroid Build Coastguard Worker }  // namespace space
207*795d594fSAndroid Build Coastguard Worker }  // namespace gc
208*795d594fSAndroid Build Coastguard Worker }  // namespace art
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_H_
211