JavaScriptCore/wtf/FastAllocBase.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 //    namespace WTF {
       
    36 //        class FastAllocBase;
       
    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 : public FastAllocBase { ... };
       
    52 //
       
    53 //    char* charPtr = fastNew<char>();
       
    54 //    fastDelete(charPtr);
       
    55 //
       
    56 //    char* charArrayPtr = fastNewArray<char>(37);
       
    57 //    fastDeleteArray(charArrayPtr);
       
    58 //
       
    59 //    void** voidPtrPtr = fastNew<void*>();
       
    60 //    fastDelete(voidPtrPtr);
       
    61 //
       
    62 //    void** voidPtrArrayPtr = fastNewArray<void*>(37);
       
    63 //    fastDeleteArray(voidPtrArrayPtr);
       
    64 //
       
    65 //    POD* podPtr = fastNew<POD>();
       
    66 //    fastDelete(podPtr);
       
    67 //
       
    68 //    POD* podArrayPtr = fastNewArray<POD>(37);
       
    69 //    fastDeleteArray(podArrayPtr);
       
    70 //
       
    71 //    Object* objectPtr = fastNew<Object>();
       
    72 //    fastDelete(objectPtr);
       
    73 //
       
    74 //    Object* objectArrayPtr = fastNewArray<Object>(37);
       
    75 //    fastDeleteArray(objectArrayPtr);
       
    76 //
       
    77 
       
    78 #include <new>
       
    79 #include <stdint.h>
       
    80 #include <stdlib.h>
       
    81 #include <string.h>
       
    82 #include "Assertions.h"
       
    83 #include "FastMalloc.h"
       
    84 #include "TypeTraits.h"
       
    85 
       
    86 namespace WTF {
       
    87 
       
    88     class FastAllocBase {
       
    89     public:
       
    90         // Placement operator new.
       
    91         void* operator new(size_t, void* p) { return p; }
       
    92         void* operator new[](size_t, void* p) { return p; }
       
    93 
       
    94         void* operator new(size_t size)
       
    95         {
       
    96             void* p = fastMalloc(size);
       
    97             fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNew);
       
    98             return p;
       
    99         }
       
   100 
       
   101         void operator delete(void* p)
       
   102         {
       
   103             fastMallocMatchValidateFree(p, Internal::AllocTypeClassNew);
       
   104             fastFree(p);
       
   105         }
       
   106 
       
   107         void* operator new[](size_t size)
       
   108         {
       
   109             void* p = fastMalloc(size);
       
   110             fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNewArray);
       
   111             return p;
       
   112         }
       
   113 
       
   114         void operator delete[](void* p)
       
   115         {
       
   116             fastMallocMatchValidateFree(p, Internal::AllocTypeClassNewArray);
       
   117             fastFree(p);
       
   118         }
       
   119     };
       
   120 
       
   121     // fastNew / fastDelete
       
   122 
       
   123     template <typename T>
       
   124     inline T* fastNew()
       
   125     {
       
   126         void* p = fastMalloc(sizeof(T));
       
   127 
       
   128         if (!p)
       
   129             return 0;
       
   130 
       
   131         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
       
   132         return ::new(p) T;
       
   133     }
       
   134 
       
   135     template <typename T, typename Arg1>
       
   136     inline T* fastNew(Arg1 arg1)
       
   137     {
       
   138         void* p = fastMalloc(sizeof(T));
       
   139 
       
   140         if (!p)
       
   141             return 0;
       
   142 
       
   143         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
       
   144         return ::new(p) T(arg1);
       
   145     }
       
   146 
       
   147     template <typename T, typename Arg1, typename Arg2>
       
   148     inline T* fastNew(Arg1 arg1, Arg2 arg2)
       
   149     {
       
   150         void* p = fastMalloc(sizeof(T));
       
   151 
       
   152         if (!p)
       
   153             return 0;
       
   154 
       
   155         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
       
   156         return ::new(p) T(arg1, arg2);
       
   157     }
       
   158 
       
   159     template <typename T, typename Arg1, typename Arg2, typename Arg3>
       
   160     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3)
       
   161     {
       
   162         void* p = fastMalloc(sizeof(T));
       
   163 
       
   164         if (!p)
       
   165             return 0;
       
   166 
       
   167         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
       
   168         return ::new(p) T(arg1, arg2, arg3);
       
   169     }
       
   170 
       
   171     template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
       
   172     inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
       
   173     {
       
   174         void* p = fastMalloc(sizeof(T));
       
   175 
       
   176         if (!p)
       
   177             return 0;
       
   178 
       
   179         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
       
   180         return ::new(p) T(arg1, arg2, arg3, arg4);
       
   181     }
       
   182 
       
   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)
       
   185     {
       
   186         void* p = fastMalloc(sizeof(T));
       
   187 
       
   188         if (!p)
       
   189             return 0;
       
   190 
       
   191         fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
       
   192         return ::new(p) T(arg1, arg2, arg3, arg4, arg5);
       
   193     }
       
   194 
       
   195     namespace Internal {
       
   196 
       
   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:
       
   201         //    struct Array {
       
   202         //        AllocAlignmentInteger m_size;
       
   203         //        T m_T[array count];
       
   204         //    };
       
   205 
       
   206         template <typename T>
       
   207         union ArraySize {
       
   208             AllocAlignmentInteger* size;
       
   209             T* t;
       
   210         };
       
   211 
       
   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)
       
   217             {
       
   218                 T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
       
   219                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
       
   220                 return p;
       
   221             }
       
   222         };
       
   223 
       
   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)
       
   229             {
       
   230                 T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
       
   231 
       
   232                 if (!p)
       
   233                     return 0;
       
   234 
       
   235                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
       
   236 
       
   237                 for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject)
       
   238                     ::new(pObject) T;
       
   239 
       
   240                 return p;
       
   241             }
       
   242         };
       
   243 
       
   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)
       
   249             {
       
   250                 void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
       
   251                 ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
       
   252 
       
   253                 if (!p)
       
   254                     return 0;
       
   255 
       
   256                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
       
   257                 *a.size++ = count;
       
   258                 // No need to construct the objects in this case.
       
   259 
       
   260                 return a.t;
       
   261             }
       
   262         };
       
   263 
       
   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)
       
   269             {
       
   270                 void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
       
   271                 ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
       
   272 
       
   273                 if (!p)
       
   274                     return 0;
       
   275 
       
   276                 fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
       
   277                 *a.size++ = count;
       
   278 
       
   279                 for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT)
       
   280                     ::new(pT) T;
       
   281 
       
   282                 return a.t;
       
   283             }
       
   284         };
       
   285     } // namespace Internal
       
   286 
       
   287     template <typename T>
       
   288     inline T* fastNewArray(size_t count)
       
   289     {
       
   290         return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count);
       
   291     }
       
   292 
       
   293     template <typename T>
       
   294     inline void fastDelete(T* p)
       
   295     {
       
   296         if (!p)
       
   297             return;
       
   298 
       
   299         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
       
   300         p->~T();
       
   301         fastFree(p);
       
   302     }
       
   303 
       
   304     template <typename T>
       
   305     inline void fastDeleteSkippingDestructor(T* p)
       
   306     {
       
   307         if (!p)
       
   308             return;
       
   309 
       
   310         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
       
   311         fastFree(p);
       
   312     }
       
   313 
       
   314     namespace Internal {
       
   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)
       
   320             {
       
   321                 // No need to destruct the objects in this case.
       
   322                 // We expect that fastFree checks for null.
       
   323                 fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
       
   324                 fastFree(p);
       
   325             }
       
   326         };
       
   327 
       
   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)
       
   333             {
       
   334                 if (!p)
       
   335                     return;
       
   336 
       
   337                 ArraySize<T> a;
       
   338                 a.t = p;
       
   339                 a.size--; // Decrement size pointer
       
   340 
       
   341                 T* pEnd = p + *a.size;
       
   342                 while (pEnd-- != p)
       
   343                     pEnd->~T();
       
   344 
       
   345                 fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
       
   346                 fastFree(a.size);
       
   347             }
       
   348         };
       
   349 
       
   350     } // namespace Internal
       
   351 
       
   352     template <typename T>
       
   353     void fastDeleteArray(T* p)
       
   354     {
       
   355         Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p);
       
   356     }
       
   357 
       
   358 
       
   359     template <typename T>
       
   360     inline void fastNonNullDelete(T* p)
       
   361     {
       
   362         fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
       
   363         p->~T();
       
   364         fastFree(p);
       
   365     }
       
   366 
       
   367     namespace Internal {
       
   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)
       
   373             {
       
   374                 fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
       
   375                 // No need to destruct the objects in this case.
       
   376                 fastFree(p);
       
   377             }
       
   378         };
       
   379 
       
   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)
       
   385             {
       
   386                 ArraySize<T> a;
       
   387                 a.t = p;
       
   388                 a.size--;
       
   389 
       
   390                 T* pEnd = p + *a.size;
       
   391                 while (pEnd-- != p)
       
   392                     pEnd->~T();
       
   393 
       
   394                 fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
       
   395                 fastFree(a.size);
       
   396             }
       
   397         };
       
   398 
       
   399     } // namespace Internal
       
   400 
       
   401     template <typename T>
       
   402     void fastNonNullDeleteArray(T* p)
       
   403     {
       
   404         Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p);
       
   405     }
       
   406 
       
   407 
       
   408 } // namespace WTF
       
   409 
       
   410 using WTF::FastAllocBase;
       
   411 using WTF::fastDeleteSkippingDestructor;
       
   412 
       
   413 #endif // FastAllocBase_h