mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Another pass at marking scoped raw arrays as deleted
This commit is contained in:
parent
81f8a95cd8
commit
76dfe97d78
5 changed files with 273 additions and 81 deletions
|
@ -140,23 +140,20 @@ namespace System
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetDeleted1(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static void SetDeleted1(void* dest);
|
||||||
*((uint8*)dest) = 0xDD;
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
}
|
static void SetDeleted4(void* dest);
|
||||||
static void SetDeleted4(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static void SetDeleted8(void* dest);
|
||||||
*((uint32*)dest) = 0xDDDDDDDD;
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
}
|
static void SetDeleted16(void* dest);
|
||||||
static void SetDeleted8(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static extern void SetDeletedX(void* dest, int size);
|
||||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
}
|
static extern void SetDeleted(void* dest, int size, int32 align, int arrayCount);
|
||||||
static void SetDeleted16(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static extern void SetDeletedArray(void* dest, int size, int32 align, int arrayCount);
|
||||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
|
||||||
*((uint64*)dest + 1) = 0xDDDDDDDDDDDDDDDDUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int MemCmp(void* memA, void* memB, int length)
|
public static int MemCmp(void* memA, void* memB, int length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,23 +118,20 @@ namespace System
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetDeleted1(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static void SetDeleted1(void* dest);
|
||||||
*((uint8*)dest) = 0xDD;
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
}
|
static void SetDeleted4(void* dest);
|
||||||
static void SetDeleted4(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static void SetDeleted8(void* dest);
|
||||||
*((uint32*)dest) = 0xDDDDDDDD;
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
}
|
static void SetDeleted16(void* dest);
|
||||||
static void SetDeleted8(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static extern void SetDeletedX(void* dest, int size);
|
||||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
}
|
static extern void SetDeleted(void* dest, int size, int32 align, int arrayCount);
|
||||||
static void SetDeleted16(void* dest)
|
[Error("Cannot be called directly"), SkipCall]
|
||||||
{
|
static extern void SetDeletedArray(void* dest, int size, int32 align, int arrayCount);
|
||||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
|
||||||
*((uint64*)dest + 1) = 0xDDDDDDDDDDDDDDDDUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int MemCmp(void* memA, void* memB, int length)
|
public static int MemCmp(void* memA, void* memB, int length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1809,7 +1809,7 @@ BfIRValue BfModule::CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime,
|
||||||
return allocaInst;
|
return allocaInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape)
|
void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape)
|
||||||
{
|
{
|
||||||
//This was removed because we want the alloc to be added to the __deferred list if it's actually a "stack"
|
//This was removed because we want the alloc to be added to the __deferred list if it's actually a "stack"
|
||||||
// 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling
|
// 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling
|
||||||
|
@ -1869,41 +1869,84 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData*
|
||||||
//TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this
|
//TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this
|
||||||
if (mayEscape)
|
if (mayEscape)
|
||||||
{
|
{
|
||||||
// Is this worth it?
|
|
||||||
// if ((!IsOptimized()) && (val.mType->IsComposite()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
|
if ((!IsOptimized()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
|
||||||
// {
|
{
|
||||||
// auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr);
|
auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr);
|
||||||
// bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData);
|
bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData);
|
||||||
// if (!isDyn)
|
if (!isDyn)
|
||||||
// {
|
{
|
||||||
// int clearSize = val.mType->mSize;
|
const char* methodName = arraySize ? "SetDeletedArray" : "SetDeleted";
|
||||||
// BfModuleMethodInstance dtorMethodInstance = GetInternalMethod("MemSet");
|
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName);
|
||||||
// BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
||||||
// SizedArray<BfIRValue, 1> llvmArgs;
|
if (!dtorMethodInstance.mMethodInstance)
|
||||||
// llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
{
|
||||||
// llvmArgs.push_back(GetConstValue8(0xDD));
|
Fail(StrFormat("Unable to find %s", methodName));
|
||||||
// llvmArgs.push_back(GetConstValue(clearSize));
|
}
|
||||||
// llvmArgs.push_back(GetConstValue32(val.mType->mAlign));
|
else
|
||||||
// llvmArgs.push_back(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0));
|
{
|
||||||
// AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
SizedArray<BfIRValue, 1> llvmArgs;
|
||||||
// }
|
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||||
// else
|
llvmArgs.push_back(GetConstValue(val.mType->mSize));
|
||||||
// {
|
llvmArgs.push_back(GetConstValue32(val.mType->mAlign));
|
||||||
// const char* funcName = "SetDeleted1";
|
if (arraySize)
|
||||||
// if (val.mType->mSize >= 16)
|
llvmArgs.push_back(arraySize);
|
||||||
// funcName = "SetDeleted16";
|
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||||
// else if (val.mType->mSize >= 8)
|
}
|
||||||
// funcName = "SetDeleted8";
|
}
|
||||||
// else if (val.mType->mSize >= 4)
|
else
|
||||||
// funcName = "SetDeleted4";
|
{
|
||||||
//
|
if ((arraySize) && (!arraySize.IsConst()) && (val.mType->mSize < mSystem->mPtrSize))
|
||||||
// BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(funcName);
|
{
|
||||||
// BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
BfIRValue clearSize = arraySize;
|
||||||
// SizedArray<BfIRValue, 1> llvmArgs;
|
if (val.mType->GetStride() > 1)
|
||||||
// llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
clearSize = mBfIRBuilder->CreateMul(clearSize, GetConstValue(val.mType->GetStride()));
|
||||||
// AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
|
||||||
// }
|
const char* methodName = "SetDeletedX";
|
||||||
// }
|
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName);
|
||||||
|
BF_ASSERT(dtorMethodInstance);
|
||||||
|
if (!dtorMethodInstance)
|
||||||
|
{
|
||||||
|
Fail(StrFormat("Unable to find %s", methodName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SizedArray<BfIRValue, 1> llvmArgs;
|
||||||
|
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||||
|
llvmArgs.push_back(clearSize);
|
||||||
|
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intptr clearSize = val.mType->mSize;
|
||||||
|
auto constant = mBfIRBuilder->GetConstant(arraySize);
|
||||||
|
if (constant != NULL)
|
||||||
|
clearSize = (intptr)(clearSize * constant->mInt64);
|
||||||
|
|
||||||
|
const char* funcName = "SetDeleted1";
|
||||||
|
if (clearSize >= 16)
|
||||||
|
funcName = "SetDeleted16";
|
||||||
|
else if (clearSize >= 8)
|
||||||
|
funcName = "SetDeleted8";
|
||||||
|
else if (clearSize >= 4)
|
||||||
|
funcName = "SetDeleted4";
|
||||||
|
|
||||||
|
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(funcName);
|
||||||
|
BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
||||||
|
if (!dtorMethodInstance)
|
||||||
|
{
|
||||||
|
Fail(StrFormat("Unable to find %s", funcName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SizedArray<BfIRValue, 1> llvmArgs;
|
||||||
|
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||||
|
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3904,6 +3947,8 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
|
||||||
{
|
{
|
||||||
if (mCurMethodInstance->mHasFailed)
|
if (mCurMethodInstance->mHasFailed)
|
||||||
return;
|
return;
|
||||||
|
if (mCurMethodInstance->mMethodDef->mIsSkipCall)
|
||||||
|
return;
|
||||||
|
|
||||||
BF_ASSERT(mCurMethodInstance->mIRFunction);
|
BF_ASSERT(mCurMethodInstance->mIRFunction);
|
||||||
|
|
||||||
|
@ -7809,7 +7854,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
mBfIRBuilder->SetInsertPoint(clearBlock);
|
mBfIRBuilder->SetInsertPoint(clearBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
|
||||||
|
|
||||||
if (!isConstSize)
|
if (!isConstSize)
|
||||||
{
|
{
|
||||||
|
@ -7839,7 +7884,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
auto loadedPtr = _CreateDynAlloc(sizeValue, arrayType->mAlign);
|
auto loadedPtr = _CreateDynAlloc(sizeValue, arrayType->mAlign);
|
||||||
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapType(arrayType)), arrayType);
|
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapType(arrayType)), arrayType);
|
||||||
if (!noDtorCall)
|
if (!noDtorCall)
|
||||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
|
||||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||||
return typedVal.mValue;
|
return typedVal.mValue;
|
||||||
}
|
}
|
||||||
|
@ -7878,7 +7923,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
if (!isDynAlloc)
|
if (!isDynAlloc)
|
||||||
mBfIRBuilder->SetInsertPoint(prevBlock);
|
mBfIRBuilder->SetInsertPoint(prevBlock);
|
||||||
if (!noDtorCall)
|
if (!noDtorCall)
|
||||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
|
||||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||||
return typedVal.mValue;
|
return typedVal.mValue;
|
||||||
}
|
}
|
||||||
|
@ -7898,7 +7943,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
auto loadedPtr = _CreateDynAlloc(sizeValue, typeInstance->mAlign);
|
auto loadedPtr = _CreateDynAlloc(sizeValue, typeInstance->mAlign);
|
||||||
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance);
|
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance);
|
||||||
if (!noDtorCall)
|
if (!noDtorCall)
|
||||||
AddStackAlloc(typedVal, NULL, scopeData, mCurMethodState->mInConditionalBlock, true);
|
AddStackAlloc(typedVal, arraySize, NULL, scopeData, mCurMethodState->mInConditionalBlock, true);
|
||||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||||
return typedVal.mValue;
|
return typedVal.mValue;
|
||||||
}
|
}
|
||||||
|
@ -7965,7 +8010,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
bool doCondAlloca = false;
|
bool doCondAlloca = false;
|
||||||
if (!IsTargetingBeefBackend())
|
if (!IsTargetingBeefBackend())
|
||||||
doCondAlloca = !wasDynAlloc && isDynAlloc && mCurMethodState->mInConditionalBlock;
|
doCondAlloca = !wasDynAlloc && isDynAlloc && mCurMethodState->mInConditionalBlock;
|
||||||
AddStackAlloc(typedVal, NULL, scopeData, doCondAlloca, true);
|
AddStackAlloc(typedVal, arraySize, NULL, scopeData, doCondAlloca, true);
|
||||||
}
|
}
|
||||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||||
|
|
||||||
|
@ -8009,7 +8054,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!noDtorCall)
|
if (!noDtorCall)
|
||||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
AddStackAlloc(typedVal, BfIRValue(), NULL, scopeData, false, true);
|
||||||
if (typeInstance != NULL)
|
if (typeInstance != NULL)
|
||||||
{
|
{
|
||||||
InitTypeInst(typedVal, scopeData, zeroMemory, GetConstValue(typeInstance->mInstSize));
|
InitTypeInst(typedVal, scopeData, zeroMemory, GetConstValue(typeInstance->mInstSize));
|
||||||
|
|
|
@ -1468,7 +1468,7 @@ public:
|
||||||
void NewScopeState(bool createLexicalBlock = true, bool flushValueScope = true); // returns prev scope data
|
void NewScopeState(bool createLexicalBlock = true, bool flushValueScope = true); // returns prev scope data
|
||||||
BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue());
|
BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue());
|
||||||
BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL);
|
BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL);
|
||||||
void AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false);
|
void AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false);
|
||||||
void RestoreScoreState_LocalVariables();
|
void RestoreScoreState_LocalVariables();
|
||||||
void RestoreScopeState();
|
void RestoreScopeState();
|
||||||
void MarkDynStack(BfScopeData* scope);
|
void MarkDynStack(BfScopeData* scope);
|
||||||
|
|
|
@ -540,6 +540,160 @@ BfDeferredCallEntry* BfModule::AddDeferredCall(const BfModuleMethodInstance& mod
|
||||||
|
|
||||||
void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags)
|
void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags)
|
||||||
{
|
{
|
||||||
|
if (moduleMethodInstance.mMethodInstance->GetOwner()->IsInstanceOf(mCompiler->mInternalTypeDef))
|
||||||
|
{
|
||||||
|
if (moduleMethodInstance.mMethodInstance->mMethodDef->mName.StartsWith("SetDeleted"))
|
||||||
|
{
|
||||||
|
intptr typeSize = 0;
|
||||||
|
intptr typeAlign = 1;
|
||||||
|
intptr clearSize = 0;
|
||||||
|
bool isDynSize = false;
|
||||||
|
|
||||||
|
bool mayBeZero = false;
|
||||||
|
auto ptrValue = llvmArgs[0];
|
||||||
|
BfIRValue arraySize;
|
||||||
|
|
||||||
|
if ((moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted") ||
|
||||||
|
(moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedArray"))
|
||||||
|
{
|
||||||
|
auto constant = mBfIRBuilder->GetConstant(llvmArgs[1]);
|
||||||
|
if (constant != NULL)
|
||||||
|
typeSize = constant->mInt64;
|
||||||
|
constant = mBfIRBuilder->GetConstant(llvmArgs[2]);
|
||||||
|
if (constant != NULL)
|
||||||
|
typeAlign = constant->mInt64;
|
||||||
|
auto arraySize = llvmArgs[3];
|
||||||
|
|
||||||
|
intptr allocSize = typeSize;
|
||||||
|
if (arraySize)
|
||||||
|
{
|
||||||
|
allocSize = BF_ALIGN(typeSize, typeAlign);
|
||||||
|
auto constant = mBfIRBuilder->GetConstant(arraySize);
|
||||||
|
if (constant != NULL)
|
||||||
|
allocSize = allocSize * (intptr)constant->mInt64;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isDynSize = true;
|
||||||
|
mayBeZero = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearSize = BF_MIN(allocSize, mSystem->mPtrSize);
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedX")
|
||||||
|
{
|
||||||
|
// Note: this infers that mayBeZero is false still, because the deferred call would not have
|
||||||
|
// been added if the array size was zero
|
||||||
|
typeSize = 1;
|
||||||
|
clearSize = typeSize;
|
||||||
|
arraySize = llvmArgs[1];
|
||||||
|
isDynSize = true;
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted1")
|
||||||
|
{
|
||||||
|
clearSize = 1;
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted2")
|
||||||
|
{
|
||||||
|
clearSize = 2;
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted4")
|
||||||
|
{
|
||||||
|
clearSize = 4;
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted8")
|
||||||
|
{
|
||||||
|
clearSize = 8;
|
||||||
|
}
|
||||||
|
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted16")
|
||||||
|
{
|
||||||
|
clearSize = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearSize > 0)
|
||||||
|
{
|
||||||
|
BfTypeCode clearTypeCode = BfTypeCode_Int8;
|
||||||
|
if (clearSize >= mSystem->mPtrSize)
|
||||||
|
clearTypeCode = BfTypeCode_IntPtr;
|
||||||
|
else if (clearSize >= 4)
|
||||||
|
clearTypeCode = BfTypeCode_Int32;
|
||||||
|
else if (clearSize >= 2)
|
||||||
|
clearTypeCode = BfTypeCode_Int16;
|
||||||
|
|
||||||
|
auto intType = GetPrimitiveType(clearTypeCode);
|
||||||
|
auto intPtrType = CreatePointerType(intType);
|
||||||
|
|
||||||
|
if (isDynSize)
|
||||||
|
{
|
||||||
|
if (clearSize >= mSystem->mPtrSize)
|
||||||
|
{
|
||||||
|
auto ddSize1Block = mBfIRBuilder->CreateBlock("DDSize1");
|
||||||
|
auto ddDoneBlock = mBfIRBuilder->CreateBlock("DDDone");
|
||||||
|
|
||||||
|
auto cmp = mBfIRBuilder->CreateCmpGT(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), true);
|
||||||
|
mBfIRBuilder->CreateCondBr(cmp, ddSize1Block, ddDoneBlock);
|
||||||
|
|
||||||
|
mBfIRBuilder->AddBlock(ddSize1Block);
|
||||||
|
mBfIRBuilder->SetInsertPoint(ddSize1Block);
|
||||||
|
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
|
||||||
|
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
|
||||||
|
mBfIRBuilder->CreateBr(ddDoneBlock);
|
||||||
|
|
||||||
|
mBfIRBuilder->AddBlock(ddDoneBlock);
|
||||||
|
mBfIRBuilder->SetInsertPoint(ddDoneBlock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we allocate at least this many then we can do an IntPtr-sized marking, otherwise just one element's worth
|
||||||
|
int intPtrCount = (int)((mSystem->mPtrSize + typeSize - 1) / typeSize);
|
||||||
|
|
||||||
|
BfIRBlock ddSizePtrBlock = mBfIRBuilder->CreateBlock("DDSizePtr");
|
||||||
|
BfIRBlock ddCheck1Block = mBfIRBuilder->CreateBlock("DDCheck1");
|
||||||
|
BfIRBlock ddSize1Block;
|
||||||
|
if (mayBeZero)
|
||||||
|
ddSize1Block = mBfIRBuilder->CreateBlock("DDSize1");
|
||||||
|
BfIRBlock ddDoneBlock = mBfIRBuilder->CreateBlock("DDDone");
|
||||||
|
|
||||||
|
auto intptrType = GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
|
auto intptrPtrType = CreatePointerType(intptrType);
|
||||||
|
|
||||||
|
auto cmpPtr = mBfIRBuilder->CreateCmpGTE(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, intPtrCount), true);
|
||||||
|
mBfIRBuilder->CreateCondBr(cmpPtr, ddSizePtrBlock, ddCheck1Block);
|
||||||
|
|
||||||
|
mBfIRBuilder->AddBlock(ddSizePtrBlock);
|
||||||
|
mBfIRBuilder->SetInsertPoint(ddSizePtrBlock);
|
||||||
|
auto intptrPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intptrPtrType));
|
||||||
|
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0xDDDDDDDDDDDDDDDDULL), intptrPtrVal);
|
||||||
|
mBfIRBuilder->CreateBr(ddDoneBlock);
|
||||||
|
|
||||||
|
mBfIRBuilder->AddBlock(ddCheck1Block);
|
||||||
|
mBfIRBuilder->SetInsertPoint(ddCheck1Block);
|
||||||
|
if (mayBeZero)
|
||||||
|
{
|
||||||
|
auto cmp1 = mBfIRBuilder->CreateCmpGT(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), true);
|
||||||
|
mBfIRBuilder->CreateCondBr(cmp1, ddSize1Block, ddDoneBlock);
|
||||||
|
|
||||||
|
mBfIRBuilder->AddBlock(ddSize1Block);
|
||||||
|
mBfIRBuilder->SetInsertPoint(ddSize1Block);
|
||||||
|
}
|
||||||
|
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
|
||||||
|
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
|
||||||
|
mBfIRBuilder->CreateBr(ddDoneBlock);
|
||||||
|
|
||||||
|
mBfIRBuilder->AddBlock(ddDoneBlock);
|
||||||
|
mBfIRBuilder->SetInsertPoint(ddDoneBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
|
||||||
|
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (moduleMethodInstance.mMethodInstance == mContext->mValueTypeDeinitSentinel)
|
if (moduleMethodInstance.mMethodInstance == mContext->mValueTypeDeinitSentinel)
|
||||||
{
|
{
|
||||||
BF_ASSERT(llvmArgs.size() == 3);
|
BF_ASSERT(llvmArgs.size() == 3);
|
||||||
|
@ -660,7 +814,6 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto moduleMethodInstance = deferredCallEntry.mModuleMethodInstance;
|
|
||||||
auto args = deferredCallEntry.mScopeArgs;
|
auto args = deferredCallEntry.mScopeArgs;
|
||||||
if (deferredCallEntry.mArgsNeedLoad)
|
if (deferredCallEntry.mArgsNeedLoad)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue