1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Added AlwaysIncludeUser, fixed context cleanup order

This commit is contained in:
Brian Fiete 2020-12-29 12:41:43 -08:00
parent 8dbfd1b0e3
commit 1954152a6d
9 changed files with 134 additions and 57 deletions

View file

@ -1313,7 +1313,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
continue;
bool needsTypeData = (needsTypeList) || ((type->IsObject()) && (needsObjectTypeData));
bool needsVData = (type->IsObject()) && (typeInst->mHasBeenInstantiated);
bool needsVData = (type->IsObject()) && (typeInst->HasBeenInstantiated());
bool forceReflectFields = false;
@ -2764,7 +2764,7 @@ void BfCompiler::GenerateSlotNums()
if ((typeInstance->mSlotNum <= 0) || (!isHotCompile))
{
if ((mContext->mReferencedIFaceSlots.Contains(typeInstance)) ||
(typeInstance->mHasBeenInstantiated) || (typeInstance->mIncludeAllMethods))
(typeInstance->mHasBeenInstantiated) || (typeInstance->IncludeAllMethods()))
{
if (typeInstance->mSlotNum == -2)
typeInstance->mSlotNum = -1;
@ -5437,7 +5437,7 @@ void BfCompiler::PopulateReified()
}
// Only check virtual stuff if we have been instantiated
if (typeInst->mHasBeenInstantiated)
if (typeInst->HasBeenInstantiated())
{
// If we have any virtual methods overrides that are unreified but the declaring virtual method is reified then we also need to reify
for (auto&& vEntry : typeInst->mVirtualMethodTable)
@ -5468,7 +5468,7 @@ void BfCompiler::PopulateReified()
auto checkType = typeInst;
while (checkType != NULL)
{
if ((checkType != typeInst) && (checkType->mHasBeenInstantiated))
if ((checkType != typeInst) && (checkType->HasBeenInstantiated()))
{
// We will already check this type here in its own loop
break;
@ -8854,7 +8854,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler,
{
if (typeInst->mIsReified)
outString += " Reified";
if (typeInst->mHasBeenInstantiated)
if (typeInst->HasBeenInstantiated())
outString += " Instantiated";
if (typeInst->mTypeFailed)
outString += " TypeFailed";

View file

@ -58,7 +58,8 @@ public:
CompileState_None,
CompileState_Normal,
CompileState_Unreified,
CompileState_VData
CompileState_VData,
CompileState_Cleanup
};
struct Stats

View file

@ -2778,6 +2778,26 @@ void BfContext::Cleanup()
// Can't clean up LLVM types, they are allocated with a bump allocator
RemoveInvalidFailTypes();
mCompiler->mCompileState = BfCompiler::CompileState_Cleanup;
// We can't remove the local methods if they still may be referenced by a BfMethodRefType used to specialize a method
if (mMethodWorkList.empty())
{
Array<BfLocalMethod*> survivingLocalMethods;
for (auto localMethod : mLocalMethodGraveyard)
{
if ((localMethod->mMethodInstanceGroup != NULL) && (localMethod->mMethodInstanceGroup->mRefCount > 0))
{
localMethod->Dispose();
survivingLocalMethods.push_back(localMethod);
}
else
delete localMethod;
}
mLocalMethodGraveyard = survivingLocalMethods;
}
// Clean up deleted BfTypes
// These need to get deleted before the modules because we access mModule in the MethodInstance dtors
for (auto type : mTypeGraveyard)
@ -2805,21 +2825,6 @@ void BfContext::Cleanup()
delete typeDef;
mTypeDefGraveyard.Clear();
// We can't remove the local methods if they still may be referenced by a BfMethodRefType used to specialize a method
if (mMethodWorkList.empty())
{
Array<BfLocalMethod*> survivingLocalMethods;
for (auto localMethod : mLocalMethodGraveyard)
{
if ((localMethod->mMethodInstanceGroup != NULL) && (localMethod->mMethodInstanceGroup->mRefCount > 0))
survivingLocalMethods.push_back(localMethod);
else
delete localMethod;
}
mLocalMethodGraveyard = survivingLocalMethods;
}
mScratchModule->Cleanup();
mUnreifiedModule->Cleanup();
for (auto module : mModules)

View file

@ -87,6 +87,20 @@ BfLocalMethod::~BfLocalMethod()
delete mMethodDef;
}
void BfLocalMethod::Dispose()
{
if (mMethodInstanceGroup == NULL)
return;
if (mMethodInstanceGroup->mDefault != NULL)
mMethodInstanceGroup->mDefault->Dispose();
if (mMethodInstanceGroup->mMethodSpecializationMap != NULL)
{
for (auto& kv : *mMethodInstanceGroup->mMethodSpecializationMap)
kv.mValue->Dispose();
}
}
void BfDeferredLocalAssignData::ExtendFrom(BfDeferredLocalAssignData* outerLocalAssignData, bool doChain)
{
mIsChained = doChain;
@ -1185,6 +1199,12 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
// causes other types rebuild BEFORE they get deleted, which is okay (though wasteful)
//BF_ASSERT((mProject == NULL) || (!mProject->mDisabled));
if (mCompiler->mCompileState == BfCompiler::CompileState_Cleanup)
{
// Cleaning up local methods may cause some necessary NewRevisions
force = true;
}
// Already on new revision?
if ((mRevision == mCompiler->mRevision) && (!force))
return;
@ -1887,7 +1907,7 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* r
return;
auto checkBaseType = val.mType->ToTypeInstance();
if ((checkBaseType != NULL) && (checkBaseType->IsObject()))
if ((checkBaseType != NULL) && (checkBaseType->IsObject()) && (!arraySize))
{
bool hadDtorCall = false;
while (checkBaseType != NULL)
@ -8571,7 +8591,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto loadedPtr = _CreateDynAlloc(sizeValue, arrayType->mAlign);
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapType(arrayType)), arrayType);
if (!noDtorCall)
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
AddStackAlloc(typedVal, BfIRValue(), NULL, scopeData, false, true);
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
return typedVal.mValue;
}
@ -8610,7 +8630,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(arrayType)), arrayType);
mBfIRBuilder->ClearDebugLocation_Last();
if (!noDtorCall)
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
AddStackAlloc(typedVal, BfIRValue(), NULL, scopeData, false, true);
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
return typedVal.mValue;
}
@ -11118,13 +11138,13 @@ void BfModule::ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bo
{
auto constant = mCurTypeInstance->mConstHolder->GetConstant(setProp.mParam.mValue);
if ((constant != NULL) && (constant->mBool))
mCurTypeInstance->mHasBeenInstantiated = true;
mCurTypeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(mCurTypeInstance->mAlwaysIncludeFlags | BfAlwaysIncludeFlag_AssumeInstantiated);
}
else if (propertyDef->mName == "IncludeAllMethods")
{
auto constant = mCurTypeInstance->mConstHolder->GetConstant(setProp.mParam.mValue);
if ((constant != NULL) && (constant->mBool))
mCurTypeInstance->mIncludeAllMethods = true;
mCurTypeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(mCurTypeInstance->mAlwaysIncludeFlags | BfAlwaysIncludeFlag_IncludeAllMethods);
}
}
}
@ -11149,6 +11169,12 @@ void BfModule::ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bo
}
}
}
if (customAttribute.mType->mAttributeData == NULL)
PopulateType(customAttribute.mType);
BF_ASSERT(customAttribute.mType->mAttributeData != NULL);
if ((customAttribute.mType->mAttributeData != NULL) && ((customAttribute.mType->mAttributeData->mAlwaysIncludeUser & BfAlwaysIncludeFlag_AssumeInstantiated) != 0))
mCurTypeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(mCurTypeInstance->mAlwaysIncludeFlags | customAttribute.mType->mAttributeData->mAlwaysIncludeUser);
}
}
}
@ -11205,6 +11231,12 @@ void BfModule::ProcessCustomAttributeData()
if (constant != NULL)
attributeData->mAttributeTargets = (BfAttributeTargets)constant->mInt32;
}
else if (propDef->mName == "AlwaysIncludeUser")
{
auto constant = mCurTypeInstance->mConstHolder->GetConstant(setProp.mParam.mValue);
if (constant != NULL)
attributeData->mAlwaysIncludeUser = (BfAlwaysIncludeFlags)constant->mInt32;
}
}
hasCustomAttribute = true;
@ -11217,6 +11249,7 @@ void BfModule::ProcessCustomAttributeData()
attributeData->mAttributeTargets = mCurTypeInstance->mBaseType->mAttributeData->mAttributeTargets;
attributeData->mInherited = mCurTypeInstance->mBaseType->mAttributeData->mInherited;
attributeData->mAllowMultiple = mCurTypeInstance->mBaseType->mAttributeData->mAllowMultiple;
attributeData->mAlwaysIncludeUser = mCurTypeInstance->mBaseType->mAttributeData->mAlwaysIncludeUser;
}
mCurTypeInstance->mAttributeData = attributeData;

View file

@ -247,6 +247,7 @@ public:
mNextWithSameName = NULL;
}
~BfLocalMethod();
void Dispose();
};
class BfDeferredCapture

View file

@ -2279,7 +2279,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
return;
}
if ((!mCompiler->mIsResolveOnly) && (!typeInstance->mHasBeenInstantiated))
if ((!mCompiler->mIsResolveOnly) && (!typeInstance->HasBeenInstantiated()))
{
for (auto& dep : typeInstance->mDependencyMap)
{
@ -2814,7 +2814,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
if (typeOptions != NULL)
{
typeInstance->mHasBeenInstantiated = typeOptions->Apply(typeInstance->mHasBeenInstantiated, BfOptionFlags_ReflectAssumeInstantiated);
typeInstance->mHasBeenInstantiated = typeOptions->Apply(typeInstance->HasBeenInstantiated(), BfOptionFlags_ReflectAssumeInstantiated);
}
}
@ -4352,7 +4352,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
implRequired = true;
declRequired = true;
}
if (typeInstance->mIncludeAllMethods)
if (typeInstance->IncludeAllMethods())
implRequired = true;
if ((typeOptionsIncludeAll) && (ApplyTypeOptionMethodFilters(true, methodDef, typeOptions)))
@ -4471,6 +4471,15 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
continue;
if ((constant->mInt8 & BfCustomAttributeFlags_AlwaysIncludeTarget) != 0)
forceMethodImpl = true;
if (attrTypeInst->mAttributeData == NULL)
PopulateType(attrTypeInst);
BF_ASSERT(attrTypeInst->mAttributeData != NULL);
if (attrTypeInst->mAttributeData != NULL)
{
if ((attrTypeInst->mAttributeData->mAlwaysIncludeUser & BfAlwaysIncludeFlag_IncludeAllMethods) != 0)
forceMethodImpl = true;
}
}
}
}

View file

@ -535,9 +535,30 @@ BfMethodInfoEx::~BfMethodInfoEx()
BfMethodInstance::~BfMethodInstance()
{
Dispose(true);
if (mHasMethodRefType)
{
auto module = GetOwner()->mModule;
if (!module->mContext->mDeleting)
{
auto methodRefType = module->CreateMethodRefType(this);
module->mContext->DeleteType(methodRefType);
}
}
delete mMethodInfoEx;
}
void BfMethodInstance::Dispose(bool isDeleting)
{
if (mIsDisposed)
return;
mIsDisposed = true;
if (mMethodInstanceGroup != NULL)
{
BfLogSys(GetOwner()->mModule->mSystem, "BfMethodInstance::~BfMethodInstance %p Local:%d InCEMachine:%d\n", this, mMethodDef->mIsLocalMethod, mInCEMachine);
BfLogSys(GetOwner()->mModule->mSystem, "BfMethodInstance::~BfMethodInstance %p Local:%d InCEMachine:%d Deleting:%d\n", this, mMethodDef->mIsLocalMethod, mInCEMachine, isDeleting);
}
else
{
@ -551,16 +572,6 @@ BfMethodInstance::~BfMethodInstance()
module->mCompiler->mCEMachine->RemoveMethod(this);
}
if (mHasMethodRefType)
{
auto module = GetOwner()->mModule;
if (!module->mContext->mDeleting)
{
auto methodRefType = module->CreateMethodRefType(this);
module->mContext->DeleteType(methodRefType);
}
}
if (mMethodProcessRequest != NULL)
{
BF_ASSERT(mMethodProcessRequest->mMethodInstance == this);
@ -572,8 +583,6 @@ BfMethodInstance::~BfMethodInstance()
mHotMethod->mFlags = (BfHotDepDataFlags)(mHotMethod->mFlags & ~BfHotDepDataFlag_IsBound);
mHotMethod->Deref();
}
delete mMethodInfoEx;
}
void BfMethodInstance::CopyFrom(BfMethodInstance* methodInstance)
@ -2205,6 +2214,8 @@ bool BfTypeInstance::IsAlwaysInclude()
auto typeOptions = mModule->mSystem->GetTypeOptions(mTypeOptionsIdx);
typeOptions->Apply(alwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType);
}
if ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_Type) != 0)
alwaysInclude = true;
return alwaysInclude;
}

View file

@ -822,6 +822,7 @@ public:
bool mDisallowCalling:1;
bool mIsInnerOverride:1;
bool mInCEMachine:1;
bool mIsDisposed:1;
BfMethodChainType mChainType;
BfCallingConvention mCallingConvention;
BfMethodInstanceGroup* mMethodInstanceGroup;
@ -859,6 +860,7 @@ public:
mDisallowCalling = false;
mIsInnerOverride = false;
mInCEMachine = false;
mIsDisposed = false;
mChainType = BfMethodChainType_None;
mCallingConvention = BfCallingConvention_Unspecified;
mMethodInstanceGroup = NULL;
@ -874,6 +876,7 @@ public:
}
~BfMethodInstance();
void Dispose(bool isDeleting = false);
void CopyFrom(BfMethodInstance* methodInstance);
@ -1545,6 +1548,7 @@ class BfAttributeData
{
public:
BfAttributeTargets mAttributeTargets;
BfAlwaysIncludeFlags mAlwaysIncludeUser;
bool mInherited;
bool mAllowMultiple;
@ -1552,6 +1556,7 @@ public:
BfAttributeData()
{
mAttributeTargets = BfAttributeTargets_All;
mAlwaysIncludeUser = BfAlwaysIncludeFlag_None;
mInherited = true;
mAllowMultiple = false;
}
@ -1794,8 +1799,8 @@ public:
int mInstSize;
int16 mInheritDepth;
int16 mSlotNum;
BfAlwaysIncludeFlags mAlwaysIncludeFlags;
bool mHasBeenInstantiated;
bool mIncludeAllMethods;
bool mIsReified;
bool mIsTypedPrimitive;
bool mIsCRepr;
@ -1862,8 +1867,8 @@ public:
mIsFinishingType = false;
mResolvingConstField = false;
mHasPackingHoles = false;
mAlwaysIncludeFlags = BfAlwaysIncludeFlag_None;
mHasBeenInstantiated = false;
mIncludeAllMethods = false;
mWantsGCMarking = false;
mHasParameterizedBase = false;
mHasDeclError = false;
@ -1953,6 +1958,9 @@ public:
BfGenericTypeInfo::GenericParamsVector* GetGenericParamsVector(BfTypeDef* declaringTypeDef);
void GenerateProjectsReferenced();
bool IsAlwaysInclude();
bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
virtual void ReportMemory(MemReporter* memReporter) override;
};

View file

@ -200,7 +200,7 @@ enum BfObjectFlags : uint8
BfObjectFlag_StackDeleted = 0x80 // We remove StackAlloc so it doesn't get scanned
};
enum BfCustomAttributeFlags
enum BfCustomAttributeFlags : uint8
{
BfCustomAttributeFlags_None,
BfCustomAttributeFlags_DisallowAllowMultiple = 1,
@ -209,6 +209,15 @@ enum BfCustomAttributeFlags
BfCustomAttributeFlags_AlwaysIncludeTarget = 8
};
enum BfAlwaysIncludeFlags : uint8
{
BfAlwaysIncludeFlag_None = 0,
BfAlwaysIncludeFlag_Type = 1,
BfAlwaysIncludeFlag_IncludeAllMethods = 2,
BfAlwaysIncludeFlag_AssumeInstantiated = 4,
BfAlwaysIncludeFlag_All = BfAlwaysIncludeFlag_Type | BfAlwaysIncludeFlag_IncludeAllMethods | BfAlwaysIncludeFlag_AssumeInstantiated
};
enum BfPlatformType
{
BfPlatformType_Unknown,