blob: d11d67c7957329912f36cb32dcc3227c8203f401 [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 {
Mathieu Chartier75165d02013-09-12 14:00:31 -0700106 if (UNLIKELY(running_on_valgrind_)) {
107 return AllocValgrind(bytes, kind);
108 }
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700109 bytes = (bytes + 3) & ~3;
110 if (UNLIKELY(ptr_ + bytes > end_)) {
111 // Obtain a new block.
112 ObtainNewArenaForAllocation(bytes);
113 if (UNLIKELY(ptr_ == nullptr)) {
114 return nullptr;
115 }
116 }
117 if (kCountAllocations) {
118 alloc_stats_[kind] += bytes;
119 ++num_allocations_;
120 }
121 uint8_t* ret = ptr_;
122 ptr_ += bytes;
123 return ret;
124 }
125
Mathieu Chartier75165d02013-09-12 14:00:31 -0700126 void* AllocValgrind(size_t bytes, ArenaAllocKind kind);
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700127 void ObtainNewArenaForAllocation(size_t allocation_size);
128 size_t BytesAllocated() const;
buzbee862a7602013-04-05 10:58:54 -0700129 void DumpMemStats(std::ostream& os) const;
130
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700131 private:
132 void UpdateBytesAllocated();
buzbee862a7602013-04-05 10:58:54 -0700133
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700134 ArenaPool* pool_;
135 uint8_t* begin_;
136 uint8_t* end_;
137 uint8_t* ptr_;
138 Arena* arena_head_;
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700139 size_t num_allocations_;
Mathieu Chartier75165d02013-09-12 14:00:31 -0700140 size_t alloc_stats_[kNumAllocKinds]; // Bytes used by various allocation kinds.
141 bool running_on_valgrind_;
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -0700142
143 DISALLOW_COPY_AND_ASSIGN(ArenaAllocator);
buzbee862a7602013-04-05 10:58:54 -0700144}; // ArenaAllocator
145
buzbee862a7602013-04-05 10:58:54 -0700146struct MemStats {
147 public:
148 void Dump(std::ostream& os) const {
149 arena_.DumpMemStats(os);
150 }
Brian Carlstrom9b7085a2013-07-18 15:15:21 -0700151 explicit MemStats(const ArenaAllocator &arena) : arena_(arena) {}
buzbee862a7602013-04-05 10:58:54 -0700152 private:
153 const ArenaAllocator &arena_;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700154}; // MemStats
buzbee862a7602013-04-05 10:58:54 -0700155
156} // namespace art
157
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700158#endif // ART_COMPILER_DEX_ARENA_ALLOCATOR_H_