xenia-hid + xenia-debugger: gamepad serializer; debugger fast-skip hook

xenia-hid grows a guest-facing X_INPUT_GAMEPAD writer (big-endian on
the wire, host-neutral GamepadState in memory) so XamInputGetState in
the kernel and the UI input thread share one POD snapshot type. Adds
the GUIDE button flag.

xenia-debugger gains Debugger::wants_hooks(), a single-branch fast
path the hot interpreter loop checks to skip the pre_step/post_step
HashMap+match work when the debugger is in cold-run mode (no bps, no
trace, StepMode::Run, not paused). Part of the Tier-3 perf landing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-05-01 16:30:03 +02:00
parent 79eb52c378
commit b1285ba560
3 changed files with 167 additions and 5 deletions

View File

@@ -42,15 +42,30 @@ impl Debugger {
}
}
/// Tier-3 perf: single branch that the hot interpreter loop checks
/// before dispatching to [`pre_step`]/[`post_step`]. When the
/// debugger is in "cold run" mode (not paused, no breakpoints,
/// `StepMode::Run`, in-memory trace off), both hooks become dead
/// code and we can skip the HashMap lookup + step-mode match + Vec
/// maintenance entirely. The compiler reliably branch-predicts the
/// stable branch direction across millions of instructions.
#[inline]
pub fn wants_hooks(&self) -> bool {
self.trace_enabled
|| self.paused
|| self.break_pending
|| !matches!(self.step_mode, StepMode::Run)
|| !self.breakpoints.is_empty()
}
/// Called before each instruction executes.
pub fn pre_step(&mut self, ctx: &PpcContext, _mem: &dyn MemoryAccess) {
// Check breakpoints
if let Some(bp) = self.breakpoints.get(&ctx.pc) {
if bp.enabled {
if let Some(bp) = self.breakpoints.get(&ctx.pc)
&& bp.enabled {
self.break_pending = true;
tracing::info!("Breakpoint hit at {:#010x}", ctx.pc);
}
}
}
/// Called after each instruction executes.