blob: 56cedfefd5f332a251e37a7ac36f406ab5f45c03 [file] [log] [blame]
buzbee862a7602013-04-05 10:58:54 -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
Nicolas Geoffray818f2102014-02-18 16:43:35 +000017#ifndef ART_COMPILER_UTILS_ARENA_ALLOCATOR_H_
18#define ART_COMPILER_UTILS_ARENA_ALLOCATOR_H_
buzbee862a7602013-04-05 10:58:54 -070019
20#include <stdint.h>
21#include <stddef.h>
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070022
23#include "base/mutex.h"
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070024#include "mem_map.h"
buzbee862a7602013-04-05 10:58:54 -070025
26namespace art {
27
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070028class Arena;
29class ArenaPool;
30class ArenaAllocator;
buzbee862a7602013-04-05 10:58:54 -070031
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070032class Arena {
33 public:
34 static constexpr size_t kDefaultSize = 128 * KB;
35 explicit Arena(size_t size = kDefaultSize);
36 ~Arena();
37 void Reset();
38 uint8_t* Begin() {
39 return memory_;
buzbee862a7602013-04-05 10:58:54 -070040 }
41
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070042 uint8_t* End() {
43 return memory_ + size_;
44 }
45
46 size_t Size() const {
47 return size_;
48 }
49
50 size_t RemainingSpace() const {
51 return Size() - bytes_allocated_;
52 }
53
54 private:
55 size_t bytes_allocated_;
56 uint8_t* memory_;
57 size_t size_;
58 MemMap* map_;
59 Arena* next_;
60 friend class ArenaPool;
61 friend class ArenaAllocator;
62 DISALLOW_COPY_AND_ASSIGN(Arena);
63};
64
65class ArenaPool {
66 public:
67 ArenaPool();
68 ~ArenaPool();
69 Arena* AllocArena(size_t size);
70 void FreeArena(Arena* arena);
71
72 private:
73 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
74 Arena* free_arenas_ GUARDED_BY(lock_);
75 DISALLOW_COPY_AND_ASSIGN(ArenaPool);
76};
77
78class ArenaAllocator {
79 public:
80 // Type of allocation for memory tuning.
81 enum ArenaAllocKind {
82 kAllocMisc,
83 kAllocBB,
84 kAllocLIR,
85 kAllocMIR,
86 kAllocDFInfo,
87 kAllocGrowableArray,
88 kAllocGrowableBitMap,
89 kAllocDalvikToSSAMap,
90 kAllocDebugInfo,
91 kAllocSuccessor,
92 kAllocRegAlloc,
93 kAllocData,
94 kAllocPredecessors,
95 kNumAllocKinds
96 };
97
98 static constexpr bool kCountAllocations = false;
99
100 explicit ArenaAllocator(ArenaPool* pool);
101 ~ArenaAllocator();
102
103 // Returns zeroed memory.
104 void* Alloc(size_t bytes, ArenaAllocKind kind) ALWAYS_INLINE {
Mathieu Chartier75165d02013-09-12 14:00:31 -0700105 if (UNLIKELY(running_on_valgrind_)) {
106 return AllocValgrind(bytes, kind);
107 }
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700108 bytes = (bytes + 3) & ~3;
109 if (UNLIKELY(ptr_ + bytes > end_)) {
110 // Obtain a new block.
111 ObtainNewArenaForAllocation(bytes);
112 if (UNLIKELY(ptr_ == nullptr)) {
113 return nullptr;
114 }
115 }
116 if (kCountAllocations) {
117 alloc_stats_[kind] += bytes;
118 ++num_allocations_;
119 }
120 uint8_t* ret = ptr_;
121 ptr_ += bytes;
122 return ret;
123 }
124
Mathieu Chartier75165d02013-09-12 14:00:31 -0700125 void* AllocValgrind(size_t bytes, ArenaAllocKind kind);
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700126 void ObtainNewArenaForAllocation(size_t allocation_size);
127 size_t BytesAllocated() const;
buzbee862a7602013-04-05 10:58:54 -0700128 void DumpMemStats(std::ostream& os) const;
129
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700130 private:
131 void UpdateBytesAllocated();
buzbee862a7602013-04-05 10:58:54 -0700132
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700133 ArenaPool* pool_;
134 uint8_t* begin_;
135 uint8_t* end_;
136 uint8_t* ptr_;
137 Arena* arena_head_;
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700138 size_t num_allocations_;
Mathieu Chartier75165d02013-09-12 14:00:31 -0700139 size_t alloc_stats_[kNumAllocKinds]; // Bytes used by various allocation kinds.
140 bool running_on_valgrind_;
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700141
142 DISALLOW_COPY_AND_ASSIGN(ArenaAllocator);
buzbee862a7602013-04-05 10:58:54 -0700143}; // ArenaAllocator
144
buzbee862a7602013-04-05 10:58:54 -0700145struct MemStats {
146 public:
147 void Dump(std::ostream& os) const {
148 arena_.DumpMemStats(os);
149 }
Brian Carlstrom9b7085a2013-07-18 15:15:21 -0700150 explicit MemStats(const ArenaAllocator &arena) : arena_(arena) {}
buzbee862a7602013-04-05 10:58:54 -0700151 private:
152 const ArenaAllocator &arena_;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700153}; // MemStats
buzbee862a7602013-04-05 10:58:54 -0700154
155} // namespace art
156
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000157#endif // ART_COMPILER_UTILS_ARENA_ALLOCATOR_H_