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

Fixed an issue of zombie failed specialized methods in resolve-only

This commit is contained in:
Brian Fiete 2020-07-21 13:14:09 -07:00
parent af9320ada6
commit fed75dfa85
6 changed files with 43 additions and 24 deletions

View file

@ -2125,7 +2125,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
BF_ASSERT(dependentType->IsDeleting() || dependentType->IsOnDemand() || !dependentType->HasBeenReferenced() || !madeFullPass || dependentType->IsSpecializedByAutoCompleteMethod());
}
}
// Not combined with previous loop because PopulateType could modify typeInst->mDependencyMap
for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end();)
{
@ -2168,11 +2168,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
// There needs to be more usage than just being used as part of the method specialization's MethodGenericArg.
// Keep in mind that actually invoking a generic method creates a DependencyFlag_LocalUsage dependency. The
// DependencyFlag_MethodGenericArg is just used by the owner during creation of the method specialization
bool isDependentUsage =
(depData.mFlags & ~(
BfDependencyMap::DependencyFlag_UnspecializedType |
BfDependencyMap::DependencyFlag_MethodGenericArg |
BfDependencyMap::DependencyFlag_GenericArgRef)) != 0;
bool isDependentUsage = (depData.mFlags & BfDependencyMap::DependencyFlag_DependentUsageMask) != 0;
// We need to consider specialized generic types separately, to remove unused specializations
if (typeInst != NULL)
@ -6091,7 +6087,10 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
// Inc revision for next run through Compile
mRevision++;
BfLogSysM("Compile Start. Revision: %d\n", mRevision);
int revision = mRevision;
BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision,
(mResolvePassData != NULL) && (mResolvePassData->mParser != NULL),
(mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL));
if (mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
mContext->mUnreifiedModule->mIsReified = true;
@ -6295,6 +6294,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
if (!hasRequiredTypes)
{
// Force rebuilding
BfLogSysM("Compile missing required types\n");
mInInvalidState = true;
mOptions.mForceRebuildIdx++;
return true;
@ -6902,7 +6902,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
CompileLog("Compile canceled\n");
}
BfLogSysM("TypesPopulated:%d MethodsDeclared:%d MethodsProcessed:%d Canceled? %d\n", mStats.mTypesPopulated, mStats.mMethodDeclarations, mStats.mMethodsProcessed, mCanceling);
BfLogSysM("Compile Done. Revision:%d TypesPopulated:%d MethodsDeclared:%d MethodsProcessed:%d Canceled? %d\n", revision, mStats.mTypesPopulated, mStats.mMethodDeclarations, mStats.mMethodsProcessed, mCanceling);
UpdateCompletion();
if ((!mIsResolveOnly) && (!mPassInstance->HasFailed()) && (!mCanceling))

View file

@ -960,7 +960,9 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
}
}
if ((!mCompiler->mIsResolveOnly) && (addToWorkList))
// At some point we thought we didn't have to do this for resolve-only, but this logic is important for removing
// specialized methods that are causing errors
if (addToWorkList)
{
if (typeDef->mDefState == BfTypeDef::DefState_Signature_Changed)
{
@ -1835,7 +1837,8 @@ void BfContext::UpdateRevisedTypes()
if (!typeInst->IsDeleting())
{
if (!typeInst->mTypeDef->mProject->mDisabled)
{
{
BfLogSysM("Rebuilding failed type %p\n", typeInst);
RebuildType(typeInst);
}
}
@ -2358,13 +2361,12 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS
BF_ASSERT(!typeInst->IsDeleting());
BP_ZONE("BfContext::QueueMethodSpecializations");
BfLogSysM("QueueMethodSpecializations %p\n", typeInst);
auto module = typeInst->mModule;
if (module == NULL)
return;
BfLogSysM("QueueMethodSpecializations methodInst %p module %p\n", typeInst, module);
BfLogSysM("QueueMethodSpecializations typeInst %p module %p\n", typeInst, module);
if (!checkSpecializedMethodRebuildFlag)
{

View file

@ -3035,7 +3035,7 @@ bool BfModule::CheckDefineMemberProtection(BfProtection protection, BfType* memb
return true;
}
void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyDependencyFlag flags)
void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyFlags flags)
{
if (usedType == userType)
return;
@ -5407,7 +5407,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
{
baseTypeId = typeInstance->mBaseType->mTypeId;
}
BfTypeOptions* typeOptions = NULL;
if (typeInstance->mTypeOptionsIdx >= 0)
typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
@ -12048,6 +12048,13 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
{
methodInstance = *methodInstancePtr;
if ((methodInstance->mRequestedByAutocomplete) && (!mCompiler->IsAutocomplete()))
{
// We didn't want to process this message yet if it was autocomplete-specific, but now we will
AddMethodToWorkList(methodInstance);
methodInstance->mRequestedByAutocomplete = false;
}
if ((isReified) && (!methodInstance->mIsReified))
{
MarkDerivedDirty(typeInst);
@ -12208,7 +12215,10 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
BF_ASSERT(added);
methodInstance = new BfMethodInstance();
*methodInstancePtr = methodInstance;
if (mCompiler->IsAutocomplete())
methodInstance->mRequestedByAutocomplete = true;
BfLogSysM("Created Specialized MethodInst: %p TypeInst: %p\n", methodInstance, typeInst);
}
@ -12303,6 +12313,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
if (mCompiler->GetAutoComplete() != NULL)
{
if (typeInst->IsSpecializedByAutoCompleteMethod())
addToWorkList = false;
if (methodInstance->mRequestedByAutocomplete)
addToWorkList = false;
}

View file

@ -1592,7 +1592,7 @@ public:
bool CheckAccessMemberProtection(BfProtection protection, BfType* memberType);
bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType);
void CheckMemberNames(BfTypeInstance* typeInst);
void AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyDependencyFlag flags);
void AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyFlags flags);
void AddCallDependency(BfMethodInstance* methodInstance, bool devirtualized = false);
void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType);
void TypeFailed(BfTypeInstance* typeInstance);

View file

@ -58,7 +58,7 @@ bool BfTypedValue::IsValuelessType() const
//////////////////////////////////////////////////////////////////////////
bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyDependencyFlag flags)
bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyFlags flags)
{
BF_ASSERT(dependentType != NULL);
BF_ASSERT(dependentType->mRevision != -1);
@ -85,7 +85,7 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen
{
if ((dependencyEntry->mFlags & flags) == flags)
return false;
dependencyEntry->mFlags = (BfDependencyMap::DependencyDependencyFlag)(dependencyEntry->mFlags | flags);
dependencyEntry->mFlags = (BfDependencyMap::DependencyFlags)(dependencyEntry->mFlags | flags);
return true;
}
}

View file

@ -75,8 +75,9 @@ enum BfGetMethodInstanceFlags : uint16
class BfDependencyMap
{
public:
enum DependencyDependencyFlag
enum DependencyFlags
{
DependencyFlag_None = 0,
DependencyFlag_Calls = 1,
DependencyFlag_InlinedCall = 2,
DependencyFlag_ReadFields = 4,
@ -102,14 +103,16 @@ public:
DependencyFlag_NameReference = 0x400000,
DependencyFlag_VirtualCall = 0x800000,
DependencyFlag_WeakReference = 0x1000000, // Keeps alive but won't rebuild
DependencyFlag_DependentUsageMask = ~(DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef)
};
struct DependencyEntry
{
int mRevision;
DependencyDependencyFlag mFlags;
DependencyFlags mFlags;
DependencyEntry(int revision, DependencyDependencyFlag flags)
DependencyEntry(int revision, DependencyFlags flags)
{
mRevision = revision;
mFlags = flags;
@ -117,11 +120,11 @@ public:
};
public:
typedef Dictionary<BfType*, DependencyEntry> TypeMap;
typedef Dictionary<BfType*, DependencyEntry> TypeMap;
TypeMap mTypeSet;
public:
bool AddUsedBy(BfType* dependentType, DependencyDependencyFlag flags);
bool AddUsedBy(BfType* dependentType, DependencyFlags flags);
bool IsEmpty();
TypeMap::iterator begin();
TypeMap::iterator end();
@ -791,6 +794,7 @@ public:
bool mHadGenericDelegateParams:1;
bool mIgnoreBody:1;
bool mIsAutocompleteMethod:1;
bool mRequestedByAutocomplete : 1;
bool mIsClosure:1;
bool mMayBeConst:1; // Only used for calcAppend currently
bool mIsForeignMethodDef:1;
@ -825,13 +829,14 @@ public:
mHadGenericDelegateParams = false;
mIgnoreBody = false;
mIsAutocompleteMethod = false;
mRequestedByAutocomplete = false;
mIsClosure = false;
mMayBeConst = true;
mIsForeignMethodDef = false;
mAlwaysInline = false;
mIsIntrinsic = false;
mHasMethodRefType = false;
mDisallowCalling = false;
mDisallowCalling = false;
mChainType = BfMethodChainType_None;
mCallingConvention = BfCallingConvention_Unspecified;
mMethodInstanceGroup = NULL;