continue handlers-chaining optimization: update time once per trace and not for every instruction

This commit is contained in:
Stanislav Shwartsman 2011-09-06 15:35:39 +00:00
parent e000b61cfd
commit 96cedbc756
5 changed files with 42 additions and 8 deletions

View File

@ -77,6 +77,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
if (setjmp(BX_CPU_THIS_PTR jmp_buf_env)) { if (setjmp(BX_CPU_THIS_PTR jmp_buf_env)) {
// can get here only from exception function or VMEXIT // can get here only from exception function or VMEXIT
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
#if BX_DEBUGGER || BX_GDBSTUB #if BX_DEBUGGER || BX_GDBSTUB
if (dbg_instruction_epilog()) return; if (dbg_instruction_epilog()) return;
#endif #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 // when handlers chaining is enabled this single call will execute entire trace
BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction
BX_SYNC_TIME();
if (BX_CPU_THIS_PTR async_event) { if (BX_CPU_THIS_PTR async_event) {
// clear stop trace magic indication that probably was set by repeat or branch32/64 // 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; 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
else else
@ -245,6 +249,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP
break; // exit always if debugger enabled break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
else // 16bit addrsize 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
else 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
else // 16bit addrsize 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
else 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
else // 16bit addrsize 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 break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR(); BX_TICK1_IF_SINGLE_PROCESSOR();
BX_SYNC_TIME();
} }
} }
} }

View File

@ -858,9 +858,12 @@ public: // for now...
bx_address prev_rsp; bx_address prev_rsp;
bx_bool speculative_rsp; bx_bool speculative_rsp;
#if BX_DEBUGGER #if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
Bit64u icount; Bit64u icount;
#endif #endif
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
Bit64u icount_last_sync;
#endif
#define BX_INHIBIT_INTERRUPTS 0x01 #define BX_INHIBIT_INTERRUPTS 0x01
#define BX_INHIBIT_DEBUG 0x02 #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 int bx_cpuid_support_rdtscp(void);
BX_SMF BX_CPP_INLINE unsigned which_cpu(void) { return BX_CPU_THIS_PTR bx_cpuid; } 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; } BX_SMF BX_CPP_INLINE Bit64u get_icount(void) { return BX_CPU_THIS_PTR icount; }
#endif #endif
BX_SMF BX_CPP_INLINE const bx_gen_reg_t *get_gen_regfile() { return BX_CPU_THIS_PTR gen_reg; } BX_SMF BX_CPP_INLINE const bx_gen_reg_t *get_gen_regfile() { return BX_CPU_THIS_PTR gen_reg; }

View File

@ -358,7 +358,7 @@ void BX_CPU_C::register_state(void)
BXRS_HEX_PARAM_SIMPLE(cpu, activity_state); BXRS_HEX_PARAM_SIMPLE(cpu, activity_state);
BXRS_HEX_PARAM_SIMPLE(cpu, inhibit_mask); BXRS_HEX_PARAM_SIMPLE(cpu, inhibit_mask);
BXRS_HEX_PARAM_SIMPLE(cpu, debug_trap); BXRS_HEX_PARAM_SIMPLE(cpu, debug_trap);
#if BX_DEBUGGER #if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
BXRS_DEC_PARAM_SIMPLE(cpu, icount); BXRS_DEC_PARAM_SIMPLE(cpu, icount);
#endif #endif
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
@ -773,8 +773,12 @@ void BX_CPU_C::reset(unsigned source)
// status and control flags register set // status and control flags register set
setEFlags(0x2); // Bit1 is always set setEFlags(0x2); // Bit1 is always set
#if BX_DEBUGGER #if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
BX_CPU_THIS_PTR icount = 0; 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 #endif
BX_CPU_THIS_PTR inhibit_mask = 0; BX_CPU_THIS_PTR inhibit_mask = 0;

View File

@ -28,11 +28,19 @@ class bxInstruction_c;
typedef void BX_INSF_TYPE; typedef void BX_INSF_TYPE;
#define BX_TICK1_IF_SINGLE_PROCESSOR() \
if (BX_SMP_PROCESSORS == 1) BX_TICK1()
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS #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) { \ #define BX_COMMIT_INSTRUCTION(i) { \
BX_CPU_THIS_PTR prev_rip = RIP; /* commit new RIP */ \ BX_CPU_THIS_PTR prev_rip = RIP; /* commit new RIP */ \
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, (i)); \ 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_TRACE(i) { return; }
#define BX_NEXT_INSTR(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 #endif
// <TAG-TYPE-EXECUTEPTR-START> // <TAG-TYPE-EXECUTEPTR-START>

View File

@ -480,6 +480,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSC(bxInstruction_c *i)
RAX = GET32L(ticks); RAX = GET32L(ticks);
RDX = GET32H(ticks); RDX = GET32H(ticks);
BX_DEBUG(("RDTSC: ticks 0x%08x:%08x", EDX, EAX));
} else { } else {
BX_ERROR(("RDTSC: not allowed to use instruction !")); BX_ERROR(("RDTSC: not allowed to use instruction !"));
exception(BX_GP_EXCEPTION, 0); exception(BX_GP_EXCEPTION, 0);