Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: xfa/fgas/crt/fgas_memory.cpp

Issue 2328403002: Fix some leaks associated with memory allocator (Closed)
Patch Set: address comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
9 #ifndef MEMORY_TOOL_REPLACES_ALLOCATOR 9 #ifndef MEMORY_TOOL_REPLACES_ALLOCATOR
10 #define MEMORY_TOOL_REPLACES_ALLOCATOR // Temporary, for CF testing. 10 // Use CFX_DefStore to replace CFX_FixedStore to simplify memory
11 // management so that some problems such Use-After-Free can be
12 // detected by Asan or ClusterFuzz tools.
13 #define MEMORY_TOOL_REPLACES_ALLOCATOR
11 #endif 14 #endif
12 15
13 #include <algorithm> 16 #include <algorithm>
14 17
15 #ifdef MEMORY_TOOL_REPLACES_ALLOCATOR
16
17 namespace {
18
19 class CFX_DefStore : public IFX_MemoryAllocator, public CFX_Target {
20 public:
21 CFX_DefStore() {}
22 ~CFX_DefStore() override {}
23
24 void* Alloc(size_t size) override { return FX_Alloc(uint8_t, size); }
25 void Free(void* pBlock) override { FX_Free(pBlock); }
26 };
27
28 } // namespace
29
30 std::unique_ptr<IFX_MemoryAllocator> IFX_MemoryAllocator::Create(
31 FX_ALLOCTYPE eType,
32 size_t chunkSize,
33 size_t blockSize) {
34 return std::unique_ptr<IFX_MemoryAllocator>(new CFX_DefStore());
35 }
36
37 #else // MEMORY_TOOL_REPLACES_ALLOCATOR
38
39 namespace { 18 namespace {
40 19
41 struct FX_STATICSTORECHUNK { 20 struct FX_STATICSTORECHUNK {
42 FX_STATICSTORECHUNK* pNextChunk; 21 FX_STATICSTORECHUNK* pNextChunk;
43 size_t iChunkSize; 22 size_t iChunkSize;
44 size_t iFreeSize; 23 size_t iFreeSize;
45 }; 24 };
46 25
47 class CFX_StaticStore : public IFX_MemoryAllocator, public CFX_Target { 26 class CFX_StaticStore : public IFX_MemoryAllocator, public CFX_Target {
48 public: 27 public:
49 CFX_StaticStore(size_t iDefChunkSize); 28 CFX_StaticStore(size_t iDefChunkSize);
50 ~CFX_StaticStore() override; 29 ~CFX_StaticStore() override;
51 30
52 void* Alloc(size_t size) override; 31 void* Alloc(size_t size) override;
53 void Free(void* pBlock) override {} 32 void Free(void* pBlock) override {}
54 33
55 private: 34 private:
56 size_t m_iAllocatedSize; 35 size_t m_iAllocatedSize;
57 size_t m_iDefChunkSize; 36 size_t m_iDefChunkSize;
58 FX_STATICSTORECHUNK* m_pChunk; 37 FX_STATICSTORECHUNK* m_pChunk;
59 FX_STATICSTORECHUNK* m_pLastChunk; 38 FX_STATICSTORECHUNK* m_pLastChunk;
60 FX_STATICSTORECHUNK* AllocChunk(size_t size); 39 FX_STATICSTORECHUNK* AllocChunk(size_t size);
61 FX_STATICSTORECHUNK* FindChunk(size_t size); 40 FX_STATICSTORECHUNK* FindChunk(size_t size);
62 }; 41 };
63 42
43 #ifdef MEMORY_TOOL_REPLACES_ALLOCATOR
44
45 class CFX_DefStore : public IFX_MemoryAllocator, public CFX_Target {
46 public:
47 CFX_DefStore() {}
48 ~CFX_DefStore() override {}
49
50 void* Alloc(size_t size) override { return FX_Alloc(uint8_t, size); }
51 void Free(void* pBlock) override { FX_Free(pBlock); }
52 };
53
54 #else
55
64 struct FX_FIXEDSTORECHUNK { 56 struct FX_FIXEDSTORECHUNK {
65 uint8_t* FirstFlag() { return reinterpret_cast<uint8_t*>(this + 1); } 57 uint8_t* FirstFlag() { return reinterpret_cast<uint8_t*>(this + 1); }
66 uint8_t* FirstBlock() { return FirstFlag() + iChunkSize; } 58 uint8_t* FirstBlock() { return FirstFlag() + iChunkSize; }
67 59
68 FX_FIXEDSTORECHUNK* pNextChunk; 60 FX_FIXEDSTORECHUNK* pNextChunk;
69 size_t iChunkSize; 61 size_t iChunkSize;
70 size_t iFreeNum; 62 size_t iFreeNum;
71 }; 63 };
72 64
73 class CFX_FixedStore : public IFX_MemoryAllocator, public CFX_Target { 65 class CFX_FixedStore : public IFX_MemoryAllocator, public CFX_Target {
74 public: 66 public:
75 CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk); 67 CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk);
76 ~CFX_FixedStore() override; 68 ~CFX_FixedStore() override;
77 void* Alloc(size_t size) override; 69 void* Alloc(size_t size) override;
78 void Free(void* pBlock) override; 70 void Free(void* pBlock) override;
79 71
80 private: 72 private:
81 FX_FIXEDSTORECHUNK* AllocChunk(); 73 FX_FIXEDSTORECHUNK* AllocChunk();
82 74
83 size_t m_iBlockSize; 75 size_t m_iBlockSize;
84 size_t m_iDefChunkSize; 76 size_t m_iDefChunkSize;
85 FX_FIXEDSTORECHUNK* m_pChunk; 77 FX_FIXEDSTORECHUNK* m_pChunk;
86 }; 78 };
87 79
80 #endif // MEMORY_TOOL_REPLACES_ALLOCATOR
81
88 } // namespace 82 } // namespace
89 83
90 #define FX_4BYTEALIGN(size) (((size) + 3) & ~3) 84 #define FX_4BYTEALIGN(size) (((size) + 3) & ~3)
91 85
92 std::unique_ptr<IFX_MemoryAllocator> IFX_MemoryAllocator::Create( 86 std::unique_ptr<IFX_MemoryAllocator> IFX_MemoryAllocator::Create(
93 FX_ALLOCTYPE eType, 87 FX_ALLOCTYPE eType,
94 size_t chunkSize, 88 size_t chunkSize,
95 size_t blockSize) { 89 size_t blockSize) {
96 switch (eType) { 90 switch (eType) {
97 case FX_ALLOCTYPE_Static: 91 case FX_ALLOCTYPE_Static:
98 return std::unique_ptr<IFX_MemoryAllocator>( 92 return std::unique_ptr<IFX_MemoryAllocator>(
99 new CFX_StaticStore(chunkSize)); 93 new CFX_StaticStore(chunkSize));
100 case FX_ALLOCTYPE_Fixed: 94 case FX_ALLOCTYPE_Fixed:
101 return std::unique_ptr<IFX_MemoryAllocator>(new CFX_FixedStore(blockSize, chunkSize); 95 #ifdef MEMORY_TOOL_REPLACES_ALLOCATOR
96 return std::unique_ptr<IFX_MemoryAllocator>(new CFX_DefStore());
97 #else
98 return std::unique_ptr<IFX_MemoryAllocator>(
99 new CFX_FixedStore(blockSize, chunkSize));
100 #endif // MEMORY_TOOL_REPLACES_ALLOCATOR
102 default: 101 default:
103 ASSERT(0); 102 ASSERT(0);
104 return std::unique_ptr<IFX_MemoryAllocator>(); 103 return std::unique_ptr<IFX_MemoryAllocator>();
105 } 104 }
106 } 105 }
107 106
108 CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize) 107 CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize)
109 : m_iAllocatedSize(0), 108 : m_iAllocatedSize(0),
110 m_iDefChunkSize(iDefChunkSize), 109 m_iDefChunkSize(iDefChunkSize),
111 m_pChunk(nullptr), 110 m_pChunk(nullptr),
112 m_pLastChunk(nullptr) { 111 m_pLastChunk(nullptr) {
113 ASSERT(m_iDefChunkSize != 0); 112 ASSERT(m_iDefChunkSize != 0);
114 } 113 }
114
115 CFX_StaticStore::~CFX_StaticStore() { 115 CFX_StaticStore::~CFX_StaticStore() {
116 FX_STATICSTORECHUNK* pChunk = m_pChunk; 116 FX_STATICSTORECHUNK* pChunk = m_pChunk;
117 while (pChunk) { 117 while (pChunk) {
118 FX_STATICSTORECHUNK* pNext = pChunk->pNextChunk; 118 FX_STATICSTORECHUNK* pNext = pChunk->pNextChunk;
119 FX_Free(pChunk); 119 FX_Free(pChunk);
120 pChunk = pNext; 120 pChunk = pNext;
121 } 121 }
122 } 122 }
123
123 FX_STATICSTORECHUNK* CFX_StaticStore::AllocChunk(size_t size) { 124 FX_STATICSTORECHUNK* CFX_StaticStore::AllocChunk(size_t size) {
124 ASSERT(size != 0); 125 ASSERT(size != 0);
125 FX_STATICSTORECHUNK* pChunk = (FX_STATICSTORECHUNK*)FX_Alloc( 126 FX_STATICSTORECHUNK* pChunk = (FX_STATICSTORECHUNK*)FX_Alloc(
126 uint8_t, sizeof(FX_STATICSTORECHUNK) + size); 127 uint8_t, sizeof(FX_STATICSTORECHUNK) + size);
127 pChunk->iChunkSize = size; 128 pChunk->iChunkSize = size;
128 pChunk->iFreeSize = size; 129 pChunk->iFreeSize = size;
129 pChunk->pNextChunk = nullptr; 130 pChunk->pNextChunk = nullptr;
130 if (!m_pLastChunk) { 131 if (!m_pLastChunk) {
131 m_pChunk = pChunk; 132 m_pChunk = pChunk;
132 } else { 133 } else {
133 m_pLastChunk->pNextChunk = pChunk; 134 m_pLastChunk->pNextChunk = pChunk;
134 } 135 }
135 m_pLastChunk = pChunk; 136 m_pLastChunk = pChunk;
136 return pChunk; 137 return pChunk;
137 } 138 }
139
138 FX_STATICSTORECHUNK* CFX_StaticStore::FindChunk(size_t size) { 140 FX_STATICSTORECHUNK* CFX_StaticStore::FindChunk(size_t size) {
139 ASSERT(size != 0); 141 ASSERT(size != 0);
140 if (!m_pLastChunk || m_pLastChunk->iFreeSize < size) { 142 if (!m_pLastChunk || m_pLastChunk->iFreeSize < size) {
141 return AllocChunk(std::max(m_iDefChunkSize, size)); 143 return AllocChunk(std::max(m_iDefChunkSize, size));
142 } 144 }
143 return m_pLastChunk; 145 return m_pLastChunk;
144 } 146 }
147
145 void* CFX_StaticStore::Alloc(size_t size) { 148 void* CFX_StaticStore::Alloc(size_t size) {
146 size = FX_4BYTEALIGN(size); 149 size = FX_4BYTEALIGN(size);
147 ASSERT(size != 0); 150 ASSERT(size != 0);
148 FX_STATICSTORECHUNK* pChunk = FindChunk(size); 151 FX_STATICSTORECHUNK* pChunk = FindChunk(size);
149 ASSERT(pChunk->iFreeSize >= size); 152 ASSERT(pChunk->iFreeSize >= size);
150 uint8_t* p = (uint8_t*)pChunk; 153 uint8_t* p = (uint8_t*)pChunk;
151 p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize; 154 p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize;
152 pChunk->iFreeSize -= size; 155 pChunk->iFreeSize -= size;
153 m_iAllocatedSize += size; 156 m_iAllocatedSize += size;
154 return p; 157 return p;
155 } 158 }
156 size_t CFX_StaticStore::SetDefChunkSize(size_t size) { 159
157 ASSERT(size != 0); 160 #ifndef MEMORY_TOOL_REPLACES_ALLOCATOR
158 size_t v = m_iDefChunkSize; 161
159 m_iDefChunkSize = size;
160 return v;
161 }
162 CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk) 162 CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk)
163 : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)), 163 : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)),
164 m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)), 164 m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)),
165 m_pChunk(nullptr) { 165 m_pChunk(nullptr) {
166 ASSERT(m_iBlockSize != 0 && m_iDefChunkSize != 0); 166 ASSERT(m_iBlockSize != 0 && m_iDefChunkSize != 0);
167 } 167 }
168
168 CFX_FixedStore::~CFX_FixedStore() { 169 CFX_FixedStore::~CFX_FixedStore() {
169 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; 170 FX_FIXEDSTORECHUNK* pChunk = m_pChunk;
170 while (pChunk) { 171 while (pChunk) {
171 FX_FIXEDSTORECHUNK* pNext = pChunk->pNextChunk; 172 FX_FIXEDSTORECHUNK* pNext = pChunk->pNextChunk;
172 FX_Free(pChunk); 173 FX_Free(pChunk);
173 pChunk = pNext; 174 pChunk = pNext;
174 } 175 }
175 } 176 }
177
176 FX_FIXEDSTORECHUNK* CFX_FixedStore::AllocChunk() { 178 FX_FIXEDSTORECHUNK* CFX_FixedStore::AllocChunk() {
177 int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize + 179 int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize +
178 m_iBlockSize * m_iDefChunkSize; 180 m_iBlockSize * m_iDefChunkSize;
179 FX_FIXEDSTORECHUNK* pChunk = 181 FX_FIXEDSTORECHUNK* pChunk =
180 (FX_FIXEDSTORECHUNK*)FX_Alloc(uint8_t, iTotalSize); 182 (FX_FIXEDSTORECHUNK*)FX_Alloc(uint8_t, iTotalSize);
181 if (!pChunk) 183 if (!pChunk)
182 return nullptr; 184 return nullptr;
183 185
184 FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize); 186 FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize);
185 pChunk->pNextChunk = m_pChunk; 187 pChunk->pNextChunk = m_pChunk;
186 pChunk->iChunkSize = m_iDefChunkSize; 188 pChunk->iChunkSize = m_iDefChunkSize;
187 pChunk->iFreeNum = m_iDefChunkSize; 189 pChunk->iFreeNum = m_iDefChunkSize;
188 m_pChunk = pChunk; 190 m_pChunk = pChunk;
189 return pChunk; 191 return pChunk;
190 } 192 }
193
191 void* CFX_FixedStore::Alloc(size_t size) { 194 void* CFX_FixedStore::Alloc(size_t size) {
192 if (size > m_iBlockSize) { 195 if (size > m_iBlockSize) {
193 return nullptr; 196 return nullptr;
194 } 197 }
195 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; 198 FX_FIXEDSTORECHUNK* pChunk = m_pChunk;
196 while (pChunk) { 199 while (pChunk) {
197 if (pChunk->iFreeNum > 0) { 200 if (pChunk->iFreeNum > 0) {
198 break; 201 break;
199 } 202 }
200 pChunk = pChunk->pNextChunk; 203 pChunk = pChunk->pNextChunk;
201 } 204 }
202 if (!pChunk) { 205 if (!pChunk) {
203 pChunk = AllocChunk(); 206 pChunk = AllocChunk();
204 } 207 }
205 uint8_t* pFlags = pChunk->FirstFlag(); 208 uint8_t* pFlags = pChunk->FirstFlag();
206 size_t i = 0; 209 size_t i = 0;
207 for (; i < pChunk->iChunkSize; i++) 210 for (; i < pChunk->iChunkSize; i++)
208 if (pFlags[i] == 0) { 211 if (pFlags[i] == 0) {
209 break; 212 break;
210 } 213 }
211 ASSERT(i < pChunk->iChunkSize); 214 ASSERT(i < pChunk->iChunkSize);
212 pFlags[i] = 1; 215 pFlags[i] = 1;
213 pChunk->iFreeNum--; 216 pChunk->iFreeNum--;
214 return pChunk->FirstBlock() + i * m_iBlockSize; 217 return pChunk->FirstBlock() + i * m_iBlockSize;
215 } 218 }
219
216 void CFX_FixedStore::Free(void* pBlock) { 220 void CFX_FixedStore::Free(void* pBlock) {
217 FX_FIXEDSTORECHUNK* pPrior = nullptr; 221 FX_FIXEDSTORECHUNK* pPrior = nullptr;
218 FX_FIXEDSTORECHUNK* pChunk = m_pChunk; 222 FX_FIXEDSTORECHUNK* pChunk = m_pChunk;
219 uint8_t* pStart = nullptr; 223 uint8_t* pStart = nullptr;
220 uint8_t* pEnd; 224 uint8_t* pEnd;
221 while (pChunk) { 225 while (pChunk) {
222 pStart = pChunk->FirstBlock(); 226 pStart = pChunk->FirstBlock();
223 if (pBlock >= pStart) { 227 if (pBlock >= pStart) {
224 pEnd = pStart + m_iBlockSize * pChunk->iChunkSize; 228 pEnd = pStart + m_iBlockSize * pChunk->iChunkSize;
225 if (pBlock < pEnd) { 229 if (pBlock < pEnd) {
(...skipping 13 matching lines...) Expand all
239 pChunk->iFreeNum++; 243 pChunk->iFreeNum++;
240 if (pChunk->iFreeNum == pChunk->iChunkSize) { 244 if (pChunk->iFreeNum == pChunk->iChunkSize) {
241 if (!pPrior) { 245 if (!pPrior) {
242 m_pChunk = pChunk->pNextChunk; 246 m_pChunk = pChunk->pNextChunk;
243 } else { 247 } else {
244 pPrior->pNextChunk = pChunk->pNextChunk; 248 pPrior->pNextChunk = pChunk->pNextChunk;
245 } 249 }
246 FX_Free(pChunk); 250 FX_Free(pChunk);
247 } 251 }
248 } 252 }
249 size_t CFX_FixedStore::SetDefChunkSize(size_t iChunkSize) {
250 ASSERT(iChunkSize != 0);
251 size_t v = m_iDefChunkSize;
252 m_iDefChunkSize = FX_4BYTEALIGN(iChunkSize);
253 return v;
254 }
255 253
256 #endif // MEMORY_TOOL_REPLACES_ALLOCATOR 254 #endif // MEMORY_TOOL_REPLACES_ALLOCATOR
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698