diff -r 000000000000 -r 4f2f89ce4247 JavaScriptCore/wtf/FastAllocBase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/JavaScriptCore/wtf/FastAllocBase.h Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,413 @@ +/* + * Copyright (C) 2008, 2009 Paul Pedriana . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FastAllocBase_h +#define FastAllocBase_h + +// Provides customizable overrides of fastMalloc/fastFree and operator new/delete +// +// Provided functionality: +// namespace WTF { +// class FastAllocBase; +// +// T* fastNew(); +// T* fastNew(arg); +// T* fastNew(arg, arg); +// T* fastNewArray(count); +// void fastDelete(T* p); +// void fastDeleteArray(T* p); +// void fastNonNullDelete(T* p); +// void fastNonNullDeleteArray(T* p); +// } +// +// FastDelete assumes that the underlying +// +// Example usage: +// class Widget : public FastAllocBase { ... }; +// +// char* charPtr = fastNew(); +// fastDelete(charPtr); +// +// char* charArrayPtr = fastNewArray(37); +// fastDeleteArray(charArrayPtr); +// +// void** voidPtrPtr = fastNew(); +// fastDelete(voidPtrPtr); +// +// void** voidPtrArrayPtr = fastNewArray(37); +// fastDeleteArray(voidPtrArrayPtr); +// +// POD* podPtr = fastNew(); +// fastDelete(podPtr); +// +// POD* podArrayPtr = fastNewArray(37); +// fastDeleteArray(podArrayPtr); +// +// Object* objectPtr = fastNew(); +// fastDelete(objectPtr); +// +// Object* objectArrayPtr = fastNewArray(37); +// fastDeleteArray(objectArrayPtr); +// + +#include +#include +#include +#include +#include "Assertions.h" +#include "FastMalloc.h" +#include "TypeTraits.h" + +namespace WTF { + + class FastAllocBase { + public: + // Placement operator new. + void* operator new(size_t, void* p) { return p; } + void* operator new[](size_t, void* p) { return p; } + + void* operator new(size_t size) + { + void* p = fastMalloc(size); + fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNew); + return p; + } + + void operator delete(void* p) + { + fastMallocMatchValidateFree(p, Internal::AllocTypeClassNew); + fastFree(p); + } + + void* operator new[](size_t size) + { + void* p = fastMalloc(size); + fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNewArray); + return p; + } + + void operator delete[](void* p) + { + fastMallocMatchValidateFree(p, Internal::AllocTypeClassNewArray); + fastFree(p); + } + }; + + // fastNew / fastDelete + + template + inline T* fastNew() + { + void* p = fastMalloc(sizeof(T)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); + return ::new(p) T; + } + + template + inline T* fastNew(Arg1 arg1) + { + void* p = fastMalloc(sizeof(T)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); + return ::new(p) T(arg1); + } + + template + inline T* fastNew(Arg1 arg1, Arg2 arg2) + { + void* p = fastMalloc(sizeof(T)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); + return ::new(p) T(arg1, arg2); + } + + template + inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3) + { + void* p = fastMalloc(sizeof(T)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); + return ::new(p) T(arg1, arg2, arg3); + } + + template + inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) + { + void* p = fastMalloc(sizeof(T)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); + return ::new(p) T(arg1, arg2, arg3, arg4); + } + + template + inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) + { + void* p = fastMalloc(sizeof(T)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); + return ::new(p) T(arg1, arg2, arg3, arg4, arg5); + } + + namespace Internal { + + // We define a union of pointer to an integer and pointer to T. + // When non-POD arrays are allocated we add a few leading bytes to tell what + // the size of the array is. We return to the user the pointer to T. + // The way to think of it is as if we allocate a struct like so: + // struct Array { + // AllocAlignmentInteger m_size; + // T m_T[array count]; + // }; + + template + union ArraySize { + AllocAlignmentInteger* size; + T* t; + }; + + // This is a support template for fastNewArray. + // This handles the case wherein T has a trivial ctor and a trivial dtor. + template + struct NewArrayImpl { + static T* fastNewArray(size_t count) + { + T* p = static_cast(fastMalloc(sizeof(T) * count)); + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); + return p; + } + }; + + // This is a support template for fastNewArray. + // This handles the case wherein T has a non-trivial ctor and a trivial dtor. + template + struct NewArrayImpl { + static T* fastNewArray(size_t count) + { + T* p = static_cast(fastMalloc(sizeof(T) * count)); + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); + + for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject) + ::new(pObject) T; + + return p; + } + }; + + // This is a support template for fastNewArray. + // This handles the case wherein T has a trivial ctor and a non-trivial dtor. + template + struct NewArrayImpl { + static T* fastNewArray(size_t count) + { + void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count)); + ArraySize a = { static_cast(p) }; + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); + *a.size++ = count; + // No need to construct the objects in this case. + + return a.t; + } + }; + + // This is a support template for fastNewArray. + // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor. + template + struct NewArrayImpl { + static T* fastNewArray(size_t count) + { + void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count)); + ArraySize a = { static_cast(p) }; + + if (!p) + return 0; + + fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); + *a.size++ = count; + + for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT) + ::new(pT) T; + + return a.t; + } + }; + } // namespace Internal + + template + inline T* fastNewArray(size_t count) + { + return Internal::NewArrayImpl::value, WTF::HasTrivialDestructor::value>::fastNewArray(count); + } + + template + inline void fastDelete(T* p) + { + if (!p) + return; + + fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); + p->~T(); + fastFree(p); + } + + template + inline void fastDeleteSkippingDestructor(T* p) + { + if (!p) + return; + + fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); + fastFree(p); + } + + namespace Internal { + // This is a support template for fastDeleteArray. + // This handles the case wherein T has a trivial dtor. + template + struct DeleteArrayImpl { + static void fastDeleteArray(void* p) + { + // No need to destruct the objects in this case. + // We expect that fastFree checks for null. + fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray); + fastFree(p); + } + }; + + // This is a support template for fastDeleteArray. + // This handles the case wherein T has a non-trivial dtor. + template + struct DeleteArrayImpl { + static void fastDeleteArray(T* p) + { + if (!p) + return; + + ArraySize a; + a.t = p; + a.size--; // Decrement size pointer + + T* pEnd = p + *a.size; + while (pEnd-- != p) + pEnd->~T(); + + fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray); + fastFree(a.size); + } + }; + + } // namespace Internal + + template + void fastDeleteArray(T* p) + { + Internal::DeleteArrayImpl::value>::fastDeleteArray(p); + } + + + template + inline void fastNonNullDelete(T* p) + { + fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); + p->~T(); + fastFree(p); + } + + namespace Internal { + // This is a support template for fastDeleteArray. + // This handles the case wherein T has a trivial dtor. + template + struct NonNullDeleteArrayImpl { + static void fastNonNullDeleteArray(void* p) + { + fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray); + // No need to destruct the objects in this case. + fastFree(p); + } + }; + + // This is a support template for fastDeleteArray. + // This handles the case wherein T has a non-trivial dtor. + template + struct NonNullDeleteArrayImpl { + static void fastNonNullDeleteArray(T* p) + { + ArraySize a; + a.t = p; + a.size--; + + T* pEnd = p + *a.size; + while (pEnd-- != p) + pEnd->~T(); + + fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray); + fastFree(a.size); + } + }; + + } // namespace Internal + + template + void fastNonNullDeleteArray(T* p) + { + Internal::NonNullDeleteArrayImpl::value>::fastNonNullDeleteArray(p); + } + + +} // namespace WTF + +using WTF::FastAllocBase; +using WTF::fastDeleteSkippingDestructor; + +#endif // FastAllocBase_h