summaryrefslogtreecommitdiff
path: root/core/src/fxcrt/mem_int.h
blob: da43023bb55f81fc7c3b2c40b060959cdfca35d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef _FXM_MEM_INT_H_
#define _FXM_MEM_INT_H_
struct FX_DefAllocator {
    IFX_Allocator			m_Allocator;
    struct CFX_MemoryMgr*	m_pFoxitMgr;
};
struct CFX_MemoryMgr {
public:
    FXMEM_SystemMgr*	m_pSystemMgr;
    FX_DefAllocator		m_DefAllocator;
    FX_LPVOID			m_pExternalMemory;
    FX_BOOL				m_bReleaseMgr;
    void			Init(FXMEM_SystemMgr* pSystemMgr);
    void*			Alloc(size_t size, int flags);
    void*			AllocDebug(size_t size, int flags, FX_LPCSTR file, int line);
    void*			Realloc(void* p, size_t size, int flags);
    void*			ReallocDebug(void* p, size_t size, int flags, FX_LPCSTR file, int line);
    void			Free(void* p, int flags);
    void			PurgeMgr();
};
extern CFX_MemoryMgr* g_pDefFoxitMgr;
#define FIXEDMEM_PAGE_EXTRASPACE		sizeof(size_t)
#define FIXEDMEM_BLOCKNUM(bs)			(8 * (FX_FIXEDMEM_PAGESIZE - FIXEDMEM_PAGE_EXTRASPACE) / (8 * bs + 1))
#define FIXEDMEM_8BYTES_BLOCKNUM		FIXEDMEM_BLOCKNUM(8)
#define FIXEDMEM_16BYTES_BLOCKNUM		FIXEDMEM_BLOCKNUM(16)
#define FIXEDMEM_32BYTES_BLOCKNUM		FIXEDMEM_BLOCKNUM(32)
extern const FX_BYTE ZeroLeadPos[256];
extern const FX_BYTE OneLeadPos[256];
template <size_t blockNum, size_t blockSize>
class CFXMEM_FixedPage
{
public:
    void		Initialize()
    {
        m_nAvailCount = blockNum;
        FXSYS_memset32(m_BusyMap, 0, (blockNum + 7) / 8);
    }
    FX_BOOL		HasFreeBlock() const
    {
        return (FX_BOOL)m_nAvailCount;
    }
    FX_LPVOID	Alloc(size_t size)
    {
        FXSYS_assert(m_nAvailCount);
        FX_LPDWORD pFind = (FX_LPDWORD)m_BusyMap;
        size_t i = 0;
        while (i < (blockNum + 7) / 8 / 4 && pFind[i] == 0xFFFFFFFF) {
            i ++;
        }
        i *= 4;
        while (m_BusyMap[i] == 0xFF) {
            i ++;
        }
        size_t pos = ZeroLeadPos[m_BusyMap[i]];
        m_BusyMap[i] |= 1 << (7 - pos);
        m_nAvailCount --;
        return (FX_LPBYTE)(this + 1) + (i * 8 + pos) * blockSize;
    }
    void		Free(FX_LPVOID p)
    {
        FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)((FX_LPBYTE)this + FX_FIXEDMEM_PAGESIZE));
        size_t pos = ((FX_LPBYTE)p - (FX_LPBYTE)(this + 1)) / blockSize;
        m_BusyMap[pos / 8] &= ~(1 << (7 - (pos % 8)));
        m_nAvailCount ++;
    }
    volatile size_t	m_nAvailCount;
    FX_BYTE			m_BusyMap[(blockNum + 7) / 8];
};
typedef CFXMEM_FixedPage<FIXEDMEM_8BYTES_BLOCKNUM, 8>	CFXMEM_8BytesPage;
typedef CFXMEM_FixedPage<FIXEDMEM_16BYTES_BLOCKNUM, 16>	CFXMEM_16BytesPage;
typedef CFXMEM_FixedPage<FIXEDMEM_32BYTES_BLOCKNUM, 32>	CFXMEM_32BytesPage;
template <size_t blockNum, size_t blockSize>
class CFXMEM_FixedPages
{
public:
    typedef CFXMEM_FixedPage<blockNum, blockSize> T;
    FX_LPBYTE		m_pStartPage;
    FX_LPBYTE		m_pLimitPos;
    FX_LPBYTE		m_pCurPage;
    volatile size_t	m_nAvailBlocks;
    void		Initialize(FX_LPBYTE pStart, size_t pages)
    {
        m_pStartPage = m_pCurPage = pStart;
        m_nAvailBlocks = pages * blockNum;
        for (size_t n = 0; n < pages; n ++) {
            ((T*)pStart)->Initialize();
            pStart += FX_FIXEDMEM_PAGESIZE;
        }
        m_pLimitPos = pStart;
    }
    FX_BOOL		IsEmpty() const
    {
        return m_nAvailBlocks == (m_pLimitPos - m_pStartPage) / FX_FIXEDMEM_PAGESIZE * blockNum;
    }
    FX_BOOL		HasFreeBlock() const
    {
        return (FX_BOOL)m_nAvailBlocks;
    }
    FX_LPVOID	Alloc(size_t size)
    {
        FXSYS_assert(m_nAvailBlocks);
        do {
            if (((T*)m_pCurPage)->HasFreeBlock()) {
                m_nAvailBlocks --;
                return ((T*)m_pCurPage)->Alloc(size);
            }
            m_pCurPage += FX_FIXEDMEM_PAGESIZE;
            if (m_pCurPage == m_pLimitPos) {
                m_pCurPage = m_pStartPage;
            }
        } while (TRUE);
        return NULL;
    }
    void		Free(FX_LPVOID p)
    {
        FXSYS_assert(p > (FX_LPVOID)m_pStartPage && p < (FX_LPVOID)m_pLimitPos);
        ((T*)(m_pStartPage + ((FX_LPBYTE)p - m_pStartPage) / FX_FIXEDMEM_PAGESIZE * FX_FIXEDMEM_PAGESIZE))->Free(p);
        m_nAvailBlocks ++;
    }
};
typedef CFXMEM_FixedPages<FIXEDMEM_8BYTES_BLOCKNUM, 8>		CFXMEM_8BytesPages;
typedef CFXMEM_FixedPages<FIXEDMEM_16BYTES_BLOCKNUM, 16>	CFXMEM_16BytesPages;
typedef CFXMEM_FixedPages<FIXEDMEM_32BYTES_BLOCKNUM, 32>	CFXMEM_32BytesPages;
class CFXMEM_Block
{
public:
    size_t			m_nBlockSize;
    CFXMEM_Block*	m_pNextBlock;
};
class CFXMEM_Page
{
public:
    size_t			m_nAvailSize;
    CFXMEM_Block*	m_pLimitPos;
    CFXMEM_Block	m_AvailHead;
    void		Initialize(size_t size);
    FX_BOOL		IsEmpty() const
    {
        return m_AvailHead.m_pNextBlock && m_AvailHead.m_nBlockSize == m_AvailHead.m_pNextBlock->m_nBlockSize;
    }
    FX_LPVOID	Alloc(size_t size);
    FX_LPVOID	Realloc(FX_LPVOID p, size_t oldSize, size_t newSize);
    void		Free(FX_LPVOID p);
protected:
    FX_LPVOID	Alloc(CFXMEM_Block* pPrevBlock, CFXMEM_Block* pNextBlock, size_t size, size_t oldsize);
};
class CFXMEM_Pages
{
public:
    CFXMEM_Page*	m_pStartPage;
    CFXMEM_Page*	m_pLimitPos;
    CFXMEM_Page*	m_pCurPage;
    size_t			m_nPageSize;
    void		Initialize(FX_LPBYTE pStart, size_t pageSize, size_t pages);
    FX_BOOL		IsEmpty() const;
    FX_LPVOID	Alloc(size_t size);
    FX_LPVOID	Realloc(FX_LPVOID p, size_t oldSize, size_t newSize);
    void		Free(FX_LPVOID p);
};
class CFXMEM_Pool
{
public:
    CFXMEM_Pool*			m_pPrevPool;
    CFXMEM_Pool*			m_pNextPool;
    CFXMEM_8BytesPages		m_8BytesPages;
    CFXMEM_16BytesPages		m_16BytesPages;
    CFXMEM_32BytesPages		m_32BytesPages;
    CFXMEM_Pages			m_MidPages;
    FX_BOOL					m_bAlone;
    FX_DWORD				m_dwReserved[3];
    FX_LPVOID				m_pLimitPos;
    CFXMEM_Page*			m_pLargePage;
    void		Initialize(const FX_MEMCONFIG* pMemConfig, size_t size, size_t pageNum8Bytes, size_t pageNum16Bytes, size_t pageNum32Bytes, size_t pageNumMid);
    FX_BOOL		IsEmpty() const;
    size_t		GetSize(FX_LPVOID p) const;
    FX_LPVOID	Realloc(FX_LPVOID p, size_t oldSize, size_t newSize);
    void		Free(FX_LPVOID p);
};
class CFXMEM_FixedMgr
{
public:
    void			Initialize(size_t size);
    FX_LPVOID		Alloc(size_t size);
    FX_LPVOID		Realloc(FX_LPVOID p, size_t newSize);
    void			Free(FX_LPVOID p);
    void			FreeAll();
    void			Purge();
    CFXMEM_Pool*	GetFirstPool()
    {
        return &m_FirstPool;
    }
    size_t			GetSize(FX_LPVOID p) const;
    FXMEM_SystemMgr		m_SystemMgr;
    FXMEM_SystemMgr2*	m_pExtender;
    FX_LPVOID			m_pReserved;
    FX_MEMCONFIG		m_MemConfig;
protected:
    FX_LPVOID		Alloc16(CFXMEM_Pool **pp32Pool = NULL, size_t size = 0);
    FX_LPVOID		Alloc32(size_t size);
    FX_LPVOID		AllocSmall(size_t size);
    FX_LPVOID		AllocMid(size_t size);
    FX_LPVOID		AllocLarge(size_t size);
    FX_LPVOID		ReallocSmall(CFXMEM_Pool* pPool, FX_LPVOID p, size_t oldSize, size_t newSize);
    void			FreePool(CFXMEM_Pool* pPool);
    CFXMEM_Pool		m_FirstPool;
};
#define FIXEDMEM_PROXYSIZE_0	(1024 * 1024 * 8)
#define FIXEDMEM_PROXYSIZE_1	(1024 * 1024 * 16)
#define FIXEDMEM_PROXYSIZE_2	(1024 * 1024 * 32)
#define FIXEDMEM_PROXYSIZE_3	(1024 * 1024 * 64)
#define FIXEDMEM_PROXYSIZE_4	(1024 * 1024 * 128)
#define FIXEDMEM_PROXYSIZE_5	(1024 * 1024 * 256)
const FX_MEMCONFIG*	FixedMgr_GetConfig(size_t nSize);
class CFixedMgr_Proxy
{
public:
    FXMEM_FoxitMgr*	Initialize(FX_LPVOID pBuffer, size_t nSize, FX_BOOL bExtensible);
    static FX_BOOL	Common_More(FXMEM_SystemMgr2* pMgr, size_t alloc_size, void** new_memory, size_t* new_size);
    static void		Common_Free(FXMEM_SystemMgr2* pMgr, void* memory);
    FXMEM_SystemMgr2	m_SystemMgr;
    CFXMEM_Page*		m_pFixedPage;
    FX_LPVOID			m_pBuffer;
    size_t				m_nSize;
    FX_BOOL				m_bExtensible;
};
#endif