blob: dda52a2ed0a8bd1c76dfcaac203bab8e66a1939b [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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_COMPILER_DEX_ARENA_ALLOCATOR_H_
18#define ART_COMPILER_DEX_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"
buzbee862a7602013-04-05 10:58:54 -070024#include "compiler_enums.h"
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070025#include "mem_map.h"
buzbee862a7602013-04-05 10:58:54 -070026
27namespace art {
28
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070029class Arena;
30class ArenaPool;
31class ArenaAllocator;
buzbee862a7602013-04-05 10:58:54 -070032
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070033class 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_;
buzbee862a7602013-04-05 10:58:54 -070041 }
42
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -070043 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
66class 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
79class 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;
buzbee862a7602013-04-05 10:58:54 -0700125 void DumpMemStats(std::ostream& os) const;
126
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700127 private:
128 void UpdateBytesAllocated();
buzbee862a7602013-04-05 10:58:54 -0700129
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700130 ArenaPool* pool_;
131 uint8_t* begin_;
132 uint8_t* end_;
133 uint8_t* ptr_;
134 Arena* arena_head_;
buzbee862a7602013-04-05 10:58:54 -0700135
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700136 // 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);
buzbee862a7602013-04-05 10:58:54 -0700141}; // ArenaAllocator
142
buzbee862a7602013-04-05 10:58:54 -0700143struct MemStats {
144 public:
145 void Dump(std::ostream& os) const {
146 arena_.DumpMemStats(os);
147 }
Brian Carlstrom9b7085a2013-07-18 15:15:21 -0700148 explicit MemStats(const ArenaAllocator &arena) : arena_(arena) {}
buzbee862a7602013-04-05 10:58:54 -0700149 private:
150 const ArenaAllocator &arena_;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700151}; // MemStats
buzbee862a7602013-04-05 10:58:54 -0700152
153} // namespace art
154
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700155#endif // ART_COMPILER_DEX_ARENA_ALLOCATOR_H_