From d623c214955af1347ad2c1549deb58b5940a02c1 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 6 May 2022 11:28:38 -0700 Subject: [PATCH] Compiler performance enhancements --- BeefySysLib/Common.cpp | 9 + BeefySysLib/Common.h | 1 + BeefySysLib/util/BumpAllocator.h | 25 +- BeefySysLib/util/Dictionary.h | 10 +- BeefySysLib/util/MultiHashSet.h | 349 ++++++++++++++++----- BeefySysLib/util/String.cpp | 5 + BeefySysLib/util/String.h | 1 + IDEHelper/Compiler/BfCompiler.cpp | 99 +++--- IDEHelper/Compiler/BfContext.cpp | 33 +- IDEHelper/Compiler/BfContext.h | 6 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 4 +- IDEHelper/Compiler/BfIRBuilder.cpp | 24 +- IDEHelper/Compiler/BfIRBuilder.h | 2 +- IDEHelper/Compiler/BfModule.cpp | 89 ++++-- IDEHelper/Compiler/BfModule.h | 11 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 76 ++--- IDEHelper/Compiler/BfNamespaceVisitor.cpp | 6 +- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 24 +- IDEHelper/Compiler/BfResolvedTypeUtils.h | 32 +- IDEHelper/Compiler/BfSystem.cpp | 54 +++- IDEHelper/Compiler/BfSystem.h | 108 ++++++- IDEHelper/IDEHelper.vcxproj | 2 +- 22 files changed, 679 insertions(+), 291 deletions(-) diff --git a/BeefySysLib/Common.cpp b/BeefySysLib/Common.cpp index b8591244..28f0e7e9 100644 --- a/BeefySysLib/Common.cpp +++ b/BeefySysLib/Common.cpp @@ -66,6 +66,12 @@ String Beefy::ToUpper(const StringImpl& theString) return aString; } +void Beefy::MakeUpper(StringImpl& theString) +{ + for (int i = 0; i < (int)theString.length(); ++i) + theString[i] = toupper(theString[i]); +} + UTF16String Beefy::ToUpper(const UTF16String& theString) { UTF16String aString = theString; @@ -1282,3 +1288,6 @@ void Beefy::BFFatalError(const char* message, const char* file, int line) BFFatalError(String(message), String(file), line); } +void MakeUpper(const StringImpl& theString) +{ +} diff --git a/BeefySysLib/Common.h b/BeefySysLib/Common.h index 781eb435..72c0de8a 100644 --- a/BeefySysLib/Common.h +++ b/BeefySysLib/Common.h @@ -199,6 +199,7 @@ void OutputDebugStrF(const char* fmt ...); UTF16String ToWString(const StringImpl& theString); String ToString(const UTF16String& theString); String ToUpper(const StringImpl& theString); +void MakeUpper(StringImpl& theString); UTF16String ToUpper(const UTF16String& theString); UTF16String ToLower(const UTF16String& theString); String ToLower(const StringImpl& theString); diff --git a/BeefySysLib/util/BumpAllocator.h b/BeefySysLib/util/BumpAllocator.h index e92a678b..5b2037b3 100644 --- a/BeefySysLib/util/BumpAllocator.h +++ b/BeefySysLib/util/BumpAllocator.h @@ -255,11 +255,11 @@ class BumpAllocator : public BumpAllocatorT<0x2000> }; -template +template class AllocatorBump { public: - BumpAllocator* mAlloc; + BumpAllocatorT* mAlloc; AllocatorBump() { @@ -286,6 +286,27 @@ public: } }; +template +class RawAllocatorBump +{ +public: + BumpAllocatorT* mAlloc; + + RawAllocatorBump() + { + mAlloc = NULL; + } + + void* rawAllocate(intptr size) + { + return mAlloc->AllocBytes(size, 16); + } + + void rawDeallocate(void* ptr) + { + + } +}; NS_BF_END diff --git a/BeefySysLib/util/Dictionary.h b/BeefySysLib/util/Dictionary.h index cd15de93..11912fd7 100644 --- a/BeefySysLib/util/Dictionary.h +++ b/BeefySysLib/util/Dictionary.h @@ -1,6 +1,6 @@ #pragma once -#include "../Common.h" +#include "Array.h" #include #define NEW_DICTIONAY @@ -9,8 +9,8 @@ NS_BF_BEGIN; #ifdef NEW_DICTIONAY -template -class Dictionary +template > +class Dictionary : public TAlloc { public: typedef int int_cosize; @@ -411,7 +411,7 @@ public: void AllocData(intptr size, Entry*& outEntries, int_cosize*& outBuckets) { - uint8* data = new uint8[size * (sizeof(Entry) + sizeof(int_cosize))]; + uint8* data = (uint8*)this->rawAllocate(size * (sizeof(Entry) + sizeof(int_cosize))); outEntries = (Entry*)data; outBuckets = (int_cosize*)(data + size * sizeof(Entry)); } @@ -436,7 +436,7 @@ public: } } - delete [] mEntries; + this->rawDeallocate(mEntries); } Dictionary& operator=(const Dictionary& rhs) diff --git a/BeefySysLib/util/MultiHashSet.h b/BeefySysLib/util/MultiHashSet.h index 5ff9efc7..79b04b11 100644 --- a/BeefySysLib/util/MultiHashSet.h +++ b/BeefySysLib/util/MultiHashSet.h @@ -37,15 +37,50 @@ public: struct Entry { T mValue; - Entry* mNext; - int mHash; + int mNext; + int mHashCode; + }; + + struct EntryRef + { + public: + MultiHashSet* mSet; + int mIndex; + + public: + EntryRef() + { + mSet = NULL; + mIndex = -1; + } + + EntryRef(MultiHashSet* set, int index) + { + mSet = set; + mIndex = index; + } + + Entry* operator*() + { + return &this->mSet->mEntries[this->mIndex]; + } + + Entry* operator->() + { + return &this->mSet->mEntries[this->mIndex]; + } + + operator bool() const + { + return this->mIndex != -1; + } }; struct Iterator { - public: + public: MultiHashSet* mSet; - Entry* mCurEntry; + int mCurEntry; int mCurBucket; public: @@ -53,15 +88,15 @@ public: { this->mSet = set; this->mCurBucket = 0; - this->mCurEntry = NULL; + this->mCurEntry = -1; } Iterator& operator++() { - if (this->mCurEntry != NULL) + if (this->mCurEntry != -1) { - this->mCurEntry = this->mCurEntry->mNext; - if (this->mCurEntry != NULL) + this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext; + if (this->mCurEntry != -1) return *this; this->mCurBucket++; } @@ -75,7 +110,7 @@ public: while (this->mCurBucket < mSet->mHashSize) { this->mCurEntry = this->mSet->mHashHeads[mCurBucket]; - if (this->mCurEntry != NULL) + if (this->mCurEntry != -1) return *this; this->mCurBucket++; } @@ -83,43 +118,135 @@ public: return *this; // At end } + T operator*() + { + return this->mSet->mEntries[this->mCurEntry].mValue; + } + + T operator->() + { + return this->mSet->mEntries[this->mCurEntry].mValue; + } + bool operator!=(const Iterator& itr) const { return ((itr.mCurEntry != this->mCurEntry) || (itr.mCurBucket != this->mCurBucket)); } - T operator*() - { - return this->mCurEntry->mValue; - } - operator bool() const { - return this->mCurEntry != NULL; + return this->mCurEntry != -1; } - + void MoveToNextHashMatch() { - int wantHash = this->mCurEntry->mHash; + int wantHash = this->mSet->mEntries[this->mCurEntry].mHashCode; do { - this->mCurEntry = this->mCurEntry->mNext; + this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext; } - while ((this->mCurEntry != NULL) && (this->mCurEntry->mHash != wantHash)); + while ((this->mCurEntry != -1) && (this->mSet->mEntries[this->mCurEntry].mHashCode != wantHash)); } }; -public: - Entry** mHashHeads; +protected: + + int GetPrimeish(int min) + { + // This is a minimal effort to help address-aligned dataa + return (min | 1); + } + + int ExpandSize(int oldSize) + { + int newSize = 2 * oldSize; + + // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow. + // Note that this check works even when mAllocSize overflowed thanks to the (uint) cast + /*if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) + { + Contract.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength"); + return MaxPrimeArrayLength; + }*/ + + return GetPrimeish(newSize); + } + + void ResizeEntries() + { + ResizeEntries(ExpandSize(mCount)); + } + + void ResizeEntries(int newSize) + { + BF_ASSERT(newSize >= mAllocSize); + Entry* newEntries = (Entry*)TFuncs::Allocate(sizeof(Entry) * newSize, alignof(Entry)); + + for (int i = 0; i < mCount; i++) + { + auto& newEntry = newEntries[i]; + auto& oldEntry = mEntries[i]; + newEntry.mHashCode = oldEntry.mHashCode; + newEntry.mNext = oldEntry.mNext; + new (&newEntry.mValue) T(std::move(*(T*)&oldEntry.mValue)); + } + for (int i = mCount; i < newSize; i++) + { + newEntries[i].mHashCode = -1; + } + + TFuncs::Deallocate(mEntries); + + mEntries = newEntries; + mAllocSize = (int)newSize; + } + + void FreeIdx(int entryIdx) + { + this->mEntries[entryIdx].mNext = this->mFreeList; + this->mFreeList = entryIdx; + this->mFreeCount++; + } + + int AllocEntry() + { + int index; + if (this->mFreeCount > 0) + { + index = this->mFreeList; + this->mFreeList = this->mEntries[index].mNext; + this->mFreeCount--; + } + else + { + if (this->mCount == this->mAllocSize) + ResizeEntries(); + index = mCount; + this->mCount++; + } + return index; + } + +public: + int* mHashHeads; + int mAllocSize; + Entry* mEntries; + int mFreeList; + int mFreeCount; + static const int cDefaultHashSize = 17; int mHashSize; int mCount; MultiHashSet() - { + { this->mHashHeads = NULL; this->mHashSize = cDefaultHashSize; + this->mEntries = NULL; + this->mAllocSize = 0; this->mCount = 0; + this->mFreeList = -1; + this->mFreeCount = 0; } ~MultiHashSet() @@ -127,71 +254,118 @@ public: this->Clear(); } + void EnsureFreeCount(int wantFreeCount) + { + int freeCount = mFreeCount + (mAllocSize - mCount); + if (freeCount >= wantFreeCount) + return; + ResizeEntries(BF_MAX(ExpandSize(mCount), mAllocSize + wantFreeCount - freeCount)); + } + + int GetCount() const + { + return mCount - mFreeCount; + } + + int size() const + { + return mCount - mFreeCount; + } + + EntryRef AddRaw(int hash) + { + if (this->mHashHeads == NULL) + { + this->mHashHeads = (int*)TFuncs::Allocate(sizeof(int) * mHashSize, alignof(int)); + memset(this->mHashHeads, -1, sizeof(int) * mHashSize); + } + + int index = AllocEntry(); + int hashIdx = (hash & 0x7FFFFFFF) % this->mHashSize; + int headEntry = this->mHashHeads[hashIdx]; + + Entry* newEntry = &mEntries[index]; + newEntry->mValue = T(); + newEntry->mNext = headEntry; + newEntry->mHashCode = hash; + + mHashHeads[hashIdx] = index; + + return EntryRef(this, index); + } + void Add(T value) { if (this->mHashHeads == NULL) - this->mHashHeads = (Entry**)TFuncs::AllocateZero(sizeof(Entry*) * mHashSize, alignof(Entry*)); + { + this->mHashHeads = (int*)TFuncs::Allocate(sizeof(int) * mHashSize, alignof(int)); + memset(this->mHashHeads, -1, sizeof(int) * mHashSize); + } + int index = AllocEntry(); int hash = TFuncs::GetHash(value); int hashIdx = (hash & 0x7FFFFFFF) % this->mHashSize; - Entry* headEntry = this->mHashHeads[hashIdx]; + int headEntry = this->mHashHeads[hashIdx]; - Entry* newEntry = (Entry*)TFuncs::Allocate(sizeof(Entry), alignof(Entry)); + Entry* newEntry = &mEntries[index]; newEntry->mValue = value; newEntry->mNext = headEntry; - newEntry->mHash = hash; - mCount++; + newEntry->mHashCode = hash; - mHashHeads[hashIdx] = newEntry; + mHashHeads[hashIdx] = index; } void AddAfter(T value, Entry* afterEntry) { int hash = TFuncs::GetHash(value); int hashIdx = (hash & 0x7FFFFFFF) % this->mHashSize; - BF_ASSERT(hash == afterEntry->mHash); + BF_ASSERT(hash == afterEntry->mHashCode); - Entry* newEntry = (Entry*)TFuncs::Allocate(sizeof(Entry), alignof(Entry)); + int index = AllocEntry(); + Entry* newEntry = &mEntries[index]; newEntry->mValue = value; newEntry->mNext = afterEntry->mNext; - newEntry->mHash = hash; - mCount++; + newEntry->mHashCode = hash; - afterEntry->mNext = newEntry; + afterEntry->mNext = index; } void Rehash(int newHashSize) { - auto newHashHeads = (Entry**)TFuncs::AllocateZero(sizeof(Entry*) * newHashSize, alignof(Entry*)); - - SizedArray entryList; - - for (int hashIdx = 0; hashIdx < mHashSize; hashIdx++) + auto newHashHeads = (int*)TFuncs::Allocate(sizeof(int) * newHashSize, alignof(int)); + memset(newHashHeads, -1, sizeof(int) * newHashSize); + + if (mHashHeads != NULL) { - Entry* checkEntry = mHashHeads[hashIdx]; - if (checkEntry != NULL) + SizedArray entryList; + for (int hashIdx = 0; hashIdx < mHashSize; hashIdx++) { - // We want to keep elements with equal hashes in their insert order so we need to - // iterate through the linked list in reverse - entryList.Clear(); - - while (checkEntry != NULL) + int checkEntryIdx = mHashHeads[hashIdx]; + if (checkEntryIdx != -1) { - entryList.Add(checkEntry); - checkEntry = checkEntry->mNext; - } - - for (int i = (int)entryList.mSize - 1; i >= 0; i--) - { - auto checkEntry = entryList[i]; - int newHashIdx = (checkEntry->mHash & 0x7FFFFFFF) % newHashSize; - checkEntry->mNext = newHashHeads[newHashIdx]; - newHashHeads[newHashIdx] = checkEntry; + // We want to keep elements with equal hashes in their insert order so we need to + // iterate through the linked list in reverse + entryList.Clear(); + + while (checkEntryIdx != -1) + { + entryList.Add(checkEntryIdx); + checkEntryIdx = mEntries[checkEntryIdx].mNext; + } + + for (int i = (int)entryList.mSize - 1; i >= 0; i--) + { + int checkEntryIdx = entryList[i]; + auto checkEntry = &mEntries[checkEntryIdx]; + int newHashIdx = (checkEntry->mHashCode & 0x7FFFFFFF) % newHashSize; + checkEntry->mNext = newHashHeads[newHashIdx]; + newHashHeads[newHashIdx] = checkEntryIdx; + } } } - } - TFuncs::Deallocate(mHashHeads); + TFuncs::Deallocate(mHashHeads); + } mHashHeads = newHashHeads; mHashSize = newHashSize; } @@ -215,16 +389,17 @@ public: int hash = TFuncs::GetHash(key); int hashIdx = (hash & 0x7FFFFFFF) % this->mHashSize; - Entry* checkEntry = this->mHashHeads[hashIdx]; - while (checkEntry != NULL) + int checkEntryIdx = this->mHashHeads[hashIdx]; + while (checkEntryIdx != -1) { - if ((checkEntry->mHash == hash) && (TFuncs::Matches(key, checkEntry->mValue))) + Entry* checkEntry = &mEntries[checkEntryIdx]; + if ((checkEntry->mHashCode == hash) && (TFuncs::Matches(key, checkEntry->mValue))) { if (val != NULL) *val = checkEntry->mValue; return true; } - checkEntry = checkEntry->mNext; + checkEntryIdx = checkEntry->mNext; } return false; } @@ -239,17 +414,18 @@ public: int hash = TFuncs::GetHash(key); int hashIdx = (hash & 0x7FFFFFFF) % this->mHashSize; - Entry* checkEntry = this->mHashHeads[hashIdx]; - while (checkEntry != NULL) + int checkEntryIdx = this->mHashHeads[hashIdx]; + while (checkEntryIdx != -1) { - if ((checkEntry->mHash == hash) && (TFuncs::Matches(key, checkEntry->mValue))) + auto checkEntry = &this->mEntries[checkEntryIdx]; + if ((checkEntry->mHashCode == hash) && (TFuncs::Matches(key, checkEntry->mValue))) { Iterator itr(this); - itr.mCurEntry = checkEntry; + itr.mCurEntry = checkEntryIdx; itr.mCurBucket = hashIdx; return itr; } - checkEntry = checkEntry->mNext; + checkEntryIdx = checkEntry->mNext; } return end(); @@ -266,19 +442,19 @@ public: int hash = TFuncs::GetHash(key); int hashIdx = (hash & 0x7FFFFFFF) % this->mHashSize; - Entry** srcCheckEntryPtr = &this->mHashHeads[hashIdx]; - Entry* checkEntry = *srcCheckEntryPtr; - while (checkEntry != NULL) + int* srcCheckEntryPtr = &this->mHashHeads[hashIdx]; + int checkEntryIdx = *srcCheckEntryPtr; + while (checkEntryIdx != -1) { - if ((checkEntry->mHash == hash) && (TFuncs::Matches(key, checkEntry->mValue))) - { - this->mCount--; + auto checkEntry = &mEntries[checkEntryIdx]; + if ((checkEntry->mHashCode == hash) && (TFuncs::Matches(key, checkEntry->mValue))) + { *srcCheckEntryPtr = checkEntry->mNext; - TFuncs::Deallocate(checkEntry); + FreeIdx(checkEntryIdx); return true; } srcCheckEntryPtr = &checkEntry->mNext; - checkEntry = checkEntry->mNext; + checkEntryIdx = checkEntry->mNext; } return false; } @@ -290,29 +466,30 @@ public: bool found = false; - auto entry = itr.mCurEntry; - int hashIdx = (entry->mHash & 0x7FFFFFFF) % this->mHashSize; + auto entryIdx = itr.mCurEntry; + auto entry = &mEntries[entryIdx]; + int hashIdx = (entry->mHashCode & 0x7FFFFFFF) % this->mHashSize; - Entry** srcCheckEntryPtr = &this->mHashHeads[hashIdx]; - Entry* checkEntry = *srcCheckEntryPtr; - while (checkEntry != NULL) + int* srcCheckEntryPtr = &this->mHashHeads[hashIdx]; + int checkEntryIdx = *srcCheckEntryPtr; + while (checkEntryIdx != -1) { - if (checkEntry == itr.mCurEntry) + auto checkEntry = &mEntries[checkEntryIdx]; + if (checkEntryIdx == itr.mCurEntry) { - this->mCount--; *srcCheckEntryPtr = checkEntry->mNext; found = true; } srcCheckEntryPtr = &checkEntry->mNext; - checkEntry = checkEntry->mNext; + checkEntryIdx = checkEntry->mNext; } BF_ASSERT(found); - TFuncs::Deallocate(entry); + FreeIdx(entryIdx); return next; } - + void Clear() { if (!TFuncs::DeallocateAll()) @@ -323,13 +500,15 @@ public: { auto entry = itr.mCurEntry; ++itr; - TFuncs::Deallocate(entry); + FreeIdx(entry); } TFuncs::Deallocate(this->mHashHeads); + TFuncs::Deallocate(this->mEntries); } this->mHashSize = cDefaultHashSize; this->mHashHeads = NULL; + this->mEntries = NULL; this->mCount = 0; } diff --git a/BeefySysLib/util/String.cpp b/BeefySysLib/util/String.cpp index a64766bc..b718bf16 100644 --- a/BeefySysLib/util/String.cpp +++ b/BeefySysLib/util/String.cpp @@ -283,6 +283,11 @@ void StringImpl::Reference(const StringView& strView) Reference(strView.mPtr, strView.mLength); } +void StringImpl::Reference(const StringImpl& str) +{ + Reference(str.GetPtr(), str.mLength); +} + String StringImpl::CreateReference(const StringView& strView) { String str; diff --git a/BeefySysLib/util/String.h b/BeefySysLib/util/String.h index e30d9679..e93afb80 100644 --- a/BeefySysLib/util/String.h +++ b/BeefySysLib/util/String.h @@ -919,6 +919,7 @@ public: void Reference(const char* str); void Reference(const char* str, intptr length); void Reference(const StringView& strView); + void Reference(const StringImpl& str); static String CreateReference(const StringView& strView); void Reserve(intptr newSize); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 61972db9..8b7b33f2 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -2312,15 +2312,16 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) { extern BfModule* gLastCreatedModule; +#ifdef _DEBUG for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end(); ++itr) { auto dependentType = itr->mKey; - if (dependentType->IsIncomplete()) { BF_ASSERT(dependentType->IsDeleting() || dependentType->IsOnDemand() || !dependentType->HasBeenReferenced() || !madeFullPass || dependentType->IsSpecializedByAutoCompleteMethod()); } } +#endif depType->mDependencyMap.mFlagsUnion = BfDependencyMap::DependencyFlag_None; @@ -3196,15 +3197,19 @@ void BfCompiler::UpdateRevisedTypes() break; // Partials combiner - auto outerTypeDefEntry = mSystem->mTypeDefs.mHashHeads[bucketIdx]; - while (outerTypeDefEntry != NULL) + auto outerTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + while (outerTypeDefEntryIdx != -1) { + // Make sure we can fit a composite without reallocating + mSystem->mTypeDefs.EnsureFreeCount(1); + + auto outerTypeDefEntry = &mSystem->mTypeDefs.mEntries[outerTypeDefEntryIdx]; auto outerTypeDef = outerTypeDefEntry->mValue; if (outerTypeDef->mDefState == BfTypeDef::DefState_Deleted) { hadChanges = true; - outerTypeDefEntry = outerTypeDefEntry->mNext; + outerTypeDefEntryIdx = mSystem->mTypeDefs.mEntries[outerTypeDefEntryIdx].mNext; continue; } @@ -3228,14 +3233,14 @@ void BfCompiler::UpdateRevisedTypes() // Initialize mPartialUsed flags if (!hadPartials) { - auto checkTypeDefEntry = mSystem->mTypeDefs.mHashHeads[bucketIdx]; - while (checkTypeDefEntry != NULL) + auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + while (checkTypeDefEntryIdx != -1) { // This clears the mPartialUsed flag for the whole bucket - auto checkTypeDef = checkTypeDefEntry->mValue; + auto checkTypeDef = mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx].mValue; if ((checkTypeDef->mIsPartial) || (checkTypeDef->mIsCombinedPartial)) checkTypeDef->mPartialUsed = false; - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx].mNext; } hadPartials = true; } @@ -3246,11 +3251,12 @@ void BfCompiler::UpdateRevisedTypes() if ((outerTypeDef->mTypeCode == BfTypeCode_Extension) && (!outerTypeDef->mPartialUsed)) { // Find root type, and we assume the composite type follows this - auto checkTypeDefEntry = mSystem->mTypeDefs.mHashHeads[bucketIdx]; - while (checkTypeDefEntry != NULL) - { + auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + while (checkTypeDefEntryIdx != -1) + { + auto checkTypeDefEntry = &mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx]; auto checkTypeDef = checkTypeDefEntry->mValue; - if ((checkTypeDefEntry->mHash != outerTypeDefEntry->mHash) || + if ((checkTypeDefEntry->mHashCode != outerTypeDefEntry->mHashCode) || (checkTypeDef->mIsCombinedPartial) || (checkTypeDef->mTypeCode == BfTypeCode_Extension) || (checkTypeDef->mDefState == BfTypeDef::DefState_Deleted) || @@ -3259,7 +3265,7 @@ void BfCompiler::UpdateRevisedTypes() (checkTypeDef->mGenericParamDefs.size() != outerTypeDef->mGenericParamDefs.size()) || (!outerTypeDef->mProject->ContainsReference(checkTypeDef->mProject))) { - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; continue; } @@ -3274,7 +3280,7 @@ void BfCompiler::UpdateRevisedTypes() compositeProject = rootTypeDef->mProject; } - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; if (compositeTypeDef != NULL) { @@ -3297,18 +3303,19 @@ void BfCompiler::UpdateRevisedTypes() compositeProject = rootTypeDef->mProject; // Find composite type, there is no explicit position for this - auto checkTypeDefEntry = mSystem->mTypeDefs.mHashHeads[bucketIdx]; - while (checkTypeDefEntry != NULL) + auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + while (checkTypeDefEntryIdx != -1) { + auto checkTypeDefEntry = &mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx]; auto checkTypeDef = checkTypeDefEntry->mValue; - if ((checkTypeDefEntry->mHash != outerTypeDefEntry->mHash) || + if ((checkTypeDefEntry->mHashCode != outerTypeDefEntry->mHashCode) || (checkTypeDef->mPartialUsed) || (checkTypeDef->mDefState == BfTypeDef::DefState_Deleted) || (!checkTypeDef->NameEquals(outerTypeDef)) || (checkTypeDef->mGenericParamDefs.size() != outerTypeDef->mGenericParamDefs.size())) { - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; continue; } @@ -3339,13 +3346,13 @@ void BfCompiler::UpdateRevisedTypes() } } - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; continue; } if (!rootTypeDef->mProject->ContainsReference(checkTypeDef->mProject)) { - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; continue; } @@ -3362,7 +3369,7 @@ void BfCompiler::UpdateRevisedTypes() if (compositeTypeDef->mDefState != BfTypeDef::DefState_Deleted) compositeTypeDef->mDefState = BfTypeDef::DefState_Defined; } - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; } } @@ -3375,12 +3382,16 @@ void BfCompiler::UpdateRevisedTypes() if (compositeTypeDef == NULL) { - if ((rootTypeDef->mIsExplicitPartial) || (rootTypeDefEntry->mNext == NULL) || - (!rootTypeDefEntry->mNext->mValue->mIsCombinedPartial) || - (rootTypeDefEntry->mNext->mValue->mTypeCode != rootTypeDef->mTypeCode) || - (rootTypeDefEntry->mNext->mValue->mIsFunction != rootTypeDef->mIsFunction) || - (rootTypeDefEntry->mNext->mValue->mIsDelegate != rootTypeDef->mIsDelegate) || - (rootTypeDefEntry->mNext->mValue->mGenericParamDefs.size() != rootTypeDef->mGenericParamDefs.size())) + BfTypeDefMap::Entry* nextEntry = NULL; + if (rootTypeDefEntry->mNext != -1) + nextEntry = &mSystem->mTypeDefs.mEntries[rootTypeDefEntry->mNext]; + + if ((rootTypeDef->mIsExplicitPartial) || (nextEntry == NULL) || + (!nextEntry->mValue->mIsCombinedPartial) || + (nextEntry->mValue->mTypeCode != rootTypeDef->mTypeCode) || + (nextEntry->mValue->mIsFunction != rootTypeDef->mIsFunction) || + (nextEntry->mValue->mIsDelegate != rootTypeDef->mIsDelegate) || + (nextEntry->mValue->mGenericParamDefs.size() != rootTypeDef->mGenericParamDefs.size())) { compositeTypeDef = new BfTypeDef(); compositeTypeDef->mSystem = rootTypeDef->mSystem; @@ -3418,8 +3429,8 @@ void BfCompiler::UpdateRevisedTypes() } else { - BF_ASSERT(rootTypeDefEntry->mNext->mValue->NameEquals(rootTypeDef)); - compositeTypeDef = rootTypeDefEntry->mNext->mValue; + BF_ASSERT(nextEntry->mValue->NameEquals(rootTypeDef)); + compositeTypeDef = nextEntry->mValue; if (rootTypeDef != NULL) { BF_ASSERT(rootTypeDef->mFullNameEx == compositeTypeDef->mFullNameEx); @@ -3448,9 +3459,10 @@ void BfCompiler::UpdateRevisedTypes() // Collect the partials BfSizedVector typeParts; typeParts.push_back(rootTypeDef); - auto checkTypeDefEntry = mSystem->mTypeDefs.mHashHeads[bucketIdx]; - while (checkTypeDefEntry != NULL) + auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + while (checkTypeDefEntryIdx != -1) { + auto checkTypeDefEntry = &mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx]; auto checkTypeDef = checkTypeDefEntry->mValue; bool isValidProject = checkTypeDef->mProject->ContainsReference(compositeProject); @@ -3464,7 +3476,7 @@ void BfCompiler::UpdateRevisedTypes() (checkTypeDef->mGenericParamDefs.size() != rootTypeDef->mGenericParamDefs.size()) || (!isValidProject)) { - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; continue; } } @@ -3498,7 +3510,7 @@ void BfCompiler::UpdateRevisedTypes() partialsHadChanges = true; } - checkTypeDefEntry = checkTypeDefEntry->mNext; + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; } // Set this down here, because the InjectNewRevision will clear this flag rootTypeDef->mIsPartial = true; @@ -3631,7 +3643,7 @@ void BfCompiler::UpdateRevisedTypes() } } - outerTypeDefEntry = outerTypeDefEntry->mNext; + outerTypeDefEntryIdx = outerTypeDefEntry->mNext; } // Handle unused partials, apply any new revisions, process pending deletes @@ -3641,11 +3653,16 @@ void BfCompiler::UpdateRevisedTypes() BfTypeDef* checkMasterTypeDef = NULL; BfTypeDef* deletedCombinedPartial = NULL; - outerTypeDefEntry = mSystem->mTypeDefs.mHashHeads[bucketIdx]; - while (outerTypeDefEntry != NULL) + outerTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + while (outerTypeDefEntryIdx != -1) { + auto outerTypeDefEntry = &mSystem->mTypeDefs.mEntries[outerTypeDefEntryIdx]; auto outerTypeDef = outerTypeDefEntry->mValue; - auto nextTypeDefEntry = outerTypeDefEntry->mNext; + auto nextTypeDefEntryIdx = outerTypeDefEntry->mNext; + + BfTypeDefMap::Entry* nextTypeDefEntry = NULL; + if (nextTypeDefEntryIdx != -1) + nextTypeDefEntry = &mSystem->mTypeDefs.mEntries[nextTypeDefEntryIdx]; if ((outerTypeDef->mIsPartial) && (!outerTypeDef->mIsExplicitPartial) && (outerTypeDef->mTypeCode != BfTypeCode_Extension) && (nextTypeDefEntry != NULL) && (!nextTypeDefEntry->mValue->mPartialUsed)) @@ -3695,7 +3712,7 @@ void BfCompiler::UpdateRevisedTypes() } } - outerTypeDefEntry = nextTypeDefEntry; + outerTypeDefEntryIdx = nextTypeDefEntryIdx; } } } @@ -5616,7 +5633,7 @@ void BfCompiler::PopulateReified() BfLogSysM("PopulateReified iteration start\n"); Array typeList; - typeList.Reserve(context->mResolvedTypes.mCount); + typeList.Reserve(context->mResolvedTypes.GetCount()); for (auto type : context->mResolvedTypes) typeList.Add(type); @@ -6155,7 +6172,7 @@ void BfCompiler::HotResolve_AddActiveMethod(const StringImpl& methodName) { BfLogSysM("HotResolve_AddActiveMethod %s\n", methodName.c_str()); - String mangledName; + StringT<512> mangledName; int hotCompileIdx = 0; int tabIdx = (int)methodName.IndexOf('\t'); @@ -7730,7 +7747,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } UpdateCompletion(); - mStats.mTotalTypes = mContext->mResolvedTypes.mCount; + mStats.mTotalTypes = mContext->mResolvedTypes.GetCount(); String compileInfo; if (mIsResolveOnly) diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 0d26309e..a302e8a4 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -207,7 +207,8 @@ void BfContext::AssignModule(BfType* type) } else { - String moduleName = GenerateModuleName(typeInst); + StringT<256> moduleName; + GenerateModuleName(typeInst, moduleName); module = new BfModule(this, moduleName); module->mIsReified = typeInst->mIsReified; module->mProject = project; @@ -1936,7 +1937,7 @@ void BfContext::UpdateAfterDeletingTypes() auto itr = mResolvedTypes.begin(); while (itr != mResolvedTypes.end()) { - auto type = itr.mCurEntry->mValue; + auto type = mResolvedTypes.mEntries[itr.mCurEntry].mValue; bool doDelete = false; //BfLogSysM("Removing entry\n"); @@ -2659,7 +2660,7 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst) } } -void BfContext::GenerateModuleName_TypeInst(BfTypeInstance* typeInst, String& name) +void BfContext::GenerateModuleName_TypeInst(BfTypeInstance* typeInst, StringImpl& name) { auto resolveModule = typeInst->mIsReified ? mScratchModule : mUnreifiedModule; auto outerType = resolveModule->GetOuterType(typeInst); @@ -2708,7 +2709,7 @@ void BfContext::GenerateModuleName_TypeInst(BfTypeInstance* typeInst, String& na } } -void BfContext::GenerateModuleName_Type(BfType* type, String& name) +void BfContext::GenerateModuleName_Type(BfType* type, StringImpl& name) { if ((!name.empty()) && (name[name.length() - 1] != '_')) name += '_'; @@ -2817,9 +2818,8 @@ void BfContext::GenerateModuleName_Type(BfType* type, String& name) } } -String BfContext::GenerateModuleName(BfTypeInstance* typeInst) -{ - String name; +void BfContext::GenerateModuleName(BfTypeInstance* typeInst, StringImpl& name) +{ GenerateModuleName_Type(typeInst, name); int maxChars = 80; @@ -2834,16 +2834,21 @@ String BfContext::GenerateModuleName(BfTypeInstance* typeInst) if (c == '@') name[i] = '_'; } - - String tryName = name; + for (int i = 2; true; i++) { - if (!mUsedModuleNames.Contains(ToUpper(tryName))) - return tryName; - tryName = name + StrFormat("_%d", i); + StringT<256> upperName = name; + MakeUpper(upperName); + if (!mUsedModuleNames.Contains(upperName)) + return; + if (i > 2) + { + int lastUnderscore = (int)name.LastIndexOf('_'); + if (lastUnderscore != -1) + name.RemoveToEnd(lastUnderscore); + } + name += StrFormat("_%d", i); } - - return name; } bool BfContext::IsSentinelMethod(BfMethodInstance* methodInstance) diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 431ff94d..48e2138e 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -448,9 +448,9 @@ public: void DeleteType(BfType* type, bool deferDepRebuilds = false); void UpdateAfterDeletingTypes(); void VerifyTypeLookups(BfTypeInstance* typeInst); - void GenerateModuleName_TypeInst(BfTypeInstance* typeInst, String& name); - void GenerateModuleName_Type(BfType* type, String& name); - String GenerateModuleName(BfTypeInstance* typeInst); + void GenerateModuleName_TypeInst(BfTypeInstance* typeInst, StringImpl& name); + void GenerateModuleName_Type(BfType* type, StringImpl& name); + void GenerateModuleName(BfTypeInstance* typeInst, StringImpl& name); bool IsSentinelMethod(BfMethodInstance* methodInstance); void SaveDeletingType(BfType* type); BfType* FindType(const StringImpl& typeName); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 0cc62527..a1bf800e 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -12700,7 +12700,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) auto _GetInvokeMethodName = [&]() { - String methodName = "Invoke$"; + StringT<512> methodName = "Invoke$"; methodName += mModule->mCurMethodInstance->mMethodDef->mName; int prevSepPos = (int)methodName.LastIndexOf('$'); @@ -12734,7 +12734,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) methodName += '$'; methodName += BfTypeUtils::HashEncode64(hashVal.mLow); - String mangledName; + StringT<512> mangledName; BfMangler::MangleMethodName(mangledName, mModule->mCompiler->GetMangleKind(), mModule->mCurTypeInstance, methodName); return mangledName; }; diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 2a5fed4f..26272b9f 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -277,7 +277,7 @@ BfIRBlock::BfIRBlock() BfIRConstHolder::BfIRConstHolder(BfModule* module) { - mModule = module; + mModule = module; } BfIRConstHolder::~BfIRConstHolder() @@ -2573,7 +2573,7 @@ BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScop if (!typeInstance->IsBoxed()) { - BfAtomComposite curNamespace; + BfAtomCompositeT<16> curNamespace; if (typeInstance->IsArray()) { auto arrayType = (BfArrayType*)typeInstance; @@ -2958,7 +2958,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, typeName, curDIScope, fileDIScope, 0, (int64)0 * 8, (int64)0 * 8, flags); auto derivedFrom = DbgGetTypeInst(mModule->mContext->mBfObjectType); - llvm::SmallVector diFieldTypes; + SizedArray diFieldTypes; auto inheritanceType = DbgCreateInheritance(diForwardDecl, derivedFrom, 0, llvm::DINode::FlagPublic); diFieldTypes.push_back(inheritanceType); DbgMakePermanent(diForwardDecl, derivedFrom, diFieldTypes); @@ -3081,7 +3081,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) //BF_ASSERT(WantsDbgDefinition(type)); - llvm::SmallVector diFieldTypes; + SizedArray diFieldTypes; int packing = 0; bool isUnion = false; @@ -3448,8 +3448,8 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) } String methodName = methodDef->mName; - llvm::SmallVector genericArgs; - llvm::SmallVector genericConstValueArgs; + SizedArray genericArgs; + SizedArray genericConstValueArgs; auto diFunction = DbgCreateMethod(funcScope, methodName, mangledName, fileDIScope, defLine + 1, diFuncType, false, false, (methodInstance->mVirtualTableIdx != -1) ? 1 : 0, @@ -3602,13 +3602,13 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst bool isGlobalContainer = typeDef->IsGlobalsContainer(); auto diForwardDecl = DbgGetTypeInst(typeInstance); - llvm::SmallVector irFieldTypes; + SizedArray irFieldTypes; if ((!typeInstance->IsTypedPrimitive()) && (typeInstance->mBaseType != NULL)) { irFieldTypes.push_back(MapTypeInst(typeInstance->mBaseType, BfIRPopulateType_Eventually_Full)); } - llvm::SmallVector diFieldTypes; + SizedArray diFieldTypes; int packing = 0; bool isUnion = false; @@ -3625,7 +3625,7 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst if (!elementType->IsValuelessType()) { - irFieldTypes.push_back(MapType(elementType, elementType->IsValueType() ? BfIRPopulateType_Eventually_Full : BfIRPopulateType_Declaration)); + irFieldTypes.Add(MapType(elementType, elementType->IsValueType() ? BfIRPopulateType_Eventually_Full : BfIRPopulateType_Declaration)); } } else @@ -5293,7 +5293,9 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT BfIRFunction retVal = WriteCmd(BfIRCmd_CreateFunction, funcType, (uint8)linkageType, name); NEW_CMD_INSERTED_IRVALUE; - mFunctionMap[name] = retVal; + + StringView nameSV = StringView(AllocStr(name), name.mLength); + mFunctionMap[nameSV] = retVal; //BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule); @@ -5926,7 +5928,7 @@ BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(BfMethodInstance* methodInstance auto methodDef = methodInstance->mMethodDef; auto typeInstance = methodInstance->GetOwner(); - llvm::SmallVector diParams; + SizedArray diParams; diParams.push_back(DbgGetType(methodInstance->mReturnType)); BfType* thisType = NULL; diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index ec73a410..8233175c 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -1019,7 +1019,7 @@ public: bool mHasDebugInfo; bool mHasDebugLineInfo; Dictionary mMethodTypeMap; - Dictionary mFunctionMap; + Dictionary mFunctionMap; Dictionary mTypeMap; Dictionary mConstMemMap; Array mDITemporaryTypes; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 19841629..64d6bc95 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -213,7 +213,12 @@ BfMethodState::~BfMethodState() } for (auto local : mLocals) - delete local; + { + if (local->mIsBumpAlloc) + local->~BfLocalVariable(); + else + delete local; + } for (auto& kv : mLambdaCache) delete kv.mValue; @@ -856,7 +861,11 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName) mContext = context; mModuleName = moduleName; if (!moduleName.empty()) - mContext->mUsedModuleNames.Add(ToUpper(moduleName)); + { + StringT<256> upperModuleName = moduleName; + MakeUpper(upperModuleName); + mContext->mUsedModuleNames.Add(upperModuleName); + } mAddedToCount = false; mParentModule = NULL; @@ -1912,7 +1921,10 @@ void BfModule::RestoreScoreState_LocalVariables() mCurMethodState->mLocalVarSet.Remove(BfLocalVarEntry(localVar)); } - delete localVar; + if (localVar->mIsBumpAlloc) + localVar->~BfLocalVariable(); + else + delete localVar; } } @@ -4029,7 +4041,7 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo else { BfLogSysM("Creating static field Module:%p Type:%p\n", this, fieldType); - StringT<128> staticVarName; + StringT<4096> staticVarName; BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance); if ((!fieldType->IsValuelessType()) && (!staticVarName.StartsWith("#"))) { @@ -5300,7 +5312,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy PopulateType(declTypeInst, BfPopulateType_DataAndMethods); PopulateType(implTypeInst, BfPopulateType_DataAndMethods); - StringT<128> classVDataName; + StringT<512> classVDataName; BfMangler::MangleStaticFieldName(classVDataName, mCompiler->GetMangleKind(), implTypeInst, "bf_hs_replace_VDataExt"); if (declTypeInst != implTypeInst) { @@ -5385,7 +5397,7 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type) auto typeTypeInst = typeTypeDef->ToTypeInstance(); auto typeInstance = type->ToTypeInstance(); - StringT<128> typeDataName; + StringT<4096> typeDataName; if (typeInstance != NULL) { BfMangler::MangleStaticFieldName(typeDataName, mCompiler->GetMangleKind(), typeInstance, "sBfTypeData"); @@ -5739,7 +5751,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin FixConstValueParams(mContext->mBfObjectType, typeValueParams); BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams); - StringT<128> typeDataName; + StringT<512> typeDataName; if ((typeInstance != NULL) && (!typeInstance->IsTypeAlias())) { BfMangler::MangleStaticFieldName(typeDataName, mCompiler->GetMangleKind(), typeInstance, "sBfTypeData"); @@ -5981,7 +5993,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin PopulateType(typeInstance, BfPopulateType_DataAndMethods); BfTypeDef* typeDef = typeInstance->mTypeDef; - StringT<128> mangledName; + StringT<512> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), typeInstance, typeInstance->mModule); if (!mIsComptimeModule) @@ -6018,7 +6030,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (typeInstance->mSlotNum >= 0) { // For interfaces we ONLY emit the slot num - StringT<128> slotVarName; + StringT<512> slotVarName; BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), typeInstance, "sBfSlotOfs"); auto intType = GetPrimitiveType(BfTypeCode_Int32); auto slotNumVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External, @@ -6485,7 +6497,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfIRValue ifaceMethodExtVar; if ((!ifaceMethodExtData.IsEmpty()) && (!mIsComptimeModule)) { - StringT<128> classVDataName; + StringT<512> classVDataName; BfMangler::MangleStaticFieldName(classVDataName, mCompiler->GetMangleKind(), typeInstance, "bf_hs_replace_IFaceExt"); auto arrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr), (int)ifaceMethodExtData.size()); ifaceMethodExtVar = mBfIRBuilder->CreateGlobalVariable(arrayType, true, @@ -8542,7 +8554,7 @@ BfGenericParamType* BfModule::GetGenericParamType(BfGenericParamKind paramKind, BfResolvedTypeSet::LookupContext lookupCtx; lookupCtx.mModule = this; - BfResolvedTypeSet::Entry* typeEntry = NULL; + BfResolvedTypeSet::EntryRef typeEntry; auto inserted = mContext->mResolvedTypes.Insert(genericParamType, &lookupCtx, &typeEntry); BF_ASSERT(inserted); typeEntry->mValue = genericParamType; @@ -10690,7 +10702,7 @@ BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tr } auto methodDef = methodInstance->mMethodDef; - StringT<128> methodName; + StringT<4096> methodName; BfMangler::Mangle(methodName, mCompiler->GetMangleKind(), methodInstance); if (isInlined != methodInstance->mAlwaysInline) { @@ -13983,7 +13995,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM if ((!mBfIRBuilder->mIgnoreWrites) && (methodInstance->mDeclModule != NULL)) { - StringT<128> mangledName; + StringT<512> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), methodInstance); bool isIntrinsic = false; SetupIRFunction(methodInstance, mangledName, false, &isIntrinsic); @@ -14479,7 +14491,7 @@ BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType) // This is necessary to reify the interface type PopulateType(ifaceType); - StringT<128> slotVarName; + StringT<512> slotVarName; BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), ifaceType, "sBfSlotOfs"); BfType* intType = GetPrimitiveType(BfTypeCode_Int32); BfIRValue value; @@ -14670,7 +14682,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) } else { - StringT<128> staticVarName; + StringT<512> staticVarName; BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance); auto typeType = fieldInstance->GetResolvedType(); @@ -15018,6 +15030,12 @@ void BfModule::DoAddLocalVariable(BfLocalVariable* localVar) localVar->mName.Remove(0); } + if (mCurMethodState->mLocals.mAllocSize == 0) + { + mCurMethodState->mLocals.Reserve(16); + mCurMethodState->mLocalVarSet.Reserve(16); + } + localVar->mLocalVarIdx = (int)mCurMethodState->mLocals.size(); mCurMethodState->mLocals.push_back(localVar); @@ -15712,7 +15730,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa } } - std::unordered_set handledSet; + HashSet handledSet; BfDeferredCallEntry* deferredCallEntry = checkScope->mDeferredCallEntries.mHead; while (deferredCallEntry != NULL) { @@ -15732,13 +15750,14 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa if (deferredCallEntry->mDeferredBlock != NULL) { - auto itr = handledSet.insert(deferredCallEntry); - if (!itr.second) + BfDeferredCallEntry** entryPtr = NULL; + if (!handledSet.TryAdd(deferredCallEntry, &entryPtr)) { // Already handled, can happen if we defer again within the block deferredCallEntry = deferredCallEntry->mNext; - continue; + continue; } + auto prevHead = checkScope->mDeferredCallEntries.mHead; EmitDeferredCall(*deferredCallEntry, true); if (prevHead != checkScope->mDeferredCallEntries.mHead) @@ -16993,7 +17012,7 @@ BfIRValue BfModule::CreateDllImportGlobalVar(BfMethodInstance* methodInstance, b return BfIRValue(); } - String name = "bf_hs_preserve@"; + StringT<512> name = "bf_hs_preserve@"; BfMangler::Mangle(name, mCompiler->GetMangleKind(), methodInstance); name += "__imp"; @@ -18446,14 +18465,17 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp if ((!mIsComptimeModule) && (argIdx == methodInstance->GetStructRetIdx())) argIdx++; + auto rootMethodState = mCurMethodState->GetRootMethodState(); + if (!methodDef->mIsStatic) { BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; - BfLocalVariable* paramVar = new BfLocalVariable(); + BfLocalVariable* paramVar = rootMethodState->mBumpAlloc.Alloc(); + paramVar->mIsBumpAlloc = true; paramVar->mResolvedType = thisType; - paramVar->mName = "this"; + paramVar->mName.Reference("this"); if (!thisType->IsValuelessType()) paramVar->mValue = mBfIRBuilder->GetArgument(argIdx); else @@ -18525,7 +18547,8 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp { // We already issues a type error for this param if we had one in declaration processing SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); - BfLocalVariable* paramVar = new BfLocalVariable(); + BfLocalVariable* paramVar = rootMethodState->mBumpAlloc.Alloc(); + paramVar->mIsBumpAlloc = true; BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; @@ -18542,7 +18565,8 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp PopulateType(resolvedType, BfPopulateType_Declaration); paramVar->mResolvedType = resolvedType; int namePrefixCount = 0; - paramVar->mName = methodInstance->GetParamName(paramIdx, namePrefixCount); + methodInstance->GetParamName(paramIdx, paramVar->mName, namePrefixCount); + paramVar->mNamePrefixCount = (uint8)namePrefixCount; paramVar->mNameNode = methodInstance->GetParamNameNode(paramIdx); if (!isParamSkipped) @@ -18774,7 +18798,12 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx) mCurMethodState->mLocalMethods.Clear(); for (auto& local : mCurMethodState->mLocals) - delete local; + { + if (local->mIsBumpAlloc) + local->~BfLocalVariable(); + else + delete local; + } mCurMethodState->mLocals.Clear(); mCurMethodState->mLocalVarSet.Clear(); }; @@ -19225,7 +19254,7 @@ void BfModule::EmitGCMarkMembers() if ((fieldDef->mIsStatic) && (!fieldDef->mIsConst)) { - StringT<128> staticVarName; + StringT<512> staticVarName; BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), &fieldInst); if (staticVarName.StartsWith('#')) continue; @@ -19582,7 +19611,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, return; } - StringT<128> mangledName; + StringT<512> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), mCurMethodInstance); if (!methodInstance->mIRFunction) { @@ -21509,7 +21538,7 @@ String BfModule::GetLocalMethodName(const StringImpl& baseName, BfAstNode* ancho { for (auto methodGenericArg : rootMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments) { - StringT<128> genericTypeName; + StringT<512> genericTypeName; BfMangler::Mangle(genericTypeName, mCompiler->GetMangleKind(), methodGenericArg); hashCtx.MixinStr(genericTypeName); } @@ -23688,7 +23717,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } } - StringT<128> mangledName; + StringT<4096> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), mCurMethodInstance); for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) @@ -24155,7 +24184,7 @@ void BfModule::UniqueSlotVirtualMethod(BfMethodInstance* methodInstance) if (implBaseType != NULL) vTableStart = implBaseType->mVirtualMethodTableSize; - StringT<128> mangledName; + StringT<512> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), methodInstance); for (int checkIdxOfs = 0; checkIdxOfs < (int)typeInstance->mHotTypeData->mVTableEntries.size(); checkIdxOfs++) { diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 6e27a7b8..b61ec09c 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -188,6 +188,7 @@ public: bool mUsedImplicitly; // Passed implicitly to a local method, capture by ref if we can bool mNotCaptured; bool mIsConst; + bool mIsBumpAlloc; BfLocalVariable* mShadowedLocal; public: @@ -219,6 +220,7 @@ public: mUsedImplicitly = false; mNotCaptured = false; mIsConst = false; + mIsBumpAlloc = false; mShadowedLocal = NULL; } @@ -1053,8 +1055,7 @@ public: bool mAllowUinitReads; bool mDisableReturns; bool mCancelledDeferredCall; - bool mNoObjectAccessChecks; - bool mHadIgnoredError; + bool mNoObjectAccessChecks; int mCurLocalVarId; // Can also refer to a label int mCurAccessId; // For checking to see if a block reads from or writes to a local @@ -1062,9 +1063,7 @@ public: BfMethodState() { mLocals.mAlloc = &mBumpAlloc; - mLocals.Reserve(8); - mLocalVarSet.mAlloc = &mBumpAlloc; - mLocalVarSet.Reserve(8); + mLocalVarSet.mAlloc = &mBumpAlloc; mMethodInstance = NULL; mPrevMethodState = NULL; @@ -1093,7 +1092,7 @@ public: mAllowUinitReads = false; mDisableReturns = false; mCancelledDeferredCall = false; - mNoObjectAccessChecks = false; + mNoObjectAccessChecks = false; mInDeferredBlock = false; mDeferredLocalAssignData = NULL; mCurLocalVarId = 0; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 677bea45..89808689 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -851,8 +851,8 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) struct MemberRef { BfMemberDef* mMemberDef; - String mName; - String mKindName; + StringView mName; + StringView mKindName; BfTypeInstance* mTypeInst; BfAstNode* mNameNode; BfProtection mProtection; @@ -920,13 +920,13 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) checkType = checkType->mBaseType; } - Dictionary memberMap; + Dictionary memberMap; memberMap.Reserve(memberList.size()); for (int i = (int)memberList.size() - 1; i >= 0; i--) { MemberRef& memberRef = memberList[i]; - if (memberRef.mName.empty()) + if (memberRef.mName.IsEmpty()) continue; if ((memberRef.mTypeInst == typeInst) && (!memberRef.mIsOverride)) { @@ -944,7 +944,7 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) { if ((prevMemberRef->mProtection != BfProtection_Private) && (memberRef.mNameNode != NULL)) { - error = Warn(BfWarning_CS0108_MemberHidesInherited, StrFormat("%s hides inherited member '%s'. Use the 'new' keyword if hiding was intentional.", prevMemberRef->mKindName.c_str(), memberRef.mName.c_str()), memberRef.mNameNode, true); + error = Warn(BfWarning_CS0108_MemberHidesInherited, StrFormat("%s hides inherited member '%s'. Use the 'new' keyword if hiding was intentional.", String(prevMemberRef->mKindName).c_str(), String(memberRef.mName).c_str()), memberRef.mNameNode, true); showPrevious = true; } } @@ -995,7 +995,7 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) } if (secondMemberRef->mNameNode != NULL) - error = Fail(StrFormat("A %s named '%s' has already been declared.", secondMemberRef->mKindName.c_str(), memberRef.mName.c_str()), secondMemberRef->mNameNode, true); + error = Fail(StrFormat("A %s named '%s' has already been declared.", String(secondMemberRef->mKindName).c_str(), String(memberRef.mName).c_str()), secondMemberRef->mNameNode, true); showPrevious = true; typeInst->mHasDeclError = true; } @@ -3185,7 +3185,7 @@ void BfModule::DoPopulateType_InitSearches(BfTypeInstance* typeInstance) { String checkNamespaceStr; typeRef->ToString(checkNamespaceStr); - BfAtomComposite checkNamespace; + BfAtomCompositeT<16> checkNamespace; if (mSystem->ParseAtomComposite(checkNamespaceStr, checkNamespace)) { if (mSystem->ContainsNamespace(checkNamespace, typeDef->mProject)) @@ -7263,7 +7263,7 @@ BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, BfResolvedTypeSet::LookupContext lookupCtx; lookupCtx.mModule = this; - BfResolvedTypeSet::Entry* typeEntry = NULL; + BfResolvedTypeSet::EntryRef typeEntry; auto inserted = mContext->mResolvedTypes.Insert(methodRefType, &lookupCtx, &typeEntry); if (typeEntry->mValue == NULL) { @@ -7992,7 +7992,7 @@ BfTypeDef* BfModule::GetCombinedPartialTypeDef(BfTypeDef* typeDef) BF_ASSERT(!typeDef->mIsExplicitPartial); if (!typeDef->mIsPartial) return typeDef; - auto result = mSystem->FindTypeDef(typeDef->mFullName.ToString(), (int)typeDef->mGenericParamDefs.size()); + auto result = mSystem->FindTypeDef(typeDef->mFullName, (int)typeDef->mGenericParamDefs.size(), NULL, {}, NULL, BfFindTypeDefFlag_None); return result; } @@ -8780,10 +8780,10 @@ BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType, B BfResolvedTypeSet::LookupContext lookupCtx; lookupCtx.mModule = this; lookupCtx.mResolveFlags = resolveFlags; - BfResolvedTypeSet::Entry* resolvedEntry = NULL; + BfResolvedTypeSet::EntryRef resolvedEntry; bool inserted = mContext->mResolvedTypes.Insert(lookupType, &lookupCtx, &resolvedEntry); - if (resolvedEntry == NULL) + if (!resolvedEntry) return NULL; if (!inserted) @@ -9667,7 +9667,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric if (!checkNamespace.IsEmpty()) { - BfAtomComposite atomComposite; + BfAtomCompositeT<16> atomComposite; if (mSystem->ParseAtomComposite(checkNamespace, atomComposite)) namespaceSearch.Add(atomComposite); } @@ -9693,7 +9693,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric } BfTypeLookupEntry typeLookupEntry; - typeLookupEntry.mName = findName; + typeLookupEntry.mName.Reference(findName); typeLookupEntry.mNumGenericParams = numGenericArgs; typeLookupEntry.mUseTypeDef = useTypeDef; @@ -9918,7 +9918,7 @@ bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef) StringT<128> leftNameStr; BfType* leftType = NULL; - BfAtomComposite leftComposite; + BfAtomCompositeT<16> leftComposite; qualifiedTypeRef->mLeft->ToString(leftNameStr); if (!mSystem->ParseAtomComposite(leftNameStr, leftComposite)) @@ -9982,11 +9982,11 @@ bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef) if (!_ToString(typeRef, true)) return false; - BfAtomComposite composite; + BfAtomCompositeT<16> composite; if (!mSystem->ParseAtomComposite(name, composite)) return false; - BfAtomComposite compositeEx; + BfAtomCompositeT<16> compositeEx; if (!mSystem->ParseAtomComposite(nameEx, compositeEx)) return false; @@ -10939,13 +10939,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula lookupCtx.mRootTypeRef = typeRef; lookupCtx.mRootTypeDef = typeDef; lookupCtx.mModule = this; - BfResolvedTypeSet::Entry* resolvedEntry = NULL; + BfResolvedTypeSet::EntryRef resolvedEntry; if (auto delegateTypeRef = BfNodeDynCastExact(typeRef)) GetDelegateTypeRefAttributes(delegateTypeRef, lookupCtx.mCallingConvention); auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry); - if (resolvedEntry == NULL) + if (!resolvedEntry) { if (lookupCtx.mHadVar) return ResolveTypeResult(typeRef, GetPrimitiveType(BfTypeCode_Var), populateType, resolveFlags); @@ -10984,7 +10984,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BfPrimitiveType* primType = new BfPrimitiveType(); primType->mTypeDef = typeDef; resolvedEntry->mValue = primType; - BF_ASSERT(BfResolvedTypeSet::Hash(primType, &lookupCtx, false) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(primType, &lookupCtx, false) == resolvedEntry->mHashCode); populateModule->InitType(primType, populateType); return ResolveTypeResult(typeRef, primType, populateType, resolveFlags); } @@ -11045,7 +11045,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedEntry->mValue = genericTypeInst; populateModule->InitType(genericTypeInst, populateType); #ifdef _DEBUG - if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx); @@ -11088,14 +11088,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula populateModule->InitType(typeInst, populateType); - if (BfResolvedTypeSet::Hash(typeInst, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(typeInst, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); int typeHash = BfResolvedTypeSet::Hash(typeInst, &lookupCtx); BF_ASSERT(refHash == typeHash); } { - BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHashCode); } return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags); } @@ -11141,7 +11141,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula arrayType->mElementCountSource = typedVal.mType; resolvedEntry->mValue = arrayType; - BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(arrayType, populateType); return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags); } @@ -11175,7 +11175,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula arrayType->mGenericDepth = elementType->GetGenericDepth() + 1; resolvedEntry->mValue = arrayType; - BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(arrayType, populateType); return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags); } @@ -11190,7 +11190,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula CheckUnspecializedGenericType(arrayType, populateType); - BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(arrayType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(arrayType, populateType); return ResolveTypeResult(typeRef, arrayType, populateType, resolveFlags); } @@ -11388,22 +11388,22 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula populateModule->InitType(genericTypeInst, populateType); #ifdef _DEBUG - if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx); BF_ASSERT(refHash == typeHash); - BF_ASSERT(refHash == resolvedEntry->mHash); + BF_ASSERT(refHash == resolvedEntry->mHashCode); } if (!BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx)) { BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx)); } - BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHash); + BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHashCode); #endif - BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHashCode); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); } else if (auto tupleTypeRef = BfNodeDynCast(typeRef)) @@ -11517,7 +11517,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } resolvedEntry->mValue = tupleType; - BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(tupleType, populateType); return ResolveTypeResult(typeRef, tupleType, populateType, resolveFlags); @@ -11548,7 +11548,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedEntry->mValue = genericTypeInst; #ifdef _DEBUG - if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx); @@ -11575,7 +11575,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedEntry->mValue = pointerType; //int hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx); - BF_ASSERT(BfResolvedTypeSet::Hash(pointerType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(pointerType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(pointerType, populateType); return ResolveTypeResult(typeRef, pointerType, populateType, resolveFlags); @@ -11604,7 +11604,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedEntry->mValue = refType; #ifdef _DEBUG - if (BfResolvedTypeSet::Hash(refType, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(refType, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx, BfResolvedTypeSet::BfHashFlag_AllowRef); int typeHash = BfResolvedTypeSet::Hash(refType, &lookupCtx); @@ -11879,7 +11879,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); #ifdef _DEBUG - if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); int typeHash = BfResolvedTypeSet::Hash(delegateType, &lookupCtx); @@ -11888,7 +11888,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BF_ASSERT(BfResolvedTypeSet::Equals(delegateType, typeRef, &lookupCtx)); #endif - BF_ASSERT(BfResolvedTypeSet::Hash(delegateType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(delegateType, &lookupCtx) == resolvedEntry->mHashCode); return ResolveTypeResult(typeRef, delegateType, populateType, resolveFlags); } @@ -11896,7 +11896,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { auto genericParamType = GetGenericParamType(genericParamTypeRef->mGenericParamKind, genericParamTypeRef->mGenericParamIdx); resolvedEntry->mValue = genericParamType; - BF_ASSERT(BfResolvedTypeSet::Hash(genericParamType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(genericParamType, &lookupCtx) == resolvedEntry->mHashCode); return ResolveTypeResult(typeRef, genericParamType, populateType, resolveFlags); } else if (auto retTypeTypeRef = BfNodeDynCast(typeRef)) @@ -11908,7 +11908,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BF_ASSERT(retTypeType->mElementType); resolvedEntry->mValue = retTypeType; - BF_ASSERT(BfResolvedTypeSet::Hash(retTypeType, &lookupCtx) == resolvedEntry->mHash); + BF_ASSERT(BfResolvedTypeSet::Hash(retTypeType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(retTypeType, populateType); return ResolveTypeResult(typeRef, retTypeType, populateType, resolveFlags); @@ -11952,7 +11952,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedEntry->mValue = constExprType; #ifdef _DEBUG - if (BfResolvedTypeSet::Hash(constExprType, &lookupCtx) != resolvedEntry->mHash) + if (BfResolvedTypeSet::Hash(constExprType, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); int typeHash = BfResolvedTypeSet::Hash(constExprType, &lookupCtx); diff --git a/IDEHelper/Compiler/BfNamespaceVisitor.cpp b/IDEHelper/Compiler/BfNamespaceVisitor.cpp index 6741c58f..78caf433 100644 --- a/IDEHelper/Compiler/BfNamespaceVisitor.cpp +++ b/IDEHelper/Compiler/BfNamespaceVisitor.cpp @@ -15,7 +15,7 @@ void BfNamespaceVisitor::Visit(BfUsingDirective* usingDirective) } String usingString = usingDirective->mNamespace->ToString(); - BfAtomComposite usingComposite; + BfAtomCompositeT<16> usingComposite; mSystem->ParseAtomComposite(usingString, usingComposite); if (mResolvePassData->mAutoComplete != NULL) @@ -45,14 +45,14 @@ void BfNamespaceVisitor::Visit(BfUsingModDirective* usingDirective) String usingString = useNode->ToString(); - BfAtomComposite usingComposite; + BfAtomCompositeT<16> usingComposite; if (mSystem->ParseAtomComposite(usingString, usingComposite)) mResolvePassData->HandleNamespaceReference(useNode, usingComposite); } void BfNamespaceVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) { - BfAtomComposite prevNamespace = mNamespace; + BfAtomCompositeT<16> prevNamespace = mNamespace; if (namespaceDeclaration->mNameNode == NULL) return; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 631d4a73..26f82802 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -1026,13 +1026,13 @@ void BfMethodInstance::GetParamName(int paramIdx, StringImpl& name, int& namePre invokeMethodInstance->GetParamName(methodParam->mDelegateParamIdx, name, namePrefixCount); return; } - name = paramDef->mName; + name.Reference(paramDef->mName); namePrefixCount = paramDef->mNamePrefixCount; } String BfMethodInstance::GetParamName(int paramIdx) { - String paramName; + StringT<256> paramName; int namePrefixCount = 0; GetParamName(paramIdx, paramName, namePrefixCount); return paramName; @@ -1040,7 +1040,7 @@ String BfMethodInstance::GetParamName(int paramIdx) String BfMethodInstance::GetParamName(int paramIdx, int& namePrefixCount) { - String paramName; + StringT<256> paramName; GetParamName(paramIdx, paramName, namePrefixCount); return paramName; } @@ -4875,9 +4875,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfAstNode* rhs, LookupContext* ctx) return false; } -void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::Entry* entry) +void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::EntryRef entry) { - int hashIdx = (entry->mHash & 0x7FFFFFFF) % mHashSize; + int hashIdx = (entry->mHashCode & 0x7FFFFFFF) % mHashSize; // if (entry->mPrev == NULL) // { // if (entry->mNext != NULL) @@ -4896,23 +4896,23 @@ void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::Entry* entry) bool found = false; - Entry** srcCheckEntryPtr = &this->mHashHeads[hashIdx]; - Entry* checkEntry = *srcCheckEntryPtr; - while (checkEntry != NULL) + int* srcCheckEntryPtr = &this->mHashHeads[hashIdx]; + int checkEntryIdx = *srcCheckEntryPtr; + while (checkEntryIdx != -1) { - if (checkEntry == entry) + auto checkEntry = &mEntries[checkEntryIdx]; + if (checkEntryIdx == entry.mIndex) { - this->mCount--; *srcCheckEntryPtr = checkEntry->mNext; found = true; } srcCheckEntryPtr = &checkEntry->mNext; - checkEntry = checkEntry->mNext; + checkEntryIdx = checkEntry->mNext; } BF_ASSERT(found); BF_ASSERT(entry->mValue == NULL); - Deallocate(entry); + FreeIdx(entry.mIndex); } // BfResolvedTypeSet::Iterator BfResolvedTypeSet::begin() diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 072f2d97..97b6ab81 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -2152,7 +2152,6 @@ public: } }; - class BfBoxedType : public BfTypeInstance { public: @@ -2664,14 +2663,13 @@ public: public: BfResolvedTypeSet() { - mHashSize = 9973; - mHashHeads = (Entry**)AllocateZero(sizeof(Entry*) * mHashSize, alignof(Entry*)); + Rehash(9973); } ~BfResolvedTypeSet(); template - bool Insert(T* findType, LookupContext* ctx, BfResolvedTypeSet::Entry** entryPtr) + bool Insert(T* findType, LookupContext* ctx, BfResolvedTypeSet::EntryRef* entryPtr) { CheckRehash(); @@ -2691,17 +2689,19 @@ public: return false; } int bucket = (hashVal & 0x7FFFFFFF) % mHashSize; - auto checkEntry = mHashHeads[bucket]; - while (checkEntry != NULL) - { + auto checkEntryIdx = mHashHeads[bucket]; + while (checkEntryIdx != -1) + { + auto checkEntry = &mEntries[checkEntryIdx]; + // checkEntry->mType can be NULL if we're in the process of filling it in (and this Insert is from an element type) // OR if the type resolution failed after node insertion - if ((checkEntry->mValue != NULL) && (hashVal == checkEntry->mHash) && (Equals(checkEntry->mValue, findType, ctx))) + if ((checkEntry->mValue != NULL) && (hashVal == checkEntry->mHashCode) && (Equals(checkEntry->mValue, findType, ctx))) { - *entryPtr = checkEntry; + *entryPtr = EntryRef(this, checkEntryIdx); return false; } - checkEntry = checkEntry->mNext; + checkEntryIdx = checkEntry->mNext; tryCount++; // If this fires off, this may indicate that our hashes are equivalent but Equals fails @@ -2715,22 +2715,14 @@ public: if ((ctx->mResolveFlags & BfResolveTypeRefFlag_NoCreate) != 0) return false; - mCount++; - Entry* entry = (Entry*)BfResolvedTypeSetFuncs::Allocate(sizeof(Entry), alignof(Entry)); - entry->mValue = NULL; -// if (mHashHeads[bucket] != NULL) -// mHashHeads[bucket]->mPrev = entry; - entry->mNext = mHashHeads[bucket]; - entry->mHash = hashVal; - mHashHeads[bucket] = entry; - *entryPtr = entry; + *entryPtr = AddRaw(hashVal); return true; } // Iterator begin(); // Iterator end(); // Iterator erase(Iterator& itr); - void RemoveEntry(Entry* entry); + void RemoveEntry(EntryRef entry); }; class BfTypeUtils diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 366d5c30..4fb59ae9 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -2504,7 +2504,7 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric // This searched globals, but we were already doing that down below at the LAST step. Right? BfTypeDef* foundTypeDef = NULL; - BfAtomComposite qualifiedFindName; + BfAtomCompositeT<16> qualifiedFindName; int foundPri = (int)0x80000000; for (int namespaceIdx = 0; namespaceIdx <= (int) namespaceSearch.size(); namespaceIdx++) @@ -2512,14 +2512,16 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric int curNamespacePri = 0; if (namespaceIdx < (int)namespaceSearch.size()) { - auto& namespaceDeclaration = namespaceSearch[namespaceIdx]; + auto& namespaceDeclaration = namespaceSearch[namespaceIdx]; qualifiedFindName.Set(namespaceDeclaration, findName); } else { qualifiedFindName = findName; } - + + int partialStartEntryIdx = -1; + auto itr = mTypeDefs.TryGet(qualifiedFindName); while (itr) { @@ -2528,10 +2530,39 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric if ((typeDef->mIsPartial) || ((typeDef->IsGlobalsContainer()) && ((flags & BfFindTypeDefFlag_AllowGlobal) == 0))) { - itr.MoveToNextHashMatch(); - continue; + bool handled = false; + if (itr.mCurEntry < mTypeDefs.mPartialSkipCache.mSize) + { + auto& entry = mTypeDefs.mPartialSkipCache[itr.mCurEntry]; + if (entry.mRevision == mTypeDefs.mRevision) + { + if (entry.mIndex == -1) + { + // No non-partial here + break; + } + + itr.mCurEntry = entry.mIndex; + typeDef = *itr; + handled = true; + } + } + + if (!handled) + { + if (partialStartEntryIdx == -1) + partialStartEntryIdx = itr.mCurEntry; + itr.MoveToNextHashMatch(); + continue; + } } + if ((partialStartEntryIdx != -1) && ((flags & BfFindTypeDefFlag_AllowGlobal) == 0)) + { + mTypeDefs.SetPartialSkipCache(partialStartEntryIdx, itr.mCurEntry); + partialStartEntryIdx = -1; + } + if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project))) { int curPri = curNamespacePri; @@ -2556,6 +2587,9 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric } itr.MoveToNextHashMatch(); } + + if ((partialStartEntryIdx != -1) && ((flags & BfFindTypeDefFlag_AllowGlobal) == 0)) + mTypeDefs.SetPartialSkipCache(partialStartEntryIdx, -1); } // Didn't match the correct number of generic params, but let the compiler complain @@ -2647,16 +2681,10 @@ bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfTypeDef* BfSystem::FindTypeDef(const StringImpl& typeName, int numGenericArgs, BfProject* project, const Array& namespaceSearch, BfTypeDef** ambiguousTypeDef, BfFindTypeDefFlags flags) { - BfAtomComposite qualifiedFindName; - BfAtom* tempData[16]; - qualifiedFindName.mAllocSize = 16; - qualifiedFindName.mParts = tempData; - + BfAtomCompositeT<16> qualifiedFindName; BfTypeDef* result = NULL; if (ParseAtomComposite(typeName, qualifiedFindName)) - result = FindTypeDef(qualifiedFindName, numGenericArgs, project, namespaceSearch, ambiguousTypeDef, flags); - if (qualifiedFindName.mParts == tempData) - qualifiedFindName.mParts = NULL; + result = FindTypeDef(qualifiedFindName, numGenericArgs, project, namespaceSearch, ambiguousTypeDef, flags); return result; } diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index 7aa41a6e..ba2a8246 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -44,7 +44,6 @@ class BfProject; class BfTypeDef; struct BfTypeDefMapFuncs; -typedef MultiHashSet BfTypeDefMap; typedef HashSet BfProjectSet; class BfAtom @@ -107,6 +106,33 @@ public: uint32 GetAtomUpdateIdx(); }; +template +class BfAtomCompositeT : public BfAtomComposite +{ +public: + BfAtom* mInternalBuffer[TBufSize]; + +public: + BfAtomCompositeT() + { + mAllocSize = (int16)TBufSize; + mParts = mInternalBuffer; + } + + BfAtomCompositeT(const BfAtomComposite& rhs) + { + mAllocSize = (int16)TBufSize; + mParts = mInternalBuffer; + *this = rhs; + } + + BfAtomCompositeT& operator=(const BfAtomComposite& rhs) + { + Set(rhs.mParts, rhs.mSize, NULL, 0); + return *this; + } +}; + class BfSizedAtomComposite : public BfAtomComposite { public: @@ -1245,6 +1271,79 @@ struct BfTypeDefMapFuncs : public MultiHashSetFuncs } }; +class BfTypeDefMap : public MultiHashSet +{ +public: + struct SkipEntry + { + public: + int mIndex; + int mRevision; + + public: + SkipEntry() + { + mIndex = -1; + mRevision = -1; + } + + SkipEntry(int index, int revision) + { + mIndex = index; + mRevision = revision; + } + }; + + Array mPartialSkipCache; + int mRevision; + +public: + BfTypeDefMap() + { + mRevision = 1; + } + + void Add(BfTypeDef* value) + { + MultiHashSet::Add(value); + mRevision++; + } + + void AddAfter(BfTypeDef* value, Entry* afterEntry) + { + MultiHashSet::AddAfter(value, afterEntry); + mRevision++; + } + + template + bool Remove(const TKey& key) + { + bool result = MultiHashSet::Remove(key); + mRevision++; + return result; + } + + Iterator Erase(const Iterator& itr) + { + auto result = MultiHashSet::Erase(itr); + mRevision++; + return result; + } + + void Clear() + { + MultiHashSet::Clear(); + mRevision++; + } + + void SetPartialSkipCache(int partialIdx, int mapToIdx) + { + while (partialIdx >= mPartialSkipCache.mSize) + mPartialSkipCache.Add(SkipEntry()); + mPartialSkipCache[partialIdx] = SkipEntry(mapToIdx, mRevision); + } +}; + enum BfTargetType { BfTargetType_BeefConsoleApplication, @@ -1663,7 +1762,7 @@ public: int mHighestYieldTime; // The following are protected by mSystemLock - can only be accessed by the compiling thread Dictionary mSystemTypeDefs; - BfTypeDefMap mTypeDefs; + BfTypeDefMap mTypeDefs; bool mNeedsTypesHandledByCompiler; BumpAllocator mAlloc; int mAtomCreateIdx; @@ -1727,7 +1826,7 @@ public: void ReleaseAtomComposite(const BfAtomComposite& atomComposite); void SanityCheckAtomComposite(const BfAtomComposite& atomComposite); void TrackName(BfTypeDef* typeDef); - void UntrackName(BfTypeDef* typeDef); + void UntrackName(BfTypeDef* typeDef); bool ParseAtomComposite(const StringView& name, BfAtomComposite& composite, bool addRefs = false); @@ -1747,7 +1846,8 @@ public: BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfProject* project = NULL, const Array& namespaceSearch = Array(), BfTypeDef** ambiguousTypeDef = NULL, BfFindTypeDefFlags flags = BfFindTypeDefFlag_None); BfTypeDef* FindTypeDef(const StringImpl& typeName, BfProject* project); BfTypeDef* FindTypeDefEx(const StringImpl& typeName); - void FindFixitNamespaces(const StringImpl& typeName, int numGenericArgs, BfProject* project, std::set& fixitNamespaces); + void ClearTypeDefCache(); + void FindFixitNamespaces(const StringImpl& typeName, int numGenericArgs, BfProject* project, std::set& fixitNamespaces); void RemoveTypeDef(BfTypeDef* typeDef); //BfTypeDefMap::Iterator RemoveTypeDef(BfTypeDefMap::Iterator typeDefItr); diff --git a/IDEHelper/IDEHelper.vcxproj b/IDEHelper/IDEHelper.vcxproj index 48c8a48e..0d1d1233 100644 --- a/IDEHelper/IDEHelper.vcxproj +++ b/IDEHelper/IDEHelper.vcxproj @@ -218,7 +218,7 @@ MaxSpeed true true - zBP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) + BP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include MultiThreaded false