#ifndef FastAllocBase_h
#define FastAllocBase_h
#include <new>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "Assertions.h"
#include "FastMalloc.h"
#include "TypeTraits.h"
namespace WTF {
class FastAllocBase {
public:
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);
}
};
template <typename T>
inline T* fastNew()
{
void* p = fastMalloc(sizeof(T));
if (!p)
return 0;
fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
return ::new(p) T;
}
template <typename T, typename Arg1>
inline T* fastNew(Arg1 arg1)
{
void* p = fastMalloc(sizeof(T));
if (!p)
return 0;
fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
return ::new(p) T(arg1);
}
template <typename T, typename Arg1, typename Arg2>
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 <typename T, typename Arg1, typename Arg2, typename Arg3>
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 <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
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 <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
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 {
template <typename T>
union ArraySize {
AllocAlignmentInteger* size;
T* t;
};
template <typename T, bool trivialCtor, bool trivialDtor>
struct NewArrayImpl {
static T* fastNewArray(size_t count)
{
T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
return p;
}
};
template <typename T>
struct NewArrayImpl<T, false, true> {
static T* fastNewArray(size_t count)
{
T* p = static_cast<T*>(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;
}
};
template <typename T>
struct NewArrayImpl<T, true, false> {
static T* fastNewArray(size_t count)
{
void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
if (!p)
return 0;
fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
*a.size++ = count;
return a.t;
}
};
template <typename T>
struct NewArrayImpl<T, false, false> {
static T* fastNewArray(size_t count)
{
void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(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;
}
};
}
template <typename T>
inline T* fastNewArray(size_t count)
{
return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count);
}
template <typename T>
inline void fastDelete(T* p)
{
if (!p)
return;
fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
p->~T();
fastFree(p);
}
template <typename T>
inline void fastDeleteSkippingDestructor(T* p)
{
if (!p)
return;
fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
fastFree(p);
}
namespace Internal {
template <typename T, bool trivialDtor>
struct DeleteArrayImpl {
static void fastDeleteArray(void* p)
{
fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
fastFree(p);
}
};
template <typename T>
struct DeleteArrayImpl<T, false> {
static void fastDeleteArray(T* p)
{
if (!p)
return;
ArraySize<T> a;
a.t = p;
a.size--;
T* pEnd = p + *a.size;
while (pEnd-- != p)
pEnd->~T();
fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
fastFree(a.size);
}
};
}
template <typename T>
void fastDeleteArray(T* p)
{
Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p);
}
template <typename T>
inline void fastNonNullDelete(T* p)
{
fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
p->~T();
fastFree(p);
}
namespace Internal {
template <typename T, bool trivialDtor>
struct NonNullDeleteArrayImpl {
static void fastNonNullDeleteArray(void* p)
{
fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
fastFree(p);
}
};
template <typename T>
struct NonNullDeleteArrayImpl<T, false> {
static void fastNonNullDeleteArray(T* p)
{
ArraySize<T> a;
a.t = p;
a.size--;
T* pEnd = p + *a.size;
while (pEnd-- != p)
pEnd->~T();
fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
fastFree(a.size);
}
};
}
template <typename T>
void fastNonNullDeleteArray(T* p)
{
Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p);
}
}
using WTF::FastAllocBase;
using WTF::fastDeleteSkippingDestructor;
#endif // FastAllocBase_h