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. 4 #include "forward_declarations.h" 5 6 #ifdef FEATURE_RWX_MEMORY 7 #define WRITE_ACCESS_HOLDER_ARG , rh::util::WriteAccessHolder *pRWAccessHolder 8 #define WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT , rh::util::WriteAccessHolder *pRWAccessHolder = NULL 9 #define PASS_WRITE_ACCESS_HOLDER_ARG , pRWAccessHolder 10 #else // FEATURE_RWX_MEMORY 11 #define WRITE_ACCESS_HOLDER_ARG 12 #define WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT 13 #define PASS_WRITE_ACCESS_HOLDER_ARG 14 #endif // FEATURE_RWX_MEMORY 15 16 class AllocHeap 17 { 18 public: 19 AllocHeap(); 20 21 #ifdef FEATURE_RWX_MEMORY 22 // If pAccessMgr is non-NULL, it will be used to manage R/W access to the memory allocated. 23 AllocHeap(UInt32 rwProtectType = PAGE_READWRITE, 24 UInt32 roProtectType = 0, // 0 indicates "same as rwProtectType" 25 rh::util::MemAccessMgr* pAccessMgr = NULL); 26 #endif // FEATURE_RWX_MEMORY 27 28 bool Init(); 29 30 bool Init(UInt8 * pbInitialMem, 31 UIntNative cbInitialMemCommit, 32 UIntNative cbInitialMemReserve, 33 bool fShouldFreeInitialMem); 34 35 ~AllocHeap(); 36 37 // If AllocHeap was created with a MemAccessMgr, pRWAccessHolder must be non-NULL. 38 // On return, the holder will permit R/W access to the allocated memory until it 39 // is destructed. 40 UInt8 * Alloc(UIntNative cbMem WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT); 41 42 // If AllocHeap was created with a MemAccessMgr, pRWAccessHolder must be non-NULL. 43 // On return, the holder will permit R/W access to the allocated memory until it 44 // is destructed. 45 UInt8 * AllocAligned(UIntNative cbMem, 46 UIntNative alignment 47 WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT); 48 49 // Returns true if this AllocHeap owns the memory range [pvMem, pvMem+cbMem) 50 bool Contains(void * pvMem, 51 UIntNative cbMem); 52 53 #ifdef FEATURE_RWX_MEMORY 54 // Used with previously-allocated memory for which RW access is needed again. 55 // Returns true on success. R/W access will be granted until the holder is 56 // destructed. 57 bool AcquireWriteAccess(void* pvMem, 58 UIntNative cbMem, 59 rh::util::WriteAccessHolder* pHolder); 60 #endif // FEATURE_RWX_MEMORY 61 62 private: 63 // Allocation Helpers 64 UInt8* _Alloc(UIntNative cbMem, UIntNative alignment WRITE_ACCESS_HOLDER_ARG); 65 bool _AllocNewBlock(UIntNative cbMem); 66 UInt8* _AllocFromCurBlock(UIntNative cbMem, UIntNative alignment WRITE_ACCESS_HOLDER_ARG); 67 bool _CommitFromCurBlock(UIntNative cbMem); 68 69 // Access protection helpers 70 #ifdef FEATURE_RWX_MEMORY 71 bool _AcquireWriteAccess(UInt8* pvMem, UIntNative cbMem, rh::util::WriteAccessHolder* pHolder); 72 #endif // FEATURE_RWX_MEMORY 73 bool _UpdateMemPtrs(UInt8* pNextFree, UInt8* pFreeCommitEnd, UInt8* pFreeReserveEnd); 74 bool _UpdateMemPtrs(UInt8* pNextFree, UInt8* pFreeCommitEnd); 75 bool _UpdateMemPtrs(UInt8* pNextFree); _UseAccessManager()76 bool _UseAccessManager() { return m_rwProtectType != m_roProtectType; } 77 78 static const UIntNative s_minBlockSize = OS_PAGE_SIZE; 79 80 typedef rh::util::MemRange Block; 81 typedef DPTR(Block) PTR_Block; 82 struct BlockListElem : public Block 83 { BlockListElemBlockListElem84 BlockListElem(Block const & block) 85 : Block(block) 86 {} 87 BlockListElemBlockListElem88 BlockListElem(UInt8 * pbMem, UIntNative cbMem) 89 : Block(pbMem, cbMem) 90 {} 91 92 Block m_block; 93 PTR_Block m_pNext; 94 }; 95 96 typedef SList<BlockListElem> BlockList; 97 BlockList m_blockList; 98 99 UInt32 m_rwProtectType; // READ/WRITE/EXECUTE/etc 100 UInt32 m_roProtectType; // What to do with fully allocated and initialized pages. 101 102 #ifdef FEATURE_RWX_MEMORY 103 rh::util::MemAccessMgr* m_pAccessMgr; 104 rh::util::WriteAccessHolder m_hCurPageRW; // Used to hold RW access to the current allocation page 105 // Passed as pHint to MemAccessMgr::AcquireWriteAccess. 106 #endif // FEATURE_RWX_MEMORY 107 UInt8 * m_pNextFree; 108 UInt8 * m_pFreeCommitEnd; 109 UInt8 * m_pFreeReserveEnd; 110 111 UInt8 * m_pbInitialMem; 112 bool m_fShouldFreeInitialMem; 113 114 Crst m_lock; 115 116 INDEBUG(bool m_fIsInit;) 117 }; 118 typedef DPTR(AllocHeap) PTR_AllocHeap; 119 120 //------------------------------------------------------------------------------------------------- 121 void * __cdecl operator new(size_t n, AllocHeap * alloc); 122 void * __cdecl operator new[](size_t n, AllocHeap * alloc); 123 124