mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32: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
|
struct Iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MultiDictionary* mSet;
|
MultiDictionary* mDict;
|
||||||
int mCurEntry;
|
int mCurEntry;
|
||||||
int mCurBucket;
|
int mCurBucket;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
Iterator(MultiDictionary* set)
|
Iterator()
|
||||||
{
|
{
|
||||||
this->mSet = set;
|
this->mDict = NULL;
|
||||||
|
this->mCurBucket = 0;
|
||||||
|
this->mCurEntry = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Iterator(MultiDictionary* dict)
|
||||||
|
{
|
||||||
|
this->mDict = dict;
|
||||||
this->mCurBucket = 0;
|
this->mCurBucket = 0;
|
||||||
this->mCurEntry = -1;
|
this->mCurEntry = -1;
|
||||||
}
|
}
|
||||||
|
@ -86,21 +94,21 @@ public:
|
||||||
{
|
{
|
||||||
if (this->mCurEntry != -1)
|
if (this->mCurEntry != -1)
|
||||||
{
|
{
|
||||||
this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext;
|
this->mCurEntry = this->mDict->mEntries[this->mCurEntry].mNext;
|
||||||
if (this->mCurEntry != -1)
|
if (this->mCurEntry != -1)
|
||||||
return *this;
|
return *this;
|
||||||
this->mCurBucket++;
|
this->mCurBucket++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSet->mHashHeads == NULL)
|
if (mDict->mHashHeads == NULL)
|
||||||
{
|
{
|
||||||
this->mCurBucket = this->mSet->mHashSize;
|
this->mCurBucket = this->mDict->mHashSize;
|
||||||
return *this; // At end
|
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)
|
if (this->mCurEntry != -1)
|
||||||
return *this;
|
return *this;
|
||||||
this->mCurBucket++;
|
this->mCurBucket++;
|
||||||
|
@ -111,12 +119,12 @@ public:
|
||||||
|
|
||||||
TKey GetKey()
|
TKey GetKey()
|
||||||
{
|
{
|
||||||
return this->mSet->mEntries[this->mCurEntry].mKey;
|
return this->mDict->mEntries[this->mCurEntry].mKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
TValue GetValue()
|
TValue GetValue()
|
||||||
{
|
{
|
||||||
return this->mSet->mEntries[this->mCurEntry].mValue;
|
return this->mDict->mEntries[this->mCurEntry].mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Iterator& itr) const
|
bool operator!=(const Iterator& itr) const
|
||||||
|
@ -131,11 +139,45 @@ public:
|
||||||
|
|
||||||
void MoveToNextHashMatch()
|
void MoveToNextHashMatch()
|
||||||
{
|
{
|
||||||
int wantHash = this->mSet->mEntries[this->mCurEntry].mHashCode;
|
int wantHash = this->mDict->mEntries[this->mCurEntry].mHashCode;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext;
|
this->mCurEntry = this->mDict->mEntries[this->mCurEntry].mNext;
|
||||||
} while ((this->mCurEntry != -1) && (this->mSet->mEntries[this->mCurEntry].mHashCode != wantHash));
|
} 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>
|
template <typename TKey>
|
||||||
Iterator TryGet(const TKey& key)
|
MatchIterator TryGet(const TKey& key)
|
||||||
{
|
{
|
||||||
if (mHashHeads == NULL)
|
if (mHashHeads == NULL)
|
||||||
return end();
|
return end();
|
||||||
|
@ -415,7 +457,7 @@ public:
|
||||||
auto checkEntry = &this->mEntries[checkEntryIdx];
|
auto checkEntry = &this->mEntries[checkEntryIdx];
|
||||||
if ((checkEntry->mHashCode == hash) && (TFuncs::Matches(key, checkEntry->mKey)))
|
if ((checkEntry->mHashCode == hash) && (TFuncs::Matches(key, checkEntry->mKey)))
|
||||||
{
|
{
|
||||||
Iterator itr(this);
|
MatchIterator itr(this, key);
|
||||||
itr.mCurEntry = checkEntryIdx;
|
itr.mCurEntry = checkEntryIdx;
|
||||||
itr.mCurBucket = hashIdx;
|
itr.mCurBucket = hashIdx;
|
||||||
return itr;
|
return itr;
|
||||||
|
|
|
@ -146,6 +146,8 @@ public:
|
||||||
this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext;
|
this->mCurEntry = this->mSet->mEntries[this->mCurEntry].mNext;
|
||||||
}
|
}
|
||||||
while ((this->mCurEntry != -1) && (this->mSet->mEntries[this->mCurEntry].mHashCode != wantHash));
|
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]"
|
Name = "[Value]"
|
||||||
Value = "*($T2*)&mValue"
|
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]]
|
[[Type]]
|
||||||
Name = "Beefy::HashSet<*, *>"
|
Name = "Beefy::HashSet<*, *>"
|
||||||
DisplayString = "{{ count={mCount - mFreeCount} }}"
|
DisplayString = "{{ count={mCount - mFreeCount} }}"
|
||||||
|
|
|
@ -5532,11 +5532,12 @@ void DbgModule::HotReplaceMethods(DbgType* newType, DbgType* primaryType)
|
||||||
bool didReplace = false;
|
bool didReplace = false;
|
||||||
if (!newMethod->mBlock.IsEmpty())
|
if (!newMethod->mBlock.IsEmpty())
|
||||||
{
|
{
|
||||||
BfLogDbg("Hot added new method %p %s Address:%p\n", newMethod, newMethod->mName, newMethod->mBlock.mLowPC);
|
|
||||||
|
|
||||||
newMethod->PopulateSubprogram();
|
newMethod->PopulateSubprogram();
|
||||||
|
|
||||||
auto symInfo = mDebugTarget->mSymbolMap.Get(newMethod->mBlock.mLowPC);
|
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)
|
if (symInfo != NULL)
|
||||||
{
|
{
|
||||||
DbgSubprogram* oldMethod = NULL;
|
DbgSubprogram* oldMethod = NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue