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:
36 // class FastAllocBase;
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
51 // class Widget : public FastAllocBase { ... };
53 // char* charPtr = fastNew<char>();
54 // fastDelete(charPtr);
56 // char* charArrayPtr = fastNewArray<char>(37);
57 // fastDeleteArray(charArrayPtr);
59 // void** voidPtrPtr = fastNew<void*>();
60 // fastDelete(voidPtrPtr);
62 // void** voidPtrArrayPtr = fastNewArray<void*>(37);
63 // fastDeleteArray(voidPtrArrayPtr);
65 // POD* podPtr = fastNew<POD>();
66 // fastDelete(podPtr);
68 // POD* podArrayPtr = fastNewArray<POD>(37);
69 // fastDeleteArray(podArrayPtr);
71 // Object* objectPtr = fastNew<Object>();
72 // fastDelete(objectPtr);
74 // Object* objectArrayPtr = fastNewArray<Object>(37);
75 // fastDeleteArray(objectArrayPtr);
82 #include "Assertions.h"
83 #include "FastMalloc.h"
84 #include "TypeTraits.h"
90 // Placement operator new.
91 void* operator new(size_t, void* p
) { return p
; }
92 void* operator new[](size_t, void* p
) { return p
; }
94 void* operator new(size_t size
)
96 void* p
= fastMalloc(size
);
97 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeClassNew
);
101 void operator delete(void* p
)
103 fastMallocMatchValidateFree(p
, Internal::AllocTypeClassNew
);
107 void* operator new[](size_t size
)
109 void* p
= fastMalloc(size
);
110 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeClassNewArray
);
114 void operator delete[](void* p
)
116 fastMallocMatchValidateFree(p
, Internal::AllocTypeClassNewArray
);
121 // fastNew / fastDelete
123 template <typename T
>
126 void* p
= fastMalloc(sizeof(T
));
131 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
135 template <typename T
, typename Arg1
>
136 inline T
* fastNew(Arg1 arg1
)
138 void* p
= fastMalloc(sizeof(T
));
143 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
144 return ::new(p
) T(arg1
);
147 template <typename T
, typename Arg1
, typename Arg2
>
148 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
)
150 void* p
= fastMalloc(sizeof(T
));
155 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
156 return ::new(p
) T(arg1
, arg2
);
159 template <typename T
, typename Arg1
, typename Arg2
, typename Arg3
>
160 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
, Arg3 arg3
)
162 void* p
= fastMalloc(sizeof(T
));
167 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
168 return ::new(p
) T(arg1
, arg2
, arg3
);
171 template <typename T
, typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
>
172 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
, Arg3 arg3
, Arg4 arg4
)
174 void* p
= fastMalloc(sizeof(T
));
179 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
180 return ::new(p
) T(arg1
, arg2
, arg3
, arg4
);
183 template <typename T
, typename Arg1
, typename Arg2
, typename Arg3
, typename Arg4
, typename Arg5
>
184 inline T
* fastNew(Arg1 arg1
, Arg2 arg2
, Arg3 arg3
, Arg4 arg4
, Arg5 arg5
)
186 void* p
= fastMalloc(sizeof(T
));
191 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNew
);
192 return ::new(p
) T(arg1
, arg2
, arg3
, arg4
, arg5
);
197 // We define a union of pointer to an integer and pointer to T.
198 // When non-POD arrays are allocated we add a few leading bytes to tell what
199 // the size of the array is. We return to the user the pointer to T.
200 // The way to think of it is as if we allocate a struct like so:
202 // AllocAlignmentInteger m_size;
203 // T m_T[array count];
206 template <typename T
>
208 AllocAlignmentInteger
* size
;
212 // This is a support template for fastNewArray.
213 // This handles the case wherein T has a trivial ctor and a trivial dtor.
214 template <typename T
, bool trivialCtor
, bool trivialDtor
>
215 struct NewArrayImpl
{
216 static T
* fastNewArray(size_t count
)
218 T
* p
= static_cast<T
*>(fastMalloc(sizeof(T
) * count
));
219 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
224 // This is a support template for fastNewArray.
225 // This handles the case wherein T has a non-trivial ctor and a trivial dtor.
226 template <typename T
>
227 struct NewArrayImpl
<T
, false, true> {
228 static T
* fastNewArray(size_t count
)
230 T
* p
= static_cast<T
*>(fastMalloc(sizeof(T
) * count
));
235 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
237 for (T
* pObject
= p
, *pObjectEnd
= pObject
+ count
; pObject
!= pObjectEnd
; ++pObject
)
244 // This is a support template for fastNewArray.
245 // This handles the case wherein T has a trivial ctor and a non-trivial dtor.
246 template <typename T
>
247 struct NewArrayImpl
<T
, true, false> {
248 static T
* fastNewArray(size_t count
)
250 void* p
= fastMalloc(sizeof(AllocAlignmentInteger
) + (sizeof(T
) * count
));
251 ArraySize
<T
> a
= { static_cast<AllocAlignmentInteger
*>(p
) };
256 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
258 // No need to construct the objects in this case.
264 // This is a support template for fastNewArray.
265 // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor.
266 template <typename T
>
267 struct NewArrayImpl
<T
, false, false> {
268 static T
* fastNewArray(size_t count
)
270 void* p
= fastMalloc(sizeof(AllocAlignmentInteger
) + (sizeof(T
) * count
));
271 ArraySize
<T
> a
= { static_cast<AllocAlignmentInteger
*>(p
) };
276 fastMallocMatchValidateMalloc(p
, Internal::AllocTypeFastNewArray
);
279 for (T
* pT
= a
.t
, *pTEnd
= pT
+ count
; pT
!= pTEnd
; ++pT
)
285 } // namespace Internal
287 template <typename T
>
288 inline T
* fastNewArray(size_t count
)
290 return Internal::NewArrayImpl
<T
, WTF::HasTrivialConstructor
<T
>::value
, WTF::HasTrivialDestructor
<T
>::value
>::fastNewArray(count
);
293 template <typename T
>
294 inline void fastDelete(T
* p
)
299 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNew
);
304 template <typename T
>
305 inline void fastDeleteSkippingDestructor(T
* p
)
310 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNew
);
315 // This is a support template for fastDeleteArray.
316 // This handles the case wherein T has a trivial dtor.
317 template <typename T
, bool trivialDtor
>
318 struct DeleteArrayImpl
{
319 static void fastDeleteArray(void* p
)
321 // No need to destruct the objects in this case.
322 // We expect that fastFree checks for null.
323 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNewArray
);
328 // This is a support template for fastDeleteArray.
329 // This handles the case wherein T has a non-trivial dtor.
330 template <typename T
>
331 struct DeleteArrayImpl
<T
, false> {
332 static void fastDeleteArray(T
* p
)
339 a
.size
--; // Decrement size pointer
341 T
* pEnd
= p
+ *a
.size
;
345 fastMallocMatchValidateFree(a
.size
, Internal::AllocTypeFastNewArray
);
350 } // namespace Internal
352 template <typename T
>
353 void fastDeleteArray(T
* p
)
355 Internal::DeleteArrayImpl
<T
, WTF::HasTrivialDestructor
<T
>::value
>::fastDeleteArray(p
);
359 template <typename T
>
360 inline void fastNonNullDelete(T
* p
)
362 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNew
);
368 // This is a support template for fastDeleteArray.
369 // This handles the case wherein T has a trivial dtor.
370 template <typename T
, bool trivialDtor
>
371 struct NonNullDeleteArrayImpl
{
372 static void fastNonNullDeleteArray(void* p
)
374 fastMallocMatchValidateFree(p
, Internal::AllocTypeFastNewArray
);
375 // No need to destruct the objects in this case.
380 // This is a support template for fastDeleteArray.
381 // This handles the case wherein T has a non-trivial dtor.
382 template <typename T
>
383 struct NonNullDeleteArrayImpl
<T
, false> {
384 static void fastNonNullDeleteArray(T
* p
)
390 T
* pEnd
= p
+ *a
.size
;
394 fastMallocMatchValidateFree(a
.size
, Internal::AllocTypeFastNewArray
);
399 } // namespace Internal
401 template <typename T
>
402 void fastNonNullDeleteArray(T
* p
)
404 Internal::NonNullDeleteArrayImpl
<T
, WTF::HasTrivialDestructor
<T
>::value
>::fastNonNullDeleteArray(p
);
410 using WTF::FastAllocBase
;
411 using WTF::fastDeleteSkippingDestructor
;
413 #endif // FastAllocBase_h