mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-27 20:18:01 +02:00
Moving corlib files out of "System" directory into root
This commit is contained in:
parent
4cd58262e4
commit
7dbfd15292
179 changed files with 3 additions and 0 deletions
250
BeefLibs/corlib/src/BumpAllocator.bf
Normal file
250
BeefLibs/corlib/src/BumpAllocator.bf
Normal file
|
@ -0,0 +1,250 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace System
|
||||
{
|
||||
interface IRawAllocator
|
||||
{
|
||||
void* Alloc(int size, int align);
|
||||
void Free(void* ptr);
|
||||
}
|
||||
|
||||
class BumpAllocator : IRawAllocator
|
||||
{
|
||||
struct DtorEntry
|
||||
{
|
||||
public uint16 mPoolIdx;
|
||||
public uint16 mPoolOfs;
|
||||
}
|
||||
|
||||
public enum DestructorHandlingKind
|
||||
{
|
||||
Allow,
|
||||
Fail,
|
||||
Ignore,
|
||||
}
|
||||
|
||||
List<Span<uint8>> mPools;
|
||||
List<DtorEntry> mDtorEntries;
|
||||
List<void*> mLargeRawAllocs;
|
||||
List<Object> mLargeDtorAllocs;
|
||||
int mPoolsSize;
|
||||
int mLageAllocs;
|
||||
public DestructorHandlingKind DestructorHandling = .Allow;
|
||||
|
||||
uint8* mCurAlloc;
|
||||
uint8* mCurPtr;
|
||||
uint8* mCurEnd;
|
||||
|
||||
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||
// We will either contain only data that needs to be marked or not, based on the first
|
||||
// data allocated. The paired allocator will contain the other type of data
|
||||
bool mMarkData;
|
||||
BumpAllocator mPairedAllocator ~ delete _;
|
||||
#endif
|
||||
|
||||
public this(DestructorHandlingKind destructorHandling = .Allow)
|
||||
{
|
||||
mCurAlloc = null;
|
||||
mCurPtr = null;
|
||||
mCurEnd = null;
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
if (mDtorEntries != null)
|
||||
{
|
||||
for (var dtorEntry in ref mDtorEntries)
|
||||
{
|
||||
uint8* ptr = mPools[dtorEntry.mPoolIdx].Ptr + dtorEntry.mPoolOfs;
|
||||
Object obj = Internal.UnsafeCastToObject(ptr);
|
||||
delete:null obj;
|
||||
}
|
||||
delete mDtorEntries;
|
||||
}
|
||||
|
||||
if (mPools != null)
|
||||
{
|
||||
for (var span in mPools)
|
||||
FreePool(span);
|
||||
delete mPools;
|
||||
}
|
||||
|
||||
if (mLargeDtorAllocs != null)
|
||||
{
|
||||
for (var obj in mLargeDtorAllocs)
|
||||
{
|
||||
delete obj;
|
||||
FreeLarge(Internal.UnsafeCastToPtr(obj));
|
||||
}
|
||||
delete mLargeDtorAllocs;
|
||||
}
|
||||
|
||||
if (mLargeRawAllocs != null)
|
||||
{
|
||||
for (var ptr in mLargeRawAllocs)
|
||||
FreeLarge(ptr);
|
||||
delete mLargeRawAllocs;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void* AllocLarge(int size, int align)
|
||||
{
|
||||
return new uint8[size]* {?};
|
||||
}
|
||||
|
||||
protected virtual void FreeLarge(void* ptr)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
protected virtual Span<uint8> AllocPool()
|
||||
{
|
||||
int poolSize = (mPools != null) ? mPools.Count : 0;
|
||||
int allocSize = Math.Clamp((int)Math.Pow(poolSize, 1.5) * 4*1024, 4*1024, 64*1024);
|
||||
return Span<uint8>(new uint8[allocSize]* {?}, allocSize);
|
||||
}
|
||||
|
||||
protected virtual void FreePool(Span<uint8> span)
|
||||
{
|
||||
delete span.Ptr;
|
||||
}
|
||||
|
||||
protected void GrowPool()
|
||||
{
|
||||
var span = AllocPool();
|
||||
mPoolsSize += span.Length;
|
||||
if (mPools == null)
|
||||
mPools = new List<Span<uint8>>();
|
||||
mPools.Add(span);
|
||||
mCurAlloc = span.Ptr;
|
||||
mCurPtr = mCurAlloc;
|
||||
mCurEnd = mCurAlloc + span.Length;
|
||||
}
|
||||
|
||||
public void* Alloc(int size, int align)
|
||||
{
|
||||
mCurPtr = (uint8*)(void*)(((int)(void*)mCurPtr + align - 1) & ~(align - 1));
|
||||
|
||||
while (mCurPtr + size >= mCurEnd)
|
||||
{
|
||||
if ((size > (mCurEnd - mCurAlloc) / 2) && (mCurAlloc != null))
|
||||
{
|
||||
mLageAllocs += size;
|
||||
void* largeAlloc = AllocLarge(size, align);
|
||||
if (mLargeRawAllocs == null)
|
||||
mLargeRawAllocs = new List<void*>();
|
||||
mLargeRawAllocs.Add(largeAlloc);
|
||||
return largeAlloc;
|
||||
}
|
||||
|
||||
GrowPool();
|
||||
}
|
||||
|
||||
uint8* ptr = mCurPtr;
|
||||
mCurPtr += size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
protected void* AllocWithDtor(int size, int align)
|
||||
{
|
||||
mCurPtr = (uint8*)(void*)(((int)(void*)mCurPtr + align - 1) & ~(align - 1));
|
||||
|
||||
while (mCurPtr + size >= mCurEnd)
|
||||
{
|
||||
if ((size > (mCurEnd - mCurAlloc) / 2) && (mCurAlloc != null))
|
||||
{
|
||||
mLageAllocs += size;
|
||||
void* largeAlloc = AllocLarge(size, align);
|
||||
if (mLargeDtorAllocs == null)
|
||||
mLargeDtorAllocs = new List<Object>();
|
||||
mLargeDtorAllocs.Add(Internal.UnsafeCastToObject(largeAlloc));
|
||||
return largeAlloc;
|
||||
}
|
||||
|
||||
GrowPool();
|
||||
}
|
||||
|
||||
DtorEntry dtorEntry;
|
||||
dtorEntry.mPoolIdx = (uint16)mPools.Count - 1;
|
||||
dtorEntry.mPoolOfs = (uint16)(mCurPtr - mCurAlloc);
|
||||
if (mDtorEntries == null)
|
||||
mDtorEntries = new List<DtorEntry>();
|
||||
mDtorEntries.Add(dtorEntry);
|
||||
|
||||
uint8* ptr = mCurPtr;
|
||||
mCurPtr += size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||
public void* AllocTyped(Type type, int size, int align)
|
||||
{
|
||||
bool markData = type.WantsMark;
|
||||
if (mPools == null)
|
||||
{
|
||||
mMarkData = markData;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mMarkData != markData)
|
||||
{
|
||||
if (mPairedAllocator == null)
|
||||
{
|
||||
mPairedAllocator = new BumpAllocator();
|
||||
mPairedAllocator.mMarkData = markData;
|
||||
}
|
||||
return mPairedAllocator.Alloc(size, align);
|
||||
}
|
||||
}
|
||||
|
||||
if ((DestructorHandling != .Ignore) && (type.HasDestructor))
|
||||
{
|
||||
if (DestructorHandling == .Fail)
|
||||
Runtime.FatalError("Destructor not allowed");
|
||||
return AllocWithDtor(size, align);
|
||||
}
|
||||
|
||||
return Alloc(size, align);
|
||||
}
|
||||
|
||||
[DisableObjectAccessChecks]
|
||||
protected override void GCMarkMembers()
|
||||
{
|
||||
GC.Mark(mPools);
|
||||
GC.Mark(mLargeRawAllocs);
|
||||
GC.Mark(mLargeDtorAllocs);
|
||||
GC.Mark(mPairedAllocator);
|
||||
GC.Mark(mDtorEntries);
|
||||
if ((mMarkData) && (mPools != null))
|
||||
{
|
||||
let arr = mPools.[Friend]mItems;
|
||||
let size = mPools.[Friend]mSize;
|
||||
if (arr != null)
|
||||
{
|
||||
for (int idx < size)
|
||||
{
|
||||
var pool = arr[idx];
|
||||
GC.Mark(pool.Ptr, pool.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[SkipCall]
|
||||
public void Free(void* ptr)
|
||||
{
|
||||
// Does nothing
|
||||
}
|
||||
|
||||
public int GetAllocSize()
|
||||
{
|
||||
return mPoolsSize - (mCurEnd - mCurPtr);
|
||||
}
|
||||
|
||||
public int GetTotalAllocSize()
|
||||
{
|
||||
return mPoolsSize;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue