1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
7 #include "memorypool.h"
10 size_t MemoryPool::GetSize()
12 LIMITED_METHOD_CONTRACT;
15 Block *block = m_blocks;
18 retval+=(BYTE*)block->elementsEnd-(BYTE*)block->elements;
24 #ifndef DACCESS_COMPILE
26 BOOL MemoryPool::AddBlock(SIZE_T elementCount)
31 INJECT_FAULT(return FALSE;);
35 // Check for arithmetic overflow
37 S_SIZE_T cbBlockSize = S_SIZE_T(elementCount) * S_SIZE_T(m_elementSize);
38 S_SIZE_T cbAllocSize = S_SIZE_T(sizeof(Block)) + cbBlockSize;
39 if (cbBlockSize.IsOverflow() || cbAllocSize.IsOverflow())
43 // Allocate the new block.
46 Block *block = (Block *) new (nothrow) BYTE [cbAllocSize.Value()];
52 // Chain all elements together for the free list
55 _ASSERTE(m_freeList == NULL);
56 Element **prev = &m_freeList;
58 Element *e = block->elements;
59 Element *eEnd = (Element *) ((BYTE*) block->elements + elementCount*m_elementSize);
67 e = (Element*) ((BYTE*)e + m_elementSize);
73 // Initialize the other block fields & link the block into the block list
76 block->elementsEnd = e;
77 block->next = m_blocks;
83 void MemoryPool::DeadBeef(Element *element)
92 int *i = &element->deadBeef;
93 int *iEnd = (int*) ((BYTE*)element + m_elementSize);
95 *i++ = (int) 0xdeadbeef;
97 LIMITED_METHOD_CONTRACT;
101 MemoryPool::MemoryPool(SIZE_T elementSize, SIZE_T initGrowth, SIZE_T initCount)
102 : m_elementSize(elementSize),
103 m_growCount(initGrowth),
108 if (initCount) THROWS; else NOTHROW;
112 _ASSERTE(elementSize >= sizeof(Element));
113 _ASSERTE((elementSize & ((sizeof(PVOID)-1))) == 0);
119 MemoryPool::~MemoryPool()
121 LIMITED_METHOD_CONTRACT;
122 Block *block = m_blocks;
123 while (block != NULL)
125 Block *next = block->next;
126 delete [] (BYTE*) block;
131 BOOL MemoryPool::IsElement(void *element)
133 LIMITED_METHOD_CONTRACT;
135 Block *block = m_blocks;
136 while (block != NULL)
138 if (element >= block->elements &&
139 element < block->elementsEnd )
141 return ((BYTE *)element - (BYTE*)block->elements) % m_elementSize == 0;
149 BOOL MemoryPool::IsAllocatedElement(void *element)
157 if (!IsElement(element))
161 // Now, make sure the element isn't
167 // In a debug build, all objects on the free list
168 // will be marked with deadbeef. This means that
169 // if the object is not deadbeef, it's not on the
172 // This check will give us decent performance in
173 // a debug build for FreeElement, since we
174 // always expect to return TRUE in that case.
177 if (((Element*)element)->deadBeef != (int) 0xdeadBeef)
181 Element *f = m_freeList;
191 // We should never get here in a debug build, because
192 // all free elements should be deadbeefed.
194 _ASSERTE(!"Unreachable");
200 void *MemoryPool::AllocateElement()
207 void *element = AllocateElementNoThrow();
214 void *MemoryPool::AllocateElementNoThrow()
219 INJECT_FAULT( return FALSE; );
222 void *element = m_freeList;
226 if (!AddBlock(m_growCount))
230 element = m_freeList;
233 // if we come there means that addblock succeeded and m_freelist isn't null anymore
234 PREFIX_ASSUME(m_freeList!= NULL);
235 m_freeList = m_freeList->next;
240 void MemoryPool::FreeElement(void *element)
248 #if _DEBUG // don't want to do this assert in a non-debug build; it is expensive
249 _ASSERTE(IsAllocatedElement(element));
252 Element *e = (Element *) element;
258 e->next = m_freeList;
262 void MemoryPool::FreeAllElements()
264 LIMITED_METHOD_CONTRACT;
266 Block *block = m_blocks;
267 while (block != NULL)
269 Block *next = block->next;
280 MemoryPool::Iterator::Iterator(MemoryPool *pool)
282 LIMITED_METHOD_CONTRACT;
285 // Warning! This only works if you haven't freed
289 m_next = pool->m_blocks;
292 m_end = (BYTE*) pool->m_freeList;
293 m_size = pool->m_elementSize;
296 BOOL MemoryPool::Iterator::Next()
298 LIMITED_METHOD_CONTRACT;
301 || (m_e == m_end && m_end != NULL))
305 m_e = (BYTE*) m_next->elements;
306 m_eEnd = (BYTE*) m_next->elementsEnd;
307 m_next = m_next->next;