1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/*
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
*
* Permission is hereby granted to use or copy this program
* for any purpose, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
/* Boehm, September 21, 1995 5:39 pm PDT */
/* 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 <string.h>
#include "config.h"
#ifdef __hpux
#include <unistd.h>
int
getpagesize()
{
return sysconf(_SC_PAGE_SIZE);
}
#endif
#if defined(SUNOS5) || defined(DRSNX)
#include <unistd.h>
int
getpagesize()
{
return sysconf(_SC_PAGESIZE);
}
#endif
#ifdef _AUX_SOURCE
#include <sys/mmu.h>
int
getpagesize()
{
return PAGESIZE;
}
#endif
#if defined(AMIGA) || defined(MACOS)
int
getpagesize()
{
return(4096);
}
#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 = (int)strlen("a"); /* 1, slightly disguised */
static int y = 0;
printf("This appears to be a %s running %s\n", MACH_TYPE, OS_TYPE);
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("On many machines the value is not fixed.\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(RS6000) || 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);
}
|