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