add --enable-jitframe for configure on x86_64

Using a frame pointer for the ABI of internal helper functions
should make the stack friendlier to tools like `perf`. There
may be a small performance cost, though.
This commit is contained in:
Matthew Flatt 2018-06-11 08:35:42 -06:00
parent 2c58937008
commit a703b608a4
4 changed files with 52 additions and 10 deletions

13
racket/src/configure vendored
View File

@ -832,6 +832,7 @@ enable_gprof
enable_gcov enable_gcov
enable_noopt enable_noopt
enable_ubsan enable_ubsan
enable_jitframe
' '
ac_precious_vars='build_alias ac_precious_vars='build_alias
host_alias host_alias
@ -1489,6 +1490,7 @@ Optional Features:
--enable-strip strip debug on install (usually enabled by default) --enable-strip strip debug on install (usually enabled by default)
--enable-noopt drop -O C flags (useful for low-level debugging) --enable-noopt drop -O C flags (useful for low-level debugging)
--enable-ubsan compile with -fsanitize=undefined) --enable-ubsan compile with -fsanitize=undefined)
--enable-jitframe x86_64: use frame pointer for internal calls
Some influential environment variables: Some influential environment variables:
CC C compiler command CC C compiler command
@ -2843,6 +2845,11 @@ if test "${enable_ubsan+set}" = set; then :
enableval=$enable_ubsan; enableval=$enable_ubsan;
fi fi
# Check whether --enable-jitframe was given.
if test "${enable_jitframe+set}" = set; then :
enableval=$enable_jitframe;
fi
###### Some flags imply other flags ####### ###### Some flags imply other flags #######
@ -3096,6 +3103,8 @@ show_explicitly_enabled "${enable_smalloskit}" "OSKit small mode"
show_explicitly_enabled "${enable_gprof}" "gprof" show_explicitly_enabled "${enable_gprof}" "gprof"
show_explicitly_enabled "${enable_gcov}" "gcov" show_explicitly_enabled "${enable_gcov}" "gcov"
show_explicitly_enabled "${enable_jitframe}" "jitframe"
show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode is intended only for debugging purposes" show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode is intended only for debugging purposes"
show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping"
show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping"
@ -4579,6 +4588,10 @@ if test "${enable_gcov}" = "yes" ; then
PROFFLAGS="$PROFFLAGS -fprofile-arcs -ftest-coverage" PROFFLAGS="$PROFFLAGS -fprofile-arcs -ftest-coverage"
fi fi
if test "${enable_jitframe}" = "yes" ; then
MZOPTIONS="$MZOPTIONS -DMZ_PROLOG_CREATE_FULL_STACK_FRAME"
fi
ORIG_CC_FOR_BUILD="${CC_FOR_BUILD}" ORIG_CC_FOR_BUILD="${CC_FOR_BUILD}"
if test "$CC_FOR_BUILD" = "" ; then if test "$CC_FOR_BUILD" = "" ; then
CC_FOR_BUILD="$CC" CC_FOR_BUILD="$CC"

View File

@ -89,6 +89,7 @@ AC_ARG_ENABLE(gcov, [ --enable-gcov compile to gather gcov statist
AC_ARG_ENABLE(noopt, [ --enable-strip strip debug on install (usually enabled by default)]) AC_ARG_ENABLE(noopt, [ --enable-strip strip debug on install (usually enabled by default)])
AC_ARG_ENABLE(noopt, [ --enable-noopt drop -O C flags (useful for low-level debugging)]) AC_ARG_ENABLE(noopt, [ --enable-noopt drop -O C flags (useful for low-level debugging)])
AC_ARG_ENABLE(ubsan, [ --enable-ubsan compile with -fsanitize=undefined)]) AC_ARG_ENABLE(ubsan, [ --enable-ubsan compile with -fsanitize=undefined)])
AC_ARG_ENABLE(jitframe,[ --enable-jitframe x86_64: use frame pointer for internal calls])
###### Some flags imply other flags ####### ###### Some flags imply other flags #######
@ -342,6 +343,8 @@ show_explicitly_enabled "${enable_smalloskit}" "OSKit small mode"
show_explicitly_enabled "${enable_gprof}" "gprof" show_explicitly_enabled "${enable_gprof}" "gprof"
show_explicitly_enabled "${enable_gcov}" "gcov" show_explicitly_enabled "${enable_gcov}" "gcov"
show_explicitly_enabled "${enable_jitframe}" "jitframe"
show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode is intended only for debugging purposes" show_explicitly_enabled "${enable_noopt}" "No-optimization" "Note that this mode is intended only for debugging purposes"
show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_enabled "${enable_strip}" "Debug-symbol stripping"
show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping" show_explicitly_disabled "${enable_strip}" "Debug-symbol stripping"
@ -678,6 +681,10 @@ if test "${enable_gcov}" = "yes" ; then
PROFFLAGS="$PROFFLAGS -fprofile-arcs -ftest-coverage" PROFFLAGS="$PROFFLAGS -fprofile-arcs -ftest-coverage"
fi fi
if test "${enable_jitframe}" = "yes" ; then
MZOPTIONS="$MZOPTIONS -DMZ_PROLOG_CREATE_FULL_STACK_FRAME"
fi
ORIG_CC_FOR_BUILD="${CC_FOR_BUILD}" ORIG_CC_FOR_BUILD="${CC_FOR_BUILD}"
if test "$CC_FOR_BUILD" = "" ; then if test "$CC_FOR_BUILD" = "" ; then
CC_FOR_BUILD="$CC" CC_FOR_BUILD="$CC"

View File

@ -820,7 +820,7 @@ static void *top;
LOCAL1 (which is a cont_mark_stack offset, if anything) LOCAL1 (which is a cont_mark_stack offset, if anything)
LOCAL2 (some pointer, never to stack or runstack) LOCAL2 (some pointer, never to stack or runstack)
LOCAL3 (temp space for misc uses; not saved across calls that might capture LWC) LOCAL3 (temp space for misc uses; not saved across calls that might capture LWC)
LOCAL4 (x86_64: = saved R14 otherwise when THREAD_LOCAL LOCAL4 (x86_64: = saved R14 when THREAD_LOCAL
x86: = RUNSTACK_BASE or THREAD_LOCAL) x86: = RUNSTACK_BASE or THREAD_LOCAL)
[some empty slots, maybe, depending on alignment] [some empty slots, maybe, depending on alignment]
[space for "flostack" --- local unboxed values, such as flonums] [space for "flostack" --- local unboxed values, such as flonums]
@ -944,9 +944,6 @@ void scheme_jit_prolog_again(mz_jit_state *jitter, int n, int ret_addr_reg)
# else # else
# define STACK_ALIGN_WORDS 3 # define STACK_ALIGN_WORDS 3
# endif # endif
# define mz_prolog(x) (ADDQiBr(-(STACK_ALIGN_WORDS * JIT_WORD_SIZE), JIT_SP))
# define mz_epilog_without_jmp() ADDQiBr((STACK_ALIGN_WORDS + 1) * JIT_WORD_SIZE, JIT_SP)
# define mz_epilog(x) (ADDQiBr(STACK_ALIGN_WORDS * JIT_WORD_SIZE, JIT_SP), RET_())
# define JIT_LOCAL3 -(JIT_WORD_SIZE * 6) # define JIT_LOCAL3 -(JIT_WORD_SIZE * 6)
# ifdef NEED_LOCAL4 # ifdef NEED_LOCAL4
# ifdef JIT_X86_64 # ifdef JIT_X86_64
@ -958,10 +955,10 @@ void scheme_jit_prolog_again(mz_jit_state *jitter, int n, int ret_addr_reg)
# else # else
# define LOCAL_FRAME_SIZE 3 # define LOCAL_FRAME_SIZE 3
# endif # endif
# define _mz_prolog(x) (ADDQiBr(-(STACK_ALIGN_WORDS * JIT_WORD_SIZE), JIT_SP))
# define _mz_epilog_without_jmp() ADDQiBr((STACK_ALIGN_WORDS + 1) * JIT_WORD_SIZE, JIT_SP)
# define _mz_epilog(x) (ADDQiBr(STACK_ALIGN_WORDS * JIT_WORD_SIZE, JIT_SP), RET_())
# else # else
# define mz_prolog(x) /* empty */
# define mz_epilog(x) RET_()
# define mz_epilog_without_jmp() ADDQir(JIT_WORD_SIZE, JIT_SP)
# define JIT_LOCAL3 JIT_LOCAL2 # define JIT_LOCAL3 JIT_LOCAL2
# ifdef NEED_LOCAL4 # ifdef NEED_LOCAL4
# define LOCAL_FRAME_SIZE 3 # define LOCAL_FRAME_SIZE 3
@ -969,10 +966,29 @@ void scheme_jit_prolog_again(mz_jit_state *jitter, int n, int ret_addr_reg)
# else # else
# define LOCAL_FRAME_SIZE 2 # define LOCAL_FRAME_SIZE 2
# endif # endif
# define _mz_prolog(x) /* empty */
# define _mz_epilog(x) RET_()
# define _mz_epilog_without_jmp() ADDQir(JIT_WORD_SIZE, JIT_SP)
# endif # endif
# ifdef NEED_LOCAL4 # ifdef NEED_LOCAL4
# define JIT_LOCAL4 -(JIT_WORD_SIZE * JIT_LOCAL4_OFFSET) # define JIT_LOCAL4 -(JIT_WORD_SIZE * JIT_LOCAL4_OFFSET)
# endif # endif
# ifdef MZ_PROLOG_CREATE_FULL_STACK_FRAME
/* Make the internal ABI the same as the main call ABI */
# define MZ_LOCAL_FRAME_SIZE 8
# define mz_prolog(x) (PUSHQr(_EBP), \
mz_get_local_p((x), JIT_LOCAL3), \
MOVQrr(_ESP, _EBP), \
ADDQiBr(-(MZ_LOCAL_FRAME_SIZE * JIT_WORD_SIZE), JIT_SP), \
mz_set_local_p((x), JIT_LOCAL3))
# define mz_epilog_without_jmp() (ADDQiBr(MZ_LOCAL_FRAME_SIZE * JIT_WORD_SIZE, JIT_SP), POPQr(_EBP), ADDQiBr(JIT_WORD_SIZE, JIT_SP))
# define mz_epilog(x) (ADDQiBr(MZ_LOCAL_FRAME_SIZE * JIT_WORD_SIZE, JIT_SP), POPQr(_EBP), RET_())
# else
/* Normal internal ABI */
# define mz_prolog(x) _mz_prolog(x)
# define mz_epilog_without_jmp(x) _mz_epilog_without_jmp(x)
# define mz_epilog(x) _mz_epilog(x)
# endif
# define mz_push_locals() SUBQir((LOCAL_FRAME_SIZE << JIT_LOG_WORD_SIZE), JIT_SP) # define mz_push_locals() SUBQir((LOCAL_FRAME_SIZE << JIT_LOG_WORD_SIZE), JIT_SP)
# define mz_pop_locals() ADDQir((LOCAL_FRAME_SIZE << JIT_LOG_WORD_SIZE), JIT_SP) # define mz_pop_locals() ADDQir((LOCAL_FRAME_SIZE << JIT_LOG_WORD_SIZE), JIT_SP)
# define JIT_FRAME_FLOSTACK_OFFSET (-(JIT_WORD_SIZE * (LOCAL_FRAME_SIZE + 3))) # define JIT_FRAME_FLOSTACK_OFFSET (-(JIT_WORD_SIZE * (LOCAL_FRAME_SIZE + 3)))

View File

@ -380,17 +380,23 @@ Scheme_Object *scheme_native_stack_trace(void)
if (STK_COMP((uintptr_t)np, real_stack_end) if (STK_COMP((uintptr_t)np, real_stack_end)
&& STK_COMP(stack_start, (uintptr_t)np)) { && STK_COMP(stack_start, (uintptr_t)np)) {
if (SCHEME_VOIDP(name)) { if (SCHEME_VOIDP(name)) {
/* JIT_LOCAL2 has the next return address (always) */ /* JIT_LOCAL2 has the next return address (always) */
q = ((void **)np)[JIT_LOCAL2 >> JIT_LOG_WORD_SIZE]; q = ((void **)np)[JIT_LOCAL2 >> JIT_LOG_WORD_SIZE];
} else { } else {
#ifdef MZ_USE_JIT_I386 #ifdef MZ_PROLOG_CREATE_FULL_STACK_FRAME
/* np is the actual stack frame */
p = np;
q = ((void **)p)[RETURN_ADDRESS_OFFSET];
#else
# ifdef MZ_USE_JIT_I386
/* Push after local stack of return-address proc /* Push after local stack of return-address proc
has the next return address */ has the next return address */
q = ((void **)np)[-(3 + LOCAL_FRAME_SIZE + 1)]; q = ((void **)np)[-(3 + LOCAL_FRAME_SIZE + 1)];
#else # else
/* JIT_LOCAL2 has the next return address */ /* JIT_LOCAL2 has the next return address */
q = ((void **)np)[JIT_LOCAL2 >> JIT_LOG_WORD_SIZE]; q = ((void **)np)[JIT_LOCAL2 >> JIT_LOG_WORD_SIZE];
# endif
#endif #endif
} }
} else { } else {