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 #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