/* Check whether setjmp actually saves registers in jmp←buf. */ /* If it doesn't, the generic mark←regs code won't work. */ /* Compilers vary as to whether they will put x in a */ /* (callee-save) register without -O. The code is */ /* contrived such that any decent compiler should put x in */ /* a callee-save register with -O. Thus it is is */ /* recommended that this be run optimized. (If the machine */ /* has no callee-save registers, then the generic code is */ /* safe, but this will not be noticed by this piece of */ /* code.) */ #include <stdio.h> #include <setjmp.h> #include "config.h" #ifdef ←←hpux /* X/OPEN PG3 defines "void* sbrk();" and this clashes with the definition */ /* in gc←private.h, so we set the clock backwards with ←CLASSIC←XOPEN←TYPES. */ /* This is for HP-UX 8.0. /* sbrk() is not used in this file, of course. W. Underwood, 15 Jun 1992 */ #define ←CLASSIC←XOPEN←TYPES #include <unistd.h> int getpagesize() { return sysconf(←SC←PAGE←SIZE); } #endif #if defined(SUNOS5) #define ←CLASSIC←XOPEN←TYPES #include <unistd.h> int getpagesize() { return sysconf(←SC←PAGESIZE); } #endif #ifdef ←AUX←SOURCE #include <sys/mmu.h> int getpagesize() { return PAGESIZE; } #endif #ifdef ←←OS2←← #define INCL←DOSFILEMGR #define INCL←DOSMISC #define INCL←DOSERRORS #include <os2.h> int getpagesize() { ULONG result[1]; if (DosQuerySysInfo(QSV←PAGE←SIZE, QSV←PAGE←SIZE, (void *)result, sizeof(ULONG)) != NO←ERROR) { fprintf(stderr, "DosQuerySysInfo failed\n"); result[0] = 4096; } return((int)(result[0])); } #endif struct {char a←a; char * a←b;} a; int * nested←sp() { int dummy; return(&dummy); } main() { int dummy; long ps = getpagesize(); jmp←buf b; register int x = strlen("a"); /* 1, slightly disguised */ static int y = 0; if (nested←sp() < &dummy) { printf("Stack appears to grow down, which is the default.\n"); printf("A good guess for STACKBOTTOM on this machine is 0x%X.\n", ((long)(&dummy) + ps) & ~(ps-1)); } else { printf("Stack appears to grow up.\n"); printf("Define STACK←GROWS←UP in gc←private.h\n"); printf("A good guess for STACKBOTTOM on this machine is 0x%X.\n", ((long)(&dummy) + ps) & ~(ps-1)); } printf("Note that this may vary between machines of ostensibly\n"); printf("the same architecture (e.g. Sun 3/50s and 3/80s).\n"); printf("A good guess for ALIGNMENT on this machine is %d.\n", (unsigned long)(&(a.a←b))-(unsigned long)(&a)); /* Encourage the compiler to keep x in a callee-save register */ x = 2*x-1; printf(""); x = 2*x-1; setjmp(b); if (y == 1) { if (x == 2) { printf("Generic mark←regs code probably wont work\n"); # if defined(SPARC) || defined(IBMRS6000) || defined(VAX) || defined(MIPS) || defined(M68K) || defined(I386) || defined(NS32K) || defined(RT) printf("Assembly code supplied\n"); # else printf("Need assembly code\n"); # endif } else if (x == 1) { printf("Generic mark←regs code may work\n"); } else { printf("Very strange setjmp implementation\n"); } } y++; x = 2; if (y == 1) longjmp(b,1); return(0); } int g(x) int x; { return(x); }