mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
MultiDictionary hotswap fix
This commit is contained in:
parent
23d4d35a73
commit
4f0ad540a7
4 changed files with 92 additions and 23 deletions
|
@ -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 <typename TKey>
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
24
IDE/dist/BeefDbgVis.toml
vendored
24
IDE/dist/BeefDbgVis.toml
vendored
|
@ -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} }}"
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue