From 5e01ffdfd8827f6476e6cff40b49c26ce5f33ffc Mon Sep 17 00:00:00 2001 From: Eladash Date: Wed, 22 Jun 2022 12:00:06 +0300 Subject: [PATCH] Debugger: Optimize cpu_thread::dump_regs() Reuse string buffer. Copies and reallocations are expensive with such large strings. --- Utilities/Thread.cpp | 2 +- rpcs3/Emu/CPU/CPUThread.cpp | 11 ++++------- rpcs3/Emu/CPU/CPUThread.h | 4 ++-- rpcs3/Emu/Cell/PPUThread.cpp | 12 +++--------- rpcs3/Emu/Cell/PPUThread.h | 4 ++-- rpcs3/Emu/Cell/SPUThread.cpp | 6 +----- rpcs3/Emu/Cell/SPUThread.h | 2 +- rpcs3/Emu/RSX/RSXDisAsm.cpp | 12 ++++++++++-- rpcs3/Emu/RSX/RSXThread.cpp | 16 ++++++---------- rpcs3/Emu/RSX/RSXThread.h | 2 +- rpcs3/rpcs3qt/debugger_frame.cpp | 4 +++- rpcs3/rpcs3qt/debugger_frame.h | 1 + 12 files changed, 35 insertions(+), 41 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 430681a8b8..d13346fb1c 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -119,7 +119,7 @@ std::string dump_useful_thread_info() if (auto cpu = get_current_cpu_thread()) { - result = cpu->dump_all(); + cpu->dump_all(result); } guard = false; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index aa5869c578..caa594da88 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -947,11 +947,11 @@ u32* cpu_thread::get_pc2() std::shared_ptr make_disasm(const cpu_thread* cpu); -std::string cpu_thread::dump_all() const +void cpu_thread::dump_all(std::string& ret) const { - std::string ret = dump_misc(); + ret += dump_misc(); ret += '\n'; - ret += dump_regs(); + dump_regs(ret); ret += '\n'; ret += dump_callstack(); ret += '\n'; @@ -972,13 +972,10 @@ std::string cpu_thread::dump_all() const ret += '\n'; } } - - return ret; } -std::string cpu_thread::dump_regs() const +void cpu_thread::dump_regs(std::string&) const { - return {}; } std::string cpu_thread::dump_callstack() const diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index e37ddc3ae7..b3912b8cbc 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -151,10 +151,10 @@ public: std::string get_name() const; // Get CPU state dump (everything) - virtual std::string dump_all() const; + virtual void dump_all(std::string&) const; // Get CPU register dump - virtual std::string dump_regs() const; + virtual void dump_regs(std::string&) const; // Get CPU call stack dump virtual std::string dump_callstack() const; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 7a9d3b94ee..80c368eb38 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -936,10 +936,8 @@ std::array op_branch_targets(u32 pc, ppu_opcode_t op) return res; } -std::string ppu_thread::dump_regs() const +void ppu_thread::dump_regs(std::string& ret) const { - std::string ret; - PPUDisAsm dis_asm(cpu_disasm_mode::normal, vm::g_sudo_addr); for (uint i = 0; i < 32; ++i) @@ -1107,8 +1105,6 @@ std::string ppu_thread::dump_regs() const *(&ret.back() - (4 - (addr % 16 / 4)) * 9 - (8 - (addr % 128 / 16)) * std::size("[0x00]"sv)) = '*'; } } - - return ret; } std::string ppu_thread::dump_callstack() const @@ -1259,9 +1255,9 @@ std::string ppu_thread::dump_misc() const return ret; } -std::string ppu_thread::dump_all() const +void ppu_thread::dump_all(std::string& ret) const { - std::string ret = cpu_thread::dump_all(); + cpu_thread::dump_all(ret); if (!call_history.data.empty()) { @@ -1271,8 +1267,6 @@ std::string ppu_thread::dump_all() const fmt::append(ret, "%s", call_history); } - - return ret; } extern thread_local std::string(*g_tls_log_prefix)(); diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 9604961da2..0dafe99919 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -130,11 +130,11 @@ public: static const u32 id_count = 100; static constexpr std::pair id_invl_range = {12, 12}; - virtual std::string dump_regs() const override; + virtual void dump_regs(std::string&) const override; virtual std::string dump_callstack() const override; virtual std::vector> dump_callstack_list() const override; virtual std::string dump_misc() const override; - virtual std::string dump_all() const override; + virtual void dump_all(std::string&) const override; virtual void cpu_task() override final; virtual void cpu_sleep() override; virtual void cpu_on_stop() override; diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 91dc6c88b5..fa269e82b9 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1030,10 +1030,8 @@ spu_imm_table_t::spu_imm_table_t() } } -std::string spu_thread::dump_regs() const +void spu_thread::dump_regs(std::string& ret) const { - std::string ret; - const bool floats_only = debugger_float_mode.load(); SPUDisAsm dis_asm(cpu_disasm_mode::normal, ls); @@ -1148,8 +1146,6 @@ std::string spu_thread::dump_regs() const fmt::append(ret, "[0x%02x] %08x %08x %08x %08x\n", i * sizeof(data[0]) , data[i + 0], data[i + 1], data[i + 2], data[i + 3]); } - - return ret; } std::string spu_thread::dump_callstack() const diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 0f81d9c7f3..935c9d1ef1 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -677,7 +677,7 @@ enum class spu_type : u32 class spu_thread : public cpu_thread { public: - virtual std::string dump_regs() const override; + virtual void dump_regs(std::string&) const override; virtual std::string dump_callstack() const override; virtual std::vector> dump_callstack_list() const override; virtual std::string dump_misc() const override; diff --git a/rpcs3/Emu/RSX/RSXDisAsm.cpp b/rpcs3/Emu/RSX/RSXDisAsm.cpp index ce2d6e8389..0eefede392 100644 --- a/rpcs3/Emu/RSX/RSXDisAsm.cpp +++ b/rpcs3/Emu/RSX/RSXDisAsm.cpp @@ -161,8 +161,16 @@ void RSXDisAsm::Write(std::string_view str, s32 count, bool is_non_inc, u32 id) { case cpu_disasm_mode::interpreter: { - last_opcode = count >= 0 ? fmt::format("[%08x] (%s%u)", dump_pc, is_non_inc ? "+" : "", count) : - fmt::format("[%08x] (x)", dump_pc); + last_opcode.clear(); + + if (count >= 0) + { + fmt::append(last_opcode, "[%08x] (%s%u)", dump_pc, is_non_inc ? "+" : "", count); + } + else + { + fmt::append(last_opcode, "[%08x] (x)", dump_pc); + } auto& res = last_opcode; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index c0e44dd6dc..ee17726a60 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2837,10 +2837,8 @@ namespace rsx void invalid_method(thread*, u32, u32); - std::string thread::dump_regs() const + void thread::dump_regs(std::string& result) const { - std::string result; - if (ctrl) { fmt::append(result, "FIFO: GET=0x%07x, PUT=0x%07x, REF=0x%08x\n", +ctrl->get, +ctrl->put, +ctrl->ref); @@ -2865,21 +2863,19 @@ namespace rsx case NV4097_ZCULL_SYNC: continue; + case NV308A_COLOR: + { + i = NV3089_SET_OBJECT; + continue; + } default: { - if (i >= NV308A_COLOR && i < NV3089_SET_OBJECT) - { - continue; - } - break; } } fmt::append(result, "[%04x] %s\n", i, ensure(rsx::get_pretty_printing_function(i))(i, method_registers.registers[i])); } - - return result; } flags32_t thread::read_barrier(u32 memory_address, u32 memory_range, bool unconditional) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 258def7975..f3449d9d88 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -521,7 +521,7 @@ namespace rsx static void fifo_wake_delay(u64 div = 1); u32 get_fifo_cmd() const; - std::string dump_regs() const override; + void dump_regs(std::string&) const override; void cpu_wait(bs_t old) override; static constexpr u32 id_base = 0x5555'5555; // See get_current_cpu_thread() diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index 14c5741356..e3fe8f97c0 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -1022,7 +1022,9 @@ void debugger_frame::WritePanels() loc = m_regs->verticalScrollBar()->value(); hloc = m_regs->horizontalScrollBar()->value(); m_regs->clear(); - m_regs->setText(qstr(cpu->dump_regs())); + m_last_reg_state.clear(); + cpu->dump_regs(m_last_reg_state); + m_regs->setText(qstr(m_last_reg_state)); m_regs->verticalScrollBar()->setValue(loc); m_regs->horizontalScrollBar()->setValue(hloc); diff --git a/rpcs3/rpcs3qt/debugger_frame.h b/rpcs3/rpcs3qt/debugger_frame.h index 83f6033925..47248da4e3 100644 --- a/rpcs3/rpcs3qt/debugger_frame.h +++ b/rpcs3/rpcs3qt/debugger_frame.h @@ -57,6 +57,7 @@ class debugger_frame : public custom_dock_widget system_state m_emu_state{}; u32 m_last_pc = -1; std::vector m_last_query_state; + std::string m_last_reg_state; u32 m_last_step_over_breakpoint = -1; u64 m_ui_update_ctr = 0; u64 m_ui_fast_update_permission_deadline = 0;