diff options
Diffstat (limited to 'nx-X11/util/memleak/stackbottom.c')
-rw-r--r-- | nx-X11/util/memleak/stackbottom.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/nx-X11/util/memleak/stackbottom.c b/nx-X11/util/memleak/stackbottom.c new file mode 100644 index 000000000..bd1a97a6a --- /dev/null +++ b/nx-X11/util/memleak/stackbottom.c @@ -0,0 +1,119 @@ +/* + * cut and paste from gc 4.4 by Hans-J. Boehm and Alan J. Demers + * + * Cutter and Paster: Jeffrey Hsu + */ + +/* $XFree86: xc/util/memleak/stackbottom.c,v 3.1 1996/12/31 05:02:27 dawes Exp $ */ + +#include <signal.h> + +typedef char * ptr_t; /* A generic pointer to which we can add */ + /* byte displacements. */ + /* Preferably identical to caddr_t, if it */ + /* exists. */ + +#ifndef bool +typedef int bool; +#endif + +#define VOLATILE volatile + +# ifndef STACK_GROWS_UP +# define STACK_GROWS_DOWN +# endif + +typedef unsigned long word; + +#define TRUE 1 + +#if defined(__alpha) || defined(__alpha__) + extern __start +# define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1))) +#endif + +void GC_noop() {} + + /* Some tools to implement HEURISTIC2 */ +# define MIN_PAGE_SIZE 256 /* Smallest conceivable page size, bytes */ +# include <setjmp.h> + /* static */ jmp_buf GC_jmp_buf; + + /*ARGSUSED*/ + void GC_fault_handler(sig) + int sig; + { + longjmp(GC_jmp_buf, 1); + } + + typedef void (*handler)(int); + + /* Return the first nonaddressible location > p (up) or */ + /* the smallest location q s.t. [q,p] is addressible (!up). */ + ptr_t GC_find_limit(p, up) + ptr_t p; + bool up; + { + static VOLATILE ptr_t result; + /* Needs to be static, since otherwise it may not be */ + /* preserved across the longjmp. Can safely be */ + /* static since it's only called once, with the */ + /* allocation lock held. */ + + static handler old_segv_handler, old_bus_handler; + /* See above for static declaration. */ + + old_segv_handler = signal(SIGSEGV, GC_fault_handler); +# ifdef SIGBUS + old_bus_handler = signal(SIGBUS, GC_fault_handler); +# endif + if (setjmp(GC_jmp_buf) == 0) { + result = (ptr_t)(((word)(p)) + & ~(MIN_PAGE_SIZE-1)); + for (;;) { + if (up) { + result += MIN_PAGE_SIZE; + } else { + result -= MIN_PAGE_SIZE; + } + GC_noop(*result); + } + } + (void) signal(SIGSEGV, old_segv_handler); +# ifdef SIGBUS + (void) signal(SIGBUS, old_bus_handler); +# endif + if (!up) { + result += MIN_PAGE_SIZE; + } + return(result); + } + +ptr_t GC_get_stack_base() +{ + word dummy; + static ptr_t result; + + if (!result) { + +# ifdef STACK_GROWS_DOWN + result = GC_find_limit((ptr_t)(&dummy), TRUE); +# ifdef HEURISTIC2_LIMIT + if (result > HEURISTIC2_LIMIT + && (ptr_t)(&dummy) < HEURISTIC2_LIMIT) { + result = HEURISTIC2_LIMIT; + } +# endif +# else + result = GC_find_limit((ptr_t)(&dummy), FALSE); +# ifdef HEURISTIC2_LIMIT + if (result < HEURISTIC2_LIMIT + && (ptr_t)(&dummy) > HEURISTIC2_LIMIT) { + result = HEURISTIC2_LIMIT; + } +# endif +# endif + } + + return(result); +} |