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_COMPILER_DEX_ARENA_ALLOCATOR_H_ 18 #define ART_COMPILER_DEX_ARENA_ALLOCATOR_H_ 19 20 #include <stdint.h> 21 #include <stddef.h> 22 23 #include "base/mutex.h" 24 #include "compiler_enums.h" 25 #include "mem_map.h" 26 27 namespace art { 28 29 class Arena; 30 class ArenaPool; 31 class ArenaAllocator; 32 33 class Arena { 34 public: 35 static constexpr size_t kDefaultSize = 128 * KB; 36 explicit Arena(size_t size = kDefaultSize); 37 ~Arena(); 38 void Reset(); 39 uint8_t* Begin() { 40 return memory_; 41 } 42 43 uint8_t* End() { 44 return memory_ + size_; 45 } 46 47 size_t Size() const { 48 return size_; 49 } 50 51 size_t RemainingSpace() const { 52 return Size() - bytes_allocated_; 53 } 54 55 private: 56 size_t bytes_allocated_; 57 uint8_t* memory_; 58 size_t size_; 59 MemMap* map_; 60 Arena* next_; 61 friend class ArenaPool; 62 friend class ArenaAllocator; 63 DISALLOW_COPY_AND_ASSIGN(Arena); 64 }; 65 66 class ArenaPool { 67 public: 68 ArenaPool(); 69 ~ArenaPool(); 70 Arena* AllocArena(size_t size); 71 void FreeArena(Arena* arena); 72 73 private: 74 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 75 Arena* free_arenas_ GUARDED_BY(lock_); 76 DISALLOW_COPY_AND_ASSIGN(ArenaPool); 77 }; 78 79 class ArenaAllocator { 80 public: 81 // Type of allocation for memory tuning. 82 enum ArenaAllocKind { 83 kAllocMisc, 84 kAllocBB, 85 kAllocLIR, 86 kAllocMIR, 87 kAllocDFInfo, 88 kAllocGrowableArray, 89 kAllocGrowableBitMap, 90 kAllocDalvikToSSAMap, 91 kAllocDebugInfo, 92 kAllocSuccessor, 93 kAllocRegAlloc, 94 kAllocData, 95 kAllocPredecessors, 96 kNumAllocKinds 97 }; 98 99 static constexpr bool kCountAllocations = false; 100 101 explicit ArenaAllocator(ArenaPool* pool); 102 ~ArenaAllocator(); 103 104 // Returns zeroed memory. 105 void* Alloc(size_t bytes, ArenaAllocKind kind) ALWAYS_INLINE { 106 bytes = (bytes + 3) & ~3; 107 if (UNLIKELY(ptr_ + bytes > end_)) { 108 // Obtain a new block. 109 ObtainNewArenaForAllocation(bytes); 110 if (UNLIKELY(ptr_ == nullptr)) { 111 return nullptr; 112 } 113 } 114 if (kCountAllocations) { 115 alloc_stats_[kind] += bytes; 116 ++num_allocations_; 117 } 118 uint8_t* ret = ptr_; 119 ptr_ += bytes; 120 return ret; 121 } 122 123 void ObtainNewArenaForAllocation(size_t allocation_size); 124 size_t BytesAllocated() const; 125 void DumpMemStats(std::ostream& os) const; 126 127 private: 128 void UpdateBytesAllocated(); 129 130 ArenaPool* pool_; 131 uint8_t* begin_; 132 uint8_t* end_; 133 uint8_t* ptr_; 134 Arena* arena_head_; 135 136 // Statistics. 137 size_t num_allocations_; 138 size_t alloc_stats_[kNumAllocKinds]; // Bytes used by various allocation kinds. 139 140 DISALLOW_COPY_AND_ASSIGN(ArenaAllocator); 141 }; // ArenaAllocator 142 143 struct MemStats { 144 public: 145 void Dump(std::ostream& os) const { 146 arena_.DumpMemStats(os); 147 } 148 explicit MemStats(const ArenaAllocator &arena) : arena_(arena) {} 149 private: 150 const ArenaAllocator &arena_; 151 }; // MemStats 152 153 } // namespace art 154 155 #endif // ART_COMPILER_DEX_ARENA_ALLOCATOR_H_ 156