OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../include/fxcrt/fx_basic.h" | 7 #include "../../include/fxcrt/fx_basic.h" |
8 #include "mem_int.h" | |
9 | |
10 void FXMEM_DestroyFoxitMgr(FXMEM_FoxitMgr* pFoxitMgr) | |
11 { | |
12 if (pFoxitMgr == NULL) { | |
13 return; | |
14 } | |
15 CFX_MemoryMgr* p = (CFX_MemoryMgr*)pFoxitMgr; | |
16 if (p->m_pSystemMgr->CollectAll) { | |
17 p->m_pSystemMgr->CollectAll(p->m_pSystemMgr); | |
18 } | |
19 if (p->m_bReleaseMgr) { | |
20 p->m_pSystemMgr->Free(p->m_pSystemMgr, p, 0); | |
21 } | |
22 if (p->m_pExternalMemory) { | |
23 free(p->m_pExternalMemory); | |
24 } | |
25 } | |
26 #ifdef __cplusplus | 8 #ifdef __cplusplus |
27 extern "C" { | 9 extern "C" { |
28 #endif | 10 #endif |
29 static void* _DefAllocDebug(IFX_Allocator* pAllocator, size_t num, size_t size,
FX_LPCSTR filename, int line) | 11 void*» FXMEM_DefaultAlloc(size_t byte_size, int flags) |
30 { | 12 { |
31 if (size == 0 || num > SIZE_MAX/size) | 13 return (void*)malloc(byte_size); |
32 return NULL; | |
33 | |
34 size = size * num; | |
35 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->AllocDebug(size, 0, file
name, line); | |
36 } | 14 } |
37 static void* _DefAlloc(IFX_Allocator* pAllocator, size_t num, size_t size) | 15 void*» FXMEM_DefaultRealloc(void* pointer, size_t new_size, int flags) |
38 { | 16 { |
39 if (size == 0 || num > SIZE_MAX/size) | 17 return realloc(pointer, new_size); |
40 return NULL; | |
41 | |
42 size = size * num; | |
43 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Alloc(size, 0); | |
44 } | 18 } |
45 static void* _DefReallocDebug(IFX_Allocator* pAllocator, void* p, size_t new_num
, size_t size, FX_LPCSTR filename, int line) | 19 void» FXMEM_DefaultFree(void* pointer, int flags) |
46 { | 20 { |
47 if (size == 0 || new_num > SIZE_MAX/size) | 21 free(pointer); |
48 return NULL; | |
49 | |
50 size = size * new_num; | |
51 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->ReallocDebug(p, size, 0,
filename, line); | |
52 } | |
53 static void* _DefRealloc(IFX_Allocator* pAllocator, void* p, size_t new_num, siz
e_t size) | |
54 { | |
55 if (size == 0 || new_num > SIZE_MAX/size) | |
56 return NULL; | |
57 | |
58 size = size * new_num; | |
59 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Realloc(p, size, 0); | |
60 } | |
61 static void _DefFree(IFX_Allocator* pAllocator, void* p) | |
62 { | |
63 ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Free(p, 0); | |
64 } | 22 } |
65 #ifdef __cplusplus | 23 #ifdef __cplusplus |
66 } | 24 } |
67 #endif | 25 #endif |
68 void CFX_MemoryMgr::Init(FXMEM_SystemMgr* pSystemMgr) | 26 CFX_GrowOnlyPool::CFX_GrowOnlyPool(size_t trunk_size) |
69 { | |
70 m_pSystemMgr = pSystemMgr; | |
71 IFX_Allocator &ac = m_DefAllocator.m_Allocator; | |
72 ac.m_Alloc = _DefAlloc; | |
73 ac.m_AllocDebug = _DefAllocDebug; | |
74 ac.m_Realloc = _DefRealloc; | |
75 ac.m_ReallocDebug = _DefReallocDebug; | |
76 ac.m_Free = _DefFree; | |
77 m_DefAllocator.m_pFoxitMgr = this; | |
78 m_pExternalMemory = NULL; | |
79 m_bReleaseMgr = TRUE; | |
80 } | |
81 void CFX_MemoryMgr::PurgeMgr() | |
82 { | |
83 if (m_pSystemMgr->Purge) { | |
84 m_pSystemMgr->Purge(m_pSystemMgr); | |
85 } | |
86 } | |
87 void* CFX_MemoryMgr::Alloc(size_t size, int flags) | |
88 { | |
89 void* p = m_pSystemMgr->Alloc(m_pSystemMgr, size, flags); | |
90 if (p == NULL) { | |
91 return NULL; | |
92 } | |
93 return p; | |
94 } | |
95 void* CFX_MemoryMgr::AllocDebug(size_t size, int flags, FX_LPCSTR file, int line
) | |
96 { | |
97 void* p = m_pSystemMgr->AllocDebug(m_pSystemMgr, size, flags, file, line); | |
98 if (p == NULL) { | |
99 return NULL; | |
100 } | |
101 return p; | |
102 } | |
103 void* CFX_MemoryMgr::Realloc(void* p, size_t size, int flags) | |
104 { | |
105 void* p1 = m_pSystemMgr->Realloc(m_pSystemMgr, p, size, flags); | |
106 if (p1 == NULL) { | |
107 return NULL; | |
108 } | |
109 return p1; | |
110 } | |
111 void* CFX_MemoryMgr::ReallocDebug(void* p, size_t size, int flags, FX_LPCSTR fil
e, int line) | |
112 { | |
113 void* p1 = m_pSystemMgr->ReallocDebug(m_pSystemMgr, p, size, flags, file, li
ne); | |
114 if (p1 == NULL) { | |
115 return NULL; | |
116 } | |
117 return p1; | |
118 } | |
119 void CFX_MemoryMgr::Free(void* p, int flags) | |
120 { | |
121 if (p == NULL) { | |
122 return; | |
123 } | |
124 m_pSystemMgr->Free(m_pSystemMgr, p, flags); | |
125 } | |
126 CFX_MemoryMgr* g_pDefFoxitMgr = NULL; | |
127 void* FXMEM_DefaultAlloc(size_t size, int flags) | |
128 { | |
129 return g_pDefFoxitMgr->Alloc(size, flags); | |
130 } | |
131 void* FXMEM_DefaultAlloc2(size_t size, size_t unit, int flags) | |
132 { | |
133 return g_pDefFoxitMgr->Alloc(size * unit, flags); | |
134 } | |
135 void* FXMEM_DefaultRealloc(void* p, size_t size, int flags) | |
136 { | |
137 if (p == NULL) { | |
138 return FXMEM_DefaultAlloc(size, flags); | |
139 } | |
140 return g_pDefFoxitMgr->Realloc(p, size, flags); | |
141 } | |
142 void* FXMEM_DefaultRealloc2(void* p, size_t size, size_t unit, int flags) | |
143 { | |
144 if (p == NULL) { | |
145 return FXMEM_DefaultAlloc2(size, unit, flags); | |
146 } | |
147 return g_pDefFoxitMgr->Realloc(p, size * unit, flags); | |
148 } | |
149 void* FXMEM_DefaultAllocDebug(size_t size, int flags, FX_LPCSTR file, int line) | |
150 { | |
151 return g_pDefFoxitMgr->AllocDebug(size, flags, file, line); | |
152 } | |
153 void* FXMEM_DefaultAllocDebug2(size_t size, size_t unit, int flags, FX_LPCSTR fi
le, int line) | |
154 { | |
155 return g_pDefFoxitMgr->AllocDebug(size * unit, flags, file, line); | |
156 } | |
157 void* FXMEM_DefaultReallocDebug(void* p, size_t size, int flags, FX_LPCSTR file,
int line) | |
158 { | |
159 if (p == NULL) { | |
160 return FXMEM_DefaultAllocDebug(size, flags, file, line); | |
161 } | |
162 return g_pDefFoxitMgr->ReallocDebug(p, size, flags, file, line); | |
163 } | |
164 void* FXMEM_DefaultReallocDebug2(void* p, size_t size, size_t unit, int flags, F
X_LPCSTR file, int line) | |
165 { | |
166 if (p == NULL) { | |
167 return FXMEM_DefaultAllocDebug2(size, unit, flags, file, line); | |
168 } | |
169 return g_pDefFoxitMgr->ReallocDebug(p, size * unit, flags, file, line); | |
170 } | |
171 void FXMEM_DefaultFree(void* p, int flags) | |
172 { | |
173 g_pDefFoxitMgr->Free(p, flags); | |
174 } | |
175 IFX_Allocator* FXMEM_GetDefAllocator() | |
176 { | |
177 return &g_pDefFoxitMgr->m_DefAllocator.m_Allocator; | |
178 } | |
179 void* CFX_Object::operator new(size_t size) | |
180 { | |
181 return g_pDefFoxitMgr->Alloc(size, 0); | |
182 } | |
183 void* CFX_Object::operator new[](size_t size) | |
184 { | |
185 return g_pDefFoxitMgr->Alloc(size, 0); | |
186 } | |
187 void* CFX_Object::operator new[](size_t size, FX_LPCSTR file, int line) | |
188 { | |
189 return g_pDefFoxitMgr->AllocDebug(size, 0, file, line); | |
190 } | |
191 void* CFX_Object::operator new(size_t size, FX_LPCSTR file, int line) | |
192 { | |
193 return g_pDefFoxitMgr->AllocDebug(size, 0, file, line); | |
194 } | |
195 void CFX_Object::operator delete(void* p) | |
196 { | |
197 g_pDefFoxitMgr->Free(p, 0); | |
198 } | |
199 void CFX_Object::operator delete[](void* p) | |
200 { | |
201 g_pDefFoxitMgr->Free(p, 0); | |
202 } | |
203 void CFX_Object::operator delete(void* p, FX_LPCSTR file, int line) | |
204 { | |
205 g_pDefFoxitMgr->Free(p, 0); | |
206 } | |
207 void CFX_Object::operator delete[](void* p, FX_LPCSTR file, int line) | |
208 { | |
209 g_pDefFoxitMgr->Free(p, 0); | |
210 } | |
211 void* CFX_AllocObject::operator new(size_t size, IFX_Allocator* pAllocator, FX_L
PCSTR filename, int line) | |
212 { | |
213 void* p = pAllocator ? pAllocator->m_AllocDebug(pAllocator, size, 1, filenam
e, line) : | |
214 g_pDefFoxitMgr->AllocDebug(size, 0, filename, line); | |
215 ((CFX_AllocObject*)p)->m_pAllocator = pAllocator; | |
216 return p; | |
217 } | |
218 void CFX_AllocObject::operator delete (void* p, IFX_Allocator* pAllocator, FX_LP
CSTR filename, int line) | |
219 { | |
220 if (pAllocator) { | |
221 pAllocator->m_Free(pAllocator, p); | |
222 } else { | |
223 g_pDefFoxitMgr->Free(p, 0); | |
224 } | |
225 } | |
226 void* CFX_AllocObject::operator new(size_t size, IFX_Allocator* pAllocator) | |
227 { | |
228 void* p = pAllocator ? pAllocator->m_Alloc(pAllocator, size, 1) : g_pDefFoxi
tMgr->Alloc(size, 0); | |
229 ((CFX_AllocObject*)p)->m_pAllocator = pAllocator; | |
230 return p; | |
231 } | |
232 void CFX_AllocObject::operator delete(void* p) | |
233 { | |
234 if (((CFX_AllocObject*)p)->m_pAllocator) { | |
235 (((CFX_AllocObject*)p)->m_pAllocator)->m_Free(((CFX_AllocObject*)p)->m_p
Allocator, p); | |
236 } else { | |
237 g_pDefFoxitMgr->Free(p, 0); | |
238 } | |
239 } | |
240 void CFX_AllocObject::operator delete(void* p, IFX_Allocator* pAllocator) | |
241 { | |
242 if (pAllocator) { | |
243 pAllocator->m_Free(pAllocator, p); | |
244 } else { | |
245 g_pDefFoxitMgr->Free(p, 0); | |
246 } | |
247 } | |
248 extern "C" { | |
249 static void* _GOPAllocDebug(IFX_Allocator* pAllocator, size_t num, size_t si
ze, FX_LPCSTR file, int line) | |
250 { | |
251 if (size == 0 || num > SIZE_MAX/size) | |
252 return NULL; | |
253 | |
254 size = size * num; | |
255 return ((CFX_GrowOnlyPool*)pAllocator)->Alloc(size); | |
256 } | |
257 static void* _GOPAlloc(IFX_Allocator* pAllocator, size_t num, size_t size) | |
258 { | |
259 if (size == 0 || num > SIZE_MAX/size) | |
260 return NULL; | |
261 | |
262 size = size * num; | |
263 return ((CFX_GrowOnlyPool*)pAllocator)->Alloc(size); | |
264 } | |
265 static void* _GOPReallocDebug(IFX_Allocator* pAllocator, void* p, size_t new
_num, size_t size, FX_LPCSTR file, int line) | |
266 { | |
267 if (size == 0 || new_num > SIZE_MAX/size) | |
268 return NULL; | |
269 | |
270 size = size * new_num; | |
271 return ((CFX_GrowOnlyPool*)pAllocator)->Realloc(p, size); | |
272 } | |
273 static void* _GOPRealloc(IFX_Allocator* pAllocator, void* p, size_t new_num,
size_t size) | |
274 { | |
275 if (size == 0 || new_num > SIZE_MAX/size) | |
276 return NULL; | |
277 | |
278 size = size * new_num; | |
279 return ((CFX_GrowOnlyPool*)pAllocator)->Realloc(p, size); | |
280 } | |
281 static void _GOPFree(IFX_Allocator* pAllocator, void* p) | |
282 { | |
283 } | |
284 }; | |
285 CFX_GrowOnlyPool::CFX_GrowOnlyPool(IFX_Allocator* pAllocator, size_t trunk_size) | |
286 { | 27 { |
287 m_TrunkSize = trunk_size; | 28 m_TrunkSize = trunk_size; |
288 m_pFirstTrunk = NULL; | 29 m_pFirstTrunk = NULL; |
289 m_pAllocator = pAllocator ? pAllocator : &g_pDefFoxitMgr->m_DefAllocator.m_A
llocator; | |
290 m_AllocDebug = _GOPAllocDebug; | |
291 m_Alloc = _GOPAlloc; | |
292 m_ReallocDebug = _GOPReallocDebug; | |
293 m_Realloc = _GOPRealloc; | |
294 m_Free = _GOPFree; | |
295 } | 30 } |
296 CFX_GrowOnlyPool::~CFX_GrowOnlyPool() | 31 CFX_GrowOnlyPool::~CFX_GrowOnlyPool() |
297 { | 32 { |
298 FreeAll(); | 33 FreeAll(); |
299 } | 34 } |
300 void CFX_GrowOnlyPool::SetAllocator(IFX_Allocator* pAllocator) | |
301 { | |
302 ASSERT(m_pFirstTrunk == NULL); | |
303 m_pAllocator = pAllocator ? pAllocator : &g_pDefFoxitMgr->m_DefAllocator.m_A
llocator; | |
304 } | |
305 struct _FX_GrowOnlyTrunk { | 35 struct _FX_GrowOnlyTrunk { |
306 size_t m_Size; | 36 size_t m_Size; |
307 size_t m_Allocated; | 37 size_t m_Allocated; |
308 _FX_GrowOnlyTrunk* m_pNext; | 38 _FX_GrowOnlyTrunk* m_pNext; |
309 }; | 39 }; |
310 void CFX_GrowOnlyPool::FreeAll() | 40 void CFX_GrowOnlyPool::FreeAll() |
311 { | 41 { |
312 _FX_GrowOnlyTrunk* pTrunk = (_FX_GrowOnlyTrunk*)m_pFirstTrunk; | 42 _FX_GrowOnlyTrunk* pTrunk = (_FX_GrowOnlyTrunk*)m_pFirstTrunk; |
313 while (pTrunk) { | 43 while (pTrunk) { |
314 _FX_GrowOnlyTrunk* pNext = pTrunk->m_pNext; | 44 _FX_GrowOnlyTrunk* pNext = pTrunk->m_pNext; |
315 m_pAllocator->m_Free(m_pAllocator, pTrunk); | 45 FX_Free(pTrunk); |
316 pTrunk = pNext; | 46 pTrunk = pNext; |
317 } | 47 } |
318 m_pFirstTrunk = NULL; | 48 m_pFirstTrunk = NULL; |
319 } | 49 } |
320 void* CFX_GrowOnlyPool::Alloc(size_t size) | 50 void* CFX_GrowOnlyPool::Alloc(size_t size) |
321 { | 51 { |
322 size = (size + 3) / 4 * 4; | 52 size = (size + 3) / 4 * 4; |
323 _FX_GrowOnlyTrunk* pTrunk = (_FX_GrowOnlyTrunk*)m_pFirstTrunk; | 53 _FX_GrowOnlyTrunk* pTrunk = (_FX_GrowOnlyTrunk*)m_pFirstTrunk; |
324 while (pTrunk) { | 54 while (pTrunk) { |
325 if (pTrunk->m_Size - pTrunk->m_Allocated >= size) { | 55 if (pTrunk->m_Size - pTrunk->m_Allocated >= size) { |
326 void* p = (FX_LPBYTE)(pTrunk + 1) + pTrunk->m_Allocated; | 56 void* p = (FX_LPBYTE)(pTrunk + 1) + pTrunk->m_Allocated; |
327 pTrunk->m_Allocated += size; | 57 pTrunk->m_Allocated += size; |
328 return p; | 58 return p; |
329 } | 59 } |
330 pTrunk = pTrunk->m_pNext; | 60 pTrunk = pTrunk->m_pNext; |
331 } | 61 } |
332 size_t alloc_size = size > m_TrunkSize ? size : m_TrunkSize; | 62 size_t alloc_size = size > m_TrunkSize ? size : m_TrunkSize; |
333 | 63 pTrunk = (_FX_GrowOnlyTrunk*)FX_Alloc(FX_BYTE, sizeof(_FX_GrowOnlyTrunk) + a
lloc_size); |
334 if (alloc_size > SIZE_MAX - sizeof(_FX_GrowOnlyTrunk) ) | |
335 return NULL; | |
336 | |
337 pTrunk = (_FX_GrowOnlyTrunk*)m_pAllocator->m_Alloc(m_pAllocator, sizeof(_FX_
GrowOnlyTrunk) + alloc_size, 1); | |
338 pTrunk->m_Size = alloc_size; | 64 pTrunk->m_Size = alloc_size; |
339 pTrunk->m_Allocated = size; | 65 pTrunk->m_Allocated = size; |
340 pTrunk->m_pNext = (_FX_GrowOnlyTrunk*)m_pFirstTrunk; | 66 pTrunk->m_pNext = (_FX_GrowOnlyTrunk*)m_pFirstTrunk; |
341 m_pFirstTrunk = pTrunk; | 67 m_pFirstTrunk = pTrunk; |
342 return pTrunk + 1; | 68 return pTrunk + 1; |
343 } | 69 } |
OLD | NEW |