From ffc3968ff217fce4e534b87059b40db0acd9d56e Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sun, 29 May 2011 09:34:30 +0000 Subject: [PATCH] Give the amd64-linux and x86-linux dispatchers two entry points, not one, so as to avoid a GSP-changed check in the common case. See vex r2155. (amd64-darwin and x86-darwin are now temporarily unbuildable.) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11786 --- coregrind/m_dispatch/dispatch-amd64-linux.S | 65 +++++++++++++-------- coregrind/m_dispatch/dispatch-x86-linux.S | 60 ++++++++++++------- coregrind/m_translate.c | 39 +++++++++---- coregrind/pub_core_dispatch.h | 6 +- 4 files changed, 109 insertions(+), 61 deletions(-) diff --git a/coregrind/m_dispatch/dispatch-amd64-linux.S b/coregrind/m_dispatch/dispatch-amd64-linux.S index 82a77bd66a..4fd663f813 100644 --- a/coregrind/m_dispatch/dispatch-amd64-linux.S +++ b/coregrind/m_dispatch/dispatch-amd64-linux.S @@ -107,8 +107,8 @@ VG_(run_innerloop): /* fall into main loop (the right one) */ cmpq $0, %rsi - je VG_(run_innerloop__dispatch_unprofiled) - jmp VG_(run_innerloop__dispatch_profiled) + je VG_(run_innerloop__dispatch_unassisted_unprofiled) + jmp VG_(run_innerloop__dispatch_unassisted_profiled) /*NOTREACHED*/ /*----------------------------------------------------*/ @@ -116,15 +116,10 @@ VG_(run_innerloop): /*----------------------------------------------------*/ .align 16 -.global VG_(run_innerloop__dispatch_unprofiled) -VG_(run_innerloop__dispatch_unprofiled): - /* AT ENTRY: %rax is next guest addr, %rbp is possibly - modified guest state ptr */ - - /* Has the guest state pointer been messed with? If yes, - exit. */ - testq $1, %rbp - jnz gsp_changed +.global VG_(run_innerloop__dispatch_unassisted_unprofiled) +VG_(run_innerloop__dispatch_unassisted_unprofiled): + /* AT ENTRY: %rax is next guest addr, %rbp is the + unmodified guest state ptr */ /* save the jump address in the guest state */ movq %rax, OFFSET_amd64_RIP(%rbp) @@ -146,8 +141,20 @@ VG_(run_innerloop__dispatch_unprofiled): /* Found a match. Jump to .host. */ jmp *%r11 ud2 /* persuade insn decoders not to speculate past here */ - /* generated code should run, then jump back to - VG_(run_innerloop__dispatch_unprofiled). */ + /* generated code should run, then jump back to either + VG_(run_innerloop__dispatch_unassisted_unprofiled) + VG_(run_innerloop__dispatch_assisted_unprofiled). */ + /*NOTREACHED*/ + +.align 16 +.global VG_(run_innerloop__dispatch_assisted_unprofiled) +VG_(run_innerloop__dispatch_assisted_unprofiled): + /* AT ENTRY: %rax is next guest addr, %rbp is the + modified guest state ptr */ + /* We know the guest state pointer has been modified. + So jump directly to gsp_changed. */ + jmp gsp_changed + ud2 /*NOTREACHED*/ /*----------------------------------------------------*/ @@ -155,15 +162,10 @@ VG_(run_innerloop__dispatch_unprofiled): /*----------------------------------------------------*/ .align 16 -.global VG_(run_innerloop__dispatch_profiled) -VG_(run_innerloop__dispatch_profiled): - /* AT ENTRY: %rax is next guest addr, %rbp is possibly - modified guest state ptr */ - - /* Has the guest state pointer been messed with? If yes, - exit. */ - testq $1, %rbp - jnz gsp_changed +.global VG_(run_innerloop__dispatch_unassisted_profiled) +VG_(run_innerloop__dispatch_unassisted_profiled): + /* AT ENTRY: %rax is next guest addr, %rbp is the + unmodified guest state ptr */ /* save the jump address in the guest state */ movq %rax, OFFSET_amd64_RIP(%rbp) @@ -183,7 +185,7 @@ VG_(run_innerloop__dispatch_profiled): jnz fast_lookup_failed /* increment bb profile counter */ - movq VG_(tt_fastN)@GOTPCREL(%rip), %rdx + movabsq $VG_(tt_fastN), %rdx shrq $1, %rbx /* entry# * sizeof(UInt*) */ movq (%rdx,%rbx,1), %rdx addl $1, (%rdx) @@ -191,8 +193,21 @@ VG_(run_innerloop__dispatch_profiled): /* Found a match. Jump to .host. */ jmp *%r11 ud2 /* persuade insn decoders not to speculate past here */ - /* generated code should run, then jump back to - VG_(run_innerloop__dispatch_profiled). */ + /* generated code should run, then jump back to either + VG_(run_innerloop__dispatch_unassisted_profiled) + VG_(run_innerloop__dispatch_assisted_profiled). */ + /*NOTREACHED*/ + +.align 16 +.global VG_(run_innerloop__dispatch_assisted_profiled) +VG_(run_innerloop__dispatch_assisted_profiled): + /* AT ENTRY: %rax is next guest addr, %rbp is the + modified guest state ptr */ + + /* Well, we know the guest state pointer has been modified. + So jump directly to gsp_changed. */ + jmp gsp_changed + ud2 /*NOTREACHED*/ /*----------------------------------------------------*/ diff --git a/coregrind/m_dispatch/dispatch-x86-linux.S b/coregrind/m_dispatch/dispatch-x86-linux.S index c719e010ac..d5ee6e1eed 100644 --- a/coregrind/m_dispatch/dispatch-x86-linux.S +++ b/coregrind/m_dispatch/dispatch-x86-linux.S @@ -96,8 +96,8 @@ L1: /* fall into main loop (the right one) */ cmpl $0, 32(%esp) /* do_profiling */ - je VG_(run_innerloop__dispatch_unprofiled) - jmp VG_(run_innerloop__dispatch_profiled) + je VG_(run_innerloop__dispatch_unassisted_unprofiled) + jmp VG_(run_innerloop__dispatch_unassisted_profiled) /*NOTREACHED*/ /*----------------------------------------------------*/ @@ -105,14 +105,10 @@ L1: /*----------------------------------------------------*/ .align 16 -.global VG_(run_innerloop__dispatch_unprofiled) -VG_(run_innerloop__dispatch_unprofiled): - /* AT ENTRY: %eax is next guest addr, %ebp is possibly - modified guest state ptr */ - - /* Has the guest state pointer been messed with? If yes, exit. */ - testl $1, %ebp - jnz gsp_changed +.global VG_(run_innerloop__dispatch_unassisted_unprofiled) +VG_(run_innerloop__dispatch_unassisted_unprofiled): + /* AT ENTRY: %eax is next guest addr, %ebp is the + unmodified guest state ptr */ /* save the jump address in the guest state */ movl %eax, OFFSET_x86_EIP(%ebp) @@ -132,8 +128,20 @@ VG_(run_innerloop__dispatch_unprofiled): /* Found a match. Jump to .host. */ jmp *%edi ud2 /* persuade insn decoders not to speculate past here */ - /* generated code should run, then jump back to - VG_(run_innerloop__dispatch_unprofiled). */ + /* generated code should run, then jump back to either + VG_(run_innerloop__dispatch_unassisted_unprofiled) or + VG_(run_innerloop__dispatch_assisted_unprofiled). */ + /*NOTREACHED*/ + +.align 16 +.global VG_(run_innerloop__dispatch_assisted_unprofiled) +VG_(run_innerloop__dispatch_assisted_unprofiled): + /* AT ENTRY: %eax is next guest addr, %ebp is the + modified guest state ptr */ + /* We know the guest state pointer has been modified. + So jump directly to gsp_changed. */ + jmp gsp_changed + ud2 /*NOTREACHED*/ /*----------------------------------------------------*/ @@ -141,14 +149,10 @@ VG_(run_innerloop__dispatch_unprofiled): /*----------------------------------------------------*/ .align 16 -.global VG_(run_innerloop__dispatch_profiled) -VG_(run_innerloop__dispatch_profiled): - /* AT ENTRY: %eax is next guest addr, %ebp is possibly - modified guest state ptr */ - - /* Has the guest state pointer been messed with? If yes, exit. */ - testl $1, %ebp - jnz gsp_changed +.global VG_(run_innerloop__dispatch_unassisted_profiled) +VG_(run_innerloop__dispatch_unassisted_profiled): + /* AT ENTRY: %eax is next guest addr, %ebp is the + unmodified guest state ptr */ /* save the jump address in the guest state */ movl %eax, OFFSET_x86_EIP(%ebp) @@ -175,8 +179,20 @@ VG_(run_innerloop__dispatch_profiled): /* Found a match. Jump to .host. */ jmp *%edi ud2 /* persuade insn decoders not to speculate past here */ - /* generated code should run, then jump back to - VG_(run_innerloop__dispatch_profiled). */ + /* generated code should run, then jump back to either + VG_(run_innerloop__dispatch_unassisted_profiled) or + VG_(run_innerloop__dispatch_assisted_profiled). */ + /*NOTREACHED*/ + +.align 16 +.global VG_(run_innerloop__dispatch_assisted_profiled) +VG_(run_innerloop__dispatch_assisted_profiled): + /* AT ENTRY: %eax is next guest addr, %ebp is the + modified guest state ptr */ + /* We know the guest state pointer has been modified. + So jump directly to gsp_changed. */ + jmp gsp_changed + ud2 /*NOTREACHED*/ /*----------------------------------------------------*/ diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index ae7312072d..0a41cd891d 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -1515,23 +1515,38 @@ Bool VG_(translate) ( ThreadId tid, /* Set up the dispatch-return info. For archs without a link register, vex generates a jump back to the specified dispatch address. Else, it just generates a branch-to-LR. */ + # if defined(VGA_x86) || defined(VGA_amd64) - vta.dispatch - = (!allow_redirection) - ? /* It's a no-redir translation. Will be run with the nonstandard - dispatcher VG_(run_a_noredir_translation) - and so needs a nonstandard return point. */ - (void*) &VG_(run_a_noredir_translation__return_point) - - : /* normal translation. Uses VG_(run_innerloop). Return - point depends on whether we're profiling bbs or not. */ - VG_(clo_profile_flags) > 0 - ? (void*) &VG_(run_innerloop__dispatch_profiled) - : (void*) &VG_(run_innerloop__dispatch_unprofiled); + if (!allow_redirection) { + /* It's a no-redir translation. Will be run with the + nonstandard dispatcher VG_(run_a_noredir_translation) and so + needs a nonstandard return point. */ + vta.dispatch_assisted + = (void*) &VG_(run_a_noredir_translation__return_point); + vta.dispatch_unassisted + = vta.dispatch_assisted; + } + else + if (VG_(clo_profile_flags) > 0) { + /* normal translation; although we're profiling. */ + vta.dispatch_assisted + = (void*) &VG_(run_innerloop__dispatch_assisted_profiled); + vta.dispatch_unassisted + = (void*) &VG_(run_innerloop__dispatch_unassisted_profiled); + } + else { + /* normal translation and we're not profiling (the normal case) */ + vta.dispatch_assisted + = (void*) &VG_(run_innerloop__dispatch_assisted_unprofiled); + vta.dispatch_unassisted + = (void*) &VG_(run_innerloop__dispatch_unassisted_unprofiled); + } + # elif defined(VGA_ppc32) || defined(VGA_ppc64) \ || defined(VGA_arm) || defined(VGA_s390x) /* See comment libvex.h; machine has link register --> dipatch = NULL */ vta.dispatch = NULL; + # else # error "Unknown arch" # endif diff --git a/coregrind/pub_core_dispatch.h b/coregrind/pub_core_dispatch.h index 8deaeca63f..47b8313224 100644 --- a/coregrind/pub_core_dispatch.h +++ b/coregrind/pub_core_dispatch.h @@ -68,8 +68,10 @@ UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling ); following somewhat bogus decls. At least on x86 and amd64. ppc32 and ppc64 use straightforward bl-blr to get from dispatcher to translation and back and so do not need these labels. */ -extern Addr VG_(run_innerloop__dispatch_unprofiled); -extern Addr VG_(run_innerloop__dispatch_profiled); +extern Addr VG_(run_innerloop__dispatch_unassisted_unprofiled); +extern Addr VG_(run_innerloop__dispatch_assisted_unprofiled); +extern Addr VG_(run_innerloop__dispatch_unassisted_profiled); +extern Addr VG_(run_innerloop__dispatch_assisted_profiled); #endif -- 2.47.2