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:
parent
8dbfd1b0e3
commit
1954152a6d
9 changed files with 134 additions and 57 deletions
|
@ -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";
|
||||
|
|
|
@ -58,7 +58,8 @@ public:
|
|||
CompileState_None,
|
||||
CompileState_Normal,
|
||||
CompileState_Unreified,
|
||||
CompileState_VData
|
||||
CompileState_VData,
|
||||
CompileState_Cleanup
|
||||
};
|
||||
|
||||
struct Stats
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -247,6 +247,7 @@ public:
|
|||
mNextWithSameName = NULL;
|
||||
}
|
||||
~BfLocalMethod();
|
||||
void Dispose();
|
||||
};
|
||||
|
||||
class BfDeferredCapture
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue