dolphin: 1 CWE-407 defect, MOAD 0002-0005 CLEAN
dolphin-0001: BreakPoints::GetRegularBreakpoint O(N) std::ranges::find over m_breakpoints vector, called per CPU instruction when breakpoints are active. Fix: unordered_map<u32, size_t> index rebuilt on mutation, O(1) lookup. 2.5x speedup at N=64, scales further with breakpoint count.
This commit is contained in:
parent
24524ac502
commit
8631453f5e
2 changed files with 276 additions and 0 deletions
98
defects/dolphin-0001/patch/dolphin-0001.patch
Normal file
98
defects/dolphin-0001/patch/dolphin-0001.patch
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
# UNDF: UNDF-2026-XXXXXXXXX
|
||||
--- a/Source/Core/Core/PowerPC/BreakPoints.h
|
||||
+++ b/Source/Core/Core/PowerPC/BreakPoints.h
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
+#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/BitSet.h"
|
||||
@@ -60,11 +61,18 @@ public:
|
||||
bool Remove(u32 address);
|
||||
void Clear();
|
||||
void ClearTemporary();
|
||||
+
|
||||
+ // Rebuild the O(1) address index. Called after any mutation.
|
||||
+ void RebuildIndex();
|
||||
|
||||
private:
|
||||
TBreakPoints m_breakpoints;
|
||||
std::optional<TBreakPoint> m_temp_breakpoint;
|
||||
Core::System& m_system;
|
||||
bool m_breaking_enabled = true;
|
||||
+
|
||||
+ // Address -> index into m_breakpoints for O(1) lookup.
|
||||
+ // Invalidated and rebuilt on every Add/Remove/Clear.
|
||||
+ std::unordered_map<u32, std::size_t> m_bp_index;
|
||||
};
|
||||
--- a/Source/Core/Core/PowerPC/BreakPoints.cpp
|
||||
+++ b/Source/Core/Core/PowerPC/BreakPoints.cpp
|
||||
@@ -52,10 +52,17 @@ const TBreakPoint* BreakPoints::GetBreakpoint(u32 address) const
|
||||
return GetRegularBreakpoint(address);
|
||||
}
|
||||
|
||||
+void BreakPoints::RebuildIndex()
|
||||
+{
|
||||
+ m_bp_index.clear();
|
||||
+ m_bp_index.reserve(m_breakpoints.size());
|
||||
+ for (std::size_t i = 0; i < m_breakpoints.size(); ++i)
|
||||
+ m_bp_index[m_breakpoints[i].address] = i;
|
||||
+}
|
||||
+
|
||||
const TBreakPoint* BreakPoints::GetRegularBreakpoint(u32 address) const
|
||||
{
|
||||
- auto bp = std::ranges::find(m_breakpoints, address, &TBreakPoint::address);
|
||||
-
|
||||
- if (bp == m_breakpoints.end())
|
||||
+ // O(1) hash lookup instead of O(N) linear scan over m_breakpoints.
|
||||
+ auto it = m_bp_index.find(address);
|
||||
+ if (it == m_bp_index.end())
|
||||
return nullptr;
|
||||
|
||||
- return &*bp;
|
||||
+ return &m_breakpoints[it->second];
|
||||
}
|
||||
|
||||
@@ -115,7 +122,9 @@ void BreakPoints::Add(TBreakPoint bp)
|
||||
if (IsAddressBreakPoint(bp.address))
|
||||
return;
|
||||
|
||||
m_system.GetJitInterface().InvalidateICache(bp.address, 4, true);
|
||||
-
|
||||
m_breakpoints.emplace_back(std::move(bp));
|
||||
+ RebuildIndex();
|
||||
}
|
||||
|
||||
@@ -133,6 +142,7 @@ void BreakPoints::Add(u32 address, bool break_on_hit, bool log_on_hit,
|
||||
{
|
||||
bp.is_enabled = iter->is_enabled;
|
||||
*iter = std::move(bp);
|
||||
+ RebuildIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_breakpoints.emplace_back(std::move(bp));
|
||||
+ RebuildIndex();
|
||||
}
|
||||
|
||||
@@ -181,7 +192,9 @@ bool BreakPoints::Remove(u32 address)
|
||||
if (iter == m_breakpoints.cend())
|
||||
return false;
|
||||
|
||||
m_breakpoints.erase(iter);
|
||||
+ RebuildIndex();
|
||||
m_system.GetJitInterface().InvalidateICache(address, 4, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -192,6 +205,7 @@ void BreakPoints::Clear()
|
||||
m_system.GetJitInterface().InvalidateICache(bp.address, 4, true);
|
||||
}
|
||||
|
||||
m_breakpoints.clear();
|
||||
+ m_bp_index.clear();
|
||||
ClearTemporary();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue