diff --git a/src/configure b/src/configure index 5dd4a89108..715a606311 100755 --- a/src/configure +++ b/src/configure @@ -6038,6 +6038,67 @@ fi if test "$inline" = "no" ; then MZOPTIONS="$MZOPTIONS -DNO_INLINE_KEYWORD" +fi +{ echo "$as_me:$LINENO: result: $inline" >&5 +echo "${ECHO_T}$inline" >&6; } + + msg="for noinline attribute" +{ echo "$as_me:$LINENO: checking $msg" >&5 +echo $ECHO_N "checking $msg... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + noinline=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +static int foo() __attribute__ ((noinline)); + static int foo() { return 0; } + int main() { + return foo(); + } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + noinline=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +noinline=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$noinline" = "yes" ; then + +cat >>confdefs.h <<\_ACEOF +#define MZ_USE_NOINLINE 1 +_ACEOF + fi { echo "$as_me:$LINENO: result: $inline" >&5 echo "${ECHO_T}$inline" >&6; } diff --git a/src/mzscheme/configure.ac b/src/mzscheme/configure.ac index e90eed7f25..55c680a812 100644 --- a/src/mzscheme/configure.ac +++ b/src/mzscheme/configure.ac @@ -722,12 +722,26 @@ AC_TRY_RUN( static inline int foo() { return 0; } int main() { return foo(); - }, inline=yes, inline=no, inline=no) + }, + inline=yes, inline=no, inline=no) if test "$inline" = "no" ; then MZOPTIONS="$MZOPTIONS -DNO_INLINE_KEYWORD" fi AC_MSG_RESULT($inline) +[ msg="for noinline attribute" ] +AC_MSG_CHECKING($msg) +AC_TRY_RUN( + static int foo() __attribute__ ((noinline)); + static int foo() { return 0; } + int main() { + return foo(); + }, noinline=yes, noinline=no, noinline=no) +if test "$noinline" = "yes" ; then + AC_DEFINE(MZ_USE_NOINLINE,1,[Have noinline attribute]) +fi +AC_MSG_RESULT($inline) + [ msg="for GNU preprocessor" ] AC_MSG_CHECKING($msg) AC_TRY_RUN( diff --git a/src/mzscheme/mzconfig.h.in b/src/mzscheme/mzconfig.h.in index 2d7056aacd..425fd7b2f3 100644 --- a/src/mzscheme/mzconfig.h.in +++ b/src/mzscheme/mzconfig.h.in @@ -32,5 +32,7 @@ /* Whether getaddrinfo works. */ #undef HAVE_GETADDRINFO +/* Whether __attribute__ ((noinline)) works */ +#undef MZ_USE_NOINLINE #endif diff --git a/src/mzscheme/src/fun.c b/src/mzscheme/src/fun.c index 74810fb41d..d1f95d53bc 100644 --- a/src/mzscheme/src/fun.c +++ b/src/mzscheme/src/fun.c @@ -1827,7 +1827,8 @@ typedef Scheme_Object *(*Overflow_K_Proc)(void); THREAD_LOCAL Scheme_Overflow_Jmp *scheme_overflow_jmp; THREAD_LOCAL void *scheme_overflow_stack_start; -/* private, but declared public to avoid inlining: */ +MZ_DO_NOT_INLINE(void scheme_really_create_overflow(void *stack_base)); + void scheme_really_create_overflow(void *stack_base) { Scheme_Overflow_Jmp *jmp; @@ -5747,7 +5748,9 @@ void scheme_drop_prompt_meta_continuations(Scheme_Object *prompt_tag) scheme_current_thread->meta_continuation = mc; } -/* private, but declared public to avoid inlining: */ +MZ_DO_NOT_INLINE(Scheme_Object *scheme_finish_apply_for_prompt(Scheme_Prompt *prompt, Scheme_Object *_prompt_tag, + Scheme_Object *proc, int argc, Scheme_Object **argv)); + Scheme_Object *scheme_finish_apply_for_prompt(Scheme_Prompt *prompt, Scheme_Object *_prompt_tag, Scheme_Object *proc, int argc, Scheme_Object **argv) { @@ -5887,7 +5890,9 @@ Scheme_Object *scheme_finish_apply_for_prompt(Scheme_Prompt *prompt, Scheme_Obje } } -/* private, but declared public to avoid inlining: */ +MZ_DO_NOT_INLINE(Scheme_Object *scheme_apply_for_prompt(Scheme_Prompt *prompt, Scheme_Object *prompt_tag, + Scheme_Object *proc, int argc, Scheme_Object **argv)); + Scheme_Object *scheme_apply_for_prompt(Scheme_Prompt *prompt, Scheme_Object *prompt_tag, Scheme_Object *proc, int argc, Scheme_Object **argv) { diff --git a/src/mzscheme/src/schpriv.h b/src/mzscheme/src/schpriv.h index 7c9b7cc040..a37bd4b790 100644 --- a/src/mzscheme/src/schpriv.h +++ b/src/mzscheme/src/schpriv.h @@ -104,6 +104,13 @@ int scheme_num_types(void); # define SET_REQUIRED_TAG(e) /* empty */ #endif +#if MZ_USE_NOINLINE +# define MZ_DO_NOT_INLINE(decl) decl __attribute__ ((noinline)); +#else +# define MZ_DO_NOT_INLINE() +#endif + + void scheme_reset_finalizations(void); extern unsigned long scheme_get_current_os_thread_stack_base(void); diff --git a/src/mzscheme/src/setjmpup.c b/src/mzscheme/src/setjmpup.c index 8aad99bf14..57e3dca67b 100644 --- a/src/mzscheme/src/setjmpup.c +++ b/src/mzscheme/src/setjmpup.c @@ -325,7 +325,9 @@ void MZ_NO_INLINE scheme_copy_stack(Scheme_Jumpup_Buf *b, void *base, void *star size); } -static void uncopy_stack(int ok, Scheme_Jumpup_Buf *b, long *prev) +MZ_DO_NOT_INLINE(void scheme_uncopy_stack(int ok, Scheme_Jumpup_Buf *b, long *prev)); + +void scheme_uncopy_stack(int ok, Scheme_Jumpup_Buf *b, long *prev) { GC_CAN_IGNORE Scheme_Jumpup_Buf *c; long top_delta = 0, bottom_delta = 0, size; @@ -337,7 +339,7 @@ static void uncopy_stack(int ok, Scheme_Jumpup_Buf *b, long *prev) z = (unsigned long)&junk[0]; - uncopy_stack(STK_COMP(z, DEEPPOS(b)), b, junk); + scheme_uncopy_stack(STK_COMP(z, DEEPPOS(b)), b, junk); } /* Vague attempt to prevent the compiler from optimizing away `prev': */ @@ -619,7 +621,7 @@ void scheme_longjmpup(Scheme_Jumpup_Buf *b) scheme_flush_stack_cache(); #endif - uncopy_stack(STK_COMP((unsigned long)&z, DEEPPOS(b)), b, junk); + scheme_uncopy_stack(STK_COMP((unsigned long)&z, DEEPPOS(b)), b, junk); } void scheme_init_jmpup_buf(Scheme_Jumpup_Buf *b) diff --git a/src/mzscheme/src/thread.c b/src/mzscheme/src/thread.c index dde50e7cf7..4fff4b5ee6 100644 --- a/src/mzscheme/src/thread.c +++ b/src/mzscheme/src/thread.c @@ -3222,7 +3222,8 @@ static Scheme_Object *def_nested_exn_handler(int argc, Scheme_Object *argv[]) return scheme_void; /* misuse of exception handler (wrong kind of thread or under prompt) */ } -/* private, but declared as public to avoid inlining: */ +MZ_DO_NOT_INLINE(Scheme_Object *scheme_call_as_nested_thread(int argc, Scheme_Object *argv[], void *max_bottom)); + Scheme_Object *scheme_call_as_nested_thread(int argc, Scheme_Object *argv[], void *max_bottom) { Scheme_Thread *p = scheme_current_thread; @@ -3791,7 +3792,7 @@ static void raise_break(Scheme_Thread *p) p->external_break = 0; - if (p->blocker && (p->block_check == syncing_ready)) { + if (p->blocker && (p->block_check == (Scheme_Ready_Fun)syncing_ready)) { /* Get out of lines for channels, etc., before calling a break exn handler. */ scheme_post_syncing_nacks((Syncing *)p->blocker); }