1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef _FXM_MEM_INT_H_ 8 #define _FXM_MEM_INT_H_ 9 struct FX_DefAllocator { 10 IFX_Allocator m_Allocator; 11 struct CFX_MemoryMgr* m_pFoxitMgr; 12 }; 13 struct CFX_MemoryMgr { 14 public: 15 FXMEM_SystemMgr* m_pSystemMgr; 16 FX_DefAllocator m_DefAllocator; 17 FX_LPVOID m_pExternalMemory; 18 FX_BOOL m_bReleaseMgr; 19 void Init(FXMEM_SystemMgr* pSystemMgr); 20 void* Alloc(size_t size, int flags); 21 void* AllocDebug(size_t size, int flags, FX_LPCSTR file, int line); 22 void* Realloc(void* p, size_t size, int flags); 23 void* ReallocDebug(void* p, size_t size, int flags, FX_LPCSTR file, int line); 24 void Free(void* p, int flags); 25 void PurgeMgr(); 26 }; 27 extern CFX_MemoryMgr* g_pDefFoxitMgr; 28 #define FIXEDMEM_PAGE_EXTRASPACE sizeof(size_t) 29 #define FIXEDMEM_BLOCKNUM(bs) (8 * (FX_FIXEDMEM_PAGESIZE - FIXEDMEM_PAGE_EXTRASPACE) / (8 * bs + 1)) 30 #define FIXEDMEM_8BYTES_BLOCKNUM FIXEDMEM_BLOCKNUM(8) 31 #define FIXEDMEM_16BYTES_BLOCKNUM FIXEDMEM_BLOCKNUM(16) 32 #define FIXEDMEM_32BYTES_BLOCKNUM FIXEDMEM_BLOCKNUM(32) 33 extern const FX_BYTE ZeroLeadPos[256]; 34 extern const FX_BYTE OneLeadPos[256]; 35 template <size_t blockNum, size_t blockSize> 36 class CFXMEM_FixedPage 37 { 38 public: 39 void Initialize() 40 { 41 m_nAvailCount = blockNum; 42 FXSYS_memset32(m_BusyMap, 0, (blockNum + 7) / 8); 43 } 44 FX_BOOL HasFreeBlock() const 45 { 46 return (FX_BOOL)m_nAvailCount; 47 } 48 FX_LPVOID Alloc(size_t size) 49 { 50 FXSYS_assert(m_nAvailCount); 51 FX_LPDWORD pFind = (FX_LPDWORD)m_BusyMap; 52 size_t i = 0; 53 while (i < (blockNum + 7) / 8 / 4 && pFind[i] == 0xFFFFFFFF) { 54 i ++; 55 } 56 i *= 4; 57 while (m_BusyMap[i] == 0xFF) { 58 i ++; 59 } 60 size_t pos = ZeroLeadPos[m_BusyMap[i]]; 61 m_BusyMap[i] |= 1 << (7 - pos); 62 m_nAvailCount --; 63 return (FX_LPBYTE)(this + 1) + (i * 8 + pos) * blockSize; 64 } 65 void Free(FX_LPVOID p) 66 { 67 FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)((FX_LPBYTE)this + FX_FIXEDMEM_PAGESIZE)); 68 size_t pos = ((FX_LPBYTE)p - (FX_LPBYTE)(this + 1)) / blockSize; 69 m_BusyMap[pos / 8] &= ~(1 << (7 - (pos % 8))); 70 m_nAvailCount ++; 71 } 72 volatile size_t m_nAvailCount; 73 FX_BYTE m_BusyMap[(blockNum + 7) / 8]; 74 }; 75 typedef CFXMEM_FixedPage<FIXEDMEM_8BYTES_BLOCKNUM, 8> CFXMEM_8BytesPage; 76 typedef CFXMEM_FixedPage<FIXEDMEM_16BYTES_BLOCKNUM, 16> CFXMEM_16BytesPage; 77 typedef CFXMEM_FixedPage<FIXEDMEM_32BYTES_BLOCKNUM, 32> CFXMEM_32BytesPage; 78 template <size_t blockNum, size_t blockSize> 79 class CFXMEM_FixedPages 80 { 81 public: 82 typedef CFXMEM_FixedPage<blockNum, blockSize> T; 83 FX_LPBYTE m_pStartPage; 84 FX_LPBYTE m_pLimitPos; 85 FX_LPBYTE m_pCurPage; 86 volatile size_t m_nAvailBlocks; 87 void Initialize(FX_LPBYTE pStart, size_t pages) 88 { 89 m_pStartPage = m_pCurPage = pStart; 90 m_nAvailBlocks = pages * blockNum; 91 for (size_t n = 0; n < pages; n ++) { 92 ((T*)pStart)->Initialize(); 93 pStart += FX_FIXEDMEM_PAGESIZE; 94 } 95 m_pLimitPos = pStart; 96 } 97 FX_BOOL IsEmpty() const 98 { 99 return m_nAvailBlocks == (m_pLimitPos - m_pStartPage) / FX_FIXEDMEM_PAGESIZE * blockNum; 100 } 101 FX_BOOL HasFreeBlock() const 102 { 103 return (FX_BOOL)m_nAvailBlocks; 104 } 105 FX_LPVOID Alloc(size_t size) 106 { 107 FXSYS_assert(m_nAvailBlocks); 108 do { 109 if (((T*)m_pCurPage)->HasFreeBlock()) { 110 m_nAvailBlocks --; 111 return ((T*)m_pCurPage)->Alloc(size); 112 } 113 m_pCurPage += FX_FIXEDMEM_PAGESIZE; 114 if (m_pCurPage == m_pLimitPos) { 115 m_pCurPage = m_pStartPage; 116 } 117 } while (TRUE); 118 return NULL; 119 } 120 void Free(FX_LPVOID p) 121 { 122 FXSYS_assert(p > (FX_LPVOID)m_pStartPage && p < (FX_LPVOID)m_pLimitPos); 123 ((T*)(m_pStartPage + ((FX_LPBYTE)p - m_pStartPage) / FX_FIXEDMEM_PAGESIZE * FX_FIXEDMEM_PAGESIZE))->Free(p); 124 m_nAvailBlocks ++; 125 } 126 }; 127 typedef CFXMEM_FixedPages<FIXEDMEM_8BYTES_BLOCKNUM, 8> CFXMEM_8BytesPages; 128 typedef CFXMEM_FixedPages<FIXEDMEM_16BYTES_BLOCKNUM, 16> CFXMEM_16BytesPages; 129 typedef CFXMEM_FixedPages<FIXEDMEM_32BYTES_BLOCKNUM, 32> CFXMEM_32BytesPages; 130 class CFXMEM_Block 131 { 132 public: 133 size_t m_nBlockSize; 134 CFXMEM_Block* m_pNextBlock; 135 }; 136 class CFXMEM_Page 137 { 138 public: 139 size_t m_nAvailSize; 140 CFXMEM_Block* m_pLimitPos; 141 CFXMEM_Block m_AvailHead; 142 void Initialize(size_t size); 143 FX_BOOL IsEmpty() const 144 { 145 return m_AvailHead.m_pNextBlock && m_AvailHead.m_nBlockSize == m_AvailHead.m_pNextBlock->m_nBlockSize; 146 } 147 FX_LPVOID Alloc(size_t size); 148 FX_LPVOID Realloc(FX_LPVOID p, size_t oldSize, size_t newSize); 149 void Free(FX_LPVOID p); 150 protected: 151 FX_LPVOID Alloc(CFXMEM_Block* pPrevBlock, CFXMEM_Block* pNextBlock, size_t size, size_t oldsize); 152 }; 153 class CFXMEM_Pages 154 { 155 public: 156 CFXMEM_Page* m_pStartPage; 157 CFXMEM_Page* m_pLimitPos; 158 CFXMEM_Page* m_pCurPage; 159 size_t m_nPageSize; 160 void Initialize(FX_LPBYTE pStart, size_t pageSize, size_t pages); 161 FX_BOOL IsEmpty() const; 162 FX_LPVOID Alloc(size_t size); 163 FX_LPVOID Realloc(FX_LPVOID p, size_t oldSize, size_t newSize); 164 void Free(FX_LPVOID p); 165 }; 166 class CFXMEM_Pool 167 { 168 public: 169 CFXMEM_Pool* m_pPrevPool; 170 CFXMEM_Pool* m_pNextPool; 171 CFXMEM_8BytesPages m_8BytesPages; 172 CFXMEM_16BytesPages m_16BytesPages; 173 CFXMEM_32BytesPages m_32BytesPages; 174 CFXMEM_Pages m_MidPages; 175 FX_BOOL m_bAlone; 176 FX_DWORD m_dwReserved[3]; 177 FX_LPVOID m_pLimitPos; 178 CFXMEM_Page* m_pLargePage; 179 void Initialize(const FX_MEMCONFIG* pMemConfig, size_t size, size_t pageNum8Bytes, size_t pageNum16Bytes, size_t pageNum32Bytes, size_t pageNumMid); 180 FX_BOOL IsEmpty() const; 181 size_t GetSize(FX_LPVOID p) const; 182 FX_LPVOID Realloc(FX_LPVOID p, size_t oldSize, size_t newSize); 183 void Free(FX_LPVOID p); 184 }; 185 class CFXMEM_FixedMgr 186 { 187 public: 188 void Initialize(size_t size); 189 FX_LPVOID Alloc(size_t size); 190 FX_LPVOID Realloc(FX_LPVOID p, size_t newSize); 191 void Free(FX_LPVOID p); 192 void FreeAll(); 193 void Purge(); 194 CFXMEM_Pool* GetFirstPool() 195 { 196 return &m_FirstPool; 197 } 198 size_t GetSize(FX_LPVOID p) const; 199 FXMEM_SystemMgr m_SystemMgr; 200 FXMEM_SystemMgr2* m_pExtender; 201 FX_LPVOID m_pReserved; 202 FX_MEMCONFIG m_MemConfig; 203 protected: 204 FX_LPVOID Alloc16(CFXMEM_Pool **pp32Pool = NULL, size_t size = 0); 205 FX_LPVOID Alloc32(size_t size); 206 FX_LPVOID AllocSmall(size_t size); 207 FX_LPVOID AllocMid(size_t size); 208 FX_LPVOID AllocLarge(size_t size); 209 FX_LPVOID ReallocSmall(CFXMEM_Pool* pPool, FX_LPVOID p, size_t oldSize, size_t newSize); 210 void FreePool(CFXMEM_Pool* pPool); 211 CFXMEM_Pool m_FirstPool; 212 }; 213 #define FIXEDMEM_PROXYSIZE_0 (1024 * 1024 * 8) 214 #define FIXEDMEM_PROXYSIZE_1 (1024 * 1024 * 16) 215 #define FIXEDMEM_PROXYSIZE_2 (1024 * 1024 * 32) 216 #define FIXEDMEM_PROXYSIZE_3 (1024 * 1024 * 64) 217 #define FIXEDMEM_PROXYSIZE_4 (1024 * 1024 * 128) 218 #define FIXEDMEM_PROXYSIZE_5 (1024 * 1024 * 256) 219 const FX_MEMCONFIG* FixedMgr_GetConfig(size_t nSize); 220 class CFixedMgr_Proxy 221 { 222 public: 223 FXMEM_FoxitMgr* Initialize(FX_LPVOID pBuffer, size_t nSize, FX_BOOL bExtensible); 224 static FX_BOOL Common_More(FXMEM_SystemMgr2* pMgr, size_t alloc_size, void** new_memory, size_t* new_size); 225 static void Common_Free(FXMEM_SystemMgr2* pMgr, void* memory); 226 FXMEM_SystemMgr2 m_SystemMgr; 227 CFXMEM_Page* m_pFixedPage; 228 FX_LPVOID m_pBuffer; 229 size_t m_nSize; 230 FX_BOOL m_bExtensible; 231 }; 232 #endif 233