1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-16 23:34:10 +02:00

Fixed GC marking of sized arrays

This commit is contained in:
Brian Fiete 2020-07-24 06:37:50 -07:00
parent 04de0512c3
commit 8fb6f7304d
2 changed files with 92 additions and 10 deletions

View file

@ -12690,14 +12690,19 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa
{
mModule->PopulateType(primStructType);
target.mType = primStructType;
if ((primStructType->IsSplattable()) && (!primStructType->IsTypedPrimitive()))
if (primStructType->IsTypedPrimitive())
{
if (target.IsAddr())
// Type is already the same
}
else if (target.IsAddr())
{
auto ptrType = mModule->CreatePointerType(primStructType);
target = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)), primStructType, true);
}
else
else if (primStructType->IsSplattable())
{
BF_ASSERT(target.IsSplat());
target.mKind = BfTypedValueKind_SplatHead;
}
}

View file

@ -16171,7 +16171,84 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m
}
else if (checkType->IsSizedArray())
{
callMarkMethod = true;
BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)checkType;
if (sizedArrayType->mElementType->WantsGCMarking())
{
BfTypedValue arrayValue = thisValue;
if (thisValue.mType != checkType)
{
BfIRValue srcValue = thisValue.mValue;
if (curOffset != 0)
{
if (!thisValue.mType->IsPointer())
{
auto int8Type = GetPrimitiveType(BfTypeCode_UInt8);
auto int8PtrType = CreatePointerType(int8Type);
srcValue = mBfIRBuilder->CreateBitCast(thisValue.mValue, mBfIRBuilder->MapType(int8PtrType));
}
srcValue = mBfIRBuilder->CreateInBoundsGEP(srcValue, curOffset);
}
arrayValue = BfTypedValue(mBfIRBuilder->CreateBitCast(srcValue, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(checkType))), checkType, BfTypedValueKind_Addr);
}
auto _SizedIndex = [&](BfIRValue target, BfIRValue index)
{
if (sizedArrayType->mElementType->IsSizeAligned())
{
auto ptrType = CreatePointerType(sizedArrayType->mElementType);
auto ptrValue = mBfIRBuilder->CreateBitCast(target, mBfIRBuilder->MapType(ptrType));
auto gepResult = mBfIRBuilder->CreateInBoundsGEP(ptrValue, index);
return BfTypedValue(gepResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
}
else
{
auto indexResult = CreateIndexedValue(sizedArrayType->mElementType, target, index);
return BfTypedValue(indexResult, sizedArrayType->mElementType, BfTypedValueKind_Addr);
}
};
if (sizedArrayType->mElementCount > 6)
{
auto intPtrType = GetPrimitiveType(BfTypeCode_IntPtr);
auto itr = CreateAlloca(intPtrType);
mBfIRBuilder->CreateStore(GetDefaultValue(intPtrType), itr);
auto loopBB = mBfIRBuilder->CreateBlock("loop", true);
auto bodyBB = mBfIRBuilder->CreateBlock("body", true);
auto doneBB = mBfIRBuilder->CreateBlock("done", true);
mBfIRBuilder->CreateBr(loopBB);
mBfIRBuilder->SetInsertPoint(loopBB);
auto loadedItr = mBfIRBuilder->CreateLoad(itr);
auto cmpRes = mBfIRBuilder->CreateCmpGTE(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), true);
mBfIRBuilder->CreateCondBr(cmpRes, doneBB, bodyBB);
mBfIRBuilder->SetInsertPoint(bodyBB);
BfTypedValue value = _SizedIndex(arrayValue.mValue, loadedItr);
EmitGCMarkValue(value, markFromGCThreadMethodInstance);
auto incValue = mBfIRBuilder->CreateAdd(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1));
mBfIRBuilder->CreateStore(incValue, itr);
mBfIRBuilder->CreateBr(loopBB);
mBfIRBuilder->SetInsertPoint(doneBB);
}
else
{
for (int dataIdx = 0; dataIdx < sizedArrayType->mElementCount; dataIdx++)
{
BfTypedValue value = _SizedIndex(arrayValue.mValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, dataIdx));
HashSet<int> objectOffsets;
EmitGCMarkValue(value, markFromGCThreadMethodInstance);
}
}
}
}
else if (typeInstance != NULL)
{