15f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian/*
25f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Copyright (C) 2008, 2009 Paul Pedriana <ppedriana@ea.com>. All rights reserved.
35f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *
45f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Redistribution and use in source and binary forms, with or without
55f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * modification, are permitted provided that the following conditions
65f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * are met:
75f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *
85f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 1.  Redistributions of source code must retain the above copyright
95f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *     notice, this list of conditions and the following disclaimer.
105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 2.  Redistributions in binary form must reproduce the above copyright
115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *     notice, this list of conditions and the following disclaimer in the
125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *     documentation and/or other materials provided with the distribution.
135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *     its contributors may be used to endorse or promote products derived
155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *     from this software without specific prior written permission.
165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *
175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */
285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#ifndef FastAllocBase_h
305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#define FastAllocBase_h
315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// Provides customizable overrides of fastMalloc/fastFree and operator new/delete
335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// Provided functionality:
35ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    Macro: WTF_MAKE_FAST_ALLOCATED
365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    namespace WTF {
375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        T*    fastNew<T>();
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        T*    fastNew<T>(arg);
405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        T*    fastNew<T>(arg, arg);
415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        T*    fastNewArray<T>(count);
425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        void  fastDelete(T* p);
435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        void  fastDeleteArray(T* p);
445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        void  fastNonNullDelete(T* p);
455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//        void  fastNonNullDeleteArray(T* p);
465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    }
475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// FastDelete assumes that the underlying
495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian// Example usage:
51ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    class Widget {
52ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//        WTF_MAKE_FAST_ALLOCATED
53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    ...
54ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    };
55ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//
56ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    struct Data {
57ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//        WTF_MAKE_FAST_ALLOCATED
58ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    public:
59ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    ...
60ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch//    };
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    char* charPtr = fastNew<char>();
635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDelete(charPtr);
645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    char* charArrayPtr = fastNewArray<char>(37);
665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDeleteArray(charArrayPtr);
675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    void** voidPtrPtr = fastNew<void*>();
695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDelete(voidPtrPtr);
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    void** voidPtrArrayPtr = fastNewArray<void*>(37);
725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDeleteArray(voidPtrArrayPtr);
735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    POD* podPtr = fastNew<POD>();
755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDelete(podPtr);
765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    POD* podArrayPtr = fastNewArray<POD>(37);
785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDeleteArray(podArrayPtr);
795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    Object* objectPtr = fastNew<Object>();
815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDelete(objectPtr);
825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    Object* objectArrayPtr = fastNewArray<Object>(37);
845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//    fastDeleteArray(objectArrayPtr);
855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian//
865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <new>
885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <stdint.h>
895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <stdlib.h>
905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <string.h>
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Assertions.h"
925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "FastMalloc.h"
935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "TypeTraits.h"
945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
95a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#define WTF_MAKE_FAST_ALLOCATED \
96a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochpublic: \
97a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void* operator new(size_t, void* p) { return p; } \
98a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void* operator new[](size_t, void* p) { return p; } \
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    \
100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void* operator new(size_t size) \
101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    { \
102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        void* p = ::WTF::fastMalloc(size); \
103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch         ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return p; \
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } \
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    \
107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void operator delete(void* p) \
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    { \
109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \
110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ::WTF::fastFree(p); \
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } \
112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    \
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void* operator new[](size_t size) \
114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    { \
115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        void* p = ::WTF::fastMalloc(size); \
116a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return p; \
118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } \
119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    \
120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void operator delete[](void* p) \
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    { \
122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch         ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \
123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch         ::WTF::fastFree(p); \
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } \
125ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochprivate: \
126ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochtypedef int ThisIsHereToForceASemicolonAfterThisMacro
127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
128ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochnamespace WTF {
1295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // fastNew / fastDelete
1315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T>
1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNew()
1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        void* p = fastMalloc(sizeof(T));
1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
1385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
1395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
1415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ::new(p) T;
1425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T, typename Arg1>
1455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNew(Arg1 arg1)
1465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        void* p = fastMalloc(sizeof(T));
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
1505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
1515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
1535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ::new(p) T(arg1);
1545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T, typename Arg1, typename Arg2>
1575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNew(Arg1 arg1, Arg2 arg2)
1585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        void* p = fastMalloc(sizeof(T));
1605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
1625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
1655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ::new(p) T(arg1, arg2);
1665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T, typename Arg1, typename Arg2, typename Arg3>
1695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3)
1705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        void* p = fastMalloc(sizeof(T));
1725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
1745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
1755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
1775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ::new(p) T(arg1, arg2, arg3);
1785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
1815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
1825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        void* p = fastMalloc(sizeof(T));
1845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
1865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
1875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
1895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ::new(p) T(arg1, arg2, arg3, arg4);
1905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        void* p = fastMalloc(sizeof(T));
1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
1995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ::new(p) T(arg1, arg2, arg3, arg4, arg5);
2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    namespace Internal {
2055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // We define a union of pointer to an integer and pointer to T.
2075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // When non-POD arrays are allocated we add a few leading bytes to tell what
2085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // the size of the array is. We return to the user the pointer to T.
2095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // The way to think of it is as if we allocate a struct like so:
2105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        //    struct Array {
2115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        //        AllocAlignmentInteger m_size;
2125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        //        T m_T[array count];
2135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        //    };
2145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T>
2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        union ArraySize {
2175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            AllocAlignmentInteger* size;
2185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            T* t;
2195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
2205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastNewArray.
2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a trivial ctor and a trivial dtor.
2235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T, bool trivialCtor, bool trivialDtor>
2245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct NewArrayImpl {
2255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static T* fastNewArray(size_t count)
2265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
2275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
2285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
2295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return p;
2305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
2315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
2325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastNewArray.
2345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a non-trivial ctor and a trivial dtor.
2355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T>
2365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct NewArrayImpl<T, false, true> {
2375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static T* fastNewArray(size_t count)
2385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
2395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
2405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (!p)
2425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    return 0;
2435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
2455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject)
2475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    ::new(pObject) T;
2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return p;
2505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
2515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
2525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastNewArray.
2545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a trivial ctor and a non-trivial dtor.
2555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T>
2565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct NewArrayImpl<T, true, false> {
2575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static T* fastNewArray(size_t count)
2585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
2595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
2615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (!p)
2635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    return 0;
2645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
2665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                *a.size++ = count;
2675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                // No need to construct the objects in this case.
2685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return a.t;
2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
2715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
2725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastNewArray.
2745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor.
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T>
2765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct NewArrayImpl<T, false, false> {
2775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static T* fastNewArray(size_t count)
2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
2795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
2805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
2815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (!p)
2835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    return 0;
2845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
2865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                *a.size++ = count;
2875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT)
2895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    ::new(pT) T;
2905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return a.t;
2925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
2935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
2945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } // namespace Internal
2955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T>
2975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline T* fastNewArray(size_t count)
2985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count);
3005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T>
3035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline void fastDelete(T* p)
3045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!p)
3065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return;
3075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
3095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        p->~T();
3105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastFree(p);
3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    template <typename T>
314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    inline void fastDeleteSkippingDestructor(T* p)
315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!p)
317231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return;
318231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
319231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
320231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        fastFree(p);
321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    namespace Internal {
3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastDeleteArray.
3255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a trivial dtor.
3265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T, bool trivialDtor>
3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct DeleteArrayImpl {
3285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static void fastDeleteArray(void* p)
3295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                // No need to destruct the objects in this case.
3315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                // We expect that fastFree checks for null.
3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastFree(p);
3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastDeleteArray.
3385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a non-trivial dtor.
3395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T>
3405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct DeleteArrayImpl<T, false> {
3415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static void fastDeleteArray(T* p)
3425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
3435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (!p)
3445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    return;
3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                ArraySize<T> a;
3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                a.t = p;
3485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                a.size--; // Decrement size pointer
3495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                T* pEnd = p + *a.size;
3515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                while (pEnd-- != p)
3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    pEnd->~T();
3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
3555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastFree(a.size);
3565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
3575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
3585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } // namespace Internal
3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T>
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void fastDeleteArray(T* p)
3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p);
3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T>
3695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    inline void fastNonNullDelete(T* p)
3705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
3725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        p->~T();
3735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        fastFree(p);
3745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    namespace Internal {
3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastDeleteArray.
3785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a trivial dtor.
3795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T, bool trivialDtor>
3805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct NonNullDeleteArrayImpl {
3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static void fastNonNullDeleteArray(void* p)
3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                // No need to destruct the objects in this case.
3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastFree(p);
3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
3875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This is a support template for fastDeleteArray.
3905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // This handles the case wherein T has a non-trivial dtor.
3915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        template <typename T>
3925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        struct NonNullDeleteArrayImpl<T, false> {
3935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static void fastNonNullDeleteArray(T* p)
3945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
3955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                ArraySize<T> a;
3965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                a.t = p;
3975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                a.size--;
3985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                T* pEnd = p + *a.size;
4005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                while (pEnd-- != p)
4015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    pEnd->~T();
4025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
4045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                fastFree(a.size);
4055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
4065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        };
4075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } // namespace Internal
4095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template <typename T>
4115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void fastNonNullDeleteArray(T* p)
4125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p);
4145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} // namespace WTF
4185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
419231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockusing WTF::fastDeleteSkippingDestructor;
4200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif // FastAllocBase_h
422