99 lines
2.6 KiB
Diff
99 lines
2.6 KiB
Diff
# UNDF: UNDF-2026-000001042
|
|
# 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();
|
|
}
|