diff options
author | ivmai <ivmai> | 2011-01-24 21:43:30 +0000 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 21:06:56 +0400 |
commit | bb4edc16faef98e2be3966eb1f6c9cec45c4ffeb (patch) | |
tree | 49666259893a4bc311454edc2c9d3ed8729bd457 | |
parent | ce3582069e602d1e6d1d1b17a2336484150fdef5 (diff) | |
download | bdwgc-bb4edc16faef98e2be3966eb1f6c9cec45c4ffeb.tar.gz |
2011-01-22 Ivan Maidanski <ivmai@mail.ru> (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).
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | darwin_stop_world.c | 4 | ||||
-rw-r--r-- | include/private/gcconfig.h | 8 | ||||
-rw-r--r-- | mach_dep.c | 40 |
4 files changed, 58 insertions, 5 deletions
@@ -1,3 +1,14 @@ +2011-01-22 Ivan Maidanski <ivmai@mail.ru> (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 <ivmai@mail.ru> * 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 <features.h> -# 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" @@ -185,8 +185,11 @@ asm static void PushMacRegisters() # include <signal.h> # ifndef NO_GETCONTEXT # include <ucontext.h> +# ifdef GETCONTEXT_FPU_EXCMASK_BUG +# include <fenv.h> +# 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 */ |