From 558f8678e12dc683a09cb719ca331ae20063ed2c Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 2 Nov 2019 06:07:16 -0700 Subject: [PATCH] Fixed dependency issues, added some dependency validation --- IDE/src/Workspace.bf | 1 - IDEHelper/Backend/BeIRCodeGen.cpp | 21 +++++++++++++++++- IDEHelper/Compiler/BfCompiler.cpp | 34 +++++++++++++++-------------- IDEHelper/Compiler/BfContext.cpp | 36 +++++++++++++++++++++++++++++++ IDEHelper/Compiler/BfContext.h | 3 ++- 5 files changed, 76 insertions(+), 19 deletions(-) diff --git a/IDE/src/Workspace.bf b/IDE/src/Workspace.bf index 262c5819..8f6642a8 100644 --- a/IDE/src/Workspace.bf +++ b/IDE/src/Workspace.bf @@ -1,4 +1,3 @@ - using System; using System.Collections.Generic; using System.Text; diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index fc090bd6..39e87ab4 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -1495,11 +1495,21 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_Load: { CMD_PARAM(BeValue*, val); -#ifdef _DEBUG +#ifdef _DEBUG auto ptrType = val->GetType(); BF_ASSERT(ptrType->IsPointer()); // We call via a function pointer so there's never a reason to allow loading of a funcPtr BF_ASSERT(((BePointerType*)ptrType)->mElementType->mTypeCode != BeTypeCode_Function); + + // Disallow loading from a NULL constant + if (val->GetTypeId() == BeConstant::TypeId) + { + if (auto constant = BeValueDynCast(val)) + { + BF_ASSERT(constant->mTarget != NULL); + } + } + #endif CMD_PARAM(bool, isVolatile); SetResult(curId, mBeModule->CreateLoad(val, isVolatile)); @@ -1511,6 +1521,15 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, alignment); CMD_PARAM(bool, isVolatile); #ifdef _DEBUG + // Disallow loading from a NULL constant + if (val->GetTypeId() == BeConstant::TypeId) + { + if (auto constant = BeValueDynCast(val)) + { + BF_ASSERT(constant->mTarget != NULL); + } + } + auto ptrType = val->GetType(); BF_ASSERT(ptrType->IsPointer()); #endif diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 974432de..cacf8ca1 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -1073,7 +1073,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) vdataHashCtx.Mixin(project->mTargetType); for (auto type : orderedTypes) - { + { if (type == NULL) continue; @@ -1092,11 +1092,11 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) vdataTypeList.push_back(type); - vdataHashCtx.Mixin(type->mTypeId); + vdataHashCtx.Mixin(type->mTypeId); BF_ASSERT((type != NULL) || (mPassInstance->HasFailed())); if ((type != NULL) && (typeInst != NULL)) - { + { auto module = typeInst->mModule; if (module == NULL) continue; @@ -1114,8 +1114,10 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) HashModuleVData(module, vdataHashCtx); } } - + + vdataHashCtx.MixinStr(module->mModuleName); vdataHashCtx.Mixin(typeInst->mTypeDef->mSignatureHash); + vdataHashCtx.Mixin(module->mHasForceLinkMarker); for (auto iface : typeInst->mInterfaces) { @@ -2064,7 +2066,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) // If we're deleting the type, OR the dependency of the type has been removed. // We detect a removed dependency by the dependent type changing but the dependency revision // is older than the dependent type. - BfLogSysM("Removing old dependent %p from %p\n", dependentType, typeInst); + BfLogSysM("Removing old dependent %p from %p\n", dependentType, depType); itr = depType->mDependencyMap.erase(itr); } else @@ -2171,7 +2173,9 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) if (deleteQueue.size() != 0) { + mContext->ValidateDependencies(); mContext->UpdateAfterDeletingTypes(); + mContext->ValidateDependencies(); } } @@ -2964,13 +2968,6 @@ void BfCompiler::UpdateRevisedTypes() compositeTypeDef->mFullNameEx = rootTypeDef->mFullNameEx; compositeTypeDef->mIsCombinedPartial = true; -// if (rootTypeDef->IsGlobalsContainer()) -// { -// //NOP; -// auto didAdd = mSystem->mGlobalsMap.TryAdd(rootTypeDef->mNamespace, compositeTypeDef); -// BF_ASSERT(didAdd); -// } - for (auto prevGenericParam : rootTypeDef->mGenericParamDefs) { BfGenericParamDef* copiedGenericParam = new BfGenericParamDef(); @@ -2979,8 +2976,6 @@ void BfCompiler::UpdateRevisedTypes() } mSystem->mTypeDefs.AddAfter(compositeTypeDef, rootTypeDefEntry); -// compositeTypeDef->mNext = rootTypeDef->mNext; -// rootTypeDef->mNext = compositeTypeDef; partialsHadChanges = true; hadSignatureChange = true; compositeIsNew = true; @@ -3249,9 +3244,13 @@ void BfCompiler::UpdateRevisedTypes() mContext->UpdateRevisedTypes(); mContext->VerifyTypeLookups(); + mContext->ValidateDependencies(); if (mStats.mTypesDeleted != 0) - mContext->UpdateAfterDeletingTypes(); - mContext->RemoveInvalidWorkItems(); + { + mContext->UpdateAfterDeletingTypes(); + mContext->ValidateDependencies(); + } + mContext->RemoveInvalidWorkItems(); for (auto typeDef : mSystem->mTypeDefs) { @@ -6253,6 +6252,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if ((!IsHotCompile()) && (!mCanceling)) ClearUnusedStringPoolEntries(); + mContext->ValidateDependencies(); mContext->UpdateAfterDeletingTypes(); } @@ -6487,6 +6487,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) bool didCancel = mCanceling && hasRequiredTypes; mCanceling = false; + mContext->ValidateDependencies(); + return !didCancel; } diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index e2c907a7..7ef7318c 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -767,6 +767,36 @@ void BfContext::AddTypeToWorkList(BfType* type) } } +void BfContext::ValidateDependencies() +{ +#if _DEBUG + BP_ZONE("BfContext::ValidateDependencies"); + BfLogSysM("ValidateDependencies\n"); + + bool deletedNewTypes = false; + auto itr = mResolvedTypes.begin(); + while (itr != mResolvedTypes.end()) + { + auto type = itr.mCurEntry->mValue; + if (type->IsGenericTypeInstance()) + { + // We can't contain deleted generic arguments without being deleted ourselves + BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type; + + for (auto genericTypeArg : genericType->mTypeGenericArguments) + { + auto depType = genericTypeArg->ToDependedType(); + if (depType != NULL) + { + BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type)); + } + } + } + ++itr; + } +#endif +} + void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuildModule, bool placeSpecializiedInPurgatory) { BfTypeInstance* typeInst = type->ToTypeInstance(); @@ -790,6 +820,12 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild return; } + if (typeInst->mRevision != mCompiler->mRevision) + { + BfLogSysM("Setting revision. Type: %p Revision: %d\n", typeInst, mCompiler->mRevision); + typeInst->mRevision = mCompiler->mRevision; + } + if ((typeInst->IsTypeAlias()) != (typeInst->mTypeDef->mTypeCode == BfTypeCode_TypeAlias)) { BfLogSysM("TypeAlias %p status changed - deleting\n", typeInst); diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 7daab6bb..d0fe8f9b 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -387,8 +387,9 @@ public: void RemoveInvalidWorkItems(); BfType* FindTypeById(int typeId); void AddTypeToWorkList(BfType* type); + void ValidateDependencies(); void RebuildType(BfType* type, bool deleteOnDemandTypes = true, bool rebuildModule = true, bool placeSpecializiedInPurgatory = true); - void RebuildDependentTypes(BfDependedType* dType); + void RebuildDependentTypes(BfDependedType* dType); void TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange); void TypeMethodSignaturesChanged(BfTypeInstance* typeInst); void TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst);