diff options
Diffstat (limited to 'runtime/gc/space/dlmalloc_space.h')
-rw-r--r-- | runtime/gc/space/dlmalloc_space.h | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/runtime/gc/space/dlmalloc_space.h b/runtime/gc/space/dlmalloc_space.h new file mode 100644 index 0000000..00df0e6 --- /dev/null +++ b/runtime/gc/space/dlmalloc_space.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_GC_SPACE_DLMALLOC_SPACE_H_ +#define ART_SRC_GC_SPACE_DLMALLOC_SPACE_H_ + +#include "gc/allocator/dlmalloc.h" +#include "space.h" + +namespace art { +namespace gc { + +namespace collector { + class MarkSweep; +} // namespace collector + +namespace space { + +// An alloc space is a space where objects may be allocated and garbage collected. +class DlMallocSpace : public MemMapSpace, public AllocSpace { + 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 + // 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. + 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); + + // Allocate num_bytes allowing the underlying mspace to grow. + virtual mirror::Object* Alloc(Thread* self, size_t num_bytes); + + // 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); + + void* MoreCore(intptr_t increment); + + 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 + // in use, indicated by num_bytes equaling zero. + void Walk(WalkCallback callback, void* arg); + + // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore. + size_t GetFootprintLimit(); + + // Set the maximum number of bytes that the heap is allowed to obtain from the system via + // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When + // 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(); + + uint64_t GetBytesAllocated() const { + return num_bytes_allocated_; + } + + uint64_t GetObjectsAllocated() const { + return num_objects_allocated_; + } + + uint64_t GetTotalBytesAllocated() const { + return total_bytes_allocated_; + } + + uint64_t GetTotalObjectsAllocated() const { + return total_objects_allocated_; + } + + protected: + DlMallocSpace(const std::string& name, MemMap* mem_map, void* mspace, byte* begin, byte* end, + size_t growth_limit); + + private: + size_t InternalAllocationSize(const mirror::Object* obj); + mirror::Object* AllocWithoutGrowthLocked(size_t num_bytes) EXCLUSIVE_LOCKS_REQUIRED(lock_); + + bool Init(size_t initial_size, size_t maximum_size, size_t growth_size, byte* requested_base); + + 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_; + + // Approximate number of bytes which have been allocated into the space. + size_t num_bytes_allocated_; + size_t num_objects_allocated_; + size_t total_bytes_allocated_; + size_t total_objects_allocated_; + + 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* const 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); +}; + +} // namespace space +} // namespace gc +} // namespace art + +#endif // ART_SRC_GC_SPACE_DLMALLOC_SPACE_H_ |