This commit is contained in:
jeanlemotan
2024-07-02 18:10:39 +02:00
commit 48ab06b1d9
733 changed files with 321088 additions and 0 deletions
+492
View File
@@ -0,0 +1,492 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
/////////////////////////////////////////////////////////////////////////////
#ifndef EASTLTEST_ALLOCATOR_H
#define EASTLTEST_ALLOCATOR_H
#include <EABase/eabase.h>
#include <EASTL/internal/config.h>
#include <new>
#include <stdio.h>
#if !EASTL_OPENSOURCE
#include <PPMalloc/EAGeneralAllocator.h>
#include <PPMalloc/EAGeneralAllocatorDebug.h>
#include <coreallocator/icoreallocator_interface.h>
#if defined(EA_COMPILER_MSVC)
#include <math.h> // VS2008 has an acknowledged bug that requires math.h (and possibly also string.h) to be #included before intrin.h.
#include <intrin.h>
#pragma intrinsic(_ReturnAddress)
#endif
///////////////////////////////////////////////////////////////////////////////
// EASTLTest_GetGeneralAllocator()
//
namespace EA
{
namespace Allocator
{
#ifdef EA_DEBUG
extern PPM_API GeneralAllocatorDebug* gpEAGeneralAllocatorDebug;
#else
extern PPM_API GeneralAllocator* gpEAGeneralAllocator;
#endif
static inline auto& EASTLTest_GetGeneralAllocator()
{
#ifdef EA_DEBUG
using GeneralAllocatorType = GeneralAllocatorDebug;
#else
using GeneralAllocatorType = GeneralAllocator;
#endif
static GeneralAllocatorType sGeneralAllocator;
return sGeneralAllocator;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// allocator counts for debugging purposes
//
int gEASTLTest_AllocationCount = 0;
int gEASTLTest_TotalAllocationCount = 0;
///////////////////////////////////////////////////////////////////////////////
// EASTLTest_ValidateHeap
//
bool EASTLTest_ValidateHeap()
{
#ifdef EA_DEBUG
return EA::Allocator::EASTLTest_GetGeneralAllocator().ValidateHeap(EA::Allocator::GeneralAllocator::kHeapValidationLevelBasic);
#else
return true;
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Microsoft function parameter annotations
// https://msdn.microsoft.com/en-CA/library/hh916382.aspx
//
#ifndef _Ret_maybenull_
#define _Ret_maybenull_
#endif
#ifndef _Post_writable_byte_size_
#define _Post_writable_byte_size_(x)
#endif
#ifndef _Ret_notnull_
#define _Ret_notnull_
#endif
///////////////////////////////////////////////////////////////////////////////
// operator new extensions
//
namespace
{
#ifdef EA_DEBUG
const char gUnattributedNewTag[] = "Anonymous new";
#endif
#if defined(EA_COMPILER_MSVC)
#define UNATTRIBUTED_NEW_FILE "raw_return_address"
#define UNATTRIBUTED_NEW_LINE ((int)(uintptr_t)_ReturnAddress())
#else
#define UNATTRIBUTED_NEW_FILE NULL
#define UNATTRIBUTED_NEW_LINE 0
#endif
}
///////////////////////////////////////////////////////////////////////////////
// system memory allocation helpers
//
namespace
{
void* PlatformMalloc(size_t size, size_t alignment = 16)
{
#ifdef EA_PLATFORM_MICROSOFT
return _aligned_malloc(size, alignment);
#else
void *p = nullptr;
alignment = alignment < sizeof( void *) ? sizeof( void *) : alignment;
posix_memalign(&p, alignment, size);
return p;
#endif
}
void PlatformFree(void* p)
{
#ifdef EA_PLATFORM_MICROSOFT
_aligned_free(p);
#else
free(p);
#endif
}
void* InternalMalloc(size_t size)
{
void* mem = nullptr;
auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator();
#ifdef EA_DEBUG
mem = allocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
#else
mem = allocator.Malloc(size);
#endif
if(mem == nullptr)
mem = PlatformMalloc(size);
return mem;
}
void* InternalMalloc(size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line)
{
void* mem = nullptr;
auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator();
#ifdef EA_DEBUG
mem = allocator.MallocDebug(size, flags, debugFlags, name, file, line);
#else
mem = allocator.Malloc(size, flags);
EA_UNUSED(debugFlags);
EA_UNUSED(file);
EA_UNUSED(line);
EA_UNUSED(name);
#endif
if(mem == nullptr)
mem = PlatformMalloc(size);
return mem;
}
void* InternalMalloc(size_t size, size_t alignment, const char* name, int flags, unsigned debugFlags, const char* file, int line)
{
void* mem = nullptr;
auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator();
#ifdef EA_DEBUG
mem = allocator.MallocAlignedDebug(size, alignment, 0, flags, debugFlags, name, file, line);
#else
mem = allocator.MallocAligned(size, alignment, flags);
EA_UNUSED(debugFlags);
EA_UNUSED(file);
EA_UNUSED(line);
EA_UNUSED(name);
#endif
if(mem == nullptr)
mem = PlatformMalloc(size, alignment);
return mem;
}
void* InternalMalloc(size_t size, size_t alignment)
{
void* mem = nullptr;
auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator();
#ifdef EA_DEBUG
mem = allocator.MallocAlignedDebug(size, alignment, 0, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE);
#else
mem = allocator.MallocAligned(size, alignment);
#endif
if(mem == nullptr)
mem = PlatformMalloc(size, alignment);
return mem;
}
void InternalFree(void* p)
{
auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator();
if(allocator.ValidateAddress(p, EA::Allocator::GeneralAllocator::kAddressTypeOwned) == p)
{
allocator.Free(p);
}
else
{
PlatformFree(p);
}
}
}
class EASTLTestICA : public EA::Allocator::ICoreAllocator
{
public:
EASTLTestICA()
{
}
virtual ~EASTLTestICA()
{
}
virtual void* Alloc(size_t size, const char* name, unsigned int flags)
{
return ::InternalMalloc(size, name, (int)flags, 0, NULL, 0);
}
virtual void* Alloc(size_t size, const char* name, unsigned int flags,
unsigned int align, unsigned int)
{
return ::InternalMalloc(size, (size_t)align, name, (int)flags, 0, NULL, 0);
}
virtual void Free(void* pData, size_t /*size*/)
{
return ::InternalFree(pData);
}
};
EA::Allocator::ICoreAllocator* EA::Allocator::ICoreAllocator::GetDefaultAllocator()
{
static EASTLTestICA sEASTLTestICA;
return &sEASTLTestICA;
}
///////////////////////////////////////////////////////////////////////////
// operator new/delete implementations
//
_Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new(size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
{
return InternalMalloc(size);
}
void operator delete(void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE()
{
if(p) // The standard specifies that 'delete NULL' is a valid operation.
{
gEASTLTest_AllocationCount--;
InternalFree(p);
}
}
_Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new[](size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
void* p = InternalMalloc(size);
return p;
}
void operator delete[](void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE()
{
if(p)
{
gEASTLTest_AllocationCount--;
InternalFree(p);
}
}
_Ret_notnull_ _Post_writable_byte_size_(size) void* operator new(size_t size)
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
void* mem = InternalMalloc(size);
#if !defined(EA_COMPILER_NO_EXCEPTIONS)
if (mem == NULL)
{
throw std::bad_alloc();
}
#endif
return mem;
}
_Ret_notnull_ _Post_writable_byte_size_(size) void* operator new[](size_t size)
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
void* mem = InternalMalloc(size);
#if !defined(EA_COMPILER_NO_EXCEPTIONS)
if (mem == NULL)
{
throw std::bad_alloc();
}
#endif
return mem;
}
void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line)
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
return InternalMalloc(size, name, flags, debugFlags, file, line);
}
void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* name, int flags, unsigned debugFlags, const char* file, int line)
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
return InternalMalloc(size, alignment, name, flags, debugFlags, file, line);
}
// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
void* operator new(size_t size, size_t alignment)
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
return InternalMalloc(size, alignment);
}
// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
return InternalMalloc(size, alignment);
}
// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
void* operator new[](size_t size, size_t alignment)
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
return InternalMalloc(size, alignment);
}
// Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler).
void* operator new[](size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
{
gEASTLTest_AllocationCount++;
gEASTLTest_TotalAllocationCount++;
return InternalMalloc(size, alignment);
}
void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE()
{
if(p) // The standard specifies that 'delete NULL' is a valid operation.
{
gEASTLTest_AllocationCount--;
InternalFree(p);
}
}
void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE()
{
if(p)
{
gEASTLTest_AllocationCount--;
InternalFree(p);
}
}
void EASTLTest_SetGeneralAllocator()
{
EA::Allocator::SetGeneralAllocator(&EA::Allocator::EASTLTest_GetGeneralAllocator());
#ifdef EA_DEBUG
EA::Allocator::gpEAGeneralAllocatorDebug->SetDefaultDebugDataFlag(EA::Allocator::GeneralAllocatorDebug::kDebugDataIdGuard);
#endif
}
#else
#if !defined(EA_PLATFORM_MICROSOFT) || defined(EA_PLATFORM_MINGW)
#include <stdlib.h>
#endif
namespace Internal
{
void* EASTLAlignedAlloc(size_t size, size_t alignment)
{
#ifdef EA_PLATFORM_MICROSOFT
return _aligned_malloc(size, alignment);
#else
void *p = nullptr;
alignment = alignment < sizeof( void *) ? sizeof( void *) : alignment;
posix_memalign(&p, alignment, size);
return p;
#endif
}
void EASTLAlignedFree(void* p)
{
#ifdef EA_PLATFORM_MICROSOFT
_aligned_free(p);
#else
free(p);
#endif
}
}
void* operator new(size_t size)
{ return Internal::EASTLAlignedAlloc(size, 16); }
void* operator new[](size_t size)
{ return Internal::EASTLAlignedAlloc(size, 16); }
void* operator new[](size_t size, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
{ return Internal::EASTLAlignedAlloc(size, 16); }
void* operator new[](size_t size, size_t alignment, size_t /*alignmentOffset*/, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/)
{ return Internal::EASTLAlignedAlloc(size, alignment); }
void* operator new(size_t size, size_t alignment)
{ return Internal::EASTLAlignedAlloc(size, alignment); }
void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE()
{ return Internal::EASTLAlignedAlloc(size, alignment); }
void* operator new[](size_t size, size_t alignment)
{ return Internal::EASTLAlignedAlloc(size, alignment); }
void* operator new[](size_t size, size_t alignment, const std::nothrow_t&)EA_THROW_SPEC_NEW_NONE()
{ return Internal::EASTLAlignedAlloc(size, alignment); }
// C++14 deleter
void operator delete(void* p, std::size_t sz ) EA_THROW_SPEC_DELETE_NONE()
{ Internal::EASTLAlignedFree(p); EA_UNUSED(sz); }
void operator delete[](void* p, std::size_t sz ) EA_THROW_SPEC_DELETE_NONE()
{ Internal::EASTLAlignedFree(p); EA_UNUSED(sz); }
void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE()
{ Internal::EASTLAlignedFree(p); }
void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE()
{ Internal::EASTLAlignedFree(p); }
void EASTLTest_SetGeneralAllocator() { /* intentionally blank */ }
bool EASTLTest_ValidateHeap() { return true; }
#endif // !EASTL_OPENSOURCE
#endif // Header include guard