1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48: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()); BF_ASSERT(dependentType->IsDeleting() || dependentType->IsOnDemand() || !dependentType->HasBeenReferenced() || !madeFullPass || dependentType->IsSpecializedByAutoCompleteMethod());
} }
} }
// Not combined with previous loop because PopulateType could modify typeInst->mDependencyMap // Not combined with previous loop because PopulateType could modify typeInst->mDependencyMap
for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end();) 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. // 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 // 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 // DependencyFlag_MethodGenericArg is just used by the owner during creation of the method specialization
bool isDependentUsage = bool isDependentUsage = (depData.mFlags & BfDependencyMap::DependencyFlag_DependentUsageMask) != 0;
(depData.mFlags & ~(
BfDependencyMap::DependencyFlag_UnspecializedType |
BfDependencyMap::DependencyFlag_MethodGenericArg |
BfDependencyMap::DependencyFlag_GenericArgRef)) != 0;
// We need to consider specialized generic types separately, to remove unused specializations // We need to consider specialized generic types separately, to remove unused specializations
if (typeInst != NULL) if (typeInst != NULL)
@ -6091,7 +6087,10 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
// Inc revision for next run through Compile // Inc revision for next run through Compile
mRevision++; 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) if (mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
mContext->mUnreifiedModule->mIsReified = true; mContext->mUnreifiedModule->mIsReified = true;
@ -6295,6 +6294,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
if (!hasRequiredTypes) if (!hasRequiredTypes)
{ {
// Force rebuilding // Force rebuilding
BfLogSysM("Compile missing required types\n");
mInInvalidState = true; mInInvalidState = true;
mOptions.mForceRebuildIdx++; mOptions.mForceRebuildIdx++;
return true; return true;
@ -6902,7 +6902,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
CompileLog("Compile canceled\n"); 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(); UpdateCompletion();
if ((!mIsResolveOnly) && (!mPassInstance->HasFailed()) && (!mCanceling)) 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) if (typeDef->mDefState == BfTypeDef::DefState_Signature_Changed)
{ {
@ -1835,7 +1837,8 @@ void BfContext::UpdateRevisedTypes()
if (!typeInst->IsDeleting()) if (!typeInst->IsDeleting())
{ {
if (!typeInst->mTypeDef->mProject->mDisabled) if (!typeInst->mTypeDef->mProject->mDisabled)
{ {
BfLogSysM("Rebuilding failed type %p\n", typeInst);
RebuildType(typeInst); RebuildType(typeInst);
} }
} }
@ -2358,13 +2361,12 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS
BF_ASSERT(!typeInst->IsDeleting()); BF_ASSERT(!typeInst->IsDeleting());
BP_ZONE("BfContext::QueueMethodSpecializations"); BP_ZONE("BfContext::QueueMethodSpecializations");
BfLogSysM("QueueMethodSpecializations %p\n", typeInst);
auto module = typeInst->mModule; auto module = typeInst->mModule;
if (module == NULL) if (module == NULL)
return; return;
BfLogSysM("QueueMethodSpecializations methodInst %p module %p\n", typeInst, module); BfLogSysM("QueueMethodSpecializations typeInst %p module %p\n", typeInst, module);
if (!checkSpecializedMethodRebuildFlag) if (!checkSpecializedMethodRebuildFlag)
{ {

View file

@ -3035,7 +3035,7 @@ bool BfModule::CheckDefineMemberProtection(BfProtection protection, BfType* memb
return true; 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) if (usedType == userType)
return; return;
@ -5407,7 +5407,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
{ {
baseTypeId = typeInstance->mBaseType->mTypeId; baseTypeId = typeInstance->mBaseType->mTypeId;
} }
BfTypeOptions* typeOptions = NULL; BfTypeOptions* typeOptions = NULL;
if (typeInstance->mTypeOptionsIdx >= 0) if (typeInstance->mTypeOptionsIdx >= 0)
typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx); typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
@ -12048,6 +12048,13 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
{ {
methodInstance = *methodInstancePtr; 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)) if ((isReified) && (!methodInstance->mIsReified))
{ {
MarkDerivedDirty(typeInst); MarkDerivedDirty(typeInst);
@ -12208,7 +12215,10 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
BF_ASSERT(added); BF_ASSERT(added);
methodInstance = new BfMethodInstance(); methodInstance = new BfMethodInstance();
*methodInstancePtr = methodInstance; *methodInstancePtr = methodInstance;
if (mCompiler->IsAutocomplete())
methodInstance->mRequestedByAutocomplete = true;
BfLogSysM("Created Specialized MethodInst: %p TypeInst: %p\n", methodInstance, typeInst); 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 (mCompiler->GetAutoComplete() != NULL)
{ {
if (typeInst->IsSpecializedByAutoCompleteMethod()) if (typeInst->IsSpecializedByAutoCompleteMethod())
addToWorkList = false;
if (methodInstance->mRequestedByAutocomplete)
addToWorkList = false; addToWorkList = false;
} }

View file

@ -1592,7 +1592,7 @@ public:
bool CheckAccessMemberProtection(BfProtection protection, BfType* memberType); bool CheckAccessMemberProtection(BfProtection protection, BfType* memberType);
bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType); bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType);
void CheckMemberNames(BfTypeInstance* typeInst); 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 AddCallDependency(BfMethodInstance* methodInstance, bool devirtualized = false);
void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType); void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType);
void TypeFailed(BfTypeInstance* typeInstance); 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 != NULL);
BF_ASSERT(dependentType->mRevision != -1); BF_ASSERT(dependentType->mRevision != -1);
@ -85,7 +85,7 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen
{ {
if ((dependencyEntry->mFlags & flags) == flags) if ((dependencyEntry->mFlags & flags) == flags)
return false; return false;
dependencyEntry->mFlags = (BfDependencyMap::DependencyDependencyFlag)(dependencyEntry->mFlags | flags); dependencyEntry->mFlags = (BfDependencyMap::DependencyFlags)(dependencyEntry->mFlags | flags);
return true; return true;
} }
} }

View file

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