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