51726f36ee7e7fbf57adaa304ff33ab437a26081
1 /********************* */
4 ** Top contributors (to current version):
5 ** Clark Barrett, Andres Noetzli, Morgan Deters
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief Region-based memory manager with stack-based push and pop.
14 ** Region-based memory manager with stack-based push and pop. Designed
15 ** for use by ContextManager.
18 #include "cvc4_private.h"
20 #ifndef CVC4__CONTEXT__CONTEXT_MM_H
21 #define CVC4__CONTEXT__CONTEXT_MM_H
30 #ifndef CVC4_DEBUG_CONTEXT_MEMORY_MANAGER
33 * Region-based memory manager for contexts. Calls to newData provide memory
34 * from the current region. This memory will persist until the entire
35 * region is deallocated (by calling pop).
37 * If push is called, the current region is deactivated and pushed on a
38 * stack, and a new current region is created. A subsequent call to pop
39 * releases the new region and restores the top region from the stack.
42 class ContextMemoryManager
{
45 * Memory in regions is allocated in chunks. This is the chunk size
47 static const unsigned chunkSizeBytes
= 16384;
50 * A list of free chunks is maintained. This is the maximum number of
53 static const unsigned maxFreeChunks
= 100;
56 * List of all chunks that are currently active
58 std::vector
<char*> d_chunkList
;
61 * Queue of free chunks (for best cache performance, LIFO order is used)
63 std::deque
<char*> d_freeChunks
;
66 * Pointer to the beginning of available memory in the current chunk in
72 * Pointer to one past the last available byte in the current chunk in
78 * The index in d_chunkList of the current chunk in the current region
80 unsigned d_indexChunkList
;
83 * Part of the stack of saved regions. This vector stores the saved value
86 std::vector
<char*> d_nextFreeStack
;
89 * Part of the stack of saved regions. This vector stores the saved value
92 std::vector
<char*> d_endChunkStack
;
95 * Part of the stack of saved regions. This vector stores the saved value
98 std::vector
<unsigned> d_indexChunkListStack
;
101 * Private method to grab a new chunk for the current region. Uses chunk
102 * from d_freeChunks if available. Creates a new one otherwise. Sets the
103 * new chunk to be the current chunk.
109 * Vector of allocations for each level. Used for accurately marking
110 * allocations as free'd in Valgrind.
112 std::vector
<std::vector
<char*>> d_allocations
;
117 * Get the maximum allocation size for this memory manager.
119 static unsigned getMaxAllocationSize() {
120 return chunkSizeBytes
;
124 * Constructor - creates an initial region and an empty stack
126 ContextMemoryManager();
129 * Destructor - deletes all memory in all regions
131 ~ContextMemoryManager();
134 * Allocate size bytes from the current region
136 void* newData(size_t size
);
139 * Create a new region. Push old region on the stack.
144 * Delete all memory allocated in the current region and restore the top
145 * region from the stack
149 };/* class ContextMemoryManager */
151 #else /* CVC4_DEBUG_CONTEXT_MEMORY_MANAGER */
154 "Using the debug version of ContextMemoryManager, expect performance degradation"
157 * Dummy implementation of the ContextMemoryManager for debugging purposes. Use
158 * the configure flag "--enable-debug-context-memory-manager" to use this
161 class ContextMemoryManager
164 static unsigned getMaxAllocationSize()
166 return std::numeric_limits
<unsigned>::max();
169 ContextMemoryManager() { d_allocations
.push_back(std::vector
<char*>()); }
170 ~ContextMemoryManager()
172 for (const auto& levelAllocs
: d_allocations
)
174 for (auto alloc
: levelAllocs
)
181 void* newData(size_t size
)
183 void* alloc
= malloc(size
);
184 d_allocations
.back().push_back(static_cast<char*>(alloc
));
188 void push() { d_allocations
.push_back(std::vector
<char*>()); }
192 for (auto alloc
: d_allocations
.back())
196 d_allocations
.pop_back();
200 std::vector
<std::vector
<char*>> d_allocations
;
201 }; /* ContextMemoryManager */
203 #endif /* CVC4_DEBUG_CONTEXT_MEMORY_MANAGER */
206 * An STL-like allocator class for allocating from context memory.
209 class ContextMemoryAllocator
{
210 ContextMemoryManager
* d_mm
;
214 typedef size_t size_type
;
215 typedef std::ptrdiff_t difference_type
;
217 typedef T
const* const_pointer
;
218 typedef T
& reference
;
219 typedef T
const& const_reference
;
220 typedef T value_type
;
221 template <class U
> struct rebind
{
222 typedef ContextMemoryAllocator
<U
> other
;
225 ContextMemoryAllocator(ContextMemoryManager
* mm
) : d_mm(mm
) {}
227 ContextMemoryAllocator(const ContextMemoryAllocator
<U
>& alloc
)
228 : d_mm(alloc
.getCMM())
231 ~ContextMemoryAllocator() {}
233 ContextMemoryManager
* getCMM() const { return d_mm
; }
234 T
* address(T
& v
) const { return &v
; }
235 T
const* address(T
const& v
) const { return &v
; }
236 size_t max_size() const
238 return ContextMemoryManager::getMaxAllocationSize() / sizeof(T
);
240 T
* allocate(size_t n
, const void* = 0) const {
241 return static_cast<T
*>(d_mm
->newData(n
* sizeof(T
)));
243 void deallocate(T
* p
, size_t n
) const {
244 /* no explicit delete */
246 void construct(T
* p
, T
const& v
) const {
247 ::new(reinterpret_cast<void*>(p
)) T(v
);
249 void destroy(T
* p
) const {
252 };/* class ContextMemoryAllocator<T> */
255 inline bool operator==(const ContextMemoryAllocator
<T
>& a1
,
256 const ContextMemoryAllocator
<T
>& a2
) {
257 return a1
.d_mm
== a2
.d_mm
;
261 inline bool operator!=(const ContextMemoryAllocator
<T
>& a1
,
262 const ContextMemoryAllocator
<T
>& a2
) {
263 return a1
.d_mm
!= a2
.d_mm
;
266 }/* CVC4::context namespace */
267 }/* CVC4 namespace */
269 #endif /* CVC4__CONTEXT__CONTEXT_MM_H */