diff options
Diffstat (limited to 'src/jit/alloc.h')
-rw-r--r-- | src/jit/alloc.h | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/jit/alloc.h b/src/jit/alloc.h new file mode 100644 index 0000000000..a769341378 --- /dev/null +++ b/src/jit/alloc.h @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#ifndef _ALLOC_H_ +#define _ALLOC_H_ + +#if !defined(_HOST_H_) +#include "host.h" +#endif // defined(_HOST_H_) + +class ArenaAllocator +{ +private: + ArenaAllocator(const ArenaAllocator& other) = delete; + ArenaAllocator& operator=(const ArenaAllocator& other) = delete; + +protected: + struct PageDescriptor + { + PageDescriptor* m_next; + PageDescriptor* m_previous; + + size_t m_pageBytes; // # of bytes allocated + size_t m_usedBytes; // # of bytes actually used. (This is only valid when we've allocated a new page.) + // See ArenaAllocator::allocateNewPage. + + BYTE m_contents[]; + }; + + // Anything less than 64K leaves VM holes since the OS allocates address space in this size. + // Thus if we want to make this smaller, we need to do a reserve / commit scheme + enum + { + DEFAULT_PAGE_SIZE = 16 * OS_page_size, + MIN_PAGE_SIZE = sizeof(PageDescriptor) + }; + + static size_t s_defaultPageSize; + + IEEMemoryManager* m_memoryManager; + + PageDescriptor* m_firstPage; + PageDescriptor* m_lastPage; + + // These two pointers (when non-null) will always point into 'm_lastPage'. + BYTE* m_nextFreeByte; + BYTE* m_lastFreeByte; + + bool isInitialized(); + + void* allocateNewPage(size_t size, bool canThrow); + + void* allocateHostMemory(size_t size); + void freeHostMemory(void* block); + +public: + ArenaAllocator(); + ArenaAllocator(IEEMemoryManager* memoryManager); + ArenaAllocator& operator=(ArenaAllocator&& other); + + // NOTE: it would be nice to have a destructor on this type to ensure that any value that + // goes out of scope is either uninitialized or has been torn down via a call to + // destroy(), but this interacts badly in methods that use SEH. #3058 tracks + // revisiting EH in the JIT; such a destructor could be added if SEH is removed + // as part of that work. + + virtual void destroy(); + +#if defined(DEBUG) + void* allocateMemory(size_t sz); +#else // defined(DEBUG) + inline void* allocateMemory(size_t size) + { + void* block = m_nextFreeByte; + m_nextFreeByte += size; + + if (m_nextFreeByte > m_lastFreeByte) + { + block = allocateNewPage(size, true); + } + + return block; + } +#endif // !defined(DEBUG) + + size_t getTotalBytesAllocated(); + size_t getTotalBytesUsed(); + + static bool bypassHostAllocator(); + static size_t getDefaultPageSize(); + + static void startup(); + static void shutdown(); + + static ArenaAllocator* getPooledAllocator(IEEMemoryManager* memoryManager); +}; + +#endif // _ALLOC_H_ |