1 /*
2  * Copyright (C) 2013 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_ALLOCATOR_ROSALLOC_H_
18 #define ART_RUNTIME_GC_ALLOCATOR_ROSALLOC_H_
19 
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <sys/mman.h>
23 #include <memory>
24 #include <set>
25 #include <string>
26 #include <unordered_set>
27 #include <vector>
28 
29 #include "base/allocator.h"
30 #include "base/bit_utils.h"
31 #include "base/mutex.h"
32 #include "base/logging.h"
33 #include "globals.h"
34 #include "thread.h"
35 
36 namespace art {
37 
38 class MemMap;
39 
40 namespace gc {
41 namespace allocator {
42 
43 // A runs-of-slots memory allocator.
44 class RosAlloc {
45  private:
46   // Represents a run of free pages.
47   class FreePageRun {
48    public:
49     uint8_t magic_num_;  // The magic number used for debugging only.
50 
IsFree()51     bool IsFree() const {
52       return !kIsDebugBuild || magic_num_ == kMagicNumFree;
53     }
ByteSize(RosAlloc * rosalloc)54     size_t ByteSize(RosAlloc* rosalloc) const EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
55       const uint8_t* fpr_base = reinterpret_cast<const uint8_t*>(this);
56       size_t pm_idx = rosalloc->ToPageMapIndex(fpr_base);
57       size_t byte_size = rosalloc->free_page_run_size_map_[pm_idx];
58       DCHECK_GE(byte_size, static_cast<size_t>(0));
59       DCHECK_ALIGNED(byte_size, kPageSize);
60       return byte_size;
61     }
SetByteSize(RosAlloc * rosalloc,size_t byte_size)62     void SetByteSize(RosAlloc* rosalloc, size_t byte_size)
63         EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
64       DCHECK_EQ(byte_size % kPageSize, static_cast<size_t>(0));
65       uint8_t* fpr_base = reinterpret_cast<uint8_t*>(this);
66       size_t pm_idx = rosalloc->ToPageMapIndex(fpr_base);
67       rosalloc->free_page_run_size_map_[pm_idx] = byte_size;
68     }
Begin()69     void* Begin() {
70       return reinterpret_cast<void*>(this);
71     }
End(RosAlloc * rosalloc)72     void* End(RosAlloc* rosalloc) EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
73       uint8_t* fpr_base = reinterpret_cast<uint8_t*>(this);
74       uint8_t* end = fpr_base + ByteSize(rosalloc);
75       return end;
76     }
IsLargerThanPageReleaseThreshold(RosAlloc * rosalloc)77     bool IsLargerThanPageReleaseThreshold(RosAlloc* rosalloc)
78         EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
79       return ByteSize(rosalloc) >= rosalloc->page_release_size_threshold_;
80     }
IsAtEndOfSpace(RosAlloc * rosalloc)81     bool IsAtEndOfSpace(RosAlloc* rosalloc)
82         EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
83       return reinterpret_cast<uint8_t*>(this) + ByteSize(rosalloc) == rosalloc->base_ + rosalloc->footprint_;
84     }
ShouldReleasePages(RosAlloc * rosalloc)85     bool ShouldReleasePages(RosAlloc* rosalloc) EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
86       switch (rosalloc->page_release_mode_) {
87         case kPageReleaseModeNone:
88           return false;
89         case kPageReleaseModeEnd:
90           return IsAtEndOfSpace(rosalloc);
91         case kPageReleaseModeSize:
92           return IsLargerThanPageReleaseThreshold(rosalloc);
93         case kPageReleaseModeSizeAndEnd:
94           return IsLargerThanPageReleaseThreshold(rosalloc) && IsAtEndOfSpace(rosalloc);
95         case kPageReleaseModeAll:
96           return true;
97         default:
98           LOG(FATAL) << "Unexpected page release mode ";
99           return false;
100       }
101     }
ReleasePages(RosAlloc * rosalloc)102     void ReleasePages(RosAlloc* rosalloc) EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
103       uint8_t* start = reinterpret_cast<uint8_t*>(this);
104       size_t byte_size = ByteSize(rosalloc);
105       DCHECK_EQ(byte_size % kPageSize, static_cast<size_t>(0));
106       if (ShouldReleasePages(rosalloc)) {
107         rosalloc->ReleasePageRange(start, start + byte_size);
108       }
109     }
110 
111    private:
112     DISALLOW_COPY_AND_ASSIGN(FreePageRun);
113   };
114 
115   // Represents a run of memory slots of the same size.
116   //
117   // A run's memory layout:
118   //
119   // +-------------------+
120   // | magic_num         |
121   // +-------------------+
122   // | size_bracket_idx  |
123   // +-------------------+
124   // | is_thread_local   |
125   // +-------------------+
126   // | to_be_bulk_freed  |
127   // +-------------------+
128   // | top_bitmap_idx    |
129   // +-------------------+
130   // |                   |
131   // | alloc bit map     |
132   // |                   |
133   // +-------------------+
134   // |                   |
135   // | bulk free bit map |
136   // |                   |
137   // +-------------------+
138   // |                   |
139   // | thread-local free |
140   // | bit map           |
141   // |                   |
142   // +-------------------+
143   // | padding due to    |
144   // | alignment         |
145   // +-------------------+
146   // | slot 0            |
147   // +-------------------+
148   // | slot 1            |
149   // +-------------------+
150   // | slot 2            |
151   // +-------------------+
152   // ...
153   // +-------------------+
154   // | last slot         |
155   // +-------------------+
156   //
157   class Run {
158    public:
159     uint8_t magic_num_;                 // The magic number used for debugging.
160     uint8_t size_bracket_idx_;          // The index of the size bracket of this run.
161     uint8_t is_thread_local_;           // True if this run is used as a thread-local run.
162     uint8_t to_be_bulk_freed_;          // Used within BulkFree() to flag a run that's involved with a bulk free.
163     uint32_t first_search_vec_idx_;  // The index of the first bitmap vector which may contain an available slot.
164     uint32_t alloc_bit_map_[0];      // The bit map that allocates if each slot is in use.
165 
166     // bulk_free_bit_map_[] : The bit map that is used for GC to
167     // temporarily mark the slots to free without using a lock. After
168     // all the slots to be freed in a run are marked, all those slots
169     // get freed in bulk with one locking per run, as opposed to one
170     // locking per slot to minimize the lock contention. This is used
171     // within BulkFree().
172 
173     // thread_local_free_bit_map_[] : The bit map that is used for GC
174     // to temporarily mark the slots to free in a thread-local run
175     // without using a lock (without synchronizing the thread that
176     // owns the thread-local run.) When the thread-local run becomes
177     // full, the thread will check this bit map and update the
178     // allocation bit map of the run (that is, the slots get freed.)
179 
180     // Returns the byte size of the header except for the bit maps.
fixed_header_size()181     static size_t fixed_header_size() {
182       Run temp;
183       size_t size = reinterpret_cast<uint8_t*>(&temp.alloc_bit_map_) - reinterpret_cast<uint8_t*>(&temp);
184       DCHECK_EQ(size, static_cast<size_t>(8));
185       return size;
186     }
187     // Returns the base address of the free bit map.
BulkFreeBitMap()188     uint32_t* BulkFreeBitMap() {
189       return reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(this) + bulkFreeBitMapOffsets[size_bracket_idx_]);
190     }
191     // Returns the base address of the thread local free bit map.
ThreadLocalFreeBitMap()192     uint32_t* ThreadLocalFreeBitMap() {
193       return reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(this) + threadLocalFreeBitMapOffsets[size_bracket_idx_]);
194     }
End()195     void* End() {
196       return reinterpret_cast<uint8_t*>(this) + kPageSize * numOfPages[size_bracket_idx_];
197     }
198     // Returns the number of bitmap words per run.
NumberOfBitmapVectors()199     size_t NumberOfBitmapVectors() const {
200       return RoundUp(numOfSlots[size_bracket_idx_], 32) / 32;
201     }
SetIsThreadLocal(bool is_thread_local)202     void SetIsThreadLocal(bool is_thread_local) {
203       is_thread_local_  = is_thread_local ? 1 : 0;
204     }
IsThreadLocal()205     bool IsThreadLocal() const {
206       return is_thread_local_ != 0;
207     }
208     // Frees slots in the allocation bit map with regard to the
209     // thread-local free bit map. Used when a thread-local run becomes
210     // full.
211     bool MergeThreadLocalFreeBitMapToAllocBitMap(bool* is_all_free_after_out);
212     // Frees slots in the allocation bit map with regard to the bulk
213     // free bit map. Used in a bulk free.
214     void MergeBulkFreeBitMapIntoAllocBitMap();
215     // Unions the slots to be freed in the free bit map into the
216     // thread-local free bit map. In a bulk free, as a two-step
217     // process, GC will first record all the slots to free in a run in
218     // the free bit map where it can write without a lock, and later
219     // acquire a lock once per run to union the bits of the free bit
220     // map to the thread-local free bit map.
221     void UnionBulkFreeBitMapToThreadLocalFreeBitMap();
222     // Allocates a slot in a run.
223     void* AllocSlot();
224     // Frees a slot in a run. This is used in a non-bulk free.
225     void FreeSlot(void* ptr);
226     // Marks the slots to free in the bulk free bit map. Returns the bracket size.
227     size_t MarkBulkFreeBitMap(void* ptr);
228     // Marks the slots to free in the thread-local free bit map.
229     void MarkThreadLocalFreeBitMap(void* ptr);
230     // Last word mask, all of the bits in the last word which aren't valid slots are set to
231     // optimize allocation path.
232     static uint32_t GetBitmapLastVectorMask(size_t num_slots, size_t num_vec);
233     // Returns true if all the slots in the run are not in use.
234     bool IsAllFree();
235     // Returns the number of free slots.
236     size_t NumberOfFreeSlots();
237     // Returns true if all the slots in the run are in use.
238     ALWAYS_INLINE bool IsFull();
239     // Returns true if the bulk free bit map is clean.
240     bool IsBulkFreeBitmapClean();
241     // Returns true if the thread local free bit map is clean.
242     bool IsThreadLocalFreeBitmapClean();
243     // Set the alloc_bit_map_ bits for slots that are past the end of the run.
244     void SetAllocBitMapBitsForInvalidSlots();
245     // Zero the run's data.
246     void ZeroData();
247     // Zero the run's header.
248     void ZeroHeader();
249     // Fill the alloc bitmap with 1s.
250     void FillAllocBitMap();
251     // Iterate over all the slots and apply the given function.
252     void InspectAllSlots(void (*handler)(void* start, void* end, size_t used_bytes, void* callback_arg), void* arg);
253     // Dump the run metadata for debugging.
254     std::string Dump();
255     // Verify for debugging.
256     void Verify(Thread* self, RosAlloc* rosalloc, bool running_on_valgrind)
257         EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
258         EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
259 
260    private:
261     // The common part of MarkFreeBitMap() and MarkThreadLocalFreeBitMap(). Returns the bracket
262     // size.
263     size_t MarkFreeBitMapShared(void* ptr, uint32_t* free_bit_map_base, const char* caller_name);
264     // Turns the bit map into a string for debugging.
265     static std::string BitMapToStr(uint32_t* bit_map_base, size_t num_vec);
266 
267     // TODO: DISALLOW_COPY_AND_ASSIGN(Run);
268   };
269 
270   // The magic number for a run.
271   static constexpr uint8_t kMagicNum = 42;
272   // The magic number for free pages.
273   static constexpr uint8_t kMagicNumFree = 43;
274   // The number of size brackets. Sync this with the length of Thread::rosalloc_runs_.
275   static constexpr size_t kNumOfSizeBrackets = kNumRosAllocThreadLocalSizeBrackets;
276   // The number of smaller size brackets that are 16 bytes apart.
277   static constexpr size_t kNumOfQuantumSizeBrackets = 32;
278   // The sizes (the slot sizes, in bytes) of the size brackets.
279   static size_t bracketSizes[kNumOfSizeBrackets];
280   // The numbers of pages that are used for runs for each size bracket.
281   static size_t numOfPages[kNumOfSizeBrackets];
282   // The numbers of slots of the runs for each size bracket.
283   static size_t numOfSlots[kNumOfSizeBrackets];
284   // The header sizes in bytes of the runs for each size bracket.
285   static size_t headerSizes[kNumOfSizeBrackets];
286   // The byte offsets of the bulk free bit maps of the runs for each size bracket.
287   static size_t bulkFreeBitMapOffsets[kNumOfSizeBrackets];
288   // The byte offsets of the thread-local free bit maps of the runs for each size bracket.
289   static size_t threadLocalFreeBitMapOffsets[kNumOfSizeBrackets];
290 
291   // Initialize the run specs (the above arrays).
292   static void Initialize();
293   static bool initialized_;
294 
295   // Returns the byte size of the bracket size from the index.
IndexToBracketSize(size_t idx)296   static size_t IndexToBracketSize(size_t idx) {
297     DCHECK_LT(idx, kNumOfSizeBrackets);
298     return bracketSizes[idx];
299   }
300   // Returns the index of the size bracket from the bracket size.
BracketSizeToIndex(size_t size)301   static size_t BracketSizeToIndex(size_t size) {
302     DCHECK(16 <= size && ((size < 1 * KB && size % 16 == 0) || size == 1 * KB || size == 2 * KB));
303     size_t idx;
304     if (UNLIKELY(size == 1 * KB)) {
305       idx = kNumOfSizeBrackets - 2;
306     } else if (UNLIKELY(size == 2 * KB)) {
307       idx = kNumOfSizeBrackets - 1;
308     } else {
309       DCHECK(size < 1 * KB);
310       DCHECK_EQ(size % 16, static_cast<size_t>(0));
311       idx = size / 16 - 1;
312     }
313     DCHECK(bracketSizes[idx] == size);
314     return idx;
315   }
316   // Returns true if the given allocation size is for a thread local allocation.
IsSizeForThreadLocal(size_t size)317   static bool IsSizeForThreadLocal(size_t size) {
318     DCHECK_GT(kNumThreadLocalSizeBrackets, 0U);
319     size_t max_thread_local_bracket_idx = kNumThreadLocalSizeBrackets - 1;
320     bool is_size_for_thread_local = size <= bracketSizes[max_thread_local_bracket_idx];
321     DCHECK(size > kLargeSizeThreshold ||
322            (is_size_for_thread_local == (SizeToIndex(size) < kNumThreadLocalSizeBrackets)));
323     return is_size_for_thread_local;
324   }
325   // Rounds up the size up the nearest bracket size.
RoundToBracketSize(size_t size)326   static size_t RoundToBracketSize(size_t size) {
327     DCHECK(size <= kLargeSizeThreshold);
328     if (LIKELY(size <= 512)) {
329       return RoundUp(size, 16);
330     } else if (512 < size && size <= 1 * KB) {
331       return 1 * KB;
332     } else {
333       DCHECK(1 * KB < size && size <= 2 * KB);
334       return 2 * KB;
335     }
336   }
337   // Returns the size bracket index from the byte size with rounding.
SizeToIndex(size_t size)338   static size_t SizeToIndex(size_t size) {
339     DCHECK(size <= kLargeSizeThreshold);
340     if (LIKELY(size <= 512)) {
341       return RoundUp(size, 16) / 16 - 1;
342     } else if (512 < size && size <= 1 * KB) {
343       return kNumOfSizeBrackets - 2;
344     } else {
345       DCHECK(1 * KB < size && size <= 2 * KB);
346       return kNumOfSizeBrackets - 1;
347     }
348   }
349   // A combination of SizeToIndex() and RoundToBracketSize().
SizeToIndexAndBracketSize(size_t size,size_t * bracket_size_out)350   static size_t SizeToIndexAndBracketSize(size_t size, size_t* bracket_size_out) {
351     DCHECK(size <= kLargeSizeThreshold);
352     if (LIKELY(size <= 512)) {
353       size_t bracket_size = RoundUp(size, 16);
354       *bracket_size_out = bracket_size;
355       size_t idx = bracket_size / 16 - 1;
356       DCHECK_EQ(bracket_size, IndexToBracketSize(idx));
357       return idx;
358     } else if (512 < size && size <= 1 * KB) {
359       size_t bracket_size = 1024;
360       *bracket_size_out = bracket_size;
361       size_t idx = kNumOfSizeBrackets - 2;
362       DCHECK_EQ(bracket_size, IndexToBracketSize(idx));
363       return idx;
364     } else {
365       DCHECK(1 * KB < size && size <= 2 * KB);
366       size_t bracket_size = 2048;
367       *bracket_size_out = bracket_size;
368       size_t idx = kNumOfSizeBrackets - 1;
369       DCHECK_EQ(bracket_size, IndexToBracketSize(idx));
370       return idx;
371     }
372   }
373   // Returns the page map index from an address. Requires that the
374   // address is page size aligned.
ToPageMapIndex(const void * addr)375   size_t ToPageMapIndex(const void* addr) const {
376     DCHECK_LE(base_, addr);
377     DCHECK_LT(addr, base_ + capacity_);
378     size_t byte_offset = reinterpret_cast<const uint8_t*>(addr) - base_;
379     DCHECK_EQ(byte_offset % static_cast<size_t>(kPageSize), static_cast<size_t>(0));
380     return byte_offset / kPageSize;
381   }
382   // Returns the page map index from an address with rounding.
RoundDownToPageMapIndex(const void * addr)383   size_t RoundDownToPageMapIndex(const void* addr) const {
384     DCHECK(base_ <= addr && addr < reinterpret_cast<uint8_t*>(base_) + capacity_);
385     return (reinterpret_cast<uintptr_t>(addr) - reinterpret_cast<uintptr_t>(base_)) / kPageSize;
386   }
387 
388   // A memory allocation request larger than this size is treated as a large object and allocated
389   // at a page-granularity.
390   static const size_t kLargeSizeThreshold = 2048;
391 
392   // If true, check that the returned memory is actually zero.
393   static constexpr bool kCheckZeroMemory = kIsDebugBuild;
394   // Valgrind protects memory, so do not check memory when running under valgrind. In a normal
395   // build with kCheckZeroMemory the whole test should be optimized away.
396   // TODO: Unprotect before checks.
397   ALWAYS_INLINE bool ShouldCheckZeroMemory();
398 
399   // If true, log verbose details of operations.
400   static constexpr bool kTraceRosAlloc = false;
401 
402   struct hash_run {
operatorhash_run403     size_t operator()(const RosAlloc::Run* r) const {
404       return reinterpret_cast<size_t>(r);
405     }
406   };
407 
408   struct eq_run {
operatoreq_run409     bool operator()(const RosAlloc::Run* r1, const RosAlloc::Run* r2) const {
410       return r1 == r2;
411     }
412   };
413 
414  public:
415   // Different page release modes.
416   enum PageReleaseMode {
417     kPageReleaseModeNone,         // Release no empty pages.
418     kPageReleaseModeEnd,          // Release empty pages at the end of the space.
419     kPageReleaseModeSize,         // Release empty pages that are larger than the threshold.
420     kPageReleaseModeSizeAndEnd,   // Release empty pages that are larger than the threshold or
421                                   // at the end of the space.
422     kPageReleaseModeAll,          // Release all empty pages.
423   };
424 
425   // The default value for page_release_size_threshold_.
426   static constexpr size_t kDefaultPageReleaseSizeThreshold = 4 * MB;
427 
428   // We use thread-local runs for the size Brackets whose indexes
429   // are less than this index. We use shared (current) runs for the rest.
430   static const size_t kNumThreadLocalSizeBrackets = 8;
431 
432  private:
433   // The base address of the memory region that's managed by this allocator.
434   uint8_t* base_;
435 
436   // The footprint in bytes of the currently allocated portion of the
437   // memory region.
438   size_t footprint_;
439 
440   // The maximum footprint. The address, base_ + capacity_, indicates
441   // the end of the memory region that's currently managed by this allocator.
442   size_t capacity_;
443 
444   // The maximum capacity. The address, base_ + max_capacity_, indicates
445   // the end of the memory region that's ever managed by this allocator.
446   size_t max_capacity_;
447 
448   // The run sets that hold the runs whose slots are not all
449   // full. non_full_runs_[i] is guarded by size_bracket_locks_[i].
450   AllocationTrackingSet<Run*, kAllocatorTagRosAlloc> non_full_runs_[kNumOfSizeBrackets];
451   // The run sets that hold the runs whose slots are all full. This is
452   // debug only. full_runs_[i] is guarded by size_bracket_locks_[i].
453   std::unordered_set<Run*, hash_run, eq_run, TrackingAllocator<Run*, kAllocatorTagRosAlloc>>
454       full_runs_[kNumOfSizeBrackets];
455   // The set of free pages.
456   AllocationTrackingSet<FreePageRun*, kAllocatorTagRosAlloc> free_page_runs_ GUARDED_BY(lock_);
457   // The dedicated full run, it is always full and shared by all threads when revoking happens.
458   // This is an optimization since enables us to avoid a null check for revoked runs.
459   static Run* dedicated_full_run_;
460   // Using size_t to ensure that it is at least word aligned.
461   static size_t dedicated_full_run_storage_[];
462   // The current runs where the allocations are first attempted for
463   // the size brackes that do not use thread-local
464   // runs. current_runs_[i] is guarded by size_bracket_locks_[i].
465   Run* current_runs_[kNumOfSizeBrackets];
466   // The mutexes, one per size bracket.
467   Mutex* size_bracket_locks_[kNumOfSizeBrackets];
468   // Bracket lock names (since locks only have char* names).
469   std::string size_bracket_lock_names_[kNumOfSizeBrackets];
470   // The types of page map entries.
471   enum PageMapKind {
472     kPageMapReleased = 0,     // Zero and released back to the OS.
473     kPageMapEmpty,            // Zero but probably dirty.
474     kPageMapRun,              // The beginning of a run.
475     kPageMapRunPart,          // The non-beginning part of a run.
476     kPageMapLargeObject,      // The beginning of a large object.
477     kPageMapLargeObjectPart,  // The non-beginning part of a large object.
478   };
479   // The table that indicates what pages are currently used for.
480   volatile uint8_t* page_map_;  // No GUARDED_BY(lock_) for kReadPageMapEntryWithoutLockInBulkFree.
481   size_t page_map_size_;
482   size_t max_page_map_size_;
483   std::unique_ptr<MemMap> page_map_mem_map_;
484 
485   // The table that indicates the size of free page runs. These sizes
486   // are stored here to avoid storing in the free page header and
487   // release backing pages.
488   std::vector<size_t, TrackingAllocator<size_t, kAllocatorTagRosAlloc>> free_page_run_size_map_
489       GUARDED_BY(lock_);
490   // The global lock. Used to guard the page map, the free page set,
491   // and the footprint.
492   Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
493   // The reader-writer lock to allow one bulk free at a time while
494   // allowing multiple individual frees at the same time. Also, this
495   // is used to avoid race conditions between BulkFree() and
496   // RevokeThreadLocalRuns() on the bulk free bitmaps.
497   ReaderWriterMutex bulk_free_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
498 
499   // The page release mode.
500   const PageReleaseMode page_release_mode_;
501   // Under kPageReleaseModeSize(AndEnd), if the free page run size is
502   // greater than or equal to this value, release pages.
503   const size_t page_release_size_threshold_;
504 
505   // Whether this allocator is running under Valgrind.
506   bool running_on_valgrind_;
507 
508   // The base address of the memory region that's managed by this allocator.
Begin()509   uint8_t* Begin() { return base_; }
510   // The end address of the memory region that's managed by this allocator.
End()511   uint8_t* End() { return base_ + capacity_; }
512 
513   // Page-granularity alloc/free
514   void* AllocPages(Thread* self, size_t num_pages, uint8_t page_map_type)
515       EXCLUSIVE_LOCKS_REQUIRED(lock_);
516   // Returns how many bytes were freed.
517   size_t FreePages(Thread* self, void* ptr, bool already_zero) EXCLUSIVE_LOCKS_REQUIRED(lock_);
518 
519   // Allocate/free a run slot.
520   void* AllocFromRun(Thread* self, size_t size, size_t* bytes_allocated, size_t* usable_size,
521                      size_t* bytes_tl_bulk_allocated)
522       LOCKS_EXCLUDED(lock_);
523   // Allocate/free a run slot without acquiring locks.
524   // TODO: EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
525   void* AllocFromRunThreadUnsafe(Thread* self, size_t size, size_t* bytes_allocated,
526                                  size_t* usable_size, size_t* bytes_tl_bulk_allocated)
527       LOCKS_EXCLUDED(lock_);
528   void* AllocFromCurrentRunUnlocked(Thread* self, size_t idx);
529 
530   // Returns the bracket size.
531   size_t FreeFromRun(Thread* self, void* ptr, Run* run)
532       LOCKS_EXCLUDED(lock_);
533 
534   // Used to allocate a new thread local run for a size bracket.
535   Run* AllocRun(Thread* self, size_t idx) LOCKS_EXCLUDED(lock_);
536 
537   // Used to acquire a new/reused run for a size bracket. Used when a
538   // thread-local or current run gets full.
539   Run* RefillRun(Thread* self, size_t idx) LOCKS_EXCLUDED(lock_);
540 
541   // The internal of non-bulk Free().
542   size_t FreeInternal(Thread* self, void* ptr) LOCKS_EXCLUDED(lock_);
543 
544   // Allocates large objects.
545   void* AllocLargeObject(Thread* self, size_t size, size_t* bytes_allocated,
546                          size_t* usable_size, size_t* bytes_tl_bulk_allocated)
547       LOCKS_EXCLUDED(lock_);
548 
549   // Revoke a run by adding it to non_full_runs_ or freeing the pages.
550   void RevokeRun(Thread* self, size_t idx, Run* run);
551 
552   // Revoke the current runs which share an index with the thread local runs.
553   void RevokeThreadUnsafeCurrentRuns();
554 
555   // Release a range of pages.
556   size_t ReleasePageRange(uint8_t* start, uint8_t* end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
557 
558   // Dumps the page map for debugging.
559   std::string DumpPageMap() EXCLUSIVE_LOCKS_REQUIRED(lock_);
560 
561  public:
562   RosAlloc(void* base, size_t capacity, size_t max_capacity,
563            PageReleaseMode page_release_mode,
564            bool running_on_valgrind,
565            size_t page_release_size_threshold = kDefaultPageReleaseSizeThreshold);
566   ~RosAlloc();
567 
568   // If kThreadUnsafe is true then the allocator may avoid acquiring some locks as an optimization.
569   // If used, this may cause race conditions if multiple threads are allocating at the same time.
570   template<bool kThreadSafe = true>
571   void* Alloc(Thread* self, size_t size, size_t* bytes_allocated, size_t* usable_size,
572               size_t* bytes_tl_bulk_allocated)
573       LOCKS_EXCLUDED(lock_);
574   size_t Free(Thread* self, void* ptr)
575       LOCKS_EXCLUDED(bulk_free_lock_);
576   size_t BulkFree(Thread* self, void** ptrs, size_t num_ptrs)
577       LOCKS_EXCLUDED(bulk_free_lock_);
578 
579   // Returns true if the given allocation request can be allocated in
580   // an existing thread local run without allocating a new run.
581   ALWAYS_INLINE bool CanAllocFromThreadLocalRun(Thread* self, size_t size);
582   // Allocate the given allocation request in an existing thread local
583   // run without allocating a new run.
584   ALWAYS_INLINE void* AllocFromThreadLocalRun(Thread* self, size_t size, size_t* bytes_allocated);
585 
586   // Returns the maximum bytes that could be allocated for the given
587   // size in bulk, that is the maximum value for the
588   // bytes_allocated_bulk out param returned by RosAlloc::Alloc().
589   ALWAYS_INLINE size_t MaxBytesBulkAllocatedFor(size_t size);
590 
591   // Returns the size of the allocated slot for a given allocated memory chunk.
592   size_t UsableSize(const void* ptr);
593   // Returns the size of the allocated slot for a given size.
UsableSize(size_t bytes)594   size_t UsableSize(size_t bytes) {
595     if (UNLIKELY(bytes > kLargeSizeThreshold)) {
596       return RoundUp(bytes, kPageSize);
597     } else {
598       return RoundToBracketSize(bytes);
599     }
600   }
601   // Try to reduce the current footprint by releasing the free page
602   // run at the end of the memory region, if any.
603   bool Trim();
604   // Iterates over all the memory slots and apply the given function.
605   void InspectAll(void (*handler)(void* start, void* end, size_t used_bytes, void* callback_arg),
606                   void* arg)
607       LOCKS_EXCLUDED(lock_);
608 
609   // Release empty pages.
610   size_t ReleasePages() LOCKS_EXCLUDED(lock_);
611   // Returns the current footprint.
612   size_t Footprint() LOCKS_EXCLUDED(lock_);
613   // Returns the current capacity, maximum footprint.
614   size_t FootprintLimit() LOCKS_EXCLUDED(lock_);
615   // Update the current capacity.
616   void SetFootprintLimit(size_t bytes) LOCKS_EXCLUDED(lock_);
617 
618   // Releases the thread-local runs assigned to the given thread back to the common set of runs.
619   // Returns the total bytes of free slots in the revoked thread local runs. This is to be
620   // subtracted from Heap::num_bytes_allocated_ to cancel out the ahead-of-time counting.
621   size_t RevokeThreadLocalRuns(Thread* thread);
622   // Releases the thread-local runs assigned to all the threads back to the common set of runs.
623   // Returns the total bytes of free slots in the revoked thread local runs. This is to be
624   // subtracted from Heap::num_bytes_allocated_ to cancel out the ahead-of-time counting.
625   size_t RevokeAllThreadLocalRuns() LOCKS_EXCLUDED(Locks::thread_list_lock_);
626   // Assert the thread local runs of a thread are revoked.
627   void AssertThreadLocalRunsAreRevoked(Thread* thread);
628   // Assert all the thread local runs are revoked.
629   void AssertAllThreadLocalRunsAreRevoked() LOCKS_EXCLUDED(Locks::thread_list_lock_);
630 
GetDedicatedFullRun()631   static Run* GetDedicatedFullRun() {
632     return dedicated_full_run_;
633   }
IsFreePage(size_t idx)634   bool IsFreePage(size_t idx) const {
635     DCHECK_LT(idx, capacity_ / kPageSize);
636     uint8_t pm_type = page_map_[idx];
637     return pm_type == kPageMapReleased || pm_type == kPageMapEmpty;
638   }
639 
640   // Callbacks for InspectAll that will count the number of bytes
641   // allocated and objects allocated, respectively.
642   static void BytesAllocatedCallback(void* start, void* end, size_t used_bytes, void* arg);
643   static void ObjectsAllocatedCallback(void* start, void* end, size_t used_bytes, void* arg);
644 
DoesReleaseAllPages()645   bool DoesReleaseAllPages() const {
646     return page_release_mode_ == kPageReleaseModeAll;
647   }
648 
649   // Verify for debugging.
650   void Verify() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
651 
652   void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes);
653 
654  private:
655   friend std::ostream& operator<<(std::ostream& os, const RosAlloc::PageMapKind& rhs);
656 
657   DISALLOW_COPY_AND_ASSIGN(RosAlloc);
658 };
659 std::ostream& operator<<(std::ostream& os, const RosAlloc::PageMapKind& rhs);
660 
661 // Callback from rosalloc when it needs to increase the footprint. Must be implemented somewhere
662 // else (currently rosalloc_space.cc).
663 void* ArtRosAllocMoreCore(allocator::RosAlloc* rosalloc, intptr_t increment);
664 
665 }  // namespace allocator
666 }  // namespace gc
667 }  // namespace art
668 
669 #endif  // ART_RUNTIME_GC_ALLOCATOR_ROSALLOC_H_
670