From 4f0ad540a72ee261441d5206c16158244fe64891 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 31 Dec 2024 07:45:16 -0800 Subject: [PATCH] MultiDictionary hotswap fix --- BeefySysLib/util/MultiDictionary.h | 74 +++++++++++++++++++++++------- BeefySysLib/util/MultiHashSet.h | 2 + IDE/dist/BeefDbgVis.toml | 24 ++++++++++ IDEHelper/DbgModule.cpp | 15 +++--- 4 files changed, 92 insertions(+), 23 deletions(-) diff --git a/BeefySysLib/util/MultiDictionary.h b/BeefySysLib/util/MultiDictionary.h index a960f110..52d12172 100644 --- a/BeefySysLib/util/MultiDictionary.h +++ b/BeefySysLib/util/MultiDictionary.h @@ -70,14 +70,22 @@ public: struct Iterator { public: - MultiDictionary* mSet; + MultiDictionary* mDict; int mCurEntry; int mCurBucket; - public: - Iterator(MultiDictionary* set) + protected: + Iterator() { - this->mSet = set; + this->mDict = NULL; + this->mCurBucket = 0; + this->mCurEntry = -1; + } + + public: + Iterator(MultiDictionary* dict) + { + this->mDict = dict; this->mCurBucket = 0; this->mCurEntry = -1; } @@ -86,21 +94,21 @@ public: { if (this->mCurEntry != -1) { - this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext; + this->mCurEntry = this->mDict->mEntries[this->mCurEntry].mNext; if (this->mCurEntry != -1) return *this; this->mCurBucket++; } - if (mSet->mHashHeads == NULL) + if (mDict->mHashHeads == NULL) { - this->mCurBucket = this->mSet->mHashSize; + this->mCurBucket = this->mDict->mHashSize; return *this; // At end } - while (this->mCurBucket < mSet->mHashSize) + while (this->mCurBucket < mDict->mHashSize) { - this->mCurEntry = this->mSet->mHashHeads[mCurBucket]; + this->mCurEntry = this->mDict->mHashHeads[mCurBucket]; if (this->mCurEntry != -1) return *this; this->mCurBucket++; @@ -111,12 +119,12 @@ public: TKey GetKey() { - return this->mSet->mEntries[this->mCurEntry].mKey; + return this->mDict->mEntries[this->mCurEntry].mKey; } TValue GetValue() { - return this->mSet->mEntries[this->mCurEntry].mValue; + return this->mDict->mEntries[this->mCurEntry].mValue; } bool operator!=(const Iterator& itr) const @@ -131,11 +139,45 @@ public: void MoveToNextHashMatch() { - int wantHash = this->mSet->mEntries[this->mCurEntry].mHashCode; + int wantHash = this->mDict->mEntries[this->mCurEntry].mHashCode; do { - this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext; - } while ((this->mCurEntry != -1) && (this->mSet->mEntries[this->mCurEntry].mHashCode != wantHash)); + this->mCurEntry = this->mDict->mEntries[this->mCurEntry].mNext; + } while ((this->mCurEntry != -1) && (this->mDict->mEntries[this->mCurEntry].mHashCode != wantHash)); + if (this->mCurEntry == -1) + this->mCurBucket = mDict->mHashSize; + } + }; + + struct MatchIterator : public Iterator + { + public: + TKey mKey; + + public: + MatchIterator(const Iterator& iterator) + { + this->mDict = iterator.mDict; + this->mCurBucket = iterator.mCurBucket; + this->mCurEntry = iterator.mCurEntry; + } + + MatchIterator(MultiDictionary* dict, const TKey& key) : Iterator(dict) + { + mKey = key; + } + + MatchIterator& operator++() + { + while (true) + { + MoveToNextHashMatch(); + if (*this == mDict->end()) + break; + if (mKey == GetKey()) + break; + } + return *this; } }; @@ -400,7 +442,7 @@ public: } template - Iterator TryGet(const TKey& key) + MatchIterator TryGet(const TKey& key) { if (mHashHeads == NULL) return end(); @@ -415,7 +457,7 @@ public: auto checkEntry = &this->mEntries[checkEntryIdx]; if ((checkEntry->mHashCode == hash) && (TFuncs::Matches(key, checkEntry->mKey))) { - Iterator itr(this); + MatchIterator itr(this, key); itr.mCurEntry = checkEntryIdx; itr.mCurBucket = hashIdx; return itr; diff --git a/BeefySysLib/util/MultiHashSet.h b/BeefySysLib/util/MultiHashSet.h index a2b0e363..3cf904bb 100644 --- a/BeefySysLib/util/MultiHashSet.h +++ b/BeefySysLib/util/MultiHashSet.h @@ -146,6 +146,8 @@ public: this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext; } while ((this->mCurEntry != -1) && (this->mSet->mEntries[this->mCurEntry].mHashCode != wantHash)); + if (this->mCurEntry == -1) + this->mCurBucket = mSet->mHashSize; } }; diff --git a/IDE/dist/BeefDbgVis.toml b/IDE/dist/BeefDbgVis.toml index 94b42a37..be17730d 100644 --- a/IDE/dist/BeefDbgVis.toml +++ b/IDE/dist/BeefDbgVis.toml @@ -567,6 +567,30 @@ Value = "*($T1*)&mKey" Name = "[Value]" Value = "*($T2*)&mValue" +[[Type]] +Name = "Beefy::MultiDictionary<*, *, *>" +DisplayString = "{{ count={mCount - mFreeCount} }}" +[[Type.Expand.Item]] +Name = "[Count]" +Value = "mCount - mFreeCount" +[Type.Expand.DictionaryItems] +Size = "mCount - mFreeCount" +Buckets = "mHashHeads" +Entries = "mEntries" +Key = "mKey" +Value = "mValue" +Next = "mNext" + +[[Type]] +Name = "Beefy::MultiDictionary<*, *, *>::Entry" +DisplayString = "{{[{mKey}, {mValue}]}}" +[[Type.Expand.Item]] +Name = "[Key]" +Value = "mKey" +[[Type.Expand.Item]] +Name = "[Value]" +Value = "mValue" + [[Type]] Name = "Beefy::HashSet<*, *>" DisplayString = "{{ count={mCount - mFreeCount} }}" diff --git a/IDEHelper/DbgModule.cpp b/IDEHelper/DbgModule.cpp index 80dfc8c9..2a847087 100644 --- a/IDEHelper/DbgModule.cpp +++ b/IDEHelper/DbgModule.cpp @@ -5408,8 +5408,8 @@ void DbgModule::HotReplaceMethods(DbgType* newType, DbgType* primaryType) return; auto symInfo = mDebugTarget->mSymbolMap.Get(oldMethod->mBlock.mLowPC); if (symInfo != NULL) - { - oldProgramMap.Add(StringView(symInfo->mName), oldMethod); + { + oldProgramMap.Add(StringView(symInfo->mName), oldMethod); } }; @@ -5531,16 +5531,17 @@ void DbgModule::HotReplaceMethods(DbgType* newType, DbgType* primaryType) { bool didReplace = false; if (!newMethod->mBlock.IsEmpty()) - { - BfLogDbg("Hot added new method %p %s Address:%p\n", newMethod, newMethod->mName, newMethod->mBlock.mLowPC); - + { newMethod->PopulateSubprogram(); - + auto symInfo = mDebugTarget->mSymbolMap.Get(newMethod->mBlock.mLowPC); + BfLogDbg("Hot added new method %p %s Address:%p Sym:%s\n", + newMethod, newMethod->mName, newMethod->mBlock.mLowPC, + (symInfo != NULL) ? symInfo->mName : "???"); if (symInfo != NULL) { DbgSubprogram* oldMethod = NULL; - for (auto itr = oldProgramMap.TryGet(StringView(symInfo->mName)); itr != oldProgramMap.end(); ++itr) + for (auto itr = oldProgramMap.TryGet(StringView(symInfo->mName)); itr != oldProgramMap.end(); ++itr) { auto oldMethod = itr.GetValue(); _HotJump(oldMethod, newMethod);