blob: 0c508b78a8a9ec175b6215b17f4f294018214d0e [file] [log] [blame]
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -07001/*
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 <set>
21#include <stdint.h>
22#include <stdlib.h>
23#include <string>
24#include <sys/mman.h>
25#include <vector>
26
27#include "base/mutex.h"
28#include "base/logging.h"
29#include "globals.h"
Hiroshi Yamauchi26d69ff2014-02-27 11:27:10 -080030#include "mem_map.h"
31#include "UniquePtr.h"
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -070032#include "utils.h"
33
34// A boilerplate to use hash_map/hash_set both on host and device.
35#ifdef HAVE_ANDROID_OS
36#include <hash_map>
37#include <hash_set>
38using std::hash_map;
39using std::hash_set;
40#else // HAVE_ANDROID_OS
41#ifdef __DEPRECATED
42#define ROSALLOC_OLD__DEPRECATED __DEPRECATED
43#undef __DEPRECATED
44#endif
45#include <ext/hash_map>
46#include <ext/hash_set>
47#ifdef ROSALLOC_OLD__DEPRECATED
48#define __DEPRECATED ROSALLOC_OLD__DEPRECATED
49#undef ROSALLOC_OLD__DEPRECATED
50#endif
51using __gnu_cxx::hash_map;
52using __gnu_cxx::hash_set;
53#endif // HAVE_ANDROID_OS
54
55namespace art {
Hiroshi Yamauchi26d69ff2014-02-27 11:27:10 -080056
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -070057namespace gc {
58namespace allocator {
59
Ian Rogers6fac4472014-02-25 17:01:10 -080060// A runs-of-slots memory allocator.
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -070061class RosAlloc {
62 private:
Ian Rogers6fac4472014-02-25 17:01:10 -080063 // Represents a run of free pages.
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -070064 class FreePageRun {
65 public:
66 byte magic_num_; // The magic number used for debugging only.
67
68 bool IsFree() const {
69 if (kIsDebugBuild) {
70 return magic_num_ == kMagicNumFree;
71 }
72 return true;
73 }
74 size_t ByteSize(RosAlloc* rosalloc) const EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
75 const byte* fpr_base = reinterpret_cast<const byte*>(this);
76 size_t pm_idx = rosalloc->ToPageMapIndex(fpr_base);
77 size_t byte_size = rosalloc->free_page_run_size_map_[pm_idx];
78 DCHECK_GE(byte_size, static_cast<size_t>(0));
79 DCHECK_EQ(byte_size % kPageSize, static_cast<size_t>(0));
80 return byte_size;
81 }
82 void SetByteSize(RosAlloc* rosalloc, size_t byte_size)
83 EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
84 DCHECK_EQ(byte_size % kPageSize, static_cast<size_t>(0));
85 byte* fpr_base = reinterpret_cast<byte*>(this);
86 size_t pm_idx = rosalloc->ToPageMapIndex(fpr_base);
87 rosalloc->free_page_run_size_map_[pm_idx] = byte_size;
88 }
89 void* Begin() {
90 return reinterpret_cast<void*>(this);
91 }
92 void* End(RosAlloc* rosalloc) EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
93 byte* fpr_base = reinterpret_cast<byte*>(this);
94 byte* end = fpr_base + ByteSize(rosalloc);
95 return end;
96 }
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -080097 bool IsLargerThanPageReleaseThreshold(RosAlloc* rosalloc)
98 EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
99 return ByteSize(rosalloc) >= rosalloc->page_release_size_threshold_;
100 }
101 bool IsAtEndOfSpace(RosAlloc* rosalloc)
102 EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
103 return reinterpret_cast<byte*>(this) + ByteSize(rosalloc) == rosalloc->base_ + rosalloc->footprint_;
104 }
105 bool ShouldReleasePages(RosAlloc* rosalloc) EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
106 switch (rosalloc->page_release_mode_) {
107 case kPageReleaseModeNone:
108 return false;
109 case kPageReleaseModeEnd:
110 return IsAtEndOfSpace(rosalloc);
111 case kPageReleaseModeSize:
112 return IsLargerThanPageReleaseThreshold(rosalloc);
113 case kPageReleaseModeSizeAndEnd:
114 return IsLargerThanPageReleaseThreshold(rosalloc) && IsAtEndOfSpace(rosalloc);
115 case kPageReleaseModeAll:
116 return true;
117 default:
118 LOG(FATAL) << "Unexpected page release mode ";
119 return false;
120 }
121 }
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700122 void ReleasePages(RosAlloc* rosalloc) EXCLUSIVE_LOCKS_REQUIRED(rosalloc->lock_) {
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800123 byte* start = reinterpret_cast<byte*>(this);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700124 size_t byte_size = ByteSize(rosalloc);
125 DCHECK_EQ(byte_size % kPageSize, static_cast<size_t>(0));
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800126 bool release_pages = ShouldReleasePages(rosalloc);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700127 if (kIsDebugBuild) {
128 // Exclude the first page that stores the magic number.
129 DCHECK_GE(byte_size, static_cast<size_t>(kPageSize));
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800130 start += kPageSize;
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700131 byte_size -= kPageSize;
132 if (byte_size > 0) {
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800133 if (release_pages) {
134 madvise(start, byte_size, MADV_DONTNEED);
135 }
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700136 }
137 } else {
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800138 if (release_pages) {
139 madvise(start, byte_size, MADV_DONTNEED);
140 }
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700141 }
142 }
143 };
144
145 // Represents a run of memory slots of the same size.
146 //
147 // A run's memory layout:
148 //
149 // +-------------------+
150 // | magic_num |
151 // +-------------------+
152 // | size_bracket_idx |
153 // +-------------------+
154 // | is_thread_local |
155 // +-------------------+
156 // | to_be_bulk_freed |
157 // +-------------------+
158 // | top_slot_idx |
159 // +-------------------+
160 // | |
161 // | alloc bit map |
162 // | |
163 // +-------------------+
164 // | |
165 // | bulk free bit map |
166 // | |
167 // +-------------------+
168 // | |
169 // | thread-local free |
170 // | bit map |
171 // | |
172 // +-------------------+
173 // | padding due to |
174 // | alignment |
175 // +-------------------+
176 // | slot 0 |
177 // +-------------------+
178 // | slot 1 |
179 // +-------------------+
180 // | slot 2 |
181 // +-------------------+
182 // ...
183 // +-------------------+
184 // | last slot |
185 // +-------------------+
186 //
187 class Run {
188 public:
Hiroshi Yamauchie5eedcb2013-11-18 11:55:39 -0800189 byte magic_num_; // The magic number used for debugging.
190 byte size_bracket_idx_; // The index of the size bracket of this run.
191 byte is_thread_local_; // True if this run is used as a thread-local run.
192 byte to_be_bulk_freed_; // Used within BulkFree() to flag a run that's involved with a bulk free.
193 uint32_t top_slot_idx_; // The top slot index when this run is in bump index mode.
194 uint32_t alloc_bit_map_[0]; // The bit map that allocates if each slot is in use.
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700195
196 // bulk_free_bit_map_[] : The bit map that is used for GC to
197 // temporarily mark the slots to free without using a lock. After
198 // all the slots to be freed in a run are marked, all those slots
199 // get freed in bulk with one locking per run, as opposed to one
200 // locking per slot to minimize the lock contention. This is used
201 // within BulkFree().
202
203 // thread_local_free_bit_map_[] : The bit map that is used for GC
204 // to temporarily mark the slots to free in a thread-local run
205 // without using a lock (without synchronizing the thread that
206 // owns the thread-local run.) When the thread-local run becomes
207 // full, the thread will check this bit map and update the
208 // allocation bit map of the run (that is, the slots get freed.)
209
210 // Returns the byte size of the header except for the bit maps.
211 static size_t fixed_header_size() {
212 Run temp;
213 size_t size = reinterpret_cast<byte*>(&temp.alloc_bit_map_) - reinterpret_cast<byte*>(&temp);
214 DCHECK_EQ(size, static_cast<size_t>(8));
215 return size;
216 }
217 // Returns the base address of the free bit map.
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800218 uint32_t* BulkFreeBitMap() {
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700219 return reinterpret_cast<uint32_t*>(reinterpret_cast<byte*>(this) + bulkFreeBitMapOffsets[size_bracket_idx_]);
220 }
221 // Returns the base address of the thread local free bit map.
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800222 uint32_t* ThreadLocalFreeBitMap() {
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700223 return reinterpret_cast<uint32_t*>(reinterpret_cast<byte*>(this) + threadLocalFreeBitMapOffsets[size_bracket_idx_]);
224 }
225 void* End() {
226 return reinterpret_cast<byte*>(this) + kPageSize * numOfPages[size_bracket_idx_];
227 }
228 // Frees slots in the allocation bit map with regard to the
229 // thread-local free bit map. Used when a thread-local run becomes
230 // full.
231 bool MergeThreadLocalFreeBitMapToAllocBitMap(bool* is_all_free_after_out);
232 // Frees slots in the allocation bit map with regard to the bulk
233 // free bit map. Used in a bulk free.
234 void MergeBulkFreeBitMapIntoAllocBitMap();
235 // Unions the slots to be freed in the free bit map into the
236 // thread-local free bit map. In a bulk free, as a two-step
237 // process, GC will first record all the slots to free in a run in
238 // the free bit map where it can write without a lock, and later
239 // acquire a lock once per run to union the bits of the free bit
240 // map to the thread-local free bit map.
241 void UnionBulkFreeBitMapToThreadLocalFreeBitMap();
242 // Allocates a slot in a run.
243 void* AllocSlot();
244 // Frees a slot in a run. This is used in a non-bulk free.
245 void FreeSlot(void* ptr);
246 // Marks the slots to free in the bulk free bit map.
247 void MarkBulkFreeBitMap(void* ptr);
248 // Marks the slots to free in the thread-local free bit map.
249 void MarkThreadLocalFreeBitMap(void* ptr);
250 // Returns true if all the slots in the run are not in use.
251 bool IsAllFree();
252 // Returns true if all the slots in the run are in use.
253 bool IsFull();
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800254 // Returns true if the bulk free bit map is clean.
255 bool IsBulkFreeBitmapClean();
256 // Returns true if the thread local free bit map is clean.
257 bool IsThreadLocalFreeBitmapClean();
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700258 // Clear all the bit maps.
259 void ClearBitMaps();
260 // Iterate over all the slots and apply the given function.
261 void InspectAllSlots(void (*handler)(void* start, void* end, size_t used_bytes, void* callback_arg), void* arg);
262 // Dump the run metadata for debugging.
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800263 std::string Dump();
264 // Verify for debugging.
265 void Verify(Thread* self, RosAlloc* rosalloc)
266 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
267 EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700268
269 private:
270 // The common part of MarkFreeBitMap() and MarkThreadLocalFreeBitMap().
271 void MarkFreeBitMapShared(void* ptr, uint32_t* free_bit_map_base, const char* caller_name);
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800272 // Turns the bit map into a string for debugging.
273 static std::string BitMapToStr(uint32_t* bit_map_base, size_t num_vec);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700274 };
275
276 // The magic number for a run.
277 static const byte kMagicNum = 42;
278 // The magic number for free pages.
279 static const byte kMagicNumFree = 43;
280 // The number of size brackets. Sync this with the length of Thread::rosalloc_runs_.
281 static const size_t kNumOfSizeBrackets = 34;
282 // The number of smaller size brackets that are 16 bytes apart.
283 static const size_t kNumOfQuantumSizeBrackets = 32;
284 // The sizes (the slot sizes, in bytes) of the size brackets.
285 static size_t bracketSizes[kNumOfSizeBrackets];
286 // The numbers of pages that are used for runs for each size bracket.
287 static size_t numOfPages[kNumOfSizeBrackets];
288 // The numbers of slots of the runs for each size bracket.
289 static size_t numOfSlots[kNumOfSizeBrackets];
290 // The header sizes in bytes of the runs for each size bracket.
291 static size_t headerSizes[kNumOfSizeBrackets];
292 // The byte offsets of the bulk free bit maps of the runs for each size bracket.
293 static size_t bulkFreeBitMapOffsets[kNumOfSizeBrackets];
294 // The byte offsets of the thread-local free bit maps of the runs for each size bracket.
295 static size_t threadLocalFreeBitMapOffsets[kNumOfSizeBrackets];
296
297 // Initialize the run specs (the above arrays).
298 static void Initialize();
299 static bool initialized_;
300
301 // Returns the byte size of the bracket size from the index.
302 static size_t IndexToBracketSize(size_t idx) {
303 DCHECK(idx < kNumOfSizeBrackets);
304 return bracketSizes[idx];
305 }
306 // Returns the index of the size bracket from the bracket size.
307 static size_t BracketSizeToIndex(size_t size) {
308 DCHECK(16 <= size && ((size < 1 * KB && size % 16 == 0) || size == 1 * KB || size == 2 * KB));
309 size_t idx;
310 if (UNLIKELY(size == 1 * KB)) {
311 idx = kNumOfSizeBrackets - 2;
312 } else if (UNLIKELY(size == 2 * KB)) {
313 idx = kNumOfSizeBrackets - 1;
314 } else {
315 DCHECK(size < 1 * KB);
316 DCHECK_EQ(size % 16, static_cast<size_t>(0));
317 idx = size / 16 - 1;
318 }
319 DCHECK(bracketSizes[idx] == size);
320 return idx;
321 }
322 // Rounds up the size up the nearest bracket size.
323 static size_t RoundToBracketSize(size_t size) {
324 DCHECK(size <= kLargeSizeThreshold);
325 if (LIKELY(size <= 512)) {
326 return RoundUp(size, 16);
327 } else if (512 < size && size <= 1 * KB) {
328 return 1 * KB;
329 } else {
330 DCHECK(1 * KB < size && size <= 2 * KB);
331 return 2 * KB;
332 }
333 }
334 // Returns the size bracket index from the byte size with rounding.
335 static size_t SizeToIndex(size_t size) {
336 DCHECK(size <= kLargeSizeThreshold);
337 if (LIKELY(size <= 512)) {
338 return RoundUp(size, 16) / 16 - 1;
339 } else if (512 < size && size <= 1 * KB) {
340 return kNumOfSizeBrackets - 2;
341 } else {
342 DCHECK(1 * KB < size && size <= 2 * KB);
343 return kNumOfSizeBrackets - 1;
344 }
345 }
346 // A combination of SizeToIndex() and RoundToBracketSize().
347 static size_t SizeToIndexAndBracketSize(size_t size, size_t* bracket_size_out) {
348 DCHECK(size <= kLargeSizeThreshold);
349 if (LIKELY(size <= 512)) {
350 size_t bracket_size = RoundUp(size, 16);
351 *bracket_size_out = bracket_size;
352 size_t idx = bracket_size / 16 - 1;
353 DCHECK_EQ(bracket_size, IndexToBracketSize(idx));
354 return idx;
355 } else if (512 < size && size <= 1 * KB) {
356 size_t bracket_size = 1024;
357 *bracket_size_out = bracket_size;
358 size_t idx = kNumOfSizeBrackets - 2;
359 DCHECK_EQ(bracket_size, IndexToBracketSize(idx));
360 return idx;
361 } else {
362 DCHECK(1 * KB < size && size <= 2 * KB);
363 size_t bracket_size = 2048;
364 *bracket_size_out = bracket_size;
365 size_t idx = kNumOfSizeBrackets - 1;
366 DCHECK_EQ(bracket_size, IndexToBracketSize(idx));
367 return idx;
368 }
369 }
370 // Returns the page map index from an address. Requires that the
371 // address is page size aligned.
372 size_t ToPageMapIndex(const void* addr) const {
373 DCHECK(base_ <= addr && addr < base_ + capacity_);
374 size_t byte_offset = reinterpret_cast<const byte*>(addr) - base_;
375 DCHECK_EQ(byte_offset % static_cast<size_t>(kPageSize), static_cast<size_t>(0));
376 return byte_offset / kPageSize;
377 }
378 // Returns the page map index from an address with rounding.
379 size_t RoundDownToPageMapIndex(void* addr) {
380 DCHECK(base_ <= addr && addr < reinterpret_cast<byte*>(base_) + capacity_);
381 return (reinterpret_cast<uintptr_t>(addr) - reinterpret_cast<uintptr_t>(base_)) / kPageSize;
382 }
383
384 // A memory allocation request larger than this size is treated as a large object and allocated
385 // at a page-granularity.
386 static const size_t kLargeSizeThreshold = 2048;
387
388 // We use use thread-local runs for the size Brackets whose indexes
389 // are less than or equal to this index. We use shared (current)
390 // runs for the rest.
391 static const size_t kMaxThreadLocalSizeBracketIdx = 10;
392
Hiroshi Yamauchi3c2856e2013-11-22 13:42:53 -0800393 // If true, check that the returned memory is actually zero.
394 static constexpr bool kCheckZeroMemory = kIsDebugBuild;
395
396 // If true, log verbose details of operations.
397 static constexpr bool kTraceRosAlloc = false;
398
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700399 struct hash_run {
400 size_t operator()(const RosAlloc::Run* r) const {
401 return reinterpret_cast<size_t>(r);
402 }
403 };
404
405 struct eq_run {
406 bool operator()(const RosAlloc::Run* r1, const RosAlloc::Run* r2) const {
407 return r1 == r2;
408 }
409 };
410
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800411 public:
412 // Different page release modes.
413 enum PageReleaseMode {
414 kPageReleaseModeNone, // Release no empty pages.
415 kPageReleaseModeEnd, // Release empty pages at the end of the space.
416 kPageReleaseModeSize, // Release empty pages that are larger than the threshold.
417 kPageReleaseModeSizeAndEnd, // Release empty pages that are larger than the threshold or
418 // at the end of the space.
419 kPageReleaseModeAll, // Release all empty pages.
420 };
421
422 // The default value for page_release_size_threshold_.
423 static constexpr size_t kDefaultPageReleaseSizeThreshold = 4 * MB;
424
425 private:
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700426 // The base address of the memory region that's managed by this allocator.
427 byte* base_;
428
429 // The footprint in bytes of the currently allocated portion of the
430 // memory region.
431 size_t footprint_;
432
433 // The maximum footprint. The address, base_ + capacity_, indicates
Hiroshi Yamauchi26d69ff2014-02-27 11:27:10 -0800434 // the end of the memory region that's currently managed by this allocator.
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700435 size_t capacity_;
436
Hiroshi Yamauchi26d69ff2014-02-27 11:27:10 -0800437 // The maximum capacity. The address, base_ + max_capacity_, indicates
438 // the end of the memory region that's ever managed by this allocator.
439 size_t max_capacity_;
440
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700441 // The run sets that hold the runs whose slots are not all
442 // full. non_full_runs_[i] is guarded by size_bracket_locks_[i].
443 std::set<Run*> non_full_runs_[kNumOfSizeBrackets];
444 // The run sets that hold the runs whose slots are all full. This is
445 // debug only. full_runs_[i] is guarded by size_bracket_locks_[i].
446 hash_set<Run*, hash_run, eq_run> full_runs_[kNumOfSizeBrackets];
447 // The set of free pages.
448 std::set<FreePageRun*> free_page_runs_ GUARDED_BY(lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700449 // The current runs where the allocations are first attempted for
450 // the size brackes that do not use thread-local
451 // runs. current_runs_[i] is guarded by size_bracket_locks_[i].
452 Run* current_runs_[kNumOfSizeBrackets];
453 // The mutexes, one per size bracket.
454 Mutex* size_bracket_locks_[kNumOfSizeBrackets];
455 // The types of page map entries.
456 enum {
457 kPageMapEmpty = 0, // Not allocated.
458 kPageMapRun = 1, // The beginning of a run.
459 kPageMapRunPart = 2, // The non-beginning part of a run.
460 kPageMapLargeObject = 3, // The beginning of a large object.
461 kPageMapLargeObjectPart = 4, // The non-beginning part of a large object.
462 };
463 // The table that indicates what pages are currently used for.
Hiroshi Yamauchi26d69ff2014-02-27 11:27:10 -0800464 byte* page_map_; // No GUARDED_BY(lock_) for kReadPageMapEntryWithoutLockInBulkFree.
465 size_t page_map_size_;
466 size_t max_page_map_size_;
467 UniquePtr<MemMap> page_map_mem_map_;
468
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700469 // The table that indicates the size of free page runs. These sizes
470 // are stored here to avoid storing in the free page header and
471 // release backing pages.
472 std::vector<size_t> free_page_run_size_map_ GUARDED_BY(lock_);
473 // The global lock. Used to guard the page map, the free page set,
474 // and the footprint.
475 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
476 // The reader-writer lock to allow one bulk free at a time while
Hiroshi Yamauchi70f60042014-02-03 12:31:29 -0800477 // allowing multiple individual frees at the same time. Also, this
478 // is used to avoid race conditions between BulkFree() and
479 // RevokeThreadLocalRuns() on the bulk free bitmaps.
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700480 ReaderWriterMutex bulk_free_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
481
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800482 // The page release mode.
483 const PageReleaseMode page_release_mode_;
484 // Under kPageReleaseModeSize(AndEnd), if the free page run size is
485 // greater than or equal to this value, release pages.
486 const size_t page_release_size_threshold_;
487
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700488 // The base address of the memory region that's managed by this allocator.
489 byte* Begin() { return base_; }
490 // The end address of the memory region that's managed by this allocator.
491 byte* End() { return base_ + capacity_; }
492
493 // Page-granularity alloc/free
494 void* AllocPages(Thread* self, size_t num_pages, byte page_map_type)
495 EXCLUSIVE_LOCKS_REQUIRED(lock_);
Mathieu Chartier8585bad2014-04-11 17:53:48 -0700496 // Returns how many pages were freed.
497 size_t FreePages(Thread* self, void* ptr) EXCLUSIVE_LOCKS_REQUIRED(lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700498
499 // Allocate/free a run slot.
500 void* AllocFromRun(Thread* self, size_t size, size_t* bytes_allocated)
501 LOCKS_EXCLUDED(lock_);
502 void FreeFromRun(Thread* self, void* ptr, Run* run)
503 LOCKS_EXCLUDED(lock_);
504
505 // Used to acquire a new/reused run for a size bracket. Used when a
506 // thread-local or current run gets full.
507 Run* RefillRun(Thread* self, size_t idx) LOCKS_EXCLUDED(lock_);
508
509 // The internal of non-bulk Free().
Mathieu Chartier8585bad2014-04-11 17:53:48 -0700510 size_t FreeInternal(Thread* self, void* ptr) LOCKS_EXCLUDED(lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700511
Hiroshi Yamauchi3c2856e2013-11-22 13:42:53 -0800512 // Allocates large objects.
513 void* AllocLargeObject(Thread* self, size_t size, size_t* bytes_allocated) LOCKS_EXCLUDED(lock_);
514
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700515 public:
Hiroshi Yamauchi26d69ff2014-02-27 11:27:10 -0800516 RosAlloc(void* base, size_t capacity, size_t max_capacity,
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800517 PageReleaseMode page_release_mode,
518 size_t page_release_size_threshold = kDefaultPageReleaseSizeThreshold);
Mathieu Chartier661974a2014-01-09 11:23:53 -0800519 ~RosAlloc();
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700520 void* Alloc(Thread* self, size_t size, size_t* bytes_allocated)
521 LOCKS_EXCLUDED(lock_);
Mathieu Chartier8585bad2014-04-11 17:53:48 -0700522 size_t Free(Thread* self, void* ptr)
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700523 LOCKS_EXCLUDED(bulk_free_lock_);
Mathieu Chartier8585bad2014-04-11 17:53:48 -0700524 size_t BulkFree(Thread* self, void** ptrs, size_t num_ptrs)
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700525 LOCKS_EXCLUDED(bulk_free_lock_);
526 // Returns the size of the allocated slot for a given allocated memory chunk.
527 size_t UsableSize(void* ptr);
528 // Returns the size of the allocated slot for a given size.
529 size_t UsableSize(size_t bytes) {
530 if (UNLIKELY(bytes > kLargeSizeThreshold)) {
531 return RoundUp(bytes, kPageSize);
532 } else {
533 return RoundToBracketSize(bytes);
534 }
535 }
536 // Try to reduce the current footprint by releasing the free page
537 // run at the end of the memory region, if any.
538 bool Trim();
539 // Iterates over all the memory slots and apply the given function.
540 void InspectAll(void (*handler)(void* start, void* end, size_t used_bytes, void* callback_arg),
541 void* arg)
542 LOCKS_EXCLUDED(lock_);
Hiroshi Yamauchid9a88de2014-04-07 13:52:31 -0700543 // Release empty pages.
544 size_t ReleasePages() LOCKS_EXCLUDED(lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700545 // Returns the current footprint.
546 size_t Footprint() LOCKS_EXCLUDED(lock_);
547 // Returns the current capacity, maximum footprint.
548 size_t FootprintLimit() LOCKS_EXCLUDED(lock_);
549 // Update the current capacity.
550 void SetFootprintLimit(size_t bytes) LOCKS_EXCLUDED(lock_);
551 // Releases the thread-local runs assigned to the given thread back to the common set of runs.
552 void RevokeThreadLocalRuns(Thread* thread);
553 // Releases the thread-local runs assigned to all the threads back to the common set of runs.
554 void RevokeAllThreadLocalRuns() LOCKS_EXCLUDED(Locks::thread_list_lock_);
Hiroshi Yamauchic93c5302014-03-20 16:15:37 -0700555 // Assert the thread local runs of a thread are revoked.
556 void AssertThreadLocalRunsAreRevoked(Thread* thread);
557 // Assert all the thread local runs are revoked.
558 void AssertAllThreadLocalRunsAreRevoked() LOCKS_EXCLUDED(Locks::thread_list_lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700559 // Dumps the page map for debugging.
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800560 std::string DumpPageMap() EXCLUSIVE_LOCKS_REQUIRED(lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700561
562 // Callbacks for InspectAll that will count the number of bytes
563 // allocated and objects allocated, respectively.
564 static void BytesAllocatedCallback(void* start, void* end, size_t used_bytes, void* arg);
565 static void ObjectsAllocatedCallback(void* start, void* end, size_t used_bytes, void* arg);
Hiroshi Yamauchi573f7d22013-12-17 11:54:23 -0800566
567 bool DoesReleaseAllPages() const {
568 return page_release_mode_ == kPageReleaseModeAll;
569 }
Hiroshi Yamauchia4adbfd2014-02-04 18:12:17 -0800570
571 // Verify for debugging.
572 void Verify() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
Hiroshi Yamauchicf58d4a2013-09-26 14:21:22 -0700573};
574
575} // namespace allocator
576} // namespace gc
577} // namespace art
578
579#endif // ART_RUNTIME_GC_ALLOCATOR_ROSALLOC_H_