2 * Copyright (C) 2008, 2009 Paul Pedriana <ppedriana@ea.com>. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef FastAllocBase_h
30 #define FastAllocBase_h
32 // Provides customizable overrides of fastMalloc/fastFree and operator new/delete
34 // Provided functionality:
35 // Macro: WTF_MAKE_FAST_ALLOCATED
39 // T* fastNew<T>(arg);
40 // T* fastNew<T>(arg, arg);
41 // T* fastNewArray<T>(count);
42 // void fastDelete(T* p);
43 // void fastDeleteArray(T* p);
44 // void fastNonNullDelete(T* p);
45 // void fastNonNullDeleteArray(T* p);
48 // FastDelete assumes that the underlying
52 // WTF_MAKE_FAST_ALLOCATED
57 // WTF_MAKE_FAST_ALLOCATED
62 // char* charPtr = fastNew<char>();
63 // fastDelete(charPtr);
65 // char* charArrayPtr = fastNewArray<char>(37);
66 // fastDeleteArray(charArrayPtr);
68 // void** voidPtrPtr = fastNew<void*>();
69 // fastDelete(voidPtrPtr);
71 // void** voidPtrArrayPtr = fastNewArray<void*>(37);
72 // fastDeleteArray(voidPtrArrayPtr);
74 // POD* podPtr = fastNew<POD>();
75 // fastDelete(podPtr);
77 // POD* podArrayPtr = fastNewArray<POD>(37);
78 // fastDeleteArray(podArrayPtr);
80 // Object* objectPtr = fastNew<Object>();
81 // fastDelete(objectPtr);
83 // Object* objectArrayPtr = fastNewArray<Object>(37);
84 // fastDeleteArray(objectArrayPtr);
91 #include "Assertions.h"
92 #include "FastMalloc.h"
93 #include "TypeTraits.h"
95 #define WTF_MAKE_FAST_ALLOCATED \
97 void* operator new(size_t, void* p) { return p; } \
98 void* operator new[](size_t, void* p) { return p; } \
100 void* operator new(size_t size) \
102 void* p = ::WTF::fastMalloc(size); \
103 ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \
107 void operator delete(void* p) \
109 ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \
110 ::WTF::fastFree(p); \
113 void* operator new[](size_t size) \
115 void* p = ::WTF::fastMalloc(size); \
116 ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \
120 void operator delete[](void* p) \
122 ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \
123 ::WTF::fastFree(p); \
126 typedef int ThisIsHereToForceASemicolonAfterThisMacro
130 // fastNew / fastDelete
132 template <typename T
>
135 void* p
= fastMalloc(sizeof(T
));
140 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
144 template <typename T
, typename Arg1
>
145 inline T
* fastNew(Arg1 arg1
)
147 void* p
= fastMalloc(sizeof(T
));
152 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
153 return ::new(p
) T(arg1
);
156 template <typename T
, typename Arg1
, typename Arg2
>
157 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
)
159 void* p
= fastMalloc(sizeof(T
));
164 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
165 return ::new(p
) T(arg1
, arg2
);
168 template <typename T
, typename Arg1
, typename Arg2
, typename Arg3
>
169 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
, Arg3 arg3
)
171 void* p
= fastMalloc(sizeof(T
));
176 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
177 return ::new(p
) T(arg1
, arg2
, arg3
);
180 template <typename T
, typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
>
181 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
, Arg3 arg3
, Arg4 arg4
)
183 void* p
= fastMalloc(sizeof(T
));
188 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
189 return ::new(p
) T(arg1
, arg2
, arg3
, arg4
);
192 template <typename T
, typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
, typename Arg5
>
193 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
, Arg3 arg3
, Arg4 arg4
, Arg5 arg5
)
195 void* p
= fastMalloc(sizeof(T
));
200 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
201 return ::new(p
) T(arg1
, arg2
, arg3
, arg4
, arg5
);
206 // We define a union of pointer to an integer and pointer to T.
207 // When non-POD arrays are allocated we add a few leading bytes to tell what
208 // the size of the array is. We return to the user the pointer to T.
209 // The way to think of it is as if we allocate a struct like so:
211 // AllocAlignmentInteger m_size;
212 // T m_T[array count];
215 template <typename T
>
217 AllocAlignmentInteger
* size
;
221 // This is a support template for fastNewArray.
222 // This handles the case wherein T has a trivial ctor and a trivial dtor.
223 template <typename T
, bool trivialCtor
, bool trivialDtor
>
224 struct NewArrayImpl
{
225 static T
* fastNewArray(size_t count
)
227 T
* p
= static_cast<T
*>(fastMalloc(sizeof(T
) * count
));
228 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
233 // This is a support template for fastNewArray.
234 // This handles the case wherein T has a non-trivial ctor and a trivial dtor.
235 template <typename T
>
236 struct NewArrayImpl
<T
, false, true> {
237 static T
* fastNewArray(size_t count
)
239 T
* p
= static_cast<T
*>(fastMalloc(sizeof(T
) * count
));
244 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
246 for (T
* pObject
= p
, *pObjectEnd
= pObject
+ count
; pObject
!= pObjectEnd
; ++pObject
)
253 // This is a support template for fastNewArray.
254 // This handles the case wherein T has a trivial ctor and a non-trivial dtor.
255 template <typename T
>
256 struct NewArrayImpl
<T
, true, false> {
257 static T
* fastNewArray(size_t count
)
259 void* p
= fastMalloc(sizeof(AllocAlignmentInteger
) + (sizeof(T
) * count
));
260 ArraySize
<T
> a
= { static_cast<AllocAlignmentInteger
*>(p
) };
265 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
267 // No need to construct the objects in this case.
273 // This is a support template for fastNewArray.
274 // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor.
275 template <typename T
>
276 struct NewArrayImpl
<T
, false, false> {
277 static T
* fastNewArray(size_t count
)
279 void* p
= fastMalloc(sizeof(AllocAlignmentInteger
) + (sizeof(T
) * count
));
280 ArraySize
<T
> a
= { static_cast<AllocAlignmentInteger
*>(p
) };
285 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
288 for (T
* pT
= a
.t
, *pTEnd
= pT
+ count
; pT
!= pTEnd
; ++pT
)
294 } // namespace Internal
296 template <typename T
>
297 inline T
* fastNewArray(size_t count
)
299 return Internal::NewArrayImpl
<T
, WTF::HasTrivialConstructor
<T
>::value
, WTF::HasTrivialDestructor
<T
>::value
>::fastNewArray(count
);
302 template <typename T
>
303 inline void fastDelete(T
* p
)
308 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNew
);
313 template <typename T
>
314 inline void fastDeleteSkippingDestructor(T
* p
)
319 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNew
);
324 // This is a support template for fastDeleteArray.
325 // This handles the case wherein T has a trivial dtor.
326 template <typename T
, bool trivialDtor
>
327 struct DeleteArrayImpl
{
328 static void fastDeleteArray(void* p
)
330 // No need to destruct the objects in this case.
331 // We expect that fastFree checks for null.
332 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNewArray
);
337 // This is a support template for fastDeleteArray.
338 // This handles the case wherein T has a non-trivial dtor.
339 template <typename T
>
340 struct DeleteArrayImpl
<T
, false> {
341 static void fastDeleteArray(T
* p
)
348 a
.size
--; // Decrement size pointer
350 T
* pEnd
= p
+ *a
.size
;
354 fastMallocMatchValidateFree(a
.size
, Internal::AllocTypeFastNewArray
);
359 } // namespace Internal
361 template <typename T
>
362 void fastDeleteArray(T
* p
)
364 Internal::DeleteArrayImpl
<T
, WTF::HasTrivialDestructor
<T
>::value
>::fastDeleteArray(p
);
368 template <typename T
>
369 inline void fastNonNullDelete(T
* p
)
371 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNew
);
377 // This is a support template for fastDeleteArray.
378 // This handles the case wherein T has a trivial dtor.
379 template <typename T
, bool trivialDtor
>
380 struct NonNullDeleteArrayImpl
{
381 static void fastNonNullDeleteArray(void* p
)
383 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNewArray
);
384 // No need to destruct the objects in this case.
389 // This is a support template for fastDeleteArray.
390 // This handles the case wherein T has a non-trivial dtor.
391 template <typename T
>
392 struct NonNullDeleteArrayImpl
<T
, false> {
393 static void fastNonNullDeleteArray(T
* p
)
399 T
* pEnd
= p
+ *a
.size
;
403 fastMallocMatchValidateFree(a
.size
, Internal::AllocTypeFastNewArray
);
408 } // namespace Internal
410 template <typename T
>
411 void fastNonNullDeleteArray(T
* p
)
413 Internal::NonNullDeleteArrayImpl
<T
, WTF::HasTrivialDestructor
<T
>::value
>::fastNonNullDeleteArray(p
);
419 using WTF::fastDeleteSkippingDestructor
;
421 #endif // FastAllocBase_h