diff --git a/racket/src/configure b/racket/src/configure index 577dfa576a..d41421d99d 100755 --- a/racket/src/configure +++ b/racket/src/configure @@ -832,6 +832,7 @@ enable_gprof enable_gcov enable_noopt enable_ubsan +enable_jitframe ' ac_precious_vars='build_alias host_alias @@ -1489,6 +1490,7 @@ Optional Features: --enable-strip strip debug on install (usually enabled by default) --enable-noopt drop -O C flags (useful for low-level debugging) --enable-ubsan compile with -fsanitize=undefined) + --enable-jitframe x86_64: use frame pointer for internal calls Some influential environment variables: CC C compiler command @@ -2843,6 +2845,11 @@ if test "${enable_ubsan+set}" = set; then : enableval=$enable_ubsan; fi +# Check whether --enable-jitframe was given. +if test "${enable_jitframe+set}" = set; then : + enableval=$enable_jitframe; +fi + ###### 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_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_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" fi +if test "${enable_jitframe}" = "yes" ; then + MZOPTIONS="$MZOPTIONS -DMZ_PROLOG_CREATE_FULL_STACK_FRAME" +fi + ORIG_CC_FOR_BUILD="${CC_FOR_BUILD}" if test "$CC_FOR_BUILD" = "" ; then CC_FOR_BUILD="$CC" diff --git a/racket/src/racket/configure.ac b/racket/src/racket/configure.ac index 67351334fb..eb935e9324 100644 --- a/racket/src/racket/configure.ac +++ b/racket/src/racket/configure.ac @@ -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-noopt drop -O C flags (useful for low-level debugging)]) 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 ####### @@ -342,6 +343,8 @@ show_explicitly_enabled "${enable_smalloskit}" "OSKit small mode" show_explicitly_enabled "${enable_gprof}" "gprof" 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_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" fi +if test "${enable_jitframe}" = "yes" ; then + MZOPTIONS="$MZOPTIONS -DMZ_PROLOG_CREATE_FULL_STACK_FRAME" +fi + ORIG_CC_FOR_BUILD="${CC_FOR_BUILD}" if test "$CC_FOR_BUILD" = "" ; then CC_FOR_BUILD="$CC" diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index a7f929ad11..ca17100983 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -820,7 +820,7 @@ static void *top; LOCAL1 (which is a cont_mark_stack offset, if anything) LOCAL2 (some pointer, never to stack or runstack) 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) [some empty slots, maybe, depending on alignment] [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 # define STACK_ALIGN_WORDS 3 # 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) # ifdef NEED_LOCAL4 # ifdef JIT_X86_64 @@ -958,10 +955,10 @@ void scheme_jit_prolog_again(mz_jit_state *jitter, int n, int ret_addr_reg) # else # define LOCAL_FRAME_SIZE 3 # 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 -# 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 # ifdef NEED_LOCAL4 # 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 # define LOCAL_FRAME_SIZE 2 # endif +# define _mz_prolog(x) /* empty */ +# define _mz_epilog(x) RET_() +# define _mz_epilog_without_jmp() ADDQir(JIT_WORD_SIZE, JIT_SP) # endif # ifdef NEED_LOCAL4 # define JIT_LOCAL4 -(JIT_WORD_SIZE * JIT_LOCAL4_OFFSET) # 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_pop_locals() ADDQir((LOCAL_FRAME_SIZE << JIT_LOG_WORD_SIZE), JIT_SP) # define JIT_FRAME_FLOSTACK_OFFSET (-(JIT_WORD_SIZE * (LOCAL_FRAME_SIZE + 3))) diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index aa25395954..bfd51f9898 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -380,17 +380,23 @@ Scheme_Object *scheme_native_stack_trace(void) if (STK_COMP((uintptr_t)np, real_stack_end) && STK_COMP(stack_start, (uintptr_t)np)) { - if (SCHEME_VOIDP(name)) { + if (SCHEME_VOIDP(name)) { /* JIT_LOCAL2 has the next return address (always) */ q = ((void **)np)[JIT_LOCAL2 >> JIT_LOG_WORD_SIZE]; } 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 has the next return address */ q = ((void **)np)[-(3 + LOCAL_FRAME_SIZE + 1)]; -#else +# else /* JIT_LOCAL2 has the next return address */ q = ((void **)np)[JIT_LOCAL2 >> JIT_LOG_WORD_SIZE]; +# endif #endif } } else {