within mzscheme, use gcc noinline attribute on some stack-mangling functions

svn: r14243
This commit is contained in:
Matthew Flatt 2009-03-23 18:54:12 +00:00
parent c656a658e9
commit 4dc6651069
7 changed files with 101 additions and 9 deletions

61
src/configure vendored
View File

@ -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; }

View File

@ -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(

View File

@ -32,5 +32,7 @@
/* Whether getaddrinfo works. */
#undef HAVE_GETADDRINFO
/* Whether __attribute__ ((noinline)) works */
#undef MZ_USE_NOINLINE
#endif

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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);
}