• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
18 #define ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
19 
20 #include "gc/allocator/dlmalloc.h"
21 #include "space.h"
22 
23 namespace art {
24 namespace gc {
25 
26 namespace collector {
27   class MarkSweep;
28 }  // namespace collector
29 
30 namespace space {
31 
32 // An alloc space is a space where objects may be allocated and garbage collected.
33 class DlMallocSpace : public MemMapSpace, public AllocSpace {
34  public:
35   typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg);
36 
GetType()37   SpaceType GetType() const {
38     if (GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) {
39       return kSpaceTypeZygoteSpace;
40     } else {
41       return kSpaceTypeAllocSpace;
42     }
43   }
44 
45   // Create a AllocSpace with the requested sizes. The requested
46   // base address is not guaranteed to be granted, if it is required,
47   // the caller should call Begin on the returned space to confirm
48   // the request was granted.
49   static DlMallocSpace* Create(const std::string& name, size_t initial_size, size_t growth_limit,
50                                size_t capacity, byte* requested_begin);
51 
52   // Allocate num_bytes without allowing the underlying mspace to grow.
53   virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes,
54                                           size_t* bytes_allocated) LOCKS_EXCLUDED(lock_);
55 
56   // Allocate num_bytes allowing the underlying mspace to grow.
57   virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated);
58 
59   // Return the storage space required by obj.
60   virtual size_t AllocationSize(const mirror::Object* obj);
61   virtual size_t Free(Thread* self, mirror::Object* ptr);
62   virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs);
63 
64   mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated);
65 
AllocationSizeNonvirtual(const mirror::Object * obj)66   size_t AllocationSizeNonvirtual(const mirror::Object* obj) {
67     return mspace_usable_size(const_cast<void*>(reinterpret_cast<const void*>(obj))) +
68         kChunkOverhead;
69   }
70 
71   void* MoreCore(intptr_t increment);
72 
GetMspace()73   void* GetMspace() const {
74     return mspace_;
75   }
76 
77   // Hands unused pages back to the system.
78   size_t Trim();
79 
80   // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be
81   // in use, indicated by num_bytes equaling zero.
82   void Walk(WalkCallback callback, void* arg) LOCKS_EXCLUDED(lock_);
83 
84   // Returns the number of bytes that the space has currently obtained from the system. This is
85   // greater or equal to the amount of live data in the space.
86   size_t GetFootprint();
87 
88   // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore.
89   size_t GetFootprintLimit();
90 
91   // Set the maximum number of bytes that the heap is allowed to obtain from the system via
92   // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When
93   // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow.
94   void SetFootprintLimit(size_t limit);
95 
96   // Removes the fork time growth limit on capacity, allowing the application to allocate up to the
97   // maximum reserved size of the heap.
ClearGrowthLimit()98   void ClearGrowthLimit() {
99     growth_limit_ = NonGrowthLimitCapacity();
100   }
101 
102   // Override capacity so that we only return the possibly limited capacity
Capacity()103   size_t Capacity() const {
104     return growth_limit_;
105   }
106 
107   // The total amount of memory reserved for the alloc space.
NonGrowthLimitCapacity()108   size_t NonGrowthLimitCapacity() const {
109     return GetMemMap()->Size();
110   }
111 
GetLiveBitmap()112   accounting::SpaceBitmap* GetLiveBitmap() const {
113     return live_bitmap_.get();
114   }
115 
GetMarkBitmap()116   accounting::SpaceBitmap* GetMarkBitmap() const {
117     return mark_bitmap_.get();
118   }
119 
120   void Dump(std::ostream& os) const;
121 
122   void SetGrowthLimit(size_t growth_limit);
123 
124   // Swap the live and mark bitmaps of this space. This is used by the GC for concurrent sweeping.
125   void SwapBitmaps();
126 
127   // Turn ourself into a zygote space and return a new alloc space which has our unused memory.
128   DlMallocSpace* CreateZygoteSpace(const char* alloc_space_name);
129 
GetBytesAllocated()130   uint64_t GetBytesAllocated() const {
131     return num_bytes_allocated_;
132   }
133 
GetObjectsAllocated()134   uint64_t GetObjectsAllocated() const {
135     return num_objects_allocated_;
136   }
137 
GetTotalBytesAllocated()138   uint64_t GetTotalBytesAllocated() const {
139     return total_bytes_allocated_;
140   }
141 
GetTotalObjectsAllocated()142   uint64_t GetTotalObjectsAllocated() const {
143     return total_objects_allocated_;
144   }
145 
146   // Returns the class of a recently freed object.
147   mirror::Class* FindRecentFreedObject(const mirror::Object* obj);
148 
149  protected:
150   DlMallocSpace(const std::string& name, MemMap* mem_map, void* mspace, byte* begin, byte* end,
151                 size_t growth_limit);
152 
153  private:
154   size_t InternalAllocationSize(const mirror::Object* obj);
155   mirror::Object* AllocWithoutGrowthLocked(size_t num_bytes, size_t* bytes_allocated)
156       EXCLUSIVE_LOCKS_REQUIRED(lock_);
157   bool Init(size_t initial_size, size_t maximum_size, size_t growth_size, byte* requested_base);
158   void RegisterRecentFree(mirror::Object* ptr);
159   static void* CreateMallocSpace(void* base, size_t morecore_start, size_t initial_size);
160 
161   UniquePtr<accounting::SpaceBitmap> live_bitmap_;
162   UniquePtr<accounting::SpaceBitmap> mark_bitmap_;
163   UniquePtr<accounting::SpaceBitmap> temp_bitmap_;
164 
165   // Recent allocation buffer.
166   static constexpr size_t kRecentFreeCount = kDebugSpaces ? (1 << 16) : 0;
167   static constexpr size_t kRecentFreeMask = kRecentFreeCount - 1;
168   std::pair<const mirror::Object*, mirror::Class*> recent_freed_objects_[kRecentFreeCount];
169   size_t recent_free_pos_;
170 
171   // Approximate number of bytes which have been allocated into the space.
172   size_t num_bytes_allocated_;
173   size_t num_objects_allocated_;
174   size_t total_bytes_allocated_;
175   size_t total_objects_allocated_;
176 
177   static size_t bitmap_index_;
178 
179   // The boundary tag overhead.
180   static const size_t kChunkOverhead = kWordSize;
181 
182   // Used to ensure mutual exclusion when the allocation spaces data structures are being modified.
183   Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
184 
185   // Underlying malloc space
186   void* const mspace_;
187 
188   // The capacity of the alloc space until such time that ClearGrowthLimit is called.
189   // The underlying mem_map_ controls the maximum size we allow the heap to grow to. The growth
190   // limit is a value <= to the mem_map_ capacity used for ergonomic reasons because of the zygote.
191   // Prior to forking the zygote the heap will have a maximally sized mem_map_ but the growth_limit_
192   // will be set to a lower value. The growth_limit_ is used as the capacity of the alloc_space_,
193   // however, capacity normally can't vary. In the case of the growth_limit_ it can be cleared
194   // one time by a call to ClearGrowthLimit.
195   size_t growth_limit_;
196 
197   friend class collector::MarkSweep;
198 
199   DISALLOW_COPY_AND_ASSIGN(DlMallocSpace);
200 };
201 
202 }  // namespace space
203 }  // namespace gc
204 }  // namespace art
205 
206 #endif  // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
207