initial import
[vuplus_webkit] / Source / JavaScriptCore / wtf / FastAllocBase.h
1 /*
2  * Copyright (C) 2008, 2009 Paul Pedriana <ppedriana@ea.com>. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
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.
16  *
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.
27  */
28
29 #ifndef FastAllocBase_h
30 #define FastAllocBase_h
31
32 // Provides customizable overrides of fastMalloc/fastFree and operator new/delete
33 //
34 // Provided functionality:
35 //    Macro: WTF_MAKE_FAST_ALLOCATED
36 //    namespace WTF {
37 //
38 //        T*    fastNew<T>();
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);
46 //    }
47 //
48 // FastDelete assumes that the underlying
49 //
50 // Example usage:
51 //    class Widget {
52 //        WTF_MAKE_FAST_ALLOCATED
53 //    ...
54 //    };
55 //
56 //    struct Data {
57 //        WTF_MAKE_FAST_ALLOCATED
58 //    public:
59 //    ...
60 //    };
61 //
62 //    char* charPtr = fastNew<char>();
63 //    fastDelete(charPtr);
64 //
65 //    char* charArrayPtr = fastNewArray<char>(37);
66 //    fastDeleteArray(charArrayPtr);
67 //
68 //    void** voidPtrPtr = fastNew<void*>();
69 //    fastDelete(voidPtrPtr);
70 //
71 //    void** voidPtrArrayPtr = fastNewArray<void*>(37);
72 //    fastDeleteArray(voidPtrArrayPtr);
73 //
74 //    POD* podPtr = fastNew<POD>();
75 //    fastDelete(podPtr);
76 //
77 //    POD* podArrayPtr = fastNewArray<POD>(37);
78 //    fastDeleteArray(podArrayPtr);
79 //
80 //    Object* objectPtr = fastNew<Object>();
81 //    fastDelete(objectPtr);
82 //
83 //    Object* objectArrayPtr = fastNewArray<Object>(37);
84 //    fastDeleteArray(objectArrayPtr);
85 //
86
87 #include <new>
88 #include <stdint.h>
89 #include <stdlib.h>
90 #include <string.h>
91 #include "Assertions.h"
92 #include "FastMalloc.h"
93 #include "TypeTraits.h"
94
95 #define WTF_MAKE_FAST_ALLOCATED \
96 public: \
97     void* operator new(size_t, void* p) { return p; } \
98     void* operator new[](size_t, void* p) { return p; } \
99     \
100     void* operator new(size_t size) \
101     { \
102         void* p = ::WTF::fastMalloc(size); \
103          ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \
104         return p; \
105     } \
106     \
107     void operator delete(void* p) \
108     { \
109         ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \
110         ::WTF::fastFree(p); \
111     } \
112     \
113     void* operator new[](size_t size) \
114     { \
115         void* p = ::WTF::fastMalloc(size); \
116         ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \
117         return p; \
118     } \
119     \
120     void operator delete[](void* p) \
121     { \
122          ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \
123          ::WTF::fastFree(p); \
124     } \
125 private: \
126 typedef int ThisIsHereToForceASemicolonAfterThisMacro
127
128 namespace WTF {
129
130     // fastNew / fastDelete
131
132     template <typename T>
133     inline T* fastNew()
134     {
135         void* p = fastMalloc(sizeof(T));
136
137         if (!p)
138             return 0;
139
140         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
141         return ::new(p) T;
142     }
143
144     template <typename T, typename Arg1>
145     inline T* fastNew(Arg1 arg1)
146     {
147         void* p = fastMalloc(sizeof(T));
148
149         if (!p)
150             return 0;
151
152         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
153         return ::new(p) T(arg1);
154     }
155
156     template <typename T, typename Arg1, typename Arg2>
157     inline T* fastNew(Arg1 arg1, Arg2 arg2)
158     {
159         void* p = fastMalloc(sizeof(T));
160
161         if (!p)
162             return 0;
163
164         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
165         return ::new(p) T(arg1, arg2);
166     }
167
168     template <typename T, typename Arg1, typename Arg2, typename Arg3>
169     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3)
170     {
171         void* p = fastMalloc(sizeof(T));
172
173         if (!p)
174             return 0;
175
176         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
177         return ::new(p) T(arg1, arg2, arg3);
178     }
179
180     template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
181     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
182     {
183         void* p = fastMalloc(sizeof(T));
184
185         if (!p)
186             return 0;
187
188         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
189         return ::new(p) T(arg1, arg2, arg3, arg4);
190     }
191
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)
194     {
195         void* p = fastMalloc(sizeof(T));
196
197         if (!p)
198             return 0;
199
200         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
201         return ::new(p) T(arg1, arg2, arg3, arg4, arg5);
202     }
203
204     namespace Internal {
205
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:
210         //    struct Array {
211         //        AllocAlignmentInteger m_size;
212         //        T m_T[array count];
213         //    };
214
215         template <typename T>
216         union ArraySize {
217             AllocAlignmentInteger* size;
218             T* t;
219         };
220
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)
226             {
227                 T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
228                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
229                 return p;
230             }
231         };
232
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)
238             {
239                 T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
240
241                 if (!p)
242                     return 0;
243
244                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
245
246                 for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject)
247                     ::new(pObject) T;
248
249                 return p;
250             }
251         };
252
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)
258             {
259                 void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
260                 ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
261
262                 if (!p)
263                     return 0;
264
265                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
266                 *a.size++ = count;
267                 // No need to construct the objects in this case.
268
269                 return a.t;
270             }
271         };
272
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)
278             {
279                 void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
280                 ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
281
282                 if (!p)
283                     return 0;
284
285                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
286                 *a.size++ = count;
287
288                 for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT)
289                     ::new(pT) T;
290
291                 return a.t;
292             }
293         };
294     } // namespace Internal
295
296     template <typename T>
297     inline T* fastNewArray(size_t count)
298     {
299         return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count);
300     }
301
302     template <typename T>
303     inline void fastDelete(T* p)
304     {
305         if (!p)
306             return;
307
308         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
309         p->~T();
310         fastFree(p);
311     }
312
313     template <typename T>
314     inline void fastDeleteSkippingDestructor(T* p)
315     {
316         if (!p)
317             return;
318
319         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
320         fastFree(p);
321     }
322
323     namespace Internal {
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)
329             {
330                 // No need to destruct the objects in this case.
331                 // We expect that fastFree checks for null.
332                 fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
333                 fastFree(p);
334             }
335         };
336
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)
342             {
343                 if (!p)
344                     return;
345
346                 ArraySize<T> a;
347                 a.t = p;
348                 a.size--; // Decrement size pointer
349
350                 T* pEnd = p + *a.size;
351                 while (pEnd-- != p)
352                     pEnd->~T();
353
354                 fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
355                 fastFree(a.size);
356             }
357         };
358
359     } // namespace Internal
360
361     template <typename T>
362     void fastDeleteArray(T* p)
363     {
364         Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p);
365     }
366
367
368     template <typename T>
369     inline void fastNonNullDelete(T* p)
370     {
371         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
372         p->~T();
373         fastFree(p);
374     }
375
376     namespace Internal {
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)
382             {
383                 fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
384                 // No need to destruct the objects in this case.
385                 fastFree(p);
386             }
387         };
388
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)
394             {
395                 ArraySize<T> a;
396                 a.t = p;
397                 a.size--;
398
399                 T* pEnd = p + *a.size;
400                 while (pEnd-- != p)
401                     pEnd->~T();
402
403                 fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
404                 fastFree(a.size);
405             }
406         };
407
408     } // namespace Internal
409
410     template <typename T>
411     void fastNonNullDeleteArray(T* p)
412     {
413         Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p);
414     }
415
416
417 } // namespace WTF
418
419 using WTF::fastDeleteSkippingDestructor;
420
421 #endif // FastAllocBase_h