From 96cedbc756bf0e286224052aba6912d2bf5ec9e0 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Tue, 6 Sep 2011 15:35:39 +0000 Subject: [PATCH] continue handlers-chaining optimization: update time once per trace and not for every instruction --- bochs/cpu/cpu.cc | 12 ++++++++++++ bochs/cpu/cpu.h | 7 +++++-- bochs/cpu/init.cc | 10 +++++++--- bochs/cpu/instr.h | 19 ++++++++++++++++--- bochs/cpu/proc_ctrl.cc | 2 ++ 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index 876b1008a..e2c9be224 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -77,6 +77,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) if (setjmp(BX_CPU_THIS_PTR jmp_buf_env)) { // can get here only from exception function or VMEXIT BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); #if BX_DEBUGGER || BX_GDBSTUB if (dbg_instruction_epilog()) return; #endif @@ -124,6 +125,8 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) // when handlers chaining is enabled this single call will execute entire trace BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction + BX_SYNC_TIME(); + if (BX_CPU_THIS_PTR async_event) { // clear stop trace magic indication that probably was set by repeat or branch32/64 BX_CPU_THIS_PTR async_event &= ~BX_ASYNC_EVENT_STOP_TRACE; @@ -226,6 +229,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } else @@ -245,6 +249,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } else // 16bit addrsize @@ -263,6 +268,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } @@ -307,6 +313,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } else @@ -326,6 +333,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } else // 16bit addrsize @@ -344,6 +352,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } } @@ -364,6 +373,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } else @@ -383,6 +393,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } else // 16bit addrsize @@ -401,6 +412,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati break; // exit always if debugger enabled BX_TICK1_IF_SINGLE_PROCESSOR(); + BX_SYNC_TIME(); } } } diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 0e1071271..15568a233 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -858,9 +858,12 @@ public: // for now... bx_address prev_rsp; bx_bool speculative_rsp; -#if BX_DEBUGGER +#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS Bit64u icount; #endif +#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS + Bit64u icount_last_sync; +#endif #define BX_INHIBIT_INTERRUPTS 0x01 #define BX_INHIBIT_DEBUG 0x02 @@ -3667,7 +3670,7 @@ public: // for now... BX_SMF BX_CPP_INLINE int bx_cpuid_support_rdtscp(void); BX_SMF BX_CPP_INLINE unsigned which_cpu(void) { return BX_CPU_THIS_PTR bx_cpuid; } -#if BX_DEBUGGER +#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS BX_SMF BX_CPP_INLINE Bit64u get_icount(void) { return BX_CPU_THIS_PTR icount; } #endif BX_SMF BX_CPP_INLINE const bx_gen_reg_t *get_gen_regfile() { return BX_CPU_THIS_PTR gen_reg; } diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index 0adb50451..e059219b8 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -358,7 +358,7 @@ void BX_CPU_C::register_state(void) BXRS_HEX_PARAM_SIMPLE(cpu, activity_state); BXRS_HEX_PARAM_SIMPLE(cpu, inhibit_mask); BXRS_HEX_PARAM_SIMPLE(cpu, debug_trap); -#if BX_DEBUGGER +#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS BXRS_DEC_PARAM_SIMPLE(cpu, icount); #endif #if BX_SUPPORT_X86_64 @@ -773,8 +773,12 @@ void BX_CPU_C::reset(unsigned source) // status and control flags register set setEFlags(0x2); // Bit1 is always set -#if BX_DEBUGGER - BX_CPU_THIS_PTR icount = 0; +#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS + if (source == BX_RESET_HARDWARE) + BX_CPU_THIS_PTR icount = 0; +#endif +#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS + BX_CPU_THIS_PTR icount_last_sync = BX_CPU_THIS_PTR icount; #endif BX_CPU_THIS_PTR inhibit_mask = 0; diff --git a/bochs/cpu/instr.h b/bochs/cpu/instr.h index afaa36645..a244cc166 100644 --- a/bochs/cpu/instr.h +++ b/bochs/cpu/instr.h @@ -28,11 +28,19 @@ class bxInstruction_c; typedef void BX_INSF_TYPE; -#define BX_TICK1_IF_SINGLE_PROCESSOR() \ - if (BX_SMP_PROCESSORS == 1) BX_TICK1() - #if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS +#define BX_TICK1_IF_SINGLE_PROCESSOR() \ + BX_CPU_THIS_PTR icount++; + +#define BX_SYNC_TIME() { \ + Bit32s delta = BX_CPU_THIS_PTR icount - BX_CPU_THIS_PTR icount_last_sync; \ + if (delta > 0) { \ + BX_CPU_THIS_PTR icount_last_sync = BX_CPU_THIS_PTR icount; \ + BX_TICKN(delta); \ + } \ +} + #define BX_COMMIT_INSTRUCTION(i) { \ BX_CPU_THIS_PTR prev_rip = RIP; /* commit new RIP */ \ BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, (i)); \ @@ -62,6 +70,11 @@ typedef void BX_INSF_TYPE; #define BX_NEXT_TRACE(i) { return; } #define BX_NEXT_INSTR(i) { return; } +#define BX_TICK1_IF_SINGLE_PROCESSOR() \ + if (BX_SMP_PROCESSORS == 1) BX_TICK1() + +#define BX_SYNC_TIME() /* do nothing */ + #endif // diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 0529049a3..bafcfee27 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -480,6 +480,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSC(bxInstruction_c *i) RAX = GET32L(ticks); RDX = GET32H(ticks); + BX_DEBUG(("RDTSC: ticks 0x%08x:%08x", EDX, EAX)); + } else { BX_ERROR(("RDTSC: not allowed to use instruction !")); exception(BX_GP_EXCEPTION, 0);