Home | History | Annotate | Download | only in fxcrt
      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"
      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
     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 }
     32 static void* _DefAlloc(IFX_Allocator* pAllocator, size_t size)
     33 {
     34     return ((FX_DefAllocator*)pAllocator)->m_pFoxitMgr->Alloc(size, 0);
     35 }
     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 }
     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 }
     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
     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 }
     64 void CFX_MemoryMgr::PurgeMgr()
     65 {
     66     if (m_pSystemMgr->Purge) {
     67         m_pSystemMgr->Purge(m_pSystemMgr);
     68     }
     69 }
     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 }
     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 }
     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 }
     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 }
    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;
    110 void* FXMEM_DefaultAlloc(size_t size, int flags)
    111 {
    112     return g_pDefFoxitMgr->Alloc(size, flags);
    113 }
    114 void* FXMEM_DefaultAlloc2(size_t size, size_t unit, int flags)
    115 {
    116     return g_pDefFoxitMgr->Alloc(size * unit, flags);
    117 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    154 void FXMEM_DefaultFree(void* p, int flags)
    155 {
    156     g_pDefFoxitMgr->Free(p, flags);
    157 }
    158 IFX_Allocator* FXMEM_GetDefAllocator()
    159 {
    160     return &g_pDefFoxitMgr->m_DefAllocator.m_Allocator;
    161 }
    162 void* CFX_Object::operator new(size_t size)
    163 {
    164     return g_pDefFoxitMgr->Alloc(size, 0);
    165 }
    166 void* CFX_Object::operator new[](size_t size)
    167 {
    168     return g_pDefFoxitMgr->Alloc(size, 0);
    169 }
    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 }
    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 }
    178 void CFX_Object::operator delete(void* p)
    179 {
    180     g_pDefFoxitMgr->Free(p, 0);
    181 }
    182 void CFX_Object::operator delete[](void* p)
    183 {
    184     g_pDefFoxitMgr->Free(p, 0);
    185 }
    186 void CFX_Object::operator delete(void* p, FX_LPCSTR file, int line)
    187 {
    188     g_pDefFoxitMgr->Free(p, 0);
    189 }
    190 void CFX_Object::operator delete[](void* p, FX_LPCSTR file, int line)
    191 {
    192     g_pDefFoxitMgr->Free(p, 0);
    193 }
    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 }
    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 }
    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 }
    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 }
    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" {
    232     static void* _GOPAllocDebug(IFX_Allocator* pAllocator, size_t size, FX_LPCSTR file, int line)
    233     {
    234         return ((CFX_GrowOnlyPool*)pAllocator)->Alloc(size);
    235     }
    236     static void* _GOPAlloc(IFX_Allocator* pAllocator, size_t size)
    237     {
    238         return ((CFX_GrowOnlyPool*)pAllocator)->Alloc(size);
    239     }
    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     }
    244     static void* _GOPRealloc(IFX_Allocator* pAllocator, void* p, size_t new_size)
    245     {
    246         return ((CFX_GrowOnlyPool*)pAllocator)->Realloc(p, new_size);
    247     }
    248     static void _GOPFree(IFX_Allocator* pAllocator, void* p)
    249     {
    250     }
    251 };
    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 }
    263 CFX_GrowOnlyPool::~CFX_GrowOnlyPool()
    264 {
    265     FreeAll();
    266 }
    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 };
    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 }
    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