[WK2] Small Caps font variant issue for Italic fonts
[framework/web/webkit-efl.git] / Source / WTF / 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 <wtf/Assertions.h>
92 #include <wtf/FastMalloc.h>
93 #include <wtf/StdLibExtras.h>
94 #include <wtf/TypeTraits.h>
95
96 #define WTF_MAKE_FAST_ALLOCATED \
97 public: \
98     void* operator new(size_t, void* p) { return p; } \
99     void* operator new[](size_t, void* p) { return p; } \
100     \
101     void* operator new(size_t size) \
102     { \
103         void* p = ::WTF::fastMalloc(size); \
104          ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \
105         return p; \
106     } \
107     \
108     void operator delete(void* p) \
109     { \
110         ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \
111         ::WTF::fastFree(p); \
112     } \
113     \
114     void* operator new[](size_t size) \
115     { \
116         void* p = ::WTF::fastMalloc(size); \
117         ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \
118         return p; \
119     } \
120     \
121     void operator delete[](void* p) \
122     { \
123          ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \
124          ::WTF::fastFree(p); \
125     } \
126     void* operator new(size_t, NotNullTag, void* location) \
127     { \
128         ASSERT(location); \
129         return location; \
130     } \
131 private: \
132 typedef int __thisIsHereToForceASemicolonAfterThisMacro
133
134 namespace WTF {
135
136     // fastNew / fastDelete
137
138     template <typename T>
139     inline T* fastNew()
140     {
141         void* p = fastMalloc(sizeof(T));
142
143         if (!p)
144             return 0;
145
146         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
147         return ::new (p) T;
148     }
149
150     template <typename T, typename Arg1>
151     inline T* fastNew(Arg1 arg1)
152     {
153         void* p = fastMalloc(sizeof(T));
154
155         if (!p)
156             return 0;
157
158         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
159         return ::new (p) T(arg1);
160     }
161
162     template <typename T, typename Arg1, typename Arg2>
163     inline T* fastNew(Arg1 arg1, Arg2 arg2)
164     {
165         void* p = fastMalloc(sizeof(T));
166
167         if (!p)
168             return 0;
169
170         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
171         return ::new (p) T(arg1, arg2);
172     }
173
174     template <typename T, typename Arg1, typename Arg2, typename Arg3>
175     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3)
176     {
177         void* p = fastMalloc(sizeof(T));
178
179         if (!p)
180             return 0;
181
182         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
183         return ::new (p) T(arg1, arg2, arg3);
184     }
185
186     template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
187     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
188     {
189         void* p = fastMalloc(sizeof(T));
190
191         if (!p)
192             return 0;
193
194         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
195         return ::new (p) T(arg1, arg2, arg3, arg4);
196     }
197
198     template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
199     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
200     {
201         void* p = fastMalloc(sizeof(T));
202
203         if (!p)
204             return 0;
205
206         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
207         return ::new (p) T(arg1, arg2, arg3, arg4, arg5);
208     }
209
210     namespace Internal {
211
212         // We define a union of pointer to an integer and pointer to T.
213         // When non-POD arrays are allocated we add a few leading bytes to tell what
214         // the size of the array is. We return to the user the pointer to T.
215         // The way to think of it is as if we allocate a struct like so:
216         //    struct Array {
217         //        AllocAlignmentInteger m_size;
218         //        T m_T[array count];
219         //    };
220
221         template <typename T>
222         union ArraySize {
223             AllocAlignmentInteger* size;
224             T* t;
225         };
226
227         // This is a support template for fastNewArray.
228         // This handles the case wherein T has a trivial ctor and a trivial dtor.
229         template <typename T, bool trivialCtor, bool trivialDtor>
230         struct NewArrayImpl {
231             static T* fastNewArray(size_t count)
232             {
233                 T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
234                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
235                 return p;
236             }
237         };
238
239         // This is a support template for fastNewArray.
240         // This handles the case wherein T has a non-trivial ctor and a trivial dtor.
241         template <typename T>
242         struct NewArrayImpl<T, false, true> {
243             static T* fastNewArray(size_t count)
244             {
245                 T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
246
247                 if (!p)
248                     return 0;
249
250                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
251
252                 for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject)
253                     ::new (pObject) T;
254
255                 return p;
256             }
257         };
258
259         // This is a support template for fastNewArray.
260         // This handles the case wherein T has a trivial ctor and a non-trivial dtor.
261         template <typename T>
262         struct NewArrayImpl<T, true, false> {
263             static T* fastNewArray(size_t count)
264             {
265                 void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
266                 ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
267
268                 if (!p)
269                     return 0;
270
271                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
272                 *a.size++ = count;
273                 // No need to construct the objects in this case.
274
275                 return a.t;
276             }
277         };
278
279         // This is a support template for fastNewArray.
280         // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor.
281         template <typename T>
282         struct NewArrayImpl<T, false, false> {
283             static T* fastNewArray(size_t count)
284             {
285                 void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
286                 ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
287
288                 if (!p)
289                     return 0;
290
291                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
292                 *a.size++ = count;
293
294                 for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT)
295                     ::new (pT) T;
296
297                 return a.t;
298             }
299         };
300     } // namespace Internal
301
302     template <typename T>
303     inline T* fastNewArray(size_t count)
304     {
305         return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count);
306     }
307
308     template <typename T>
309     inline void fastDelete(T* p)
310     {
311         if (!p)
312             return;
313
314         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
315         p->~T();
316         fastFree(p);
317     }
318
319     template <typename T>
320     inline void fastDeleteSkippingDestructor(T* p)
321     {
322         if (!p)
323             return;
324
325         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
326         fastFree(p);
327     }
328
329     namespace Internal {
330         // This is a support template for fastDeleteArray.
331         // This handles the case wherein T has a trivial dtor.
332         template <typename T, bool trivialDtor>
333         struct DeleteArrayImpl {
334             static void fastDeleteArray(void* p)
335             {
336                 // No need to destruct the objects in this case.
337                 // We expect that fastFree checks for null.
338                 fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
339                 fastFree(p);
340             }
341         };
342
343         // This is a support template for fastDeleteArray.
344         // This handles the case wherein T has a non-trivial dtor.
345         template <typename T>
346         struct DeleteArrayImpl<T, false> {
347             static void fastDeleteArray(T* p)
348             {
349                 if (!p)
350                     return;
351
352                 ArraySize<T> a;
353                 a.t = p;
354                 a.size--; // Decrement size pointer
355
356                 T* pEnd = p + *a.size;
357                 while (pEnd-- != p)
358                     pEnd->~T();
359
360                 fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
361                 fastFree(a.size);
362             }
363         };
364
365     } // namespace Internal
366
367     template <typename T>
368     void fastDeleteArray(T* p)
369     {
370         Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p);
371     }
372
373
374     template <typename T>
375     inline void fastNonNullDelete(T* p)
376     {
377         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
378         p->~T();
379         fastFree(p);
380     }
381
382     namespace Internal {
383         // This is a support template for fastDeleteArray.
384         // This handles the case wherein T has a trivial dtor.
385         template <typename T, bool trivialDtor>
386         struct NonNullDeleteArrayImpl {
387             static void fastNonNullDeleteArray(void* p)
388             {
389                 fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
390                 // No need to destruct the objects in this case.
391                 fastFree(p);
392             }
393         };
394
395         // This is a support template for fastDeleteArray.
396         // This handles the case wherein T has a non-trivial dtor.
397         template <typename T>
398         struct NonNullDeleteArrayImpl<T, false> {
399             static void fastNonNullDeleteArray(T* p)
400             {
401                 ArraySize<T> a;
402                 a.t = p;
403                 a.size--;
404
405                 T* pEnd = p + *a.size;
406                 while (pEnd-- != p)
407                     pEnd->~T();
408
409                 fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
410                 fastFree(a.size);
411             }
412         };
413
414     } // namespace Internal
415
416     template <typename T>
417     void fastNonNullDeleteArray(T* p)
418     {
419         Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p);
420     }
421
422
423 } // namespace WTF
424
425 using WTF::fastDeleteSkippingDestructor;
426
427 #endif // FastAllocBase_h