diff options
Diffstat (limited to 'runtime/gc/space/dlmalloc_space.h')
-rw-r--r-- | runtime/gc/space/dlmalloc_space.h | 117 |
1 files changed, 27 insertions, 90 deletions
diff --git a/runtime/gc/space/dlmalloc_space.h b/runtime/gc/space/dlmalloc_space.h index 59dafe3f2a..63b1c216ce 100644 --- a/runtime/gc/space/dlmalloc_space.h +++ b/runtime/gc/space/dlmalloc_space.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ #include "gc/allocator/dlmalloc.h" +#include "malloc_space.h" #include "space.h" namespace art { @@ -30,33 +31,19 @@ namespace collector { namespace space { // An alloc space is a space where objects may be allocated and garbage collected. -class DlMallocSpace : public ContinuousMemMapAllocSpace { +class DlMallocSpace : public MallocSpace { public: - typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg); - - SpaceType GetType() const { - if (GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) { - return kSpaceTypeZygoteSpace; - } else { - return kSpaceTypeAllocSpace; - } - } - // Create a AllocSpace with the requested sizes. The requested + // Create a DlMallocSpace with the requested sizes. The requested // base address is not guaranteed to be granted, if it is required, - // the caller should call Begin on the returned space to confirm - // the request was granted. + // the caller should call Begin on the returned space to confirm the + // request was granted. static DlMallocSpace* Create(const std::string& name, size_t initial_size, size_t growth_limit, size_t capacity, byte* requested_begin); - // Allocate num_bytes without allowing the underlying mspace to grow. virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated) LOCKS_EXCLUDED(lock_); - - // Allocate num_bytes allowing the underlying mspace to grow. virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated); - - // Return the storage space required by obj. virtual size_t AllocationSize(const mirror::Object* obj); virtual size_t Free(Thread* self, mirror::Object* ptr); virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs); @@ -64,17 +51,19 @@ class DlMallocSpace : public ContinuousMemMapAllocSpace { mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated); size_t AllocationSizeNonvirtual(const mirror::Object* obj) { - return mspace_usable_size(const_cast<void*>(reinterpret_cast<const void*>(obj))) + - kChunkOverhead; + void* obj_ptr = const_cast<void*>(reinterpret_cast<const void*>(obj)); + return mspace_usable_size(obj_ptr) + kChunkOverhead; } - void* MoreCore(intptr_t increment); +#ifndef NDEBUG + // Override only in the debug build. + void CheckMoreCoreForPrecondition(); +#endif void* GetMspace() const { return mspace_; } - // Hands unused pages back to the system. size_t Trim(); // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be @@ -93,39 +82,8 @@ class DlMallocSpace : public ContinuousMemMapAllocSpace { // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow. void SetFootprintLimit(size_t limit); - // Removes the fork time growth limit on capacity, allowing the application to allocate up to the - // maximum reserved size of the heap. - void ClearGrowthLimit() { - growth_limit_ = NonGrowthLimitCapacity(); - } - - // Override capacity so that we only return the possibly limited capacity - size_t Capacity() const { - return growth_limit_; - } - - // The total amount of memory reserved for the alloc space. - size_t NonGrowthLimitCapacity() const { - return GetMemMap()->Size(); - } - - accounting::SpaceBitmap* GetLiveBitmap() const { - return live_bitmap_.get(); - } - - accounting::SpaceBitmap* GetMarkBitmap() const { - return mark_bitmap_.get(); - } - - void Dump(std::ostream& os) const; - - void SetGrowthLimit(size_t growth_limit); - - // Swap the live and mark bitmaps of this space. This is used by the GC for concurrent sweeping. - void SwapBitmaps(); - - // Turn ourself into a zygote space and return a new alloc space which has our unused memory. - DlMallocSpace* CreateZygoteSpace(const char* alloc_space_name); + MallocSpace* CreateInstance(const std::string& name, MemMap* mem_map, void* allocator, + byte* begin, byte* end, byte* limit, size_t growth_limit); uint64_t GetBytesAllocated(); uint64_t GetObjectsAllocated(); @@ -136,66 +94,45 @@ class DlMallocSpace : public ContinuousMemMapAllocSpace { return GetObjectsAllocated() + total_objects_freed_; } - // Returns the old mark bitmap. - accounting::SpaceBitmap* BindLiveToMarkBitmap(); - bool HasBoundBitmaps() const; - void UnBindBitmaps(); - // Returns the class of a recently freed object. mirror::Class* FindRecentFreedObject(const mirror::Object* obj); - // Used to ensure that failure happens when you free / allocate into an invalidated space. If we - // don't do this we may get heap corruption instead of a segfault at null. - void InvalidateMSpace() { + virtual void InvalidateAllocator() { mspace_ = nullptr; } + virtual bool IsDlMallocSpace() const { + return true; + } + virtual DlMallocSpace* AsDlMallocSpace() { + return this; + } + protected: DlMallocSpace(const std::string& name, MemMap* mem_map, void* mspace, byte* begin, byte* end, byte* limit, size_t growth_limit); private: size_t InternalAllocationSize(const mirror::Object* obj); - mirror::Object* AllocWithoutGrowthLocked(size_t num_bytes, size_t* bytes_allocated) - EXCLUSIVE_LOCKS_REQUIRED(lock_); - bool Init(size_t initial_size, size_t maximum_size, size_t growth_size, byte* requested_base); - void RegisterRecentFree(mirror::Object* ptr) EXCLUSIVE_LOCKS_REQUIRED(lock_); - static void* CreateMallocSpace(void* base, size_t morecore_start, size_t initial_size); - UniquePtr<accounting::SpaceBitmap> live_bitmap_; - UniquePtr<accounting::SpaceBitmap> mark_bitmap_; - UniquePtr<accounting::SpaceBitmap> temp_bitmap_; + mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated) + EXCLUSIVE_LOCKS_REQUIRED(lock_); - // Recent allocation buffer. - static constexpr size_t kRecentFreeCount = kDebugSpaces ? (1 << 16) : 0; - static constexpr size_t kRecentFreeMask = kRecentFreeCount - 1; - std::pair<const mirror::Object*, mirror::Class*> recent_freed_objects_[kRecentFreeCount]; - size_t recent_free_pos_; + void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size) { + return CreateMspace(base, morecore_start, initial_size); + } + static void* CreateMspace(void* base, size_t morecore_start, size_t initial_size); // Approximate number of bytes and objects which have been deallocated in the space. size_t total_bytes_freed_; size_t total_objects_freed_; - static size_t bitmap_index_; - // The boundary tag overhead. static const size_t kChunkOverhead = kWordSize; - // Used to ensure mutual exclusion when the allocation spaces data structures are being modified. - Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - // Underlying malloc space void* mspace_; - // The capacity of the alloc space until such time that ClearGrowthLimit is called. - // The underlying mem_map_ controls the maximum size we allow the heap to grow to. The growth - // limit is a value <= to the mem_map_ capacity used for ergonomic reasons because of the zygote. - // Prior to forking the zygote the heap will have a maximally sized mem_map_ but the growth_limit_ - // will be set to a lower value. The growth_limit_ is used as the capacity of the alloc_space_, - // however, capacity normally can't vary. In the case of the growth_limit_ it can be cleared - // one time by a call to ClearGrowthLimit. - size_t growth_limit_; - friend class collector::MarkSweep; DISALLOW_COPY_AND_ASSIGN(DlMallocSpace); |