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 "xfa/fgas/crt/fgas_memory.h" | 7 #include "xfa/fgas/crt/fgas_memory.h" |
8 | 8 |
dsinclair
2016/05/03 20:43:52
I gather we shouldn't roll into chromium with this
Tom Sepez
2016/05/03 20:59:31
It only affects XFA, and we might just want to avo
| |
9 #define MEMORY_TOOL_REPLACES_ALLOCATOR // Temporary, for CF testing. | |
10 | |
9 #include <algorithm> | 11 #include <algorithm> |
10 | 12 |
13 #ifdef MEMORY_TOOL_REPLACES_ALLOCATOR | |
14 | |
11 namespace { | 15 namespace { |
12 | 16 |
13 class CFX_DefStore : public IFX_MEMAllocator, public CFX_Target { | 17 class CFX_DefStore : public IFX_MemoryAllocator, public CFX_Target { |
14 public: | 18 public: |
15 CFX_DefStore() {} | 19 CFX_DefStore() {} |
16 ~CFX_DefStore() {} | 20 ~CFX_DefStore() {} |
17 virtual void Release() { delete this; } | 21 virtual void Release() { delete this; } |
18 virtual void* Alloc(size_t size) { return FX_Alloc(uint8_t, size); } | 22 virtual void* Alloc(size_t size) { return FX_Alloc(uint8_t, size); } |
19 virtual void Free(void* pBlock) { FX_Free(pBlock); } | 23 virtual void Free(void* pBlock) { FX_Free(pBlock); } |
20 virtual size_t GetBlockSize() const { return 0; } | 24 virtual size_t GetBlockSize() const { return 0; } |
21 virtual size_t GetDefChunkSize() const { return 0; } | 25 virtual size_t GetDefChunkSize() const { return 0; } |
22 virtual size_t SetDefChunkSize(size_t size) { return 0; } | 26 virtual size_t SetDefChunkSize(size_t size) { return 0; } |
23 virtual size_t GetCurrentDataSize() const { return 0; } | 27 virtual size_t GetCurrentDataSize() const { return 0; } |
24 }; | 28 }; |
25 | 29 |
26 #if _FX_OS_ != _FX_ANDROID_ | 30 } // namespace |
27 #pragma pack(push, 1) | 31 |
28 #endif | 32 IFX_MemoryAllocator* IFX_MemoryAllocator::Create(FX_ALLOCTYPE eType, |
33 size_t chunkSize, | |
34 size_t blockSize) { | |
35 return new CFX_DefStore(); | |
36 } | |
37 | |
38 #else // MEMORY_TOOL_REPLACES_ALLOCATOR | |
39 | |
40 namespace { | |
41 | |
29 struct FX_STATICSTORECHUNK { | 42 struct FX_STATICSTORECHUNK { |
30 FX_STATICSTORECHUNK* pNextChunk; | 43 FX_STATICSTORECHUNK* pNextChunk; |
31 size_t iChunkSize; | 44 size_t iChunkSize; |
32 size_t iFreeSize; | 45 size_t iFreeSize; |
33 }; | 46 }; |
34 #if _FX_OS_ != _FX_ANDROID_ | |
35 #pragma pack(pop) | |
36 #endif | |
37 | 47 |
38 class CFX_StaticStore : public IFX_MEMAllocator, public CFX_Target { | 48 class CFX_StaticStore : public IFX_MemoryAllocator, public CFX_Target { |
39 public: | 49 public: |
40 CFX_StaticStore(size_t iDefChunkSize = 4096); | 50 CFX_StaticStore(size_t iDefChunkSize = 4096); |
41 ~CFX_StaticStore(); | 51 ~CFX_StaticStore(); |
42 virtual void Release() { delete this; } | 52 virtual void Release() { delete this; } |
43 virtual void* Alloc(size_t size); | 53 virtual void* Alloc(size_t size); |
44 virtual void Free(void* pBlock) {} | 54 virtual void Free(void* pBlock) {} |
45 virtual size_t GetBlockSize() const { return 0; } | 55 virtual size_t GetBlockSize() const { return 0; } |
46 virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; } | 56 virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; } |
47 virtual size_t SetDefChunkSize(size_t size); | 57 virtual size_t SetDefChunkSize(size_t size); |
48 virtual size_t GetCurrentDataSize() const { return m_iAllocatedSize; } | 58 virtual size_t GetCurrentDataSize() const { return m_iAllocatedSize; } |
49 | 59 |
50 protected: | 60 protected: |
51 size_t m_iAllocatedSize; | 61 size_t m_iAllocatedSize; |
52 size_t m_iDefChunkSize; | 62 size_t m_iDefChunkSize; |
53 FX_STATICSTORECHUNK* m_pChunk; | 63 FX_STATICSTORECHUNK* m_pChunk; |
54 FX_STATICSTORECHUNK* m_pLastChunk; | 64 FX_STATICSTORECHUNK* m_pLastChunk; |
55 FX_STATICSTORECHUNK* AllocChunk(size_t size); | 65 FX_STATICSTORECHUNK* AllocChunk(size_t size); |
56 FX_STATICSTORECHUNK* FindChunk(size_t size); | 66 FX_STATICSTORECHUNK* FindChunk(size_t size); |
57 }; | 67 }; |
58 | 68 |
59 #if _FX_OS_ != _FX_ANDROID_ | |
60 #pragma pack(push, 1) | |
61 #endif | |
62 struct FX_FIXEDSTORECHUNK { | 69 struct FX_FIXEDSTORECHUNK { |
63 uint8_t* FirstFlag() { return reinterpret_cast<uint8_t*>(this + 1); } | 70 uint8_t* FirstFlag() { return reinterpret_cast<uint8_t*>(this + 1); } |
64 uint8_t* FirstBlock() { return FirstFlag() + iChunkSize; } | 71 uint8_t* FirstBlock() { return FirstFlag() + iChunkSize; } |
65 | 72 |
66 FX_FIXEDSTORECHUNK* pNextChunk; | 73 FX_FIXEDSTORECHUNK* pNextChunk; |
67 size_t iChunkSize; | 74 size_t iChunkSize; |
68 size_t iFreeNum; | 75 size_t iFreeNum; |
69 }; | 76 }; |
70 #if _FX_OS_ != _FX_ANDROID_ | |
71 #pragma pack(pop) | |
72 #endif | |
73 | 77 |
74 class CFX_FixedStore : public IFX_MEMAllocator, public CFX_Target { | 78 class CFX_FixedStore : public IFX_MemoryAllocator, public CFX_Target { |
75 public: | 79 public: |
76 CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk); | 80 CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk); |
77 virtual ~CFX_FixedStore(); | 81 virtual ~CFX_FixedStore(); |
78 virtual void Release() { delete this; } | 82 virtual void Release() { delete this; } |
79 virtual void* Alloc(size_t size); | 83 virtual void* Alloc(size_t size); |
80 virtual void Free(void* pBlock); | 84 virtual void Free(void* pBlock); |
81 virtual size_t GetBlockSize() const { return m_iBlockSize; } | 85 virtual size_t GetBlockSize() const { return m_iBlockSize; } |
82 virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; } | 86 virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; } |
83 virtual size_t SetDefChunkSize(size_t iChunkSize); | 87 virtual size_t SetDefChunkSize(size_t iChunkSize); |
84 virtual size_t GetCurrentDataSize() const { return 0; } | 88 virtual size_t GetCurrentDataSize() const { return 0; } |
85 | 89 |
86 protected: | 90 protected: |
87 FX_FIXEDSTORECHUNK* AllocChunk(); | 91 FX_FIXEDSTORECHUNK* AllocChunk(); |
88 | 92 |
89 size_t m_iBlockSize; | 93 size_t m_iBlockSize; |
90 size_t m_iDefChunkSize; | 94 size_t m_iDefChunkSize; |
91 FX_FIXEDSTORECHUNK* m_pChunk; | 95 FX_FIXEDSTORECHUNK* m_pChunk; |
92 }; | 96 }; |
93 | 97 |
94 #if _FX_OS_ != _FX_ANDROID_ | |
95 #pragma pack(push, 1) | |
96 #endif | |
97 struct FX_DYNAMICSTOREBLOCK { | |
98 uint8_t* Data() { return reinterpret_cast<uint8_t*>(this + 1); } | |
99 FX_DYNAMICSTOREBLOCK* NextBlock() { | |
100 return reinterpret_cast<FX_DYNAMICSTOREBLOCK*>(Data() + iBlockSize); | |
101 } | |
102 size_t iBlockSize; | |
103 FX_BOOL bUsed; | |
104 }; | |
105 | |
106 struct FX_DYNAMICSTORECHUNK { | |
107 FX_DYNAMICSTOREBLOCK* FirstBlock() { | |
108 return reinterpret_cast<FX_DYNAMICSTOREBLOCK*>(this + 1); | |
109 } | |
110 FX_DYNAMICSTORECHUNK* pNextChunk; | |
111 size_t iChunkSize; | |
112 size_t iFreeSize; | |
113 }; | |
114 #if _FX_OS_ != _FX_ANDROID_ | |
115 #pragma pack(pop) | |
116 #endif | |
117 | |
118 class CFX_DynamicStore : public IFX_MEMAllocator, public CFX_Target { | |
119 public: | |
120 CFX_DynamicStore(size_t iDefChunkSize = 4096); | |
121 virtual ~CFX_DynamicStore(); | |
122 virtual void Release() { delete this; } | |
123 virtual void* Alloc(size_t size); | |
124 virtual void Free(void* pBlock); | |
125 virtual size_t GetBlockSize() const { return 0; } | |
126 virtual size_t GetDefChunkSize() const { return m_iDefChunkSize; } | |
127 virtual size_t SetDefChunkSize(size_t size); | |
128 virtual size_t GetCurrentDataSize() const { return 0; } | |
129 | |
130 protected: | |
131 FX_DYNAMICSTORECHUNK* AllocChunk(size_t size); | |
132 | |
133 size_t m_iDefChunkSize; | |
134 FX_DYNAMICSTORECHUNK* m_pChunk; | |
135 }; | |
136 | |
137 } // namespace | 98 } // namespace |
138 | 99 |
139 #define FX_4BYTEALIGN(size) (((size) + 3) / 4 * 4) | 100 #define FX_4BYTEALIGN(size) (((size) + 3) & ~3) |
140 | 101 |
141 IFX_MEMAllocator* FX_CreateAllocator(FX_ALLOCTYPE eType, | 102 IFX_MemoryAllocator* IFX_MemoryAllocator::Create(FX_ALLOCTYPE eType, |
142 size_t chunkSize, | 103 size_t chunkSize, |
143 size_t blockSize) { | 104 size_t blockSize) { |
144 switch (eType) { | 105 switch (eType) { |
145 case FX_ALLOCTYPE_Dynamic: | |
146 return new CFX_DynamicStore(chunkSize); | |
147 case FX_ALLOCTYPE_Default: | |
148 return new CFX_DefStore(); | |
149 case FX_ALLOCTYPE_Static: | 106 case FX_ALLOCTYPE_Static: |
150 return new CFX_StaticStore(chunkSize); | 107 return new CFX_StaticStore(chunkSize); |
151 case FX_ALLOCTYPE_Fixed: | 108 case FX_ALLOCTYPE_Fixed: |
152 return new CFX_FixedStore(blockSize, chunkSize); | 109 return new CFX_FixedStore(blockSize, chunkSize); |
153 default: | 110 default: |
154 return NULL; | 111 ASSERT(0); |
112 return nullptr; | |
155 } | 113 } |
156 } | 114 } |
115 | |
157 CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize) | 116 CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize) |
158 : m_iAllocatedSize(0), | 117 : m_iAllocatedSize(0), |
159 m_iDefChunkSize(iDefChunkSize), | 118 m_iDefChunkSize(iDefChunkSize), |
160 m_pChunk(NULL), | 119 m_pChunk(nullptr), |
161 m_pLastChunk(NULL) { | 120 m_pLastChunk(nullptr) { |
162 ASSERT(m_iDefChunkSize != 0); | 121 ASSERT(m_iDefChunkSize != 0); |
163 } | 122 } |
164 CFX_StaticStore::~CFX_StaticStore() { | 123 CFX_StaticStore::~CFX_StaticStore() { |
165 FX_STATICSTORECHUNK* pChunk = m_pChunk; | 124 FX_STATICSTORECHUNK* pChunk = m_pChunk; |
166 while (pChunk) { | 125 while (pChunk) { |
167 FX_STATICSTORECHUNK* pNext = pChunk->pNextChunk; | 126 FX_STATICSTORECHUNK* pNext = pChunk->pNextChunk; |
168 FX_Free(pChunk); | 127 FX_Free(pChunk); |
169 pChunk = pNext; | 128 pChunk = pNext; |
170 } | 129 } |
171 } | 130 } |
172 FX_STATICSTORECHUNK* CFX_StaticStore::AllocChunk(size_t size) { | 131 FX_STATICSTORECHUNK* CFX_StaticStore::AllocChunk(size_t size) { |
173 ASSERT(size != 0); | 132 ASSERT(size != 0); |
174 FX_STATICSTORECHUNK* pChunk = (FX_STATICSTORECHUNK*)FX_Alloc( | 133 FX_STATICSTORECHUNK* pChunk = (FX_STATICSTORECHUNK*)FX_Alloc( |
175 uint8_t, sizeof(FX_STATICSTORECHUNK) + size); | 134 uint8_t, sizeof(FX_STATICSTORECHUNK) + size); |
176 pChunk->iChunkSize = size; | 135 pChunk->iChunkSize = size; |
177 pChunk->iFreeSize = size; | 136 pChunk->iFreeSize = size; |
178 pChunk->pNextChunk = NULL; | 137 pChunk->pNextChunk = nullptr; |
179 if (m_pLastChunk == NULL) { | 138 if (m_pLastChunk == nullptr) { |
dsinclair
2016/05/03 20:43:52
if (!m_pLastChunk)
Tom Sepez
2016/05/03 20:59:30
Done.
| |
180 m_pChunk = pChunk; | 139 m_pChunk = pChunk; |
181 } else { | 140 } else { |
182 m_pLastChunk->pNextChunk = pChunk; | 141 m_pLastChunk->pNextChunk = pChunk; |
183 } | 142 } |
184 m_pLastChunk = pChunk; | 143 m_pLastChunk = pChunk; |
185 return pChunk; | 144 return pChunk; |
186 } | 145 } |
187 FX_STATICSTORECHUNK* CFX_StaticStore::FindChunk(size_t size) { | 146 FX_STATICSTORECHUNK* CFX_StaticStore::FindChunk(size_t size) { |
188 ASSERT(size != 0); | 147 ASSERT(size != 0); |
189 if (m_pLastChunk == NULL || m_pLastChunk->iFreeSize < size) { | 148 if (m_pLastChunk == nullptr || m_pLastChunk->iFreeSize < size) { |
dsinclair
2016/05/03 20:43:52
if (!m_pLastChunk
Tom Sepez
2016/05/03 20:59:30
Done.
| |
190 return AllocChunk(std::max(m_iDefChunkSize, size)); | 149 return AllocChunk(std::max(m_iDefChunkSize, size)); |
191 } | 150 } |
192 return m_pLastChunk; | 151 return m_pLastChunk; |
193 } | 152 } |
194 void* CFX_StaticStore::Alloc(size_t size) { | 153 void* CFX_StaticStore::Alloc(size_t size) { |
195 size = FX_4BYTEALIGN(size); | 154 size = FX_4BYTEALIGN(size); |
196 ASSERT(size != 0); | 155 ASSERT(size != 0); |
197 FX_STATICSTORECHUNK* pChunk = FindChunk(size); | 156 FX_STATICSTORECHUNK* pChunk = FindChunk(size); |
198 ASSERT(pChunk->iFreeSize >= size); | 157 ASSERT(pChunk->iFreeSize >= size); |
199 uint8_t* p = (uint8_t*)pChunk; | 158 uint8_t* p = (uint8_t*)pChunk; |
200 p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize; | 159 p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize; |
201 pChunk->iFreeSize -= size; | 160 pChunk->iFreeSize -= size; |
202 m_iAllocatedSize += size; | 161 m_iAllocatedSize += size; |
203 return p; | 162 return p; |
204 } | 163 } |
205 size_t CFX_StaticStore::SetDefChunkSize(size_t size) { | 164 size_t CFX_StaticStore::SetDefChunkSize(size_t size) { |
206 ASSERT(size != 0); | 165 ASSERT(size != 0); |
207 size_t v = m_iDefChunkSize; | 166 size_t v = m_iDefChunkSize; |
208 m_iDefChunkSize = size; | 167 m_iDefChunkSize = size; |
209 return v; | 168 return v; |
210 } | 169 } |
211 CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk) | 170 CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk) |
212 : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)), | 171 : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)), |
213 m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)), | 172 m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)), |
214 m_pChunk(NULL) { | 173 m_pChunk(nullptr) { |
215 ASSERT(m_iBlockSize != 0 && m_iDefChunkSize != 0); | 174 ASSERT(m_iBlockSize != 0 && m_iDefChunkSize != 0); |
216 } | 175 } |
217 CFX_FixedStore::~CFX_FixedStore() { | 176 CFX_FixedStore::~CFX_FixedStore() { |
218 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; | 177 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; |
219 while (pChunk) { | 178 while (pChunk) { |
220 FX_FIXEDSTORECHUNK* pNext = pChunk->pNextChunk; | 179 FX_FIXEDSTORECHUNK* pNext = pChunk->pNextChunk; |
221 FX_Free(pChunk); | 180 FX_Free(pChunk); |
222 pChunk = pNext; | 181 pChunk = pNext; |
223 } | 182 } |
224 } | 183 } |
225 FX_FIXEDSTORECHUNK* CFX_FixedStore::AllocChunk() { | 184 FX_FIXEDSTORECHUNK* CFX_FixedStore::AllocChunk() { |
226 int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize + | 185 int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize + |
227 m_iBlockSize * m_iDefChunkSize; | 186 m_iBlockSize * m_iDefChunkSize; |
228 FX_FIXEDSTORECHUNK* pChunk = | 187 FX_FIXEDSTORECHUNK* pChunk = |
229 (FX_FIXEDSTORECHUNK*)FX_Alloc(uint8_t, iTotalSize); | 188 (FX_FIXEDSTORECHUNK*)FX_Alloc(uint8_t, iTotalSize); |
230 if (pChunk == NULL) { | 189 if (pChunk == nullptr) { |
dsinclair
2016/05/03 20:43:51
if (!pChunk)
Tom Sepez
2016/05/03 20:59:31
Done.
| |
231 return NULL; | 190 return nullptr; |
232 } | 191 } |
233 FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize); | 192 FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize); |
234 pChunk->pNextChunk = m_pChunk; | 193 pChunk->pNextChunk = m_pChunk; |
235 pChunk->iChunkSize = m_iDefChunkSize; | 194 pChunk->iChunkSize = m_iDefChunkSize; |
236 pChunk->iFreeNum = m_iDefChunkSize; | 195 pChunk->iFreeNum = m_iDefChunkSize; |
237 m_pChunk = pChunk; | 196 m_pChunk = pChunk; |
238 return pChunk; | 197 return pChunk; |
239 } | 198 } |
240 void* CFX_FixedStore::Alloc(size_t size) { | 199 void* CFX_FixedStore::Alloc(size_t size) { |
241 if (size > m_iBlockSize) { | 200 if (size > m_iBlockSize) { |
242 return NULL; | 201 return nullptr; |
243 } | 202 } |
244 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; | 203 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; |
245 while (pChunk != NULL) { | 204 while (pChunk != nullptr) { |
dsinclair
2016/05/03 20:43:52
while (pChunk)
Tom Sepez
2016/05/03 20:59:31
Done.
| |
246 if (pChunk->iFreeNum > 0) { | 205 if (pChunk->iFreeNum > 0) { |
247 break; | 206 break; |
248 } | 207 } |
249 pChunk = pChunk->pNextChunk; | 208 pChunk = pChunk->pNextChunk; |
250 } | 209 } |
251 if (pChunk == NULL) { | 210 if (pChunk == nullptr) { |
dsinclair
2016/05/03 20:43:52
if (!pChunk)
Tom Sepez
2016/05/03 20:59:31
Done.
| |
252 pChunk = AllocChunk(); | 211 pChunk = AllocChunk(); |
253 } | 212 } |
254 ASSERT(pChunk != NULL); | 213 ASSERT(pChunk != nullptr); |
dsinclair
2016/05/03 20:43:52
ASSERT(pChunk)
Tom Sepez
2016/05/03 20:59:30
Pointless, removed.
| |
255 uint8_t* pFlags = pChunk->FirstFlag(); | 214 uint8_t* pFlags = pChunk->FirstFlag(); |
256 size_t i = 0; | 215 size_t i = 0; |
257 for (; i < pChunk->iChunkSize; i++) | 216 for (; i < pChunk->iChunkSize; i++) |
258 if (pFlags[i] == 0) { | 217 if (pFlags[i] == 0) { |
259 break; | 218 break; |
260 } | 219 } |
261 ASSERT(i < pChunk->iChunkSize); | 220 ASSERT(i < pChunk->iChunkSize); |
262 pFlags[i] = 1; | 221 pFlags[i] = 1; |
263 pChunk->iFreeNum--; | 222 pChunk->iFreeNum--; |
264 return pChunk->FirstBlock() + i * m_iBlockSize; | 223 return pChunk->FirstBlock() + i * m_iBlockSize; |
265 } | 224 } |
266 void CFX_FixedStore::Free(void* pBlock) { | 225 void CFX_FixedStore::Free(void* pBlock) { |
267 ASSERT(pBlock != NULL); | 226 ASSERT(pBlock != nullptr); |
dsinclair
2016/05/03 20:43:52
ASSERT(pBlock)
Tom Sepez
2016/05/03 20:59:30
removed.
| |
268 FX_FIXEDSTORECHUNK* pPrior = NULL; | 227 FX_FIXEDSTORECHUNK* pPrior = nullptr; |
269 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; | 228 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; |
270 uint8_t* pStart = NULL; | 229 uint8_t* pStart = nullptr; |
271 uint8_t* pEnd; | 230 uint8_t* pEnd; |
272 while (pChunk != NULL) { | 231 while (pChunk != nullptr) { |
dsinclair
2016/05/03 20:43:52
while (pChunk)
Tom Sepez
2016/05/03 20:59:30
Done.
| |
273 pStart = pChunk->FirstBlock(); | 232 pStart = pChunk->FirstBlock(); |
274 if (pBlock >= pStart) { | 233 if (pBlock >= pStart) { |
275 pEnd = pStart + m_iBlockSize * pChunk->iChunkSize; | 234 pEnd = pStart + m_iBlockSize * pChunk->iChunkSize; |
276 if (pBlock < pEnd) { | 235 if (pBlock < pEnd) { |
277 break; | 236 break; |
278 } | 237 } |
279 } | 238 } |
280 pPrior = pChunk, pChunk = pChunk->pNextChunk; | 239 pPrior = pChunk, pChunk = pChunk->pNextChunk; |
281 } | 240 } |
282 ASSERT(pChunk != NULL); | 241 ASSERT(pChunk != nullptr); |
dsinclair
2016/05/03 20:43:51
ASSERT(pChunk)
Tom Sepez
2016/05/03 20:59:30
Done.
| |
283 size_t iPos = ((uint8_t*)pBlock - pStart) / m_iBlockSize; | 242 size_t iPos = ((uint8_t*)pBlock - pStart) / m_iBlockSize; |
284 ASSERT(iPos < pChunk->iChunkSize); | 243 ASSERT(iPos < pChunk->iChunkSize); |
285 uint8_t* pFlags = pChunk->FirstFlag(); | 244 uint8_t* pFlags = pChunk->FirstFlag(); |
286 if (pFlags[iPos] == 0) { | 245 if (pFlags[iPos] == 0) { |
287 return; | 246 return; |
288 } | 247 } |
289 pFlags[iPos] = 0; | 248 pFlags[iPos] = 0; |
290 pChunk->iFreeNum++; | 249 pChunk->iFreeNum++; |
291 if (pChunk->iFreeNum == pChunk->iChunkSize) { | 250 if (pChunk->iFreeNum == pChunk->iChunkSize) { |
292 if (pPrior == NULL) { | 251 if (pPrior == nullptr) { |
dsinclair
2016/05/03 20:43:52
if (!pPrior)
Tom Sepez
2016/05/03 20:59:30
Done.
| |
293 m_pChunk = pChunk->pNextChunk; | 252 m_pChunk = pChunk->pNextChunk; |
294 } else { | 253 } else { |
295 pPrior->pNextChunk = pChunk->pNextChunk; | 254 pPrior->pNextChunk = pChunk->pNextChunk; |
296 } | 255 } |
297 FX_Free(pChunk); | 256 FX_Free(pChunk); |
298 } | 257 } |
299 } | 258 } |
300 size_t CFX_FixedStore::SetDefChunkSize(size_t iChunkSize) { | 259 size_t CFX_FixedStore::SetDefChunkSize(size_t iChunkSize) { |
301 ASSERT(iChunkSize != 0); | 260 ASSERT(iChunkSize != 0); |
302 size_t v = m_iDefChunkSize; | 261 size_t v = m_iDefChunkSize; |
303 m_iDefChunkSize = FX_4BYTEALIGN(iChunkSize); | 262 m_iDefChunkSize = FX_4BYTEALIGN(iChunkSize); |
304 return v; | 263 return v; |
305 } | 264 } |
306 CFX_DynamicStore::CFX_DynamicStore(size_t iDefChunkSize) | 265 |
307 : m_iDefChunkSize(iDefChunkSize), m_pChunk(NULL) { | 266 #endif // MEMORY_TOOL_REPLACES_ALLOCATOR |
308 ASSERT(m_iDefChunkSize != 0); | |
309 } | |
310 CFX_DynamicStore::~CFX_DynamicStore() { | |
311 FX_DYNAMICSTORECHUNK* pChunk = m_pChunk; | |
312 while (pChunk) { | |
313 FX_DYNAMICSTORECHUNK* pNext = pChunk->pNextChunk; | |
314 FX_Free(pChunk); | |
315 pChunk = pNext; | |
316 } | |
317 } | |
318 FX_DYNAMICSTORECHUNK* CFX_DynamicStore::AllocChunk(size_t size) { | |
319 ASSERT(size != 0); | |
320 FX_DYNAMICSTORECHUNK* pChunk = (FX_DYNAMICSTORECHUNK*)FX_Alloc( | |
321 uint8_t, | |
322 sizeof(FX_DYNAMICSTORECHUNK) + sizeof(FX_DYNAMICSTOREBLOCK) * 2 + size); | |
323 if (pChunk == NULL) { | |
324 return NULL; | |
325 } | |
326 pChunk->iChunkSize = size; | |
327 pChunk->iFreeSize = size; | |
328 FX_DYNAMICSTOREBLOCK* pBlock = pChunk->FirstBlock(); | |
329 pBlock->iBlockSize = size; | |
330 pBlock->bUsed = FALSE; | |
331 pBlock = pBlock->NextBlock(); | |
332 pBlock->iBlockSize = 0; | |
333 pBlock->bUsed = TRUE; | |
334 if (m_pChunk != NULL && size >= m_iDefChunkSize) { | |
335 FX_DYNAMICSTORECHUNK* pLast = m_pChunk; | |
336 while (pLast->pNextChunk != NULL) { | |
337 pLast = pLast->pNextChunk; | |
338 } | |
339 pLast->pNextChunk = pChunk; | |
340 pChunk->pNextChunk = NULL; | |
341 } else { | |
342 pChunk->pNextChunk = m_pChunk; | |
343 m_pChunk = pChunk; | |
344 } | |
345 return pChunk; | |
346 } | |
347 void* CFX_DynamicStore::Alloc(size_t size) { | |
348 size = FX_4BYTEALIGN(size); | |
349 ASSERT(size != 0); | |
350 FX_DYNAMICSTORECHUNK* pChunk = m_pChunk; | |
351 FX_DYNAMICSTOREBLOCK* pBlock = NULL; | |
352 while (pChunk != NULL) { | |
353 if (pChunk->iFreeSize >= size) { | |
354 pBlock = pChunk->FirstBlock(); | |
355 FX_BOOL bFind = FALSE; | |
356 while (pBlock->iBlockSize != 0) { | |
357 if (!pBlock->bUsed && pBlock->iBlockSize >= size) { | |
358 bFind = TRUE; | |
359 break; | |
360 } | |
361 pBlock = pBlock->NextBlock(); | |
362 } | |
363 if (bFind) { | |
364 break; | |
365 } | |
366 } | |
367 pChunk = pChunk->pNextChunk; | |
368 } | |
369 if (pChunk == NULL) { | |
370 pChunk = AllocChunk(std::max(m_iDefChunkSize, size)); | |
371 pBlock = pChunk->FirstBlock(); | |
372 } | |
373 ASSERT(pChunk != NULL && pBlock != NULL); | |
374 size_t m = size + sizeof(FX_DYNAMICSTOREBLOCK); | |
375 pBlock->bUsed = TRUE; | |
376 if (pBlock->iBlockSize > m) { | |
377 size_t n = pBlock->iBlockSize; | |
378 pBlock->iBlockSize = size; | |
379 FX_DYNAMICSTOREBLOCK* pNextBlock = pBlock->NextBlock(); | |
380 pNextBlock->bUsed = FALSE; | |
381 pNextBlock->iBlockSize = n - size - sizeof(FX_DYNAMICSTOREBLOCK); | |
382 pChunk->iFreeSize -= size + sizeof(FX_DYNAMICSTOREBLOCK); | |
383 } else { | |
384 pChunk->iFreeSize -= pBlock->iBlockSize; | |
385 } | |
386 return pBlock->Data(); | |
387 } | |
388 void CFX_DynamicStore::Free(void* pBlock) { | |
389 ASSERT(pBlock != NULL); | |
390 FX_DYNAMICSTORECHUNK* pPriorChunk = NULL; | |
391 FX_DYNAMICSTORECHUNK* pChunk = m_pChunk; | |
392 while (pChunk != NULL) { | |
393 if (pBlock > pChunk && | |
394 pBlock <= ((uint8_t*)pChunk + sizeof(FX_DYNAMICSTORECHUNK) + | |
395 pChunk->iChunkSize)) { | |
396 break; | |
397 } | |
398 pPriorChunk = pChunk, pChunk = pChunk->pNextChunk; | |
399 } | |
400 ASSERT(pChunk != NULL); | |
401 FX_DYNAMICSTOREBLOCK* pPriorBlock = NULL; | |
402 FX_DYNAMICSTOREBLOCK* pFindBlock = pChunk->FirstBlock(); | |
403 while (pFindBlock->iBlockSize != 0) { | |
404 if (pBlock == (void*)pFindBlock->Data()) { | |
405 break; | |
406 } | |
407 pPriorBlock = pFindBlock; | |
408 pFindBlock = pFindBlock->NextBlock(); | |
409 } | |
410 ASSERT(pFindBlock->iBlockSize != 0 && pFindBlock->bUsed && | |
411 pBlock == (void*)pFindBlock->Data()); | |
412 pFindBlock->bUsed = FALSE; | |
413 pChunk->iFreeSize += pFindBlock->iBlockSize; | |
414 if (pPriorBlock == NULL) { | |
415 pPriorBlock = pChunk->FirstBlock(); | |
416 } else if (pPriorBlock->bUsed) { | |
417 pPriorBlock = pFindBlock; | |
418 } | |
419 pFindBlock = pPriorBlock; | |
420 size_t sizeFree = 0; | |
421 size_t sizeBlock = 0; | |
422 while (pFindBlock->iBlockSize != 0 && !pFindBlock->bUsed) { | |
423 if (pFindBlock != pPriorBlock) { | |
424 sizeFree += sizeof(FX_DYNAMICSTOREBLOCK); | |
425 sizeBlock += sizeof(FX_DYNAMICSTOREBLOCK); | |
426 } | |
427 sizeBlock += pFindBlock->iBlockSize; | |
428 pFindBlock = pFindBlock->NextBlock(); | |
429 } | |
430 pPriorBlock->iBlockSize = sizeBlock; | |
431 pChunk->iFreeSize += sizeFree; | |
432 if (pChunk->iFreeSize == pChunk->iChunkSize) { | |
433 if (pPriorChunk == NULL) { | |
434 m_pChunk = pChunk->pNextChunk; | |
435 } else { | |
436 pPriorChunk->pNextChunk = pChunk->pNextChunk; | |
437 } | |
438 FX_Free(pChunk); | |
439 } | |
440 } | |
441 size_t CFX_DynamicStore::SetDefChunkSize(size_t size) { | |
442 ASSERT(size != 0); | |
443 size_t v = m_iDefChunkSize; | |
444 m_iDefChunkSize = size; | |
445 return v; | |
446 } | |
OLD | NEW |