rosalloc_space.h revision 4ce1f00cc74867188347e463f4a5ecb9fe55cde5
1cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi/* 2cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Copyright (C) 2013 The Android Open Source Project 3cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * 4cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Licensed under the Apache License, Version 2.0 (the "License"); 5cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * you may not use this file except in compliance with the License. 6cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * You may obtain a copy of the License at 7cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * 8cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * http://www.apache.org/licenses/LICENSE-2.0 9cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * 10cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Unless required by applicable law or agreed to in writing, software 11cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * distributed under the License is distributed on an "AS IS" BASIS, 12cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * See the License for the specific language governing permissions and 14cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * limitations under the License. 15cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi */ 16cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 17cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_H_ 18cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#define ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_H_ 19cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 20cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "gc/allocator/rosalloc.h" 21cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "malloc_space.h" 22cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "space.h" 23cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 24cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace art { 25cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace gc { 26cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 27cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace collector { 28cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi class MarkSweep; 29cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace collector 30cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 31cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace space { 32cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 33cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// An alloc space is a space where objects may be allocated and garbage collected. 34cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass RosAllocSpace : public MallocSpace { 35cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi public: 36cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Create a RosAllocSpace with the requested sizes. The requested 37cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // base address is not guaranteed to be granted, if it is required, 38cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // the caller should call Begin on the returned space to confirm the 39cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // request was granted. 40cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static RosAllocSpace* Create(const std::string& name, size_t initial_size, size_t growth_limit, 41cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t capacity, byte* requested_begin); 42cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 43cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, 44cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t* bytes_allocated) LOCKS_EXCLUDED(lock_); 45cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated); 46cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t AllocationSize(const mirror::Object* obj); 47cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t Free(Thread* self, mirror::Object* ptr); 48cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs); 49cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 50cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated); 51cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 52cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t AllocationSizeNonvirtual(const mirror::Object* obj) 53cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi NO_THREAD_SAFETY_ANALYSIS { 54cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // TODO: NO_THREAD_SAFETY_ANALYSIS because SizeOf() requires that mutator_lock is held. 55cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void* obj_ptr = const_cast<void*>(reinterpret_cast<const void*>(obj)); 56cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // obj is a valid object. Use its class in the header to get the size. 57cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t size = obj->SizeOf(); 58cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t size_by_size = rosalloc_->UsableSize(size); 59cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (kIsDebugBuild) { 60cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t size_by_ptr = rosalloc_->UsableSize(obj_ptr); 61cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (size_by_size != size_by_ptr) { 62cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi LOG(INFO) << "Found a bad sized obj of size " << size 63cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << " at " << std::hex << reinterpret_cast<intptr_t>(obj_ptr) << std::dec 64cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << " size_by_size=" << size_by_size << " size_by_ptr=" << size_by_ptr; 65cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 66cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi DCHECK_EQ(size_by_size, size_by_ptr); 67cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 68cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return size_by_size; 69cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 70cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 71cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi art::gc::allocator::RosAlloc* GetRosAlloc() { 72cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return rosalloc_; 73cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 74cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 75cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t Trim(); 76cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void Walk(WalkCallback callback, void* arg) LOCKS_EXCLUDED(lock_); 77cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t GetFootprint(); 78cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t GetFootprintLimit(); 79cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void SetFootprintLimit(size_t limit); 80cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 81cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi MallocSpace* CreateInstance(const std::string& name, MemMap* mem_map, void* allocator, 82cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi byte* begin, byte* end, byte* limit, size_t growth_limit); 83cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 84cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi uint64_t GetBytesAllocated(); 85cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi uint64_t GetObjectsAllocated(); 86cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi uint64_t GetTotalBytesAllocated() { 87cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return GetBytesAllocated() + total_bytes_freed_atomic_; 88cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 89cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi uint64_t GetTotalObjectsAllocated() { 90cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return GetObjectsAllocated() + total_objects_freed_atomic_; 91cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 92cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 93cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void RevokeThreadLocalBuffers(Thread* thread); 94cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void RevokeAllThreadLocalBuffers(); 95cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 96cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Returns the class of a recently freed object. 97cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi mirror::Class* FindRecentFreedObject(const mirror::Object* obj); 98cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 99cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual void InvalidateAllocator() { 1004ce1f00cc74867188347e463f4a5ecb9fe55cde5Hiroshi Yamauchi rosalloc_for_alloc_ = NULL; 101cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 102cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 103cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual bool IsRosAllocSpace() const { 104cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return true; 105cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 106cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual RosAllocSpace* AsRosAllocSpace() { 107cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return this; 108cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 109cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 110cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi protected: 111cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi RosAllocSpace(const std::string& name, MemMap* mem_map, allocator::RosAlloc* rosalloc, 112cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi byte* begin, byte* end, byte* limit, size_t growth_limit); 113cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 114cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi private: 115cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t InternalAllocationSize(const mirror::Object* obj); 116cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated); 117cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 118cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size) { 119cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return CreateRosAlloc(base, morecore_start, initial_size); 120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static allocator::RosAlloc* CreateRosAlloc(void* base, size_t morecore_start, size_t initial_size); 122cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 123cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void InspectAllRosAlloc(void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg), 125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void* arg) 126cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, Locks::thread_list_lock_); 127cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 128cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Approximate number of bytes and objects which have been deallocated in the space. 129cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi AtomicInteger total_bytes_freed_atomic_; 130cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi AtomicInteger total_objects_freed_atomic_; 131cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 132cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Underlying rosalloc. 1334ce1f00cc74867188347e463f4a5ecb9fe55cde5Hiroshi Yamauchi art::gc::allocator::RosAlloc* const rosalloc_; 1344ce1f00cc74867188347e463f4a5ecb9fe55cde5Hiroshi Yamauchi 1354ce1f00cc74867188347e463f4a5ecb9fe55cde5Hiroshi Yamauchi // A rosalloc pointer used for allocation. Equals to what rosalloc_ 1364ce1f00cc74867188347e463f4a5ecb9fe55cde5Hiroshi Yamauchi // points to or nullptr after InvalidateAllocator() is called. 1374ce1f00cc74867188347e463f4a5ecb9fe55cde5Hiroshi Yamauchi art::gc::allocator::RosAlloc* rosalloc_for_alloc_; 138cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 139cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi friend class collector::MarkSweep; 140cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 141cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(RosAllocSpace); 142cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi}; 143cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 144cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace space 145cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace gc 146cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace art 147cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 148cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif // ART_RUNTIME_GC_SPACE_ROSALLOC_SPACE_H_ 149