From: ivmai Date: Mon, 24 Jan 2011 21:43:30 +0000 (+0000) Subject: 2011-01-22 Ivan Maidanski (mostly Jean-Claude Beaudoin) X-Git-Tag: gc7_2alpha6~108 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb4edc16faef98e2be3966eb1f6c9cec45c4ffeb;p=gc 2011-01-22 Ivan Maidanski (mostly Jean-Claude Beaudoin) * darwin_stop_world.c (GC_FindTopOfStack): Prefix and suffix "volatile" keyword with double underscore. * mach_dep.c (GETCONTEXT_FPU_EXCMASK_BUG): Recognize new macro and include fenv.h if defined (unless NO_GETCONTEXT or HAVE_PUSH_REGS). * mach_dep.c (GC_with_callee_saves_pushed): Restore FPU exception mask corrupted by getcontext if GETCONTEXT_FPU_EXCMASK_BUG. * include/private/gcconfig.h (GETCONTEXT_FPU_EXCMASK_BUG): Define for Linux/amd64 (since its GLibc getcontext currently has the bug). --- diff --git a/ChangeLog b/ChangeLog index da3b65ac..2c8dc557 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-01-22 Ivan Maidanski (mostly Jean-Claude Beaudoin) + + * darwin_stop_world.c (GC_FindTopOfStack): Prefix and suffix + "volatile" keyword with double underscore. + * mach_dep.c (GETCONTEXT_FPU_EXCMASK_BUG): Recognize new macro and + include fenv.h if defined (unless NO_GETCONTEXT or HAVE_PUSH_REGS). + * mach_dep.c (GC_with_callee_saves_pushed): Restore FPU exception + mask corrupted by getcontext if GETCONTEXT_FPU_EXCMASK_BUG. + * include/private/gcconfig.h (GETCONTEXT_FPU_EXCMASK_BUG): Define + for Linux/amd64 (since its GLibc getcontext currently has the bug). + 2011-01-17 Ivan Maidanski * allchblk.c (GC_use_entire_heap): Change type to int (as declared diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 6af69184..db462295 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -56,9 +56,9 @@ GC_INNER ptr_t GC_FindTopOfStack(unsigned long stack_start) if (stack_start == 0) { # ifdef POWERPC # if CPP_WORDSZ == 32 - __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); + __asm__ __volatile__ ("lwz %0,0(r1)" : "=r" (frame)); # else - __asm__ volatile("ld %0,0(r1)" : "=r" (frame)); + __asm__ __volatile__ ("ld %0,0(r1)" : "=r" (frame)); # endif # endif } else { diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index cbfe735c..c75b7cee 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -707,7 +707,7 @@ # ifdef __ELF__ # define DYNAMIC_LOADING # include -# if defined(__GLIBC__)&& __GLIBC__>=2 +# if defined(__GLIBC__) && __GLIBC__ >= 2 # define SEARCH_FOR_DATA_START # else /* !GLIBC2 */ # ifdef PLATFORM_ANDROID @@ -2063,6 +2063,12 @@ # define PREFETCH(x) __builtin_prefetch((x), 0, 0) # define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1) # endif +# if defined(__GLIBC__) + /* At present, there's a bug in GLibc getcontext() on */ + /* Linux/x64 (it clears FPU exception mask). We define this */ + /* macro to workaround it. */ +# define GETCONTEXT_FPU_EXCMASK_BUG +# endif # endif # ifdef DARWIN # define OS_TYPE "DARWIN" diff --git a/mach_dep.c b/mach_dep.c index 0829c8ca..0753d504 100644 --- a/mach_dep.c +++ b/mach_dep.c @@ -185,8 +185,11 @@ asm static void PushMacRegisters() # include # ifndef NO_GETCONTEXT # include +# ifdef GETCONTEXT_FPU_EXCMASK_BUG +# include +# endif # endif -#endif +#endif /* !HAVE_PUSH_REGS */ /* Ensure that either registers are pushed, or callee-save registers */ /* are somewhere on the stack, and then call fn(arg, ctxt). */ @@ -204,8 +207,41 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), /* ARM and MIPS Linux often doesn't support a real */ /* getcontext(). */ ucontext_t ctxt; +# ifdef GETCONTEXT_FPU_EXCMASK_BUG + /* Workaround a bug (clearing the FPU exception mask) in */ + /* getcontext on Linux/x86_64. */ +# ifdef X86_64 + /* We inline fegetexcept and feenableexcept here just not to */ + /* force the client application to use -lm linker option. */ + unsigned short except_mask; + __asm__ __volatile__ ("fstcw %0" : "=m" (*&except_mask)); + except_mask &= FE_ALL_EXCEPT; +# else + int except_mask = fegetexcept(); +# endif +# endif if (getcontext(&ctxt) < 0) - ABORT ("Getcontext failed: Use another register retrieval method?"); + ABORT ("getcontext failed: Use another register retrieval method?"); +# ifdef GETCONTEXT_FPU_EXCMASK_BUG +# ifdef X86_64 + { + unsigned short new_exc; + unsigned int new_exc_sse; + /* Get the current control word of the x87 FPU. */ + __asm__ __volatile__ ("fstcw %0" : "=m" (*&new_exc)); + new_exc &= except_mask; + __asm__ __volatile__ ("fldcw %0" : : "m" (*&new_exc)); + /* And now the same for the SSE MXCSR register. */ + __asm__ __volatile__ ("stmxcsr %0" : "=m" (*&new_exc_sse)); + /* The SSE exception masks are shifted by 7 bits. */ + new_exc_sse &= except_mask << 7; + __asm__ __volatile__ ("ldmxcsr %0" : : "m" (*&new_exc_sse)); + } +# else /* !X86_64 */ + if (feenableexcept(except_mask) < 0) + ABORT("feenableexcept failed"); +# endif +# endif context = &ctxt; # if defined(SPARC) || defined(IA64) /* On a register window machine, we need to save register */