diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index ee5069f6..643a332c 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -84,7 +84,9 @@ public: int mReifiedModuleCount; int mIRBytes; - int mConstBytes; + int mConstBytes; + + int mMidCompileRebuilds; }; Stats mStats; diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 2d42dce8..ccc694a9 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -510,7 +510,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) break; auto workItemRef = mMethodSpecializationWorkList[workIdx]; - if (workItemRef == NULL) + if ((workItemRef == NULL) || (!IsWorkItemValid(workItemRef))) { workIdx = mMethodSpecializationWorkList.RemoveAt(workIdx); continue; @@ -577,7 +577,8 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) wantProcessMethod = false; else if (workItem->mType->IsDeleting()) wantProcessMethod = false; - + if (!IsWorkItemValid(workItem)) + wantProcessMethod = false; if (methodInstance != NULL) BF_ASSERT(methodInstance->mMethodProcessRequest == workItem); @@ -633,7 +634,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) if (methodInstance != NULL) methodInstance->mMethodProcessRequest = NULL; - if ((!module->mAwaitingFinish) && (module->WantsFinishModule())) + if ((!module->mAwaitingFinish) && (module->WantsFinishModule()) && (wantProcessMethod)) { BfLogSysM("Module finished: %p %s HadBuildErrors:%d\n", module, module->mModuleName.c_str(), module->mHadBuildError); QueueFinishModule(module); @@ -772,7 +773,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) BF_ASSERT(module->mContext == this); BF_ASSERT(module->mIsModuleMutable); - if (module->WantsFinishModule()) + if ((wantProcessMethod) && (!module->mAwaitingFinish) && (module->WantsFinishModule())) { BfLogSysM("Module finished: %s (from inlining)\n", module->mModuleName.c_str()); QueueFinishModule(module); @@ -1269,9 +1270,8 @@ void BfContext::RebuildDependentTypes_MidCompile(BfDependedType* dType, const St BF_ASSERT(!module->mIsDeleting); BF_ASSERT(!module->mOwnedTypeInstances.IsEmpty()); } - - + mCompiler->mStats.mMidCompileRebuilds++; dType->mRebuildFlags = (BfTypeRebuildFlags)(dType->mRebuildFlags | BfTypeRebuildFlag_ChangedMidCompile); int prevDeletedTypes = mCompiler->mStats.mTypesDeleted; if (mCompiler->mIsResolveOnly) @@ -2978,6 +2978,52 @@ void ReportRemovedItem(BfMethodProcessRequest* workItem BfLogSys(workItem->mFromModule->mSystem, "DoRemoveInvalidWorkItems MethodInstance:%p\n", workItem->mMethodInstance); } +bool BfContext::IsWorkItemValid(BfWorkListEntry* item) +{ + return true; +} + +bool BfContext::IsWorkItemValid(BfMethodProcessRequest* item) +{ + // If we had mid-compile rebuilds then we may have deleted types referenced in methods + if (mCompiler->mStats.mMidCompileRebuilds == 0) + return true; + + if (item->mMethodInstance == NULL) + return false; + + for (auto& param : item->mMethodInstance->mParams) + { + if (param.mResolvedType->IsDeleting()) + return false; + } + + if (item->mMethodInstance->mMethodInfoEx != NULL) + { + for (auto genericArg : item->mMethodInstance->mMethodInfoEx->mMethodGenericArguments) + if (genericArg->IsDeleting()) + return false; + } + + return true; +} + +bool BfContext::IsWorkItemValid(BfMethodSpecializationRequest* item) +{ + // If we had mid-compile rebuilds then we may have deleted types referenced in methods + if (mCompiler->mStats.mMidCompileRebuilds == 0) + return true; + + for (auto type : item->mMethodGenericArguments) + if (type->IsDeleting()) + return false; + + if ((item->mForeignType != NULL) && (item->mForeignType->IsDeleting())) + return false; + + return true; +} + template void DoRemoveInvalidWorkItems(BfContext* bfContext, WorkQueue& workList, bool requireValidType) { @@ -3001,7 +3047,8 @@ void DoRemoveInvalidWorkItems(BfContext* bfContext, WorkQueue& workList, bool ((workItem->mSignatureRevision != -1) && (typeInst != NULL) && (workItem->mSignatureRevision != typeInst->mSignatureRevision)) || ((workItem->mFromModuleRevision != -1) && (workItem->mFromModuleRevision != workItem->mFromModule->mRevision)) || ((workItem->mFromModule != NULL) && (workItem->mFromModule->mIsDeleting)) || - ((requireValidType) && (workItem->mType->mDefineState == BfTypeDefineState_Undefined))) + ((requireValidType) && (workItem->mType->mDefineState == BfTypeDefineState_Undefined)) || + (!bfContext->IsWorkItemValid(workItem))) { if (typeInst != NULL) { diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 48e2138e..57db1d36 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -477,6 +477,9 @@ public: void QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkSpecializedMethodRebuildFlag); void MarkAsReferenced(BfDependedType* depType); void RemoveInvalidFailTypes(); + bool IsWorkItemValid(BfWorkListEntry* item); + bool IsWorkItemValid(BfMethodProcessRequest* item); + bool IsWorkItemValid(BfMethodSpecializationRequest* item); void RemoveInvalidWorkItems(); BfType* FindTypeById(int typeId); void AddTypeToWorkList(BfType* type); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 146cad13..65f62737 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -23343,6 +23343,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } } + BF_ASSERT(!resolvedParamType->IsDeleting()); + if (!methodInstance->IsSpecializedGenericMethod()) AddDependency(resolvedParamType, typeInstance, BfDependencyMap::DependencyFlag_ParamOrReturnValue); PopulateType(resolvedParamType, BfPopulateType_Declaration); @@ -23456,8 +23458,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { hadDelegateParams = true; - // This means we copy the params from a delegate - BfMethodParam methodParam; + // This means we copy the params from a delegate + BfMethodParam methodParam; methodParam.mResolvedType = resolvedParamType; methodParam.mParamDefIdx = paramDefIdx; methodParam.mDelegateParamIdx = 0; @@ -23794,6 +23796,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool // if (methodInstance->mIsReified) // CheckHotMethod(methodInstance, mangledName); + for (auto& param : methodInstance->mParams) + { + BF_ASSERT(!param.mResolvedType->IsDeleting()); + } + BfLogSysM("DoMethodDeclaration %s Module: %p Type: %p MethodInst: %p Reified: %d Unspecialized: %d IRFunction: %d MethodId:%llx\n", mangledName.c_str(), this, mCurTypeInstance, methodInstance, methodInstance->mIsReified, mCurTypeInstance->IsUnspecializedType(), methodInstance->mIRFunction.mId, methodInstance->mIdHash); SizedArray diParams; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index a680207d..b9c986d2 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1171,7 +1171,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType // RebuildMethods(typeInst); // } // else -// mContext->RebuildType(typeInst, false, false); +// mContext->RebuildType(typeInst, false, false); if (typeInst->mGenericTypeInfo != NULL) { @@ -1302,7 +1302,12 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType BfTypeDef* typeDef = NULL; if (typeInstance != NULL) typeDef = typeInstance->mTypeDef; - BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d TypeDef:%p\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId, typeDef); + + auto typeModule = resolvedTypeRef->GetModule(); + if (typeModule != NULL) + BF_ASSERT(!typeModule->mAwaitingFinish); + + BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d TypeDef:%p\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, resolvedTypeRef->GetModule(), resolvedTypeRef->mTypeId, typeDef); BF_ASSERT(!resolvedTypeRef->IsDeleting()); }