95 lines
3.9 KiB
Diff
95 lines
3.9 KiB
Diff
# UNDF: UNDF-2026-000001078
|
|
--- a/desmume/src/NDSSystem.cpp
|
|
+++ b/desmume/src/NDSSystem.cpp
|
|
@@ -1,5 +1,6 @@
|
|
#include <string.h>
|
|
#include <algorithm>
|
|
+#include <unordered_set>
|
|
|
|
// ...
|
|
|
|
@@ -1955,6 +1955,14 @@ template<bool doarm9, bool doarm7>
|
|
static /*donotinline*/ std::pair<s32,s32> armInnerLoop(
|
|
const u64 nds_timer_base, const s32 s32next, s32 arm9, s32 arm7)
|
|
{
|
|
+ // DEFECT (removed): O(B) linear scan of breakPoints vector on every CPU instruction.
|
|
+ // With B breakpoints set, the NDS_ARM9 and NDS_ARM7 loops each scan the full vector
|
|
+ // per instruction, giving O(B * I) per second where I is the instruction rate
|
|
+ // (~66 MHz ARM9 + ~33 MHz ARM7). Fix: replace std::vector<u32> *breakPoints with
|
|
+ // std::unordered_set<u32> *breakPoints (O(1) lookup).
|
|
+ //
|
|
+ // In armcpu.h: change std::vector<u32> *breakPoints;
|
|
+ // to std::unordered_set<u32> *breakPoints;
|
|
+ //
|
|
+ // In armcpu.cpp armcpu_init(): change armcpu->breakPoints = new std::vector<u32>;
|
|
+ // to armcpu->breakPoints = new std::unordered_set<u32>;
|
|
+ //
|
|
+ // In disView.cpp: change push_back -> insert; erase(begin()+i) -> erase(value).
|
|
|
|
s32 timer = minarmtime<doarm9,doarm7>(arm9,arm7);
|
|
while(timer < s32next && !sequencer.reschedule && execute)
|
|
{
|
|
// breakpoint handling
|
|
#if defined(HOST_WINDOWS) && !defined(TARGET_INTERFACE)
|
|
- const std::vector<u32> *breakpointList9 = NDS_ARM9.breakPoints;
|
|
- for (int i = 0; i < breakpointList9->size(); ++i) {
|
|
- if (NDS_ARM9.instruct_adr == (*breakpointList9)[i] && !NDS_ARM9.debugStep) {
|
|
+ // PATCHED: O(1) hash-set lookup instead of O(B) linear scan.
|
|
+ if (NDS_ARM9.breakPoints->count(NDS_ARM9.instruct_adr) && !NDS_ARM9.debugStep) {
|
|
emu_paused = true;
|
|
paused = true;
|
|
execute = false;
|
|
// update debug display
|
|
PostMessageA(DisViewWnd[0], WM_COMMAND, IDC_DISASMSEEK, NDS_ARM9.instruct_adr);
|
|
InvalidateRect(DisViewWnd[0], NULL, FALSE);
|
|
return std::make_pair(arm9, arm7);
|
|
- }
|
|
}
|
|
- const std::vector<u32> *breakpointList7 = NDS_ARM7.breakPoints;
|
|
- for (int i = 0; i < breakpointList7->size(); ++i) {
|
|
- if (NDS_ARM7.instruct_adr == (*breakpointList7)[i] && !NDS_ARM7.debugStep) {
|
|
+ if (NDS_ARM7.breakPoints->count(NDS_ARM7.instruct_adr) && !NDS_ARM7.debugStep) {
|
|
emu_paused = true;
|
|
paused = true;
|
|
execute = false;
|
|
// update debug display
|
|
PostMessageA(DisViewWnd[1], WM_COMMAND, IDC_DISASMSEEK, NDS_ARM7.instruct_adr);
|
|
InvalidateRect(DisViewWnd[1], NULL, FALSE);
|
|
return std::make_pair(arm9, arm7);
|
|
- }
|
|
}
|
|
#endif //HOST_WINDOWS
|
|
|
|
--- a/desmume/src/armcpu.h
|
|
+++ b/desmume/src/armcpu.h
|
|
@@ -313,7 +313,8 @@ typedef struct armcpu_t {
|
|
// ...
|
|
- std::vector<u32> *breakPoints;
|
|
+ // PATCHED: unordered_set gives O(1) lookup vs O(B) linear scan in armInnerLoop.
|
|
+ std::unordered_set<u32> *breakPoints;
|
|
// ...
|
|
|
|
--- a/desmume/src/armcpu.cpp
|
|
+++ b/desmume/src/armcpu.cpp
|
|
@@ -149,7 +149,7 @@ void armcpu_init(armcpu_t *armcpu, u32 adr)
|
|
- armcpu->breakPoints = new std::vector<u32>;
|
|
+ armcpu->breakPoints = new std::unordered_set<u32>;
|
|
|
|
--- a/desmume/src/frontend/windows/disView.cpp
|
|
+++ b/desmume/src/frontend/windows/disView.cpp
|
|
@@ -550,7 +550,7 @@ LRESULT CALLBACK DisViewWndProc(...)
|
|
- NDS_ARM7.breakPoints->push_back(adr);
|
|
+ NDS_ARM7.breakPoints->insert(adr);
|
|
...
|
|
- if (DisView7->break_pos < NDS_ARM7.breakPoints->size()) {
|
|
- NDS_ARM7.breakPoints->erase(NDS_ARM7.breakPoints->begin() + DisView7->break_pos);
|
|
+ if (NDS_ARM7.breakPoints->count(adr)) {
|
|
+ NDS_ARM7.breakPoints->erase(adr);
|
|
@@ -883,7 +883,7 @@ LRESULT CALLBACK DisViewWndProc(...)
|
|
- NDS_ARM9.breakPoints->push_back(adr);
|
|
+ NDS_ARM9.breakPoints->insert(adr);
|
|
...
|
|
- if (DisView9->break_pos < NDS_ARM9.breakPoints->size()) {
|
|
- NDS_ARM9.breakPoints->erase(NDS_ARM9.breakPoints->begin() + DisView9->break_pos);
|
|
+ if (NDS_ARM9.breakPoints->count(adr)) {
|
|
+ NDS_ARM9.breakPoints->erase(adr);
|