1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 20:42:21 +02:00

Fixed large allocation issues

This commit is contained in:
Brian Fiete 2019-12-05 06:51:11 -08:00
parent 9ad57895e2
commit c531ade968
5 changed files with 59 additions and 35 deletions

View file

@ -28,8 +28,13 @@ namespace System.Collections.Generic
{
private const int_cosize cDefaultCapacity = 4;
#if BF_LARGE_COLLECTIONS
const int_cosize SizeFlags = 0x7FFFFFFF'FFFFFFFF;
const int_cosize DynAllocFlag = (int_cosize)0x80000000'00000000;
#else
const int_cosize SizeFlags = 0x7FFFFFFF;
const int_cosize DynAllocFlag = (int_cosize)0x80000000;
#endif
#if BF_ENABLE_REALTIME_LEAK_CHECK
static DbgRawAllocData sRawAllocData;
@ -393,11 +398,13 @@ namespace System.Collections.Generic
int allocSize = AllocSize;
if (allocSize < min)
{
int_cosize newCapacity = (int_cosize)(allocSize == 0 ? cDefaultCapacity : allocSize * 2);
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when mItems.Length overflowed thanks to the (uint) cast
//if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
if (newCapacity < min) newCapacity = (int_cosize)min;
int newCapacity = allocSize == 0 ? cDefaultCapacity : allocSize + allocSize / 2;
// If we overflow, try to set to max. The "< min" check after still still bump us up
// if necessary
if (newCapacity > SizeFlags)
newCapacity = SizeFlags;
if (newCapacity < min)
newCapacity = min;
Capacity = newCapacity;
}
}
@ -459,6 +466,23 @@ namespace System.Collections.Generic
#endif
}
public void Insert(int index, Span<T> items)
{
if (items.Length == 0)
return;
int addCount = items.Length;
if (mSize + addCount > AllocSize) EnsureCapacity(mSize + addCount);
if (index < mSize)
{
Internal.MemCpy(mItems + index + addCount, mItems + index, (mSize - index) * strideof(T), alignof(T));
}
Internal.MemCpy(mItems + index, items.Ptr, addCount * strideof(T));
mSize += (int_cosize)addCount;
#if VERSION_LIST
mVersion++;
#endif
}
public void RemoveAt(int index)
{
Debug.Assert((uint)index < (uint)mSize);

View file

@ -685,7 +685,7 @@ namespace System
void Realloc(int newSize)
{
Debug.Assert(AllocSize > 0, "String has been frozen");
Debug.Assert((uint_strsize)newSize < 0x40000000);
Debug.Assert((uint_strsize)newSize <= cSizeFlags);
char8* newPtr = new:this char8[newSize]*;
Internal.MemCpy(newPtr, Ptr, mLength);
if (IsDynAlloc)
@ -703,7 +703,7 @@ namespace System
void Realloc(char8* newPtr, int newSize)
{
Debug.Assert(AllocSize > 0, "String has been frozen");
Debug.Assert((uint_strsize)newSize < 0x40000000);
Debug.Assert((uint_strsize)newSize <= cSizeFlags);
Internal.MemCpy(newPtr, Ptr, mLength);
if (IsDynAlloc)
delete:this mPtr;