SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 32a419ad2e6301fcf12eb889f9fbb9707bc31697 parent 237e127b36eaee574e2a1d7900da21bda0775405 Author: Lior Halphon <LIJI32@gmail.com> Date: Tue, 25 Apr 2023 13:06:14 +0300 Do not inline the slow path of frequently called functions Diffstat:
| M | Core/cheats.c | 11 | ++++++++--- |
| M | Core/debugger.c | 38 | +++++++++++++++++++++++++------------- |
| M | Core/defs.h | 1 | + |
| M | Core/gb.c | 4 | ++-- |
| M | Core/gb.h | 1 | + |
| M | Core/sm83_cpu.c | 2 | +- |
6 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/Core/cheats.c b/Core/cheats.c @@ -30,10 +30,8 @@ static uint16_t bank_for_addr(GB_gameboy_t *gb, uint16_t addr) return 0; } -void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value) +static noinline void apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value) { - if (likely(!gb->cheat_enabled)) return; - if (likely(gb->cheat_count == 0)) return; // Optimization if (unlikely(!gb->boot_rom_finished)) return; const GB_cheat_hash_t *hash = gb->cheat_hash[hash_addr(address)]; if (likely(!hash)) return; @@ -49,6 +47,13 @@ void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value) } } +void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value) +{ + if (likely(!gb->cheat_enabled)) return; + if (likely(gb->cheat_count == 0)) return; // Optimization + apply_cheat(gb, address, value); +} + bool GB_cheats_enabled(GB_gameboy_t *gb) { return gb->cheat_enabled; diff --git a/Core/debugger.c b/Core/debugger.c @@ -685,6 +685,11 @@ exit: return ret; } +static void update_debug_active(GB_gameboy_t *gb) +{ + gb->debug_active = !gb->debug_disable && (gb->debug_stopped || gb->debug_fin_command || gb->debug_next_command || gb->breakpoints); +} + struct debugger_command_s; typedef bool debugger_command_imp_t(GB_gameboy_t *gb, char *arguments, char *modifiers, const struct debugger_command_s *command); typedef char *debugger_completer_imp_t(GB_gameboy_t *gb, const char *string, uintptr_t *context); @@ -763,7 +768,7 @@ static bool interrupt(GB_gameboy_t *gb, char *arguments, char *modifiers, const return true; } - gb->debug_stopped = true; + GB_debugger_break(gb); return true; } @@ -2253,7 +2258,7 @@ static bool _GB_debugger_test_write_watchpoint(GB_gameboy_t *gb, value_t addr, u return false; } if (!gb->watchpoints[index].condition) { - gb->debug_stopped = true; + GB_debugger_break(gb); GB_log(gb, "Watchpoint: [%s] = $%02x\n", debugger_value_to_string(gb, addr, true), value); return true; } @@ -2266,7 +2271,7 @@ static bool _GB_debugger_test_write_watchpoint(GB_gameboy_t *gb, value_t addr, u return false; } if (condition) { - gb->debug_stopped = true; + GB_debugger_break(gb); GB_log(gb, "Watchpoint: [%s] = $%02x\n", debugger_value_to_string(gb, addr, true), value); return true; } @@ -2298,7 +2303,7 @@ static bool _GB_debugger_test_read_watchpoint(GB_gameboy_t *gb, value_t addr) return false; } if (!gb->watchpoints[index].condition) { - gb->debug_stopped = true; + GB_debugger_break(gb); GB_log(gb, "Watchpoint: [%s]\n", debugger_value_to_string(gb, addr, true)); return true; } @@ -2311,7 +2316,7 @@ static bool _GB_debugger_test_read_watchpoint(GB_gameboy_t *gb, value_t addr) return false; } if (condition) { - gb->debug_stopped = true; + GB_debugger_break(gb); GB_log(gb, "Watchpoint: [%s]\n", debugger_value_to_string(gb, addr, true)); return true; } @@ -2464,10 +2469,8 @@ typedef enum { static jump_to_return_t test_jump_to_breakpoints(GB_gameboy_t *gb, uint16_t *address); -void GB_debugger_run(GB_gameboy_t *gb) +static void noinline debugger_run(GB_gameboy_t *gb) { - if (gb->debug_disable) return; - if (!gb->undo_state) { gb->undo_state = malloc(GB_get_save_state_size_no_bess(gb)); GB_save_state_to_buffer_no_bess(gb, gb->undo_state); @@ -2475,10 +2478,10 @@ void GB_debugger_run(GB_gameboy_t *gb) char *input = NULL; if (gb->debug_next_command && gb->debug_call_depth <= 0 && !gb->halted) { - gb->debug_stopped = true; + GB_debugger_break(gb); } if (gb->debug_fin_command && gb->debug_call_depth <= -1) { - gb->debug_stopped = true; + GB_debugger_break(gb); } if (gb->debug_stopped) { if (!gb->help_shown) { @@ -2492,7 +2495,7 @@ next_command: free(input); } if (gb->breakpoints && !gb->debug_stopped && should_break(gb, gb->pc, false)) { - gb->debug_stopped = true; + GB_debugger_break(gb); GB_log(gb, "Breakpoint: PC = %s\n", value_to_string(gb, gb->pc, true)); GB_cpu_disassemble(gb, gb->pc, 5); } @@ -2511,11 +2514,11 @@ next_command: GB_log(gb, "Jumping to breakpoint: PC = %s\n", value_to_string(gb, gb->pc, true)); GB_cpu_disassemble(gb, gb->pc, 5); GB_load_state_from_buffer(gb, gb->nontrivial_jump_state, -1); - gb->debug_stopped = true; + GB_debugger_break(gb); } } else if (jump_to_result == JUMP_TO_BREAK) { - gb->debug_stopped = true; + GB_debugger_break(gb); GB_log(gb, "Jumping to breakpoint: PC = %s\n", value_to_string(gb, address, true)); GB_cpu_disassemble(gb, gb->pc, 5); gb->non_trivial_jump_breakpoint_occured = false; @@ -2548,6 +2551,7 @@ next_command: if (input == NULL) { /* Debugging is no currently available, continue running */ gb->debug_stopped = false; + update_debug_active(gb); return; } @@ -2557,6 +2561,12 @@ next_command: free(input); } + update_debug_active(gb); +} +void GB_debugger_run(GB_gameboy_t *gb) +{ + if (likely(!gb->debug_active)) return; + debugger_run(gb); } void GB_debugger_handle_async_commands(GB_gameboy_t *gb) @@ -2675,6 +2685,7 @@ bool GB_debugger_evaluate(GB_gameboy_t *gb, const char *string, uint16_t *result void GB_debugger_break(GB_gameboy_t *gb) { gb->debug_stopped = true; + update_debug_active(gb); } bool GB_debugger_is_stopped(GB_gameboy_t *gb) @@ -2685,6 +2696,7 @@ bool GB_debugger_is_stopped(GB_gameboy_t *gb) void GB_debugger_set_disabled(GB_gameboy_t *gb, bool disabled) { gb->debug_disable = disabled; + update_debug_active(gb); } /* Jump-to breakpoints */ diff --git a/Core/defs.h b/Core/defs.h @@ -11,6 +11,7 @@ #define unlikely(x) GB_unlikely(x) #define internal __attribute__((visibility("internal"))) +#define noinline __attribute__((noinline)) #if __clang__ #define unrolled _Pragma("unroll") diff --git a/Core/gb.c b/Core/gb.c @@ -76,7 +76,7 @@ static char *default_input_callback(GB_gameboy_t *gb) } if (expression[0] == '\x03') { - gb->debug_stopped = true; + GB_debugger_break(gb); free(expression); return strdup(""); } @@ -1183,7 +1183,7 @@ unsigned GB_run(GB_gameboy_t *gb) GB_set_running_thread(gb); GB_cpu_run(gb); GB_clear_running_thread(gb); - if (gb->vblank_just_occured) { + if (unlikely(gb->vblank_just_occured)) { GB_debugger_handle_async_commands(gb); GB_set_running_thread(gb); GB_rewind_push(gb); diff --git a/Core/gb.h b/Core/gb.h @@ -736,6 +736,7 @@ struct GB_gameboy_internal_s { /*** Debugger ***/ volatile bool debug_stopped, debug_disable; bool debug_fin_command, debug_next_command; + bool debug_active; // Cached value determining if GB_debugger_run does anything bool help_shown; /* Breakpoints */ diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c @@ -950,7 +950,7 @@ LD_X_Y(a,b) LD_X_Y(a,c) LD_X_Y(a,d) LD_X_Y(a,e) LD_X_Y(a,h) LD_X_Y(a,l) LD_X_DHL static void ld_b_b(GB_gameboy_t *gb, uint8_t opcode) { if (gb->has_software_breakpoints) { - gb->debug_stopped = true; + GB_debugger_break(gb); } }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.