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 #include "../../include/fxcrt/fx_basic.h"
8 #include "mem_int.h"
FXMEM_DestroyFoxitMgr(FXMEM_FoxitMgr * pFoxitMgr)9 void FXMEM_DestroyFoxitMgr(FXMEM_FoxitMgr* pFoxitMgr)
10 {
11 if (pFoxitMgr == NULL) {
12 return;
13 }
14 CFX_MemoryMgr* p = (CFX_MemoryMgr*)pFoxitMgr;
15 if (p->m_pSystemMgr->CollectAll) {
16 p->m_pSystemMgr->CollectAll(p->m_pSystemMgr);
17 }
18 if (p->m_bReleaseMgr) {
19 p->m_pSystemMgr->Free(p->m_pSystemMgr, p, 0);
20 }
21 if (p->m_pExternalMemory) {
22 free(p->m_pExternalMemory);
23 }
24 }
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
_DefAllocDebug(IFX_Allocator * pAllocator,size_t size,FX_LPCSTR filename,int line)28 static void* _DefAllocDebug(IFX_Allocator* pAllocator, size_t size, FX_LPCSTR filename, int line)
29 {
30 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->AllocDebug(size, 0, filename, line);
31 }
_DefAlloc(IFX_Allocator * pAllocator,size_t size)32 static void* _DefAlloc(IFX_Allocator* pAllocator, size_t size)
33 {
34 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Alloc(size, 0);
35 }
_DefReallocDebug(IFX_Allocator * pAllocator,void * p,size_t size,FX_LPCSTR filename,int line)36 static void* _DefReallocDebug(IFX_Allocator* pAllocator, void* p, size_t size, FX_LPCSTR filename, int line)
37 {
38 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->ReallocDebug(p, size, 0, filename, line);
39 }
_DefRealloc(IFX_Allocator * pAllocator,void * p,size_t size)40 static void* _DefRealloc(IFX_Allocator* pAllocator, void* p, size_t size)
41 {
42 return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Realloc(p, size, 0);
43 }
_DefFree(IFX_Allocator * pAllocator,void * p)44 static void _DefFree(IFX_Allocator* pAllocator, void* p)
45 {
46 ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Free(p, 0);
47 }
48 #ifdef __cplusplus
49 }
50 #endif
Init(FXMEM_SystemMgr * pSystemMgr)51 void CFX_MemoryMgr::Init(FXMEM_SystemMgr* pSystemMgr)
52 {
53 m_pSystemMgr = pSystemMgr;
54 IFX_Allocator &ac = m_DefAllocator.m_Allocator;
55 ac.m_Alloc = _DefAlloc;
56 ac.m_AllocDebug = _DefAllocDebug;
57 ac.m_Realloc = _DefRealloc;
58 ac.m_ReallocDebug = _DefReallocDebug;
59 ac.m_Free = _DefFree;
60 m_DefAllocator.m_pFoxitMgr = this;
61 m_pExternalMemory = NULL;
62 m_bReleaseMgr = TRUE;
63 }
PurgeMgr()64 void CFX_MemoryMgr::PurgeMgr()
65 {
66 if (m_pSystemMgr->Purge) {
67 m_pSystemMgr->Purge(m_pSystemMgr);
68 }
69 }
Alloc(size_t size,int flags)70 void* CFX_MemoryMgr::Alloc(size_t size, int flags)
71 {
72 void* p = m_pSystemMgr->Alloc(m_pSystemMgr, size, flags);
73 if (p == NULL) {
74 return NULL;
75 }
76 return p;
77 }
AllocDebug(size_t size,int flags,FX_LPCSTR file,int line)78 void* CFX_MemoryMgr::AllocDebug(size_t size, int flags, FX_LPCSTR file, int line)
79 {
80 void* p = m_pSystemMgr->AllocDebug(m_pSystemMgr, size, flags, file, line);
81 if (p == NULL) {
82 return NULL;
83 }
84 return p;
85 }
Realloc(void * p,size_t size,int flags)86 void* CFX_MemoryMgr::Realloc(void* p, size_t size, int flags)
87 {
88 void* p1 = m_pSystemMgr->Realloc(m_pSystemMgr, p, size, flags);
89 if (p1 == NULL) {
90 return NULL;
91 }
92 return p1;
93 }
ReallocDebug(void * p,size_t size,int flags,FX_LPCSTR file,int line)94 void* CFX_MemoryMgr::ReallocDebug(void* p, size_t size, int flags, FX_LPCSTR file, int line)
95 {
96 void* p1 = m_pSystemMgr->ReallocDebug(m_pSystemMgr, p, size, flags, file, line);
97 if (p1 == NULL) {
98 return NULL;
99 }
100 return p1;
101 }
Free(void * p,int flags)102 void CFX_MemoryMgr::Free(void* p, int flags)
103 {
104 if (p == NULL) {
105 return;
106 }
107 m_pSystemMgr->Free(m_pSystemMgr, p, flags);
108 }
109 CFX_MemoryMgr* g_pDefFoxitMgr = NULL;
FXMEM_DefaultAlloc(size_t size,int flags)110 void* FXMEM_DefaultAlloc(size_t size, int flags)
111 {
112 return g_pDefFoxitMgr->Alloc(size, flags);
113 }
FXMEM_DefaultAlloc2(size_t size,size_t unit,int flags)114 void* FXMEM_DefaultAlloc2(size_t size, size_t unit, int flags)
115 {
116 return g_pDefFoxitMgr->Alloc(size * unit, flags);
117 }
FXMEM_DefaultRealloc(void * p,size_t size,int flags)118 void* FXMEM_DefaultRealloc(void* p, size_t size, int flags)
119 {
120 if (p == NULL) {
121 return FXMEM_DefaultAlloc(size, flags);
122 }
123 return g_pDefFoxitMgr->Realloc(p, size, flags);
124 }
FXMEM_DefaultRealloc2(void * p,size_t size,size_t unit,int flags)125 void* FXMEM_DefaultRealloc2(void* p, size_t size, size_t unit, int flags)
126 {
127 if (p == NULL) {
128 return FXMEM_DefaultAlloc2(size, unit, flags);
129 }
130 return g_pDefFoxitMgr->Realloc(p, size * unit, flags);
131 }
FXMEM_DefaultAllocDebug(size_t size,int flags,FX_LPCSTR file,int line)132 void* FXMEM_DefaultAllocDebug(size_t size, int flags, FX_LPCSTR file, int line)
133 {
134 return g_pDefFoxitMgr->AllocDebug(size, flags, file, line);
135 }
FXMEM_DefaultAllocDebug2(size_t size,size_t unit,int flags,FX_LPCSTR file,int line)136 void* FXMEM_DefaultAllocDebug2(size_t size, size_t unit, int flags, FX_LPCSTR file, int line)
137 {
138 return g_pDefFoxitMgr->AllocDebug(size * unit, flags, file, line);
139 }
FXMEM_DefaultReallocDebug(void * p,size_t size,int flags,FX_LPCSTR file,int line)140 void* FXMEM_DefaultReallocDebug(void* p, size_t size, int flags, FX_LPCSTR file, int line)
141 {
142 if (p == NULL) {
143 return FXMEM_DefaultAllocDebug(size, flags, file, line);
144 }
145 return g_pDefFoxitMgr->ReallocDebug(p, size, flags, file, line);
146 }
FXMEM_DefaultReallocDebug2(void * p,size_t size,size_t unit,int flags,FX_LPCSTR file,int line)147 void* FXMEM_DefaultReallocDebug2(void* p, size_t size, size_t unit, int flags, FX_LPCSTR file, int line)
148 {
149 if (p == NULL) {
150 return FXMEM_DefaultAllocDebug2(size, unit, flags, file, line);
151 }
152 return g_pDefFoxitMgr->ReallocDebug(p, size * unit, flags, file, line);
153 }
FXMEM_DefaultFree(void * p,int flags)154 void FXMEM_DefaultFree(void* p, int flags)
155 {
156 g_pDefFoxitMgr->Free(p, flags);
157 }
FXMEM_GetDefAllocator()158 IFX_Allocator* FXMEM_GetDefAllocator()
159 {
160 return &g_pDefFoxitMgr->m_DefAllocator.m_Allocator;
161 }
operator new(size_t size)162 void* CFX_Object::operator new(size_t size)
163 {
164 return g_pDefFoxitMgr->Alloc(size, 0);
165 }
operator new[](size_t size)166 void* CFX_Object::operator new[](size_t size)
167 {
168 return g_pDefFoxitMgr->Alloc(size, 0);
169 }
operator new[](size_t size,FX_LPCSTR file,int line)170 void* CFX_Object::operator new[](size_t size, FX_LPCSTR file, int line)
171 {
172 return g_pDefFoxitMgr->AllocDebug(size, 0, file, line);
173 }
operator new(size_t size,FX_LPCSTR file,int line)174 void* CFX_Object::operator new(size_t size, FX_LPCSTR file, int line)
175 {
176 return g_pDefFoxitMgr->AllocDebug(size, 0, file, line);
177 }
operator delete(void * p)178 void CFX_Object::operator delete(void* p)
179 {
180 g_pDefFoxitMgr->Free(p, 0);
181 }
operator delete[](void * p)182 void CFX_Object::operator delete[](void* p)
183 {
184 g_pDefFoxitMgr->Free(p, 0);
185 }
operator delete(void * p,FX_LPCSTR file,int line)186 void CFX_Object::operator delete(void* p, FX_LPCSTR file, int line)
187 {
188 g_pDefFoxitMgr->Free(p, 0);
189 }
operator delete[](void * p,FX_LPCSTR file,int line)190 void CFX_Object::operator delete[](void* p, FX_LPCSTR file, int line)
191 {
192 g_pDefFoxitMgr->Free(p, 0);
193 }
operator new(size_t size,IFX_Allocator * pAllocator,FX_LPCSTR filename,int line)194 void* CFX_AllocObject::operator new(size_t size, IFX_Allocator* pAllocator, FX_LPCSTR filename, int line)
195 {
196 void* p = pAllocator ? pAllocator->m_AllocDebug(pAllocator, size, filename, line) :
197 g_pDefFoxitMgr->AllocDebug(size, 0, filename, line);
198 ((CFX_AllocObject*)p)->m_pAllocator = pAllocator;
199 return p;
200 }
operator delete(void * p,IFX_Allocator * pAllocator,FX_LPCSTR filename,int line)201 void CFX_AllocObject::operator delete (void* p, IFX_Allocator* pAllocator, FX_LPCSTR filename, int line)
202 {
203 if (pAllocator) {
204 pAllocator->m_Free(pAllocator, p);
205 } else {
206 g_pDefFoxitMgr->Free(p, 0);
207 }
208 }
operator new(size_t size,IFX_Allocator * pAllocator)209 void* CFX_AllocObject::operator new(size_t size, IFX_Allocator* pAllocator)
210 {
211 void* p = pAllocator ? pAllocator->m_Alloc(pAllocator, size) : g_pDefFoxitMgr->Alloc(size, 0);
212 ((CFX_AllocObject*)p)->m_pAllocator = pAllocator;
213 return p;
214 }
operator delete(void * p)215 void CFX_AllocObject::operator delete(void* p)
216 {
217 if (((CFX_AllocObject*)p)->m_pAllocator) {
218 (((CFX_AllocObject*)p)->m_pAllocator)->m_Free(((CFX_AllocObject*)p)->m_pAllocator, p);
219 } else {
220 g_pDefFoxitMgr->Free(p, 0);
221 }
222 }
operator delete(void * p,IFX_Allocator * pAllocator)223 void CFX_AllocObject::operator delete(void* p, IFX_Allocator* pAllocator)
224 {
225 if (pAllocator) {
226 pAllocator->m_Free(pAllocator, p);
227 } else {
228 g_pDefFoxitMgr->Free(p, 0);
229 }
230 }
231 extern "C" {
_GOPAllocDebug(IFX_Allocator * pAllocator,size_t size,FX_LPCSTR file,int line)232 static void* _GOPAllocDebug(IFX_Allocator* pAllocator, size_t size, FX_LPCSTR file, int line)
233 {
234 return ((CFX_GrowOnlyPool*)pAllocator)->Alloc(size);
235 }
_GOPAlloc(IFX_Allocator * pAllocator,size_t size)236 static void* _GOPAlloc(IFX_Allocator* pAllocator, size_t size)
237 {
238 return ((CFX_GrowOnlyPool*)pAllocator)->Alloc(size);
239 }
_GOPReallocDebug(IFX_Allocator * pAllocator,void * p,size_t new_size,FX_LPCSTR file,int line)240 static void* _GOPReallocDebug(IFX_Allocator* pAllocator, void* p, size_t new_size, FX_LPCSTR file, int line)
241 {
242 return ((CFX_GrowOnlyPool*)pAllocator)->Realloc(p, new_size);
243 }
_GOPRealloc(IFX_Allocator * pAllocator,void * p,size_t new_size)244 static void* _GOPRealloc(IFX_Allocator* pAllocator, void* p, size_t new_size)
245 {
246 return ((CFX_GrowOnlyPool*)pAllocator)->Realloc(p, new_size);
247 }
_GOPFree(IFX_Allocator * pAllocator,void * p)248 static void _GOPFree(IFX_Allocator* pAllocator, void* p)
249 {
250 }
251 };
CFX_GrowOnlyPool(IFX_Allocator * pAllocator,size_t trunk_size)252 CFX_GrowOnlyPool::CFX_GrowOnlyPool(IFX_Allocator* pAllocator, size_t trunk_size)
253 {
254 m_TrunkSize = trunk_size;
255 m_pFirstTrunk = NULL;
256 m_pAllocator = pAllocator ? pAllocator : &g_pDefFoxitMgr->m_DefAllocator.m_Allocator;
257 m_AllocDebug = _GOPAllocDebug;
258 m_Alloc = _GOPAlloc;
259 m_ReallocDebug = _GOPReallocDebug;
260 m_Realloc = _GOPRealloc;
261 m_Free = _GOPFree;
262 }
~CFX_GrowOnlyPool()263 CFX_GrowOnlyPool::~CFX_GrowOnlyPool()
264 {
265 FreeAll();
266 }
SetAllocator(IFX_Allocator * pAllocator)267 void CFX_GrowOnlyPool::SetAllocator(IFX_Allocator* pAllocator)
268 {
269 ASSERT(m_pFirstTrunk == NULL);
270 m_pAllocator = pAllocator ? pAllocator : &g_pDefFoxitMgr->m_DefAllocator.m_Allocator;
271 }
272 struct _FX_GrowOnlyTrunk {
273 size_t m_Size;
274 size_t m_Allocated;
275 _FX_GrowOnlyTrunk* m_pNext;
276 };
FreeAll()277 void CFX_GrowOnlyPool::FreeAll()
278 {
279 _FX_GrowOnlyTrunk* pTrunk = (_FX_GrowOnlyTrunk*)m_pFirstTrunk;
280 while (pTrunk) {
281 _FX_GrowOnlyTrunk* pNext = pTrunk->m_pNext;
282 m_pAllocator->m_Free(m_pAllocator, pTrunk);
283 pTrunk = pNext;
284 }
285 m_pFirstTrunk = NULL;
286 }
Alloc(size_t size)287 void* CFX_GrowOnlyPool::Alloc(size_t size)
288 {
289 size = (size + 3) / 4 * 4;
290 _FX_GrowOnlyTrunk* pTrunk = (_FX_GrowOnlyTrunk*)m_pFirstTrunk;
291 while (pTrunk) {
292 if (pTrunk->m_Size - pTrunk->m_Allocated >= size) {
293 void* p = (FX_LPBYTE)(pTrunk + 1) + pTrunk->m_Allocated;
294 pTrunk->m_Allocated += size;
295 return p;
296 }
297 pTrunk = pTrunk->m_pNext;
298 }
299 size_t alloc_size = size > m_TrunkSize ? size : m_TrunkSize;
300 pTrunk = (_FX_GrowOnlyTrunk*)m_pAllocator->m_Alloc(m_pAllocator, sizeof(_FX_GrowOnlyTrunk) + alloc_size);
301 pTrunk->m_Size = alloc_size;
302 pTrunk->m_Allocated = size;
303 pTrunk->m_pNext = (_FX_GrowOnlyTrunk*)m_pFirstTrunk;
304 m_pFirstTrunk = pTrunk;
305 return pTrunk + 1;
306 }
307