Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 68 additions & 10 deletions src/coreclr/runtime/portable/AllocFast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
//

#include <fcall.h>
#include <gcinterface.h>
#include "../gc/env/gcenv.ee.h"

extern void RhExceptionHandling_FailedAllocation(MethodTable *pMT, bool isOverflow);
EXTERN_C Object* RhpGcAlloc(MethodTable* pMT, uint32_t uFlags, uintptr_t numElements, void * pTransitionFrame);

EXTERN_C FCDECL2(Object*, RhpNewVariableSizeObject, MethodTable* pMT, INT_PTR numElements)
static Object* _AllocateObject(MethodTable* pMT, uint32_t uFlags, INT_PTR numElements)
{
Object* obj = RhpGcAlloc(pMT, 0, numElements, nullptr);
Object* obj = RhpGcAlloc(pMT, uFlags, numElements, nullptr);
if (obj == NULL)
{
RhExceptionHandling_FailedAllocation(pMT, false /* isOverflow */);
Expand All @@ -18,6 +20,11 @@ EXTERN_C FCDECL2(Object*, RhpNewVariableSizeObject, MethodTable* pMT, INT_PTR nu
return obj;
}

EXTERN_C FCDECL2(Object*, RhpNewVariableSizeObject, MethodTable* pMT, INT_PTR numElements)
{
return _AllocateObject(pMT, 0, numElements);
}

static Object* _RhpNewArrayFastCore(MethodTable* pMT, INT_PTR size)
{
FCALL_CONTRACT;
Expand All @@ -41,7 +48,64 @@ static Object* _RhpNewArrayFastCore(MethodTable* pMT, INT_PTR size)
return pObject;
}

return RhpNewVariableSizeObject(pMT, size);
return _AllocateObject(pMT, 0, size);
}

static Object* _RhpNewArrayFastAlign8Core(MethodTable* pMT, INT_PTR size)
{
FCALL_CONTRACT;
_ASSERTE(pMT != NULL);
_ASSERTE(size < INT32_MAX);

Thread* thread = GetThread();
ee_alloc_context* cxt = thread->GetEEAllocContext();

size_t sizeInBytes = (size_t)pMT->GetBaseSize() + ((size_t)size * (size_t)pMT->RawGetComponentSize());
sizeInBytes = ALIGN_UP(sizeInBytes, sizeof(void*));

uint8_t* alloc_ptr = cxt->getAllocPtr();
int requiresAlignObject = ((uint32_t)alloc_ptr) & 7;
size_t paddedSize = sizeInBytes;
if (requiresAlignObject)
{
paddedSize += 12;
}

ASSERT(alloc_ptr <= cxt->getAllocLimit());
if ((size_t)(cxt->getAllocLimit() - alloc_ptr) >= paddedSize)
{
cxt->setAllocPtr(alloc_ptr + paddedSize);
if (requiresAlignObject)
{
Object* dummy = (Object*)alloc_ptr;
dummy->SetMethodTable(GCToEEInterface::GetFreeObjectMethodTable());
alloc_ptr += 12;
}
PtrArray* pObject = (PtrArray *)alloc_ptr;
pObject->SetMethodTable(pMT);
pObject->SetNumComponents((INT32)size);
return pObject;
}

return _AllocateObject(pMT, GC_ALLOC_ALIGN8, size);
}

EXTERN_C FCDECL2(Object*, RhpNewArrayFastAlign8, MethodTable* pMT, INT_PTR size)
{
FCALL_CONTRACT;
_ASSERTE(pMT != NULL);

#ifndef HOST_64BIT
// if the element count is <= 0x10000, no overflow is possible because the component size is
// <= 0xffff, and thus the product is <= 0xffff0000, and the base size is only ~12 bytes
if (size > 0x10000)
{
// Overflow here should result in an OOM. Let the slow path take care of it.
return _AllocateObject(pMT, GC_ALLOC_ALIGN8, size);
}
#endif // !HOST_64BIT

return _RhpNewArrayFastAlign8Core(pMT, size);
}

EXTERN_C FCDECL2(Object*, RhpNewArrayFast, MethodTable* pMT, INT_PTR size)
Expand All @@ -55,7 +119,7 @@ EXTERN_C FCDECL2(Object*, RhpNewArrayFast, MethodTable* pMT, INT_PTR size)
if (size > 0x10000)
{
// Overflow here should result in an OOM. Let the slow path take care of it.
return RhpNewVariableSizeObject(pMT, size);
return _AllocateObject(pMT, 0, size);
}
#endif // !HOST_64BIT

Expand All @@ -74,12 +138,6 @@ EXTERN_C FCDECL1(Object*, RhpNewFast, MethodTable* pMT)
return nullptr;
}

EXTERN_C FCDECL2(Object*, RhpNewArrayFastAlign8, MethodTable* pMT, INT_PTR size)
{
PORTABILITY_ASSERT("RhpNewArrayFastAlign8 is not yet implemented");
return nullptr;
}

EXTERN_C FCDECL1(Object*, RhpNewFastAlign8, MethodTable* pMT)
{
PORTABILITY_ASSERT("RhpNewFastAlign8 is not yet implemented");
Expand Down
28 changes: 10 additions & 18 deletions src/tests/JIT/interpreter/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2517,16 +2517,12 @@ public static bool TestArray()
if (!ArrayUInt32(32, uint.MinValue)) return false;
if (!ArrayUInt32(32, uint.MaxValue)) return false;

// active issue https://github.com/dotnet/runtime/issues/120659
if (RuntimeInformation.ProcessArchitecture != Architecture.Wasm)
{
// // long
if (!ArrayInt64(0, 0)) return false;
if (!ArrayInt64(1, 1)) return false;
if (!ArrayInt64(32, 32)) return false;
if (!ArrayInt64(32, Int64.MinValue)) return false;
if (!ArrayInt64(32, Int64.MaxValue)) return false;
}
// long
if (!ArrayInt64(0, 0)) return false;
if (!ArrayInt64(1, 1)) return false;
if (!ArrayInt64(32, 32)) return false;
if (!ArrayInt64(32, Int64.MinValue)) return false;
if (!ArrayInt64(32, Int64.MaxValue)) return false;

// float
if (!ArrayFloat(0, 0)) return false;
Expand All @@ -2535,14 +2531,10 @@ public static bool TestArray()
if (!ArrayFloat(32, float.MinValue)) return false;
if (!ArrayFloat(32, float.MaxValue)) return false;

// active issue https://github.com/dotnet/runtime/issues/120659
if (RuntimeInformation.ProcessArchitecture != Architecture.Wasm)
{
// double
if (!ArrayDouble(0, 0)) return false;
if (!ArrayDouble(1, 1)) return false;
if (!ArrayDouble(32, 32)) return false;
}
// double
if (!ArrayDouble(0, 0)) return false;
if (!ArrayDouble(1, 1)) return false;
if (!ArrayDouble(32, 32)) return false;

// ref and value types
if (!TestObjectArray()) return false;
Expand Down
Loading