From fed75dfa85f8f3da77bfd421ab56ddb2b17ff629 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 21 Jul 2020 13:14:09 -0700 Subject: [PATCH] Fixed an issue of zombie failed specialized methods in resolve-only --- IDEHelper/Compiler/BfCompiler.cpp | 16 ++++++++-------- IDEHelper/Compiler/BfContext.cpp | 10 ++++++---- IDEHelper/Compiler/BfModule.cpp | 18 +++++++++++++++--- IDEHelper/Compiler/BfModule.h | 2 +- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 4 ++-- IDEHelper/Compiler/BfResolvedTypeUtils.h | 17 +++++++++++------ 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index d36e854a..503d9861 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -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)) diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 7a77fe16..9f147df5 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -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) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index a59ee717..47349192 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -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& 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; } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index e42fac57..1bb0ba71 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -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); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 15b38a6a..4aa6b847 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -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; } } diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 7e2c3186..0f48bf21 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -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 TypeMap; + typedef Dictionary 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;