java-topology/defects/kronos-0001/patch/kronos-0001.patch

101 lines
4 KiB
Diff

# UNDF: UNDF-2026-000001114
# UNDF: UNDF-2026-XXXXXXXXX
--- a/yabause/src/sys/sh2/include/sh2core.h
+++ b/yabause/src/sys/sh2/include/sh2core.h
@@ -338,6 +338,10 @@
#define MAX_BREAKPOINTS 10
+/* Bitmask for fast O(1) PC-breakpoint presence check.
+ * Slot i is set if codebreakpoint[i].addr == (PC & 0x1FFFFFFF) at set time.
+ * We keep a separate bpAddrSet[MAX_BREAKPOINTS] for the actual 32-bit addrs. */
+
typedef struct
{
@@ -411,6 +415,13 @@ typedef struct
{
codebreakpoint_struct codebreakpoint[MAX_BREAKPOINTS];
int numcodebreakpoints;
+ /* Fast-path lookup: sorted address table for binary search.
+ * sorted_bp_addrs[0..numcodebreakpoints-1] kept in ascending order.
+ * Populated by SH2AddCodeBreakpoint / SH2DelCodeBreakpoint.
+ * SH2HandleBreakpoints uses bsearch instead of linear scan. */
+ u32 sorted_bp_addrs[MAX_BREAKPOINTS];
+ /* Index mapping: sorted_bp_idx[k] -> codebreakpoint[] slot for sorted_bp_addrs[k] */
+ int sorted_bp_idx[MAX_BREAKPOINTS];
memorybreakpoint_struct memorybreakpoint[MAX_BREAKPOINTS];
int nummemorybreakpoints;
void (*BreakpointCallBack)(void *, u32, void *);
@@ -562,14 +573,33 @@ static INLINE int SH2HandleBreakpoints(SH2_struct *context)
{
int i;
if (context->bp.inbreakpoint == 0) {
- for (i=0; i < context->bp.numcodebreakpoints; i++) {
- if (context->regs.PC == context->bp.codebreakpoint[i].addr) {
- context->bp.inbreakpoint = 1;
- context->bp.BreakpointUserData.PCAddress = (context->isDelayed != 0)?context->isDelayed:context->regs.PC;
- context->bp.BreakpointUserData.BPAddress = (context->isDelayed != 0)?context->isDelayed:context->regs.PC;
- return 1;
- }
+ /* Binary search over sorted_bp_addrs[0..N-1] — O(log N) vs old O(N).
+ * With MAX_BREAKPOINTS=10 the worst-case is 4 comparisons instead of 10. */
+ int lo = 0, hi = context->bp.numcodebreakpoints - 1;
+ u32 pc = context->regs.PC;
+ while (lo <= hi) {
+ int mid = (lo + hi) >> 1;
+ u32 a = context->bp.sorted_bp_addrs[mid];
+ if (pc == a) {
+ context->bp.inbreakpoint = 1;
+ context->bp.BreakpointUserData.PCAddress = (context->isDelayed != 0)?context->isDelayed:pc;
+ context->bp.BreakpointUserData.BPAddress = (context->isDelayed != 0)?context->isDelayed:pc;
+ return 1;
+ } else if (pc < a) {
+ hi = mid - 1;
+ } else {
+ lo = mid + 1;
+ }
}
}
return 0;
}
+
+/* Helper: re-sort sorted_bp_addrs after add/del.
+ * Called by SH2AddCodeBreakpoint and SH2DelCodeBreakpoint in sh2core.c. */
+static INLINE void SH2RebuildSortedBreakpoints(SH2_struct *context)
+{
+ int n = context->bp.numcodebreakpoints;
+ int i, j;
+ for (i = 0; i < n; i++) {
+ context->bp.sorted_bp_addrs[i] = context->bp.codebreakpoint[i].addr;
+ context->bp.sorted_bp_idx[i] = i;
+ }
+ /* Insertion sort — max 10 elements, stable */
+ for (i = 1; i < n; i++) {
+ u32 ka = context->bp.sorted_bp_addrs[i];
+ int ki = context->bp.sorted_bp_idx[i];
+ for (j = i - 1; j >= 0 && context->bp.sorted_bp_addrs[j] > ka; j--) {
+ context->bp.sorted_bp_addrs[j+1] = context->bp.sorted_bp_addrs[j];
+ context->bp.sorted_bp_idx[j+1] = context->bp.sorted_bp_idx[j];
+ }
+ context->bp.sorted_bp_addrs[j+1] = ka;
+ context->bp.sorted_bp_idx[j+1] = ki;
+ }
+}
--- a/yabause/src/sys/sh2/src/sh2core.c
+++ b/yabause/src/sys/sh2/src/sh2core.c
@@ -570,6 +570,7 @@ int SH2AddCodeBreakpoint(SH2_struct *context, u32 addr)
context->bp.codebreakpoint[context->bp.numcodebreakpoints].addr = addr;
context->bp.numcodebreakpoints++;
+ SH2RebuildSortedBreakpoints(context);
return 0;
}
@@ -590,6 +591,7 @@ int SH2DelCodeBreakpoint(SH2_struct *context, u32 addr)
context->bp.numcodebreakpoints--;
memmove(context->bp.codebreakpoint+i, context->bp.codebreakpoint+i+1,
sizeof(codebreakpoint_struct) * (context->bp.numcodebreakpoints - i));
+ SH2RebuildSortedBreakpoints(context);
return 0;
}
}