OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public License | |
15 * along with this library; see the file COPYING.LIB. If not, write to | |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 * Boston, MA 02110-1301, USA. | |
18 * | |
19 */ | |
20 | |
21 #ifndef WTF_FastMalloc_h | |
22 #define WTF_FastMalloc_h | |
23 | |
24 #include <wtf/Platform.h> | |
25 #include <wtf/PossiblyNull.h> | |
26 #include <stdlib.h> | |
27 #include <new> | |
28 | |
29 namespace WTF { | |
30 | |
31 // These functions call CRASH() if an allocation fails. | |
32 WTF_EXPORT_PRIVATE void* fastMalloc(size_t); | |
33 WTF_EXPORT_PRIVATE void* fastZeroedMalloc(size_t); | |
34 WTF_EXPORT_PRIVATE void* fastCalloc(size_t numElements, size_t elementSize); | |
35 WTF_EXPORT_PRIVATE void* fastRealloc(void*, size_t); | |
36 WTF_EXPORT_PRIVATE char* fastStrDup(const char*); | |
37 WTF_EXPORT_PRIVATE size_t fastMallocSize(const void*); | |
38 WTF_EXPORT_PRIVATE size_t fastMallocGoodSize(size_t); | |
39 | |
40 struct TryMallocReturnValue { | |
41 TryMallocReturnValue(void* data) | |
42 : m_data(data) | |
43 { | |
44 } | |
45 TryMallocReturnValue(const TryMallocReturnValue& source) | |
46 : m_data(source.m_data) | |
47 { | |
48 source.m_data = 0; | |
49 } | |
50 ~TryMallocReturnValue() { ASSERT(!m_data); } | |
51 template <typename T> bool getValue(T& data) WARN_UNUSED_RETURN; | |
52 template <typename T> operator PossiblyNull<T>() | |
53 { | |
54 T value; | |
55 getValue(value); | |
56 return PossiblyNull<T>(value); | |
57 } | |
58 private: | |
59 mutable void* m_data; | |
60 }; | |
61 | |
62 template <typename T> bool TryMallocReturnValue::getValue(T& data) | |
63 { | |
64 union u { void* data; T target; } res; | |
65 res.data = m_data; | |
66 data = res.target; | |
67 bool returnValue = !!m_data; | |
68 m_data = 0; | |
69 return returnValue; | |
70 } | |
71 | |
72 WTF_EXPORT_PRIVATE TryMallocReturnValue tryFastMalloc(size_t n); | |
73 TryMallocReturnValue tryFastZeroedMalloc(size_t n); | |
74 WTF_EXPORT_PRIVATE TryMallocReturnValue tryFastCalloc(size_t n_elements, siz
e_t element_size); | |
75 WTF_EXPORT_PRIVATE TryMallocReturnValue tryFastRealloc(void* p, size_t n); | |
76 | |
77 WTF_EXPORT_PRIVATE void fastFree(void*); | |
78 | |
79 #ifndef NDEBUG | |
80 WTF_EXPORT_PRIVATE void fastMallocForbid(); | |
81 WTF_EXPORT_PRIVATE void fastMallocAllow(); | |
82 #endif | |
83 | |
84 WTF_EXPORT_PRIVATE void releaseFastMallocFreeMemory(); | |
85 | |
86 struct FastMallocStatistics { | |
87 size_t reservedVMBytes; | |
88 size_t committedVMBytes; | |
89 size_t freeListBytes; | |
90 }; | |
91 WTF_EXPORT_PRIVATE FastMallocStatistics fastMallocStatistics(); | |
92 | |
93 // This defines a type which holds an unsigned integer and is the same | |
94 // size as the minimally aligned memory allocation. | |
95 typedef unsigned long long AllocAlignmentInteger; | |
96 | |
97 namespace Internal { | |
98 enum AllocType { // Start with an unusual number inst
ead of zero, because zero is common. | |
99 AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroe
dMalloc, fastCalloc, fastRealloc. | |
100 AllocTypeClassNew, // Encompasses class operator new fr
om FastAllocBase. | |
101 AllocTypeClassNewArray, // Encompasses class operator new[]
from FastAllocBase. | |
102 AllocTypeFastNew, // Encompasses fastNew. | |
103 AllocTypeFastNewArray, // Encompasses fastNewArray. | |
104 AllocTypeNew, // Encompasses global operator new. | |
105 AllocTypeNewArray // Encompasses global operator new[]
. | |
106 }; | |
107 | |
108 enum { | |
109 ValidationPrefix = 0xf00df00d, | |
110 ValidationSuffix = 0x0badf00d | |
111 }; | |
112 | |
113 typedef unsigned ValidationTag; | |
114 | |
115 struct ValidationHeader { | |
116 AllocType m_type; | |
117 unsigned m_size; | |
118 ValidationTag m_prefix; | |
119 unsigned m_alignment; | |
120 }; | |
121 | |
122 static const int ValidationBufferSize = sizeof(ValidationHeader) + sizeo
f(ValidationTag); | |
123 } | |
124 | |
125 #if ENABLE(WTF_MALLOC_VALIDATION) | |
126 | |
127 // Malloc validation is a scheme whereby a tag is attached to an | |
128 // allocation which identifies how it was originally allocated. | |
129 // This allows us to verify that the freeing operation matches the | |
130 // allocation operation. If memory is allocated with operator new[] | |
131 // but freed with free or delete, this system would detect that. | |
132 // In the implementation here, the tag is an integer prepended to | |
133 // the allocation memory which is assigned one of the AllocType | |
134 // enumeration values. An alternative implementation of this | |
135 // scheme could store the tag somewhere else or ignore it. | |
136 // Users of FastMalloc don't need to know or care how this tagging | |
137 // is implemented. | |
138 | |
139 namespace Internal { | |
140 | |
141 // Handle a detected alloc/free mismatch. By default this calls CRASH(). | |
142 void fastMallocMatchFailed(void* p); | |
143 | |
144 inline ValidationHeader* fastMallocValidationHeader(void* p) | |
145 { | |
146 return reinterpret_cast<ValidationHeader*>(static_cast<char*>(p) - s
izeof(ValidationHeader)); | |
147 } | |
148 | |
149 inline ValidationTag* fastMallocValidationSuffix(void* p) | |
150 { | |
151 ValidationHeader* header = fastMallocValidationHeader(p); | |
152 if (header->m_prefix != static_cast<unsigned>(ValidationPrefix)) | |
153 fastMallocMatchFailed(p); | |
154 | |
155 return reinterpret_cast<ValidationTag*>(static_cast<char*>(p) + head
er->m_size); | |
156 } | |
157 | |
158 // Return the AllocType tag associated with the allocated block p. | |
159 inline AllocType fastMallocMatchValidationType(void* p) | |
160 { | |
161 return fastMallocValidationHeader(p)->m_type; | |
162 } | |
163 | |
164 // Set the AllocType tag to be associaged with the allocated block p. | |
165 inline void setFastMallocMatchValidationType(void* p, AllocType allocTyp
e) | |
166 { | |
167 fastMallocValidationHeader(p)->m_type = allocType; | |
168 } | |
169 | |
170 } // namespace Internal | |
171 | |
172 // This is a higher level function which is used by FastMalloc-using code. | |
173 inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType alloc
Type) | |
174 { | |
175 if (!p) | |
176 return; | |
177 | |
178 Internal::setFastMallocMatchValidationType(p, allocType); | |
179 } | |
180 | |
181 // This is a higher level function which is used by FastMalloc-using code. | |
182 inline void fastMallocMatchValidateFree(void* p, Internal::AllocType) | |
183 { | |
184 if (!p) | |
185 return; | |
186 | |
187 Internal::ValidationHeader* header = Internal::fastMallocValidationHeade
r(p); | |
188 if (header->m_prefix != static_cast<unsigned>(Internal::ValidationPrefix
)) | |
189 Internal::fastMallocMatchFailed(p); | |
190 | |
191 if (*Internal::fastMallocValidationSuffix(p) != Internal::ValidationSuff
ix) | |
192 Internal::fastMallocMatchFailed(p); | |
193 | |
194 Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc)
; // Set it to this so that fastFree thinks it's OK. | |
195 } | |
196 | |
197 inline void fastMallocValidate(void* p) | |
198 { | |
199 if (!p) | |
200 return; | |
201 | |
202 Internal::ValidationHeader* header = Internal::fastMallocValidationHeade
r(p); | |
203 if (header->m_prefix != static_cast<unsigned>(Internal::ValidationPrefix
)) | |
204 Internal::fastMallocMatchFailed(p); | |
205 | |
206 if (*Internal::fastMallocValidationSuffix(p) != Internal::ValidationSuff
ix) | |
207 Internal::fastMallocMatchFailed(p); | |
208 } | |
209 | |
210 #else | |
211 | |
212 inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType) | |
213 { | |
214 } | |
215 | |
216 inline void fastMallocMatchValidateFree(void*, Internal::AllocType) | |
217 { | |
218 } | |
219 | |
220 #endif | |
221 | |
222 } // namespace WTF | |
223 | |
224 using WTF::fastCalloc; | |
225 using WTF::fastFree; | |
226 using WTF::fastMalloc; | |
227 using WTF::fastMallocGoodSize; | |
228 using WTF::fastMallocSize; | |
229 using WTF::fastRealloc; | |
230 using WTF::fastStrDup; | |
231 using WTF::fastZeroedMalloc; | |
232 using WTF::tryFastCalloc; | |
233 using WTF::tryFastMalloc; | |
234 using WTF::tryFastRealloc; | |
235 using WTF::tryFastZeroedMalloc; | |
236 | |
237 #ifndef NDEBUG | |
238 using WTF::fastMallocForbid; | |
239 using WTF::fastMallocAllow; | |
240 #endif | |
241 | |
242 #endif /* WTF_FastMalloc_h */ | |
OLD | NEW |