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