Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / include / private / gcconfig.h
1 /*
2  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
4  * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
5  * Copyright (c) 2000-2004 Hewlett-Packard Development Company, L.P.
6  *
7  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
9  *
10  * Permission is hereby granted to use or copy this program
11  * for any purpose,  provided the above notices are retained on all copies.
12  * Permission to modify the code and to distribute modified code is granted,
13  * provided the above notices are retained, and a notice that the code was
14  * modified is included with the above copyright notice.
15  */
16
17 /*
18  * This header is private to the gc.  It is almost always included from
19  * gc_priv.h.  However it is possible to include it by itself if just the
20  * configuration macros are needed.  In that
21  * case, a few declarations relying on types declared in gc_priv.h will be
22  * omitted.
23  */
24
25 #ifndef GCCONFIG_H
26
27 # define GCCONFIG_H
28
29 # ifndef GC_PRIVATE_H
30     /* Fake ptr_t declaration, just to avoid compilation errors.        */
31     /* This avoids many instances if "ifndef GC_PRIVATE_H" below.       */
32     typedef struct GC_undefined_struct * ptr_t;
33 #   include <stddef.h>  /* For size_t etc. */
34 # endif
35
36 /* Machine dependent parameters.  Some tuning parameters can be found   */
37 /* near the top of gc_private.h.                                        */
38
39 /* Machine specific parts contributed by various people.  See README file. */
40
41 /* First a unified test for Linux: */
42 # if defined(linux) || defined(__linux__)
43 #  ifndef LINUX
44 #    define LINUX
45 #  endif
46 # endif
47
48 /* And one for NetBSD: */
49 # if defined(__NetBSD__)
50 #    define NETBSD
51 # endif
52
53 /* And one for OpenBSD: */
54 # if defined(__OpenBSD__)
55 #    define OPENBSD
56 # endif
57
58 /* And one for FreeBSD: */
59 # if (defined(__FreeBSD__) || defined(__DragonFly__) || \
60       defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
61 #    define FREEBSD
62 # endif
63
64 /* And one for Darwin: */
65 # if defined(macosx) || (defined(__APPLE__) && defined(__MACH__))
66 #   define DARWIN
67 # endif
68
69 /* Determine the machine type: */
70 # if defined(__arm__) || defined(__thumb__)
71 #    define ARM32
72 #    if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) \
73         && !defined(DARWIN) && !defined(_WIN32) && !defined(__CEGCC__)
74 #      define NOSYS
75 #      define mach_type_known
76 #    endif
77 # endif
78 # if defined(sun) && defined(mc68000)
79 #    error SUNOS4 no longer supported
80 # endif
81 # if defined(hp9000s300)
82 #    error M68K based HP machines no longer supported.
83 # endif
84 # if defined(OPENBSD) && defined(m68k)
85      /* FIXME: Should we remove this case? */
86 #    define M68K
87 #    define mach_type_known
88 # endif
89 # if defined(OPENBSD) && defined(__sparc__)
90 #    define SPARC
91 #    define mach_type_known
92 # endif
93 # if defined(OPENBSD) && defined(__arm__)
94 #    define ARM32
95 #    define mach_type_known
96 # endif
97 # if defined(OPENBSD) && defined(__sh__)
98 #    define SH
99 #    define mach_type_known
100 # endif
101 # if defined(NETBSD) && (defined(m68k) || defined(__m68k__))
102 #    define M68K
103 #    define mach_type_known
104 # endif
105 # if defined(NETBSD) && defined(__powerpc__)
106 #    define POWERPC
107 #    define mach_type_known
108 # endif
109 # if defined(NETBSD) && (defined(__arm32__) || defined(__arm__))
110 #    define ARM32
111 #    define mach_type_known
112 # endif
113 # if defined(NETBSD) && defined(__sh__)
114 #    define SH
115 #    define mach_type_known
116 # endif
117 # if defined(vax) || defined(__vax__)
118 #    define VAX
119 #    ifdef ultrix
120 #       define ULTRIX
121 #    else
122 #       define BSD
123 #    endif
124 #    define mach_type_known
125 # endif
126 # if defined(__NetBSD__) && defined(__vax__)
127 #    define VAX
128 #    define mach_type_known
129 # endif
130 # if defined(mips) || defined(__mips) || defined(_mips)
131 #    define MIPS
132 #    if defined(nec_ews) || defined(_nec_ews)
133 #      define EWS4800
134 #    endif
135 #    if !defined(LINUX) && !defined(EWS4800) && !defined(NETBSD) \
136         && !defined(OPENBSD)
137 #      if defined(ultrix) || defined(__ultrix)
138 #        define ULTRIX
139 #      else
140 #        define IRIX5   /* or IRIX 6.X */
141 #      endif
142 #    endif /* !LINUX */
143 #    if defined(__NetBSD__) && defined(__MIPSEL__)
144 #      undef ULTRIX
145 #    endif
146 #    define mach_type_known
147 # endif
148 # if defined(DGUX) && (defined(i386) || defined(__i386__))
149 #    define I386
150 #    ifndef _USING_DGUX
151 #    define _USING_DGUX
152 #    endif
153 #    define mach_type_known
154 # endif
155 # if defined(sequent) && (defined(i386) || defined(__i386__))
156 #    define I386
157 #    define SEQUENT
158 #    define mach_type_known
159 # endif
160 # if defined(sun) && (defined(i386) || defined(__i386__))
161 #    define I386
162 #    define SOLARIS
163 #    define mach_type_known
164 # endif
165 # if defined(sun) && defined(__amd64)
166 #    define X86_64
167 #    define SOLARIS
168 #    define mach_type_known
169 # endif
170 # if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__)
171 #    define I386
172 #    define OS2
173 #    define mach_type_known
174 # endif
175 # if defined(ibm032)
176 #   error IBM PC/RT no longer supported.
177 # endif
178 # if defined(sun) && (defined(sparc) || defined(__sparc))
179 #   define SPARC
180     /* Test for SunOS 5.x */
181 #     include <errno.h>
182 #     define SOLARIS
183 #   define mach_type_known
184 # endif
185 # if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
186      && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) \
187      && !defined(__DragonFly__)
188 #   define SPARC
189 #   define DRSNX
190 #   define mach_type_known
191 # endif
192 # if defined(_IBMR2)
193 #   define POWERPC
194 #   define AIX
195 #   define mach_type_known
196 # endif
197 # if defined(__NetBSD__) && defined(__sparc__)
198 #   define SPARC
199 #   define mach_type_known
200 # endif
201 # if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386)
202         /* The above test may need refinement   */
203 #   define I386
204 #   if defined(_SCO_ELF)
205 #     define SCO_ELF
206 #   else
207 #     define SCO
208 #   endif
209 #   define mach_type_known
210 # endif
211 # if defined(_AUX_SOURCE)
212 #   error A/UX no longer supported
213 # endif
214 # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
215      || defined(hppa) || defined(__hppa__)
216 #   define HP_PA
217 #   if !defined(LINUX) && !defined(HPUX) && !defined(OPENBSD)
218 #     define HPUX
219 #   endif
220 #   define mach_type_known
221 # endif
222 # if defined(__ia64) && (defined(_HPUX_SOURCE) || defined(__HP_aCC))
223 #   define IA64
224 #   ifndef HPUX
225 #     define HPUX
226 #   endif
227 #   define mach_type_known
228 # endif
229 # if defined(__BEOS__) && defined(_X86_)
230 #    define I386
231 #    define BEOS
232 #    define mach_type_known
233 # endif
234 # if defined(OPENBSD) && defined(__amd64__)
235 #    define X86_64
236 #    define mach_type_known
237 # endif
238 # if defined(LINUX) && (defined(i386) || defined(__i386__))
239 #    define I386
240 #    define mach_type_known
241 # endif
242 # if defined(LINUX) && defined(__x86_64__)
243 #    define X86_64
244 #    define mach_type_known
245 # endif
246 # if defined(LINUX) && (defined(__ia64__) || defined(__ia64))
247 #    define IA64
248 #    define mach_type_known
249 # endif
250 # if defined(LINUX) && defined(__arm__)
251 #    define ARM32
252 #    define mach_type_known
253 # endif
254 # if defined(LINUX) && defined(__cris__)
255 #    ifndef CRIS
256 #       define CRIS
257 #    endif
258 #    define mach_type_known
259 # endif
260 # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || \
261                         defined(powerpc64) || defined(__powerpc64__))
262 #    define POWERPC
263 #    define mach_type_known
264 # endif
265 # if defined(FREEBSD) && (defined(powerpc) || defined(__powerpc__))
266 #    define POWERPC
267 #    define mach_type_known
268 # endif
269 # if defined(LINUX) && defined(__mc68000__)
270 #    define M68K
271 #    define mach_type_known
272 # endif
273 # if defined(LINUX) && (defined(sparc) || defined(__sparc__))
274 #    define SPARC
275 #    define mach_type_known
276 # endif
277 # if defined(LINUX) && defined(__arm__)
278 #    define ARM32
279 #    define mach_type_known
280 # endif
281 # if defined(LINUX) && defined(__sh__)
282 #    define SH
283 #    define mach_type_known
284 # endif
285 # if defined(LINUX) && defined(__m32r__)
286 #    define M32R
287 #    define mach_type_known
288 # endif
289 # if defined(__alpha) || defined(__alpha__)
290 #   define ALPHA
291 #   if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) && !defined(FREEBSD)
292 #     define OSF1       /* a.k.a Digital Unix */
293 #   endif
294 #   define mach_type_known
295 # endif
296 # if defined(_AMIGA) && !defined(AMIGA)
297 #   define AMIGA
298 # endif
299 # ifdef AMIGA
300 #   define M68K
301 #   define mach_type_known
302 # endif
303 # if defined(THINK_C) || defined(__MWERKS__) && !defined(__powerc)
304 #   define M68K
305 #   define MACOS
306 #   define mach_type_known
307 # endif
308 # if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__)
309 #   define POWERPC
310 #   define MACOS
311 #   define mach_type_known
312 # endif
313 # if defined(__OpenBSD__) && defined(__powerpc__)
314 #   define POWERPC
315 #   define OPENBSD
316 #   define mach_type_known
317 # endif
318 # if defined(DARWIN)
319 #   if defined(__ppc__)  || defined(__ppc64__)
320 #    define POWERPC
321 #    define mach_type_known
322 #   elif defined(__x86_64__)
323 #    define X86_64
324 #    define mach_type_known
325 #   elif defined(__i386__)
326 #    define I386
327 #    define mach_type_known
328 #   elif defined(__arm__)
329 #    define ARM32
330 #    define mach_type_known
331 #    define DARWIN_DONT_PARSE_STACK
332 #   endif
333 # endif
334 # if defined(NeXT) && defined(mc68000)
335 #   define M68K
336 #   define NEXT
337 #   define mach_type_known
338 # endif
339 # if defined(NeXT) && (defined(i386) || defined(__i386__))
340 #   define I386
341 #   define NEXT
342 #   define mach_type_known
343 # endif
344 # if defined(__OpenBSD__) && (defined(i386) || defined(__i386__))
345 #   define I386
346 #   define OPENBSD
347 #   define mach_type_known
348 # endif
349 # if defined(FREEBSD) && (defined(i386) || defined(__i386__))
350 #   define I386
351 #   define mach_type_known
352 # endif
353 # if defined(FREEBSD) && defined(__x86_64__)
354 #   define X86_64
355 #   define mach_type_known
356 # endif
357 # if defined(__NetBSD__) && (defined(i386) || defined(__i386__))
358 #   define I386
359 #   define mach_type_known
360 # endif
361 # if defined(__NetBSD__) && defined(__x86_64__)
362 #    define X86_64
363 #    define mach_type_known
364 # endif
365 # if defined(FREEBSD) && defined(__sparc__)
366 #    define SPARC
367 #    define mach_type_known
368 # endif
369 # if defined(bsdi) && (defined(i386) || defined(__i386__))
370 #    define I386
371 #    define BSDI
372 #    define mach_type_known
373 # endif
374 # if !defined(mach_type_known) && defined(__386BSD__)
375 #   define I386
376 #   define THREE86BSD
377 #   define mach_type_known
378 # endif
379 # if defined(_CX_UX) && defined(_M88K)
380 #   define M88K
381 #   define CX_UX
382 #   define mach_type_known
383 # endif
384 # if defined(DGUX) && defined(m88k)
385 #   define M88K
386     /* DGUX defined */
387 #   define mach_type_known
388 # endif
389 # if defined(_WIN32_WCE) || defined(__CEGCC__) || defined(__MINGW32CE__)
390     /* SH3, SH4, MIPS already defined for corresponding architectures */
391 #   if defined(SH3) || defined(SH4)
392 #     define SH
393 #   endif
394 #   if defined(x86) || defined(__i386__)
395 #     define I386
396 #   endif
397 #   if defined(_M_ARM) || defined(ARM) || defined(_ARM_)
398 #     define ARM32
399 #   endif
400 #   define MSWINCE
401 #   define mach_type_known
402 # else
403 #   if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \
404         || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
405 #     if defined(__LP64__) || defined(_WIN64)
406 #       define X86_64
407 #     else
408 #       define I386
409 #     endif
410 #     define MSWIN32    /* or Win64 */
411 #     define mach_type_known
412 #   endif
413 #   if defined(_MSC_VER) && defined(_M_IA64)
414 #     define IA64
415 #     define MSWIN32    /* Really win64, but we don't treat 64-bit      */
416                         /* variants as a different platform.            */
417 #   endif
418 # endif
419 # if defined(__DJGPP__)
420 #   define I386
421 #   ifndef DJGPP
422 #     define DJGPP  /* MSDOS running the DJGPP port of GCC */
423 #   endif
424 #   define mach_type_known
425 # endif
426 # if defined(__CYGWIN32__) || defined(__CYGWIN__)
427 #   define I386
428 #   define CYGWIN32
429 #   define mach_type_known
430 # endif
431 # if defined(__MINGW32__) && !defined(mach_type_known)
432 #   define I386
433 #   define MSWIN32
434 #   define mach_type_known
435 # endif
436 # if defined(__BORLANDC__)
437 #   define I386
438 #   define MSWIN32
439 #   define mach_type_known
440 # endif
441 # if defined(_UTS) && !defined(mach_type_known)
442 #   define S370
443 #   define UTS4
444 #   define mach_type_known
445 # endif
446 # if defined(__pj__)
447 #   error PicoJava no longer supported
448     /* The implementation had problems, and I haven't heard of users    */
449     /* in ages.  If you want it resurrected, let me know.               */
450 # endif
451 # if defined(__embedded__) && defined(PPC)
452 #   define POWERPC
453 #   define NOSYS
454 #   define mach_type_known
455 # endif
456 /* Ivan Demakov */
457 # if defined(__WATCOMC__) && defined(__386__)
458 #   define I386
459 #   if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW)
460 #     if defined(__OS2__)
461 #       define OS2
462 #     else
463 #       if defined(__WINDOWS_386__) || defined(__NT__)
464 #         define MSWIN32
465 #       else
466 #         define DOS4GW
467 #       endif
468 #     endif
469 #   endif
470 #   define mach_type_known
471 # endif
472 # if defined(__s390__) && defined(LINUX)
473 #    define S390
474 #    define mach_type_known
475 # endif
476 # if defined(__GNU__)
477 #   if defined(__i386__)
478 /* The Debian Hurd running on generic PC */
479 #     define  HURD
480 #     define  I386
481 #     define  mach_type_known
482 #    endif
483 # endif
484 # if defined(__TANDEM)
485     /* Nonstop S-series */
486     /* FIXME: Should recognize Integrity series? */
487 #   define MIPS
488 #   define NONSTOP
489 #   define mach_type_known
490 # endif
491
492 /* Feel free to add more clauses here */
493
494 /* Or manually define the machine type here.  A machine type is         */
495 /* characterized by the architecture.  Some                             */
496 /* machine types are further subdivided by OS.                          */
497 /* Macros such as LINUX, FREEBSD, etc. distinguish them.                */
498 /* SYSV on an M68K actually means A/UX.                                 */
499 /* The distinction in these cases is usually the stack starting address */
500 # ifndef mach_type_known
501 #   error "The collector has not been ported to this machine/OS combination."
502 # endif
503                     /* Mapping is: M68K       ==> Motorola 680X0        */
504                     /*             (NEXT, and SYSV (A/UX),              */
505                     /*             MACOS and AMIGA variants)            */
506                     /*             I386       ==> Intel 386             */
507                     /*              (SEQUENT, OS2, SCO, LINUX, NETBSD,  */
508                     /*               FREEBSD, THREE86BSD, MSWIN32,      */
509                     /*               BSDI,SOLARIS, NEXT, other variants)        */
510                     /*             NS32K      ==> Encore Multimax       */
511                     /*             MIPS       ==> R2000 through R14K    */
512                     /*                  (many variants)                 */
513                     /*             VAX        ==> DEC VAX               */
514                     /*                  (BSD, ULTRIX variants)          */
515                     /*             HP_PA      ==> HP9000/700 & /800     */
516                     /*                            HP/UX, LINUX          */
517                     /*             SPARC      ==> SPARC v7/v8/v9        */
518                     /*                  (SOLARIS, LINUX, DRSNX variants)        */
519                     /*             ALPHA      ==> DEC Alpha             */
520                     /*                  (OSF1 and LINUX variants)       */
521                     /*             M88K       ==> Motorola 88XX0        */
522                     /*                  (CX_UX and DGUX)                */
523                     /*             S370       ==> 370-like machine      */
524                     /*                  running Amdahl UTS4             */
525                     /*             S390       ==> 390-like machine      */
526                     /*                  running LINUX                   */
527                     /*             ARM32      ==> Intel StrongARM       */
528                     /*             IA64       ==> Intel IPF             */
529                     /*                            (e.g. Itanium)        */
530                     /*                  (LINUX and HPUX)                */
531                     /*             SH         ==> Hitachi SuperH        */
532                     /*                  (LINUX & MSWINCE)               */
533                     /*             X86_64     ==> AMD x86-64            */
534                     /*             POWERPC    ==> IBM/Apple PowerPC     */
535                     /*                  (MACOS(<=9),DARWIN(incl.MACOSX),*/
536                     /*                   LINUX, NETBSD, AIX, NOSYS      */
537                     /*                   variants)                      */
538                     /*                  Handles 32 and 64-bit variants. */
539                     /*             CRIS       ==> Axis Etrax            */
540                     /*             M32R       ==> Renesas M32R          */
541
542
543 /*
544  * For each architecture and OS, the following need to be defined:
545  *
546  * CPP_WORDSZ is a simple integer constant representing the word size.
547  * in bits.  We assume byte addressability, where a byte has 8 bits.
548  * We also assume CPP_WORDSZ is either 32 or 64.
549  * (We care about the length of pointers, not hardware
550  * bus widths.  Thus a 64 bit processor with a C compiler that uses
551  * 32 bit pointers should use CPP_WORDSZ of 32, not 64. Default is 32.)
552  *
553  * MACH_TYPE is a string representation of the machine type.
554  * OS_TYPE is analogous for the OS.
555  *
556  * ALIGNMENT is the largest N, such that
557  * all pointer are guaranteed to be aligned on N byte boundaries.
558  * defining it to be 1 will always work, but perform poorly.
559  *
560  * DATASTART is the beginning of the data segment.
561  * On some platforms SEARCH_FOR_DATA_START is defined.
562  * SEARCH_FOR_DATASTART will cause GC_data_start to
563  * be set to an address determined by accessing data backwards from _end
564  * until an unmapped page is found.  DATASTART will be defined to be
565  * GC_data_start.
566  * On UNIX-like systems, the collector will scan the area between DATASTART
567  * and DATAEND for root pointers.
568  *
569  * DATAEND, if not `end' where `end' is defined as ``extern int end[];''.
570  * RTH suggests gaining access to linker script synth'd values with
571  * this idiom instead of `&end' where `end' is defined as ``extern int end;'' .
572  * Otherwise, ``GCC will assume these are in .sdata/.sbss'' and it will, e.g.,
573  * cause failures on alpha*-*-* with ``-msmall-data or -fpic'' or mips-*-*
574  * without any special options.
575  *
576  * STACKBOTTOM is the cool end of the stack, which is usually the
577  * highest address in the stack.
578  * Under PCR or OS/2, we have other ways of finding thread stacks.
579  * For each machine, the following should:
580  * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
581  * 2) define exactly one of
582  *      STACKBOTTOM (should be defined to be an expression)
583  *      LINUX_STACKBOTTOM
584  *      HEURISTIC1
585  *      HEURISTIC2
586  * If STACKBOTTOM is defined, then it's value will be used directly as the
587  * stack base.  If LINUX_STACKBOTTOM is defined, then it will be determined
588  * with a method appropriate for most Linux systems.  Currently we look
589  * first for __libc_stack_end (currently only id USE_LIBC_PRIVATES is
590  * defined), and if that fails read it from /proc.  (If USE_LIBC_PRIVATES
591  * is not defined and NO_PROC_STAT is defined, we revert to HEURISTIC2.)
592  * If either of the last two macros are defined, then STACKBOTTOM is computed
593  * during collector startup using one of the following two heuristics:
594  * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to
595  *              the next multiple of STACK_GRAN.
596  * HEURISTIC2:  Take an address inside GC_init's frame, increment it repeatedly
597  *              in small steps (decrement if STACK_GROWS_UP), and read the value
598  *              at each location.  Remember the value when the first
599  *              Segmentation violation or Bus error is signaled.  Round that
600  *              to the nearest plausible page boundary, and use that instead
601  *              of STACKBOTTOM.
602  *
603  * Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines,
604  * the value of environ is a pointer that can serve as STACKBOTTOM.
605  * I expect that HEURISTIC2 can be replaced by this approach, which
606  * interferes far less with debugging.  However it has the disadvantage
607  * that it's confused by a putenv call before the collector is initialized.
608  * This could be dealt with by intercepting putenv ...
609  *
610  * If no expression for STACKBOTTOM can be found, and neither of the above
611  * heuristics are usable, the collector can still be used with all of the above
612  * undefined, provided one of the following is done:
613  * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s)
614  *    without reference to STACKBOTTOM.  This is appropriate for use in
615  *    conjunction with thread packages, since there will be multiple stacks.
616  *    (Allocating thread stacks in the heap, and treating them as ordinary
617  *    heap data objects is also possible as a last resort.  However, this is
618  *    likely to introduce significant amounts of excess storage retention
619  *    unless the dead parts of the thread stacks are periodically cleared.)
620  * 2) Client code may set GC_stackbottom before calling any GC_ routines.
621  *    If the author of the client code controls the main program, this is
622  *    easily accomplished by introducing a new main program, setting
623  *    GC_stackbottom to the address of a local variable, and then calling
624  *    the original main program.  The new main program would read something
625  *    like (provided real_main() is not inlined by the compiler):
626  *
627  *              # include "gc_private.h"
628  *
629  *              main(argc, argv, envp)
630  *              int argc;
631  *              char **argv, **envp;
632  *              {
633  *                  int dummy;
634  *
635  *                  GC_stackbottom = (ptr_t)(&dummy);
636  *                  return(real_main(argc, argv, envp));
637  *              }
638  *
639  *
640  * Each architecture may also define the style of virtual dirty bit
641  * implementation to be used:
642  *   MPROTECT_VDB: Write protect the heap and catch faults.
643  *   GWW_VDB: Use win32 GetWriteWatch primitive.
644  *   PROC_VDB: Use the SVR4 /proc primitives to read dirty bits.
645  *
646  * The first and second one may be combined, in which case a runtime
647  * selection will be made, based on GetWriteWatch availability.
648  *
649  * An architecture may define DYNAMIC_LOADING if dynamic_load.c
650  * defined GC_register_dynamic_libraries() for the architecture.
651  *
652  * An architecture may define PREFETCH(x) to preload the cache with *x.
653  * This defaults to a no-op.
654  *
655  * PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
656  *
657  * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
658  * clear the two words at GC_malloc-aligned address x.  By default,
659  * word stores of 0 are used instead.
660  *
661  * HEAP_START may be defined as the initial address hint for mmap-based
662  * allocation.
663  */
664
665 /* If we are using a recent version of gcc, we can use __builtin_unwind_init()
666  * to push the relevant registers onto the stack.
667  */
668 # if defined(__GNUC__) && ((__GNUC__ >= 3) || \
669                            (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \
670                        && !defined(__INTEL_COMPILER) && !defined(__PATHCC__)
671 #   define HAVE_BUILTIN_UNWIND_INIT
672 # endif
673
674 # define STACK_GRAN 0x1000000
675 # ifdef M68K
676 #   define MACH_TYPE "M68K"
677 #   define ALIGNMENT 2
678 #   ifdef OPENBSD
679         /* FIXME: Should we remove this case? */
680 #       define OS_TYPE "OPENBSD"
681 #       define HEURISTIC2
682 #       ifdef __ELF__
683 #         define DATASTART GC_data_start
684 #         define DYNAMIC_LOADING
685 #       else
686           extern char etext[];
687 #         define DATASTART ((ptr_t)(etext))
688 #       endif
689 #   endif
690 #   ifdef NETBSD
691 #       define OS_TYPE "NETBSD"
692 #       define HEURISTIC2
693 #       ifdef __ELF__
694 #         define DATASTART GC_data_start
695 #         define DYNAMIC_LOADING
696 #       else
697           extern char etext[];
698 #         define DATASTART ((ptr_t)(etext))
699 #       endif
700 #   endif
701 #   ifdef LINUX
702 #       define OS_TYPE "LINUX"
703 #       define LINUX_STACKBOTTOM
704 #       define MPROTECT_VDB
705 #       ifdef __ELF__
706 #            define DYNAMIC_LOADING
707 #            include <features.h>
708 #            if defined(__GLIBC__)&& __GLIBC__>=2
709 #              define SEARCH_FOR_DATA_START
710 #            else /* !GLIBC2 */
711                extern char **__environ;
712 #              define DATASTART ((ptr_t)(&__environ))
713                              /* hideous kludge: __environ is the first */
714                              /* word in crt0.o, and delimits the start */
715                              /* of the data segment, no matter which   */
716                              /* ld options were passed through.        */
717                              /* We could use _etext instead, but that  */
718                              /* would include .rodata, which may       */
719                              /* contain large read-only data tables    */
720                              /* that we'd rather not scan.             */
721 #            endif /* !GLIBC2 */
722              extern int _end[];
723 #            define DATAEND (ptr_t)(_end)
724 #       else
725              extern int etext[];
726 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
727 #       endif
728 #   endif
729 #   ifdef AMIGA
730 #       define OS_TYPE "AMIGA"
731                 /* STACKBOTTOM and DATASTART handled specially  */
732                 /* in os_dep.c                                  */
733 #       define DATAEND  /* not needed */
734 #       define GETPAGESIZE() 4096
735 #   endif
736 #   ifdef MACOS
737 #     ifndef __LOWMEM__
738 #     include <LowMem.h>
739 #     endif
740 #     define OS_TYPE "MACOS"
741                         /* see os_dep.c for details of global data segments. */
742 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
743 #     define DATAEND    /* not needed */
744 #     define GETPAGESIZE() 4096
745 #   endif
746 #   ifdef NEXT
747 #       define OS_TYPE "NEXT"
748 #       define DATASTART ((ptr_t) get_etext())
749 #       define STACKBOTTOM ((ptr_t) 0x4000000)
750 #       define DATAEND  /* not needed */
751 #   endif
752 # endif
753
754 # if defined(POWERPC)
755 #   define MACH_TYPE "POWERPC"
756 #   ifdef MACOS
757 #     define ALIGNMENT 2  /* Still necessary?  Could it be 4?   */
758 #     ifndef __LOWMEM__
759 #     include <LowMem.h>
760 #     endif
761 #     define OS_TYPE "MACOS"
762                         /* see os_dep.c for details of global data segments. */
763 #     define STACKBOTTOM ((ptr_t) LMGetCurStackBase())
764 #     define DATAEND  /* not needed */
765 #   endif
766 #   ifdef LINUX
767 #     if defined(__powerpc64__)
768 #       define ALIGNMENT 8
769 #       define CPP_WORDSZ 64
770 #       ifndef HBLKSIZE
771 #         define HBLKSIZE 4096
772 #       endif
773 #     else
774 #       define ALIGNMENT 4
775 #     endif
776 #     define OS_TYPE "LINUX"
777       /* HEURISTIC1 has been reliably reported to fail for a 32-bit     */
778       /* executable on a 64 bit kernel.                                 */
779 #     define LINUX_STACKBOTTOM
780 #     define DYNAMIC_LOADING
781 #     define SEARCH_FOR_DATA_START
782       extern int _end[];
783 #     define DATAEND (ptr_t)(_end)
784 #   endif
785 #   ifdef DARWIN
786 #     define OS_TYPE "DARWIN"
787 #     define DYNAMIC_LOADING
788 #     if defined(__ppc64__)
789 #       define ALIGNMENT 8
790 #       define CPP_WORDSZ 64
791 #       define STACKBOTTOM ((ptr_t) 0x7fff5fc00000)
792 #       define CACHE_LINE_SIZE 64
793 #       ifndef HBLKSIZE
794 #         define HBLKSIZE 4096
795 #       endif
796 #     else
797 #       define ALIGNMENT 4
798 #       define STACKBOTTOM ((ptr_t) 0xc0000000)
799 #     endif
800       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
801          These aren't used when dyld support is enabled (it is by default) */
802 #     define DATASTART ((ptr_t) get_etext())
803 #     define DATAEND    ((ptr_t) get_end())
804 #     ifndef USE_MMAP
805 #       define USE_MMAP
806 #     endif
807 #     define USE_MMAP_ANON
808 #     ifdef GC_DARWIN_THREADS
809 #       define MPROTECT_VDB
810 #     endif
811 #     include <unistd.h>
812 #     define GETPAGESIZE() getpagesize()
813 #     if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
814         /* The performance impact of prefetches is untested */
815 #       define PREFETCH(x) \
816           __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
817 #       define PREFETCH_FOR_WRITE(x) \
818           __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
819 #     endif
820       /* There seems to be some issues with trylock hanging on darwin. This
821          should be looked into some more */
822 #     define NO_PTHREAD_TRYLOCK
823 #   endif
824 #   ifdef OPENBSD
825 #     define OS_TYPE "OPENBSD"
826 #     define ALIGNMENT 4
827 #     ifdef GC_OPENBSD_THREADS
828 #      define UTHREAD_SP_OFFSET 268
829 #     else
830 #       include <sys/param.h>
831 #       include <uvm/uvm_extern.h>
832 #       define STACKBOTTOM USRSTACK
833 #     endif
834       extern int __data_start[];
835 #     define DATASTART ((ptr_t)__data_start)
836       extern char _end[];
837 #     define DATAEND ((ptr_t)(&_end))
838 #     define DYNAMIC_LOADING
839 #   endif
840 #   ifdef FREEBSD
841 #       define ALIGNMENT 4
842 #       define OS_TYPE "FREEBSD"
843 #       ifndef GC_FREEBSD_THREADS
844 #           define MPROTECT_VDB
845 #       endif
846 #       define SIG_SUSPEND SIGUSR1
847 #       define SIG_THR_RESTART SIGUSR2
848 #       define FREEBSD_STACKBOTTOM
849 #       ifdef __ELF__
850 #           define DYNAMIC_LOADING
851 #       endif
852         extern char etext[];
853         ptr_t GC_FreeBSDGetDataStart(size_t max_page_size, ptr_t etext_addr);
854 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
855 #   endif
856 #   ifdef NETBSD
857 #     define ALIGNMENT 4
858 #     define OS_TYPE "NETBSD"
859 #     define HEURISTIC2
860       extern char etext[];
861 #     define DATASTART GC_data_start
862 #     define DYNAMIC_LOADING
863 #   endif
864 #   ifdef AIX
865 #     define OS_TYPE "AIX"
866 #     undef ALIGNMENT /* in case it's defined   */
867 #     ifdef IA64
868 #       undef IA64
869           /* DOB: some AIX installs stupidly define IA64 in */
870           /* /usr/include/sys/systemcfg.h                   */
871 #     endif
872 #     ifdef __64BIT__
873 #       define ALIGNMENT 8
874 #       define CPP_WORDSZ 64
875 #       define STACKBOTTOM ((ptr_t)0x1000000000000000)
876 #     else
877 #       define ALIGNMENT 4
878 #       define CPP_WORDSZ 32
879 #       define STACKBOTTOM ((ptr_t)((ulong)&errno))
880 #     endif
881 #     ifndef USE_MMAP
882 #       define USE_MMAP
883 #     endif
884 #     define USE_MMAP_ANON
885         /* From AIX linker man page:
886         _text Specifies the first location of the program.
887         _etext Specifies the first location after the program.
888         _data Specifies the first location of the data.
889         _edata Specifies the first location after the initialized data
890         _end or end Specifies the first location after all data.
891         */
892       extern int _data[], _end[];
893 #     define DATASTART ((ptr_t)((ulong)_data))
894 #     define DATAEND ((ptr_t)((ulong)_end))
895       extern int errno;
896 #     define DYNAMIC_LOADING
897         /* For really old versions of AIX, this may have to be removed. */
898 #   endif
899
900 #   ifdef NOSYS
901 #     define ALIGNMENT 4
902 #     define OS_TYPE "NOSYS"
903       extern void __end[], __dso_handle[];
904 #     define DATASTART (__dso_handle)  /* OK, that's ugly.  */
905 #     define DATAEND (ptr_t)(__end)
906         /* Stack starts at 0xE0000000 for the simulator.  */
907 #     undef STACK_GRAN
908 #     define STACK_GRAN 0x10000000
909 #     define HEURISTIC1
910 #   endif
911 # endif
912
913 # ifdef VAX
914 #   define MACH_TYPE "VAX"
915 #   define ALIGNMENT 4  /* Pointers are longword aligned by 4.2 C compiler */
916     extern char etext[];
917 #   define DATASTART ((ptr_t)(etext))
918 #   ifdef BSD
919 #       define OS_TYPE "BSD"
920 #       define HEURISTIC1
921                         /* HEURISTIC2 may be OK, but it's hard to test. */
922 #   endif
923 #   ifdef ULTRIX
924 #       define OS_TYPE "ULTRIX"
925 #       define STACKBOTTOM ((ptr_t) 0x7fffc800)
926 #   endif
927 # endif
928
929 # ifdef SPARC
930 #   define MACH_TYPE "SPARC"
931 #   if defined(__arch64__) || defined(__sparcv9)
932 #     define ALIGNMENT 8
933 #     define CPP_WORDSZ 64
934 #     define ELF_CLASS ELFCLASS64
935 #   else
936 #     define ALIGNMENT 4        /* Required by hardware */
937 #     define CPP_WORDSZ 32
938 #   endif
939     /* Don't define USE_ASM_PUSH_REGS.  We do use an asm helper, but    */
940     /* not to push the registers on the mark stack.                     */
941 #   ifdef SOLARIS
942 #       define OS_TYPE "SOLARIS"
943         extern int _etext[];
944         extern int _end[];
945         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
946 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
947 #       define DATAEND (ptr_t)(_end)
948 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
949 #         define USE_MMAP
950             /* Otherwise we now use calloc.  Mmap may result in the     */
951             /* heap interleaved with thread stacks, which can result in */
952             /* excessive blacklisting.  Sbrk is unusable since it       */
953             /* doesn't interact correctly with the system malloc.       */
954 #       endif
955 #       ifdef USE_MMAP
956 #         define HEAP_START (ptr_t)0x40000000
957 #       else
958 #         define HEAP_START DATAEND
959 #       endif
960 #       define PROC_VDB
961 /*      HEURISTIC1 reportedly no longer works under 2.7.                */
962 /*      HEURISTIC2 probably works, but this appears to be preferable.   */
963 /*      Apparently USRSTACK is defined to be USERLIMIT, but in some     */
964 /*      installations that's undefined.  We work around this with a     */
965 /*      gross hack:                                                     */
966 #       include <sys/vmparam.h>
967 #       ifdef USERLIMIT
968           /* This should work everywhere, but doesn't.  */
969 #         define STACKBOTTOM ((ptr_t) USRSTACK)
970 #       else
971 #         define HEURISTIC2
972 #       endif
973 #       include <unistd.h>
974 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
975                 /* getpagesize() appeared to be missing from at least one */
976                 /* Solaris 5.4 installation.  Weird.                      */
977 #       define DYNAMIC_LOADING
978 #   endif
979 #   ifdef DRSNX
980 #       define OS_TYPE "DRSNX"
981         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
982         extern int etext[];
983 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
984 #       define MPROTECT_VDB
985 #       define STACKBOTTOM ((ptr_t) 0xdfff0000)
986 #       define DYNAMIC_LOADING
987 #   endif
988 #   ifdef LINUX
989 #     define OS_TYPE "LINUX"
990 #     ifdef __ELF__
991 #       define DYNAMIC_LOADING
992 #     else
993           Linux Sparc/a.out not supported
994 #     endif
995       extern int _end[];
996       extern int _etext[];
997 #     define DATAEND (ptr_t)(_end)
998 #     define SVR4
999       ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1000 #     ifdef __arch64__
1001 #       define DATASTART GC_SysVGetDataStart(0x100000, (ptr_t)_etext)
1002 #     else
1003 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1004 #     endif
1005 #     define LINUX_STACKBOTTOM
1006 #   endif
1007 #   ifdef OPENBSD
1008 #     define OS_TYPE "OPENBSD"
1009 #     ifdef GC_OPENBSD_THREADS
1010 #      define UTHREAD_SP_OFFSET 232
1011 #     else
1012 #       include <sys/param.h>
1013 #       include <uvm/uvm_extern.h>
1014 #       define STACKBOTTOM USRSTACK
1015 #     endif
1016       extern int __data_start[];
1017 #     define DATASTART ((ptr_t)__data_start)
1018       extern char _end[];
1019 #     define DATAEND ((ptr_t)(&_end))
1020 #     define DYNAMIC_LOADING
1021 #   endif
1022 #   ifdef NETBSD
1023 #     define OS_TYPE "NETBSD"
1024 #     define HEURISTIC2
1025 #     ifdef __ELF__
1026 #       define DATASTART GC_data_start
1027 #       define DYNAMIC_LOADING
1028 #     else
1029         extern char etext[];
1030 #       define DATASTART ((ptr_t)(etext))
1031 #     endif
1032 #   endif
1033 #   ifdef FREEBSD
1034 #       define OS_TYPE "FREEBSD"
1035 #       define SIG_SUSPEND SIGUSR1
1036 #       define SIG_THR_RESTART SIGUSR2
1037 #       define FREEBSD_STACKBOTTOM
1038 #       ifdef __ELF__
1039 #           define DYNAMIC_LOADING
1040 #       endif
1041         extern char etext[];
1042         extern char edata[];
1043         extern char end[];
1044 #       define NEED_FIND_LIMIT
1045 #       define DATASTART ((ptr_t)(&etext))
1046 #       define DATAEND (GC_find_limit (DATASTART, TRUE))
1047 #       define DATASTART2 ((ptr_t)(&edata))
1048 #       define DATAEND2 ((ptr_t)(&end))
1049 #   endif
1050 # endif
1051
1052 # ifdef I386
1053 #   define MACH_TYPE "I386"
1054 #   if defined(__LP64__) || defined(_WIN64)
1055 #     error This should be handled as X86_64
1056 #   else
1057 #     define CPP_WORDSZ 32
1058 #     define ALIGNMENT 4
1059                         /* Appears to hold for all "32 bit" compilers   */
1060                         /* except Borland.  The -a4 option fixes        */
1061                         /* Borland.                                     */
1062                         /* Ivan Demakov: For Watcom the option is -zp4. */
1063 #   endif
1064 #   ifdef SEQUENT
1065 #       define OS_TYPE "SEQUENT"
1066         extern int etext[];
1067 #       define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1068 #       define STACKBOTTOM ((ptr_t) 0x3ffff000)
1069 #   endif
1070 #   ifdef BEOS
1071 #     define OS_TYPE "BEOS"
1072 #     include <OS.h>
1073 #     define GETPAGESIZE() B_PAGE_SIZE
1074       extern int etext[];
1075 #     define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1076 #   endif
1077 #   ifdef SOLARIS
1078 #       define OS_TYPE "SOLARIS"
1079         extern int _etext[], _end[];
1080         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1081 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
1082 #       define DATAEND (ptr_t)(_end)
1083 /*      # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,      */
1084 /*      but reportedly breaks under 2.8.  It appears that the stack     */
1085 /*      base is a property of the executable, so this should not break  */
1086 /*      old executables.                                                */
1087 /*      HEURISTIC2 probably works, but this appears to be preferable.   */
1088 #       include <sys/vm.h>
1089 #       define STACKBOTTOM ((ptr_t) USRSTACK)
1090 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
1091 /* It appears to be fixed in 2.8 and 2.9.                               */
1092 #       ifdef SOLARIS25_PROC_VDB_BUG_FIXED
1093 #         define PROC_VDB
1094 #       endif
1095 #       define DYNAMIC_LOADING
1096 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1097 #         define USE_MMAP
1098             /* Otherwise we now use calloc.  Mmap may result in the     */
1099             /* heap interleaved with thread stacks, which can result in */
1100             /* excessive blacklisting.  Sbrk is unusable since it       */
1101             /* doesn't interact correctly with the system malloc.       */
1102 #       endif
1103 #       ifdef USE_MMAP
1104 #         define HEAP_START (ptr_t)0x40000000
1105 #       else
1106 #         define HEAP_START DATAEND
1107 #       endif
1108 #   endif
1109 #   ifdef SCO
1110 #       define OS_TYPE "SCO"
1111         extern int etext[];
1112 #       define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \
1113                                   & ~0x3fffff) \
1114                                  +((word)etext & 0xfff))
1115 #       define STACKBOTTOM ((ptr_t) 0x7ffffffc)
1116 #   endif
1117 #   ifdef SCO_ELF
1118 #       define OS_TYPE "SCO_ELF"
1119         extern int etext[];
1120 #       define DATASTART ((ptr_t)(etext))
1121 #       define STACKBOTTOM ((ptr_t) 0x08048000)
1122 #       define DYNAMIC_LOADING
1123 #       define ELF_CLASS ELFCLASS32
1124 #   endif
1125 #   ifdef DGUX
1126 #       define OS_TYPE "DGUX"
1127         extern int _etext, _end;
1128         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1129 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)(&_etext))
1130 #       define DATAEND (ptr_t)(&_end)
1131 #       define STACK_GROWS_DOWN
1132 #       define HEURISTIC2
1133 #       include <unistd.h>
1134 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
1135 #       define DYNAMIC_LOADING
1136 #       ifndef USE_MMAP
1137 #         define USE_MMAP
1138 #       endif
1139 #       define MAP_FAILED (void *) ((word)-1)
1140 #       ifdef USE_MMAP
1141 #         define HEAP_START (ptr_t)0x40000000
1142 #       else /* USE_MMAP */
1143 #         define HEAP_START DATAEND
1144 #       endif /* USE_MMAP */
1145 #   endif /* DGUX */
1146
1147 #   ifdef LINUX
1148 #       define OS_TYPE "LINUX"
1149 #       define LINUX_STACKBOTTOM
1150 #       if 0
1151 #         define HEURISTIC1
1152 #         undef STACK_GRAN
1153 #         define STACK_GRAN 0x10000000
1154           /* STACKBOTTOM is usually 0xc0000000, but this changes with   */
1155           /* different kernel configurations.  In particular, systems   */
1156           /* with 2GB physical memory will usually move the user        */
1157           /* address space limit, and hence initial SP to 0x80000000.   */
1158 #       endif
1159 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
1160 #           define MPROTECT_VDB
1161 #       else
1162             /* We seem to get random errors in incremental mode,        */
1163             /* possibly because Linux threads is itself a malloc client */
1164             /* and can't deal with the signals.                         */
1165 #       endif
1166 #       define HEAP_START (ptr_t)0x1000
1167                 /* This encourages mmap to give us low addresses,       */
1168                 /* thus allowing the heap to grow to ~3GB               */
1169 #       ifdef __ELF__
1170 #            define DYNAMIC_LOADING
1171 #            ifdef UNDEFINED    /* includes ro data */
1172                extern int _etext[];
1173 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
1174 #            endif
1175 #            include <features.h>
1176 #            if defined(__GLIBC__) && __GLIBC__ >= 2
1177 #                define SEARCH_FOR_DATA_START
1178 #            else
1179                  extern char **__environ;
1180 #                define DATASTART ((ptr_t)(&__environ))
1181                               /* hideous kludge: __environ is the first */
1182                               /* word in crt0.o, and delimits the start */
1183                               /* of the data segment, no matter which   */
1184                               /* ld options were passed through.        */
1185                               /* We could use _etext instead, but that  */
1186                               /* would include .rodata, which may       */
1187                               /* contain large read-only data tables    */
1188                               /* that we'd rather not scan.             */
1189 #            endif
1190              extern int _end[];
1191 #            define DATAEND (ptr_t)(_end)
1192 #       else
1193              extern int etext[];
1194 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1195 #       endif
1196 #       ifdef USE_I686_PREFETCH
1197           /* FIXME: Thus should use __builtin_prefetch, but we'll leave that    */
1198           /* for the next rtelease.                                             */
1199 #         define PREFETCH(x) \
1200             __asm__ __volatile__ ("     prefetchnta     %0": : "m"(*(char *)(x)))
1201             /* Empirically prefetcht0 is much more effective at reducing        */
1202             /* cache miss stalls for the targeted load instructions.  But it    */
1203             /* seems to interfere enough with other cache traffic that the net  */
1204             /* result is worse than prefetchnta.                                */
1205 #         if 0
1206             /* Using prefetches for write seems to have a slight negative       */
1207             /* impact on performance, at least for a PIII/500.                  */
1208 #           define PREFETCH_FOR_WRITE(x) \
1209               __asm__ __volatile__ ("   prefetcht0      %0": : "m"(*(char *)(x)))
1210 #         endif
1211 #       endif
1212 #       ifdef USE_3DNOW_PREFETCH
1213 #         define PREFETCH(x) \
1214             __asm__ __volatile__ ("     prefetch        %0": : "m"(*(char *)(x)))
1215 #         define PREFETCH_FOR_WRITE(x) \
1216             __asm__ __volatile__ ("     prefetchw       %0": : "m"(*(char *)(x)))
1217 #       endif
1218 #   endif
1219 #   ifdef CYGWIN32
1220 #       define OS_TYPE "CYGWIN32"
1221 #       define DATASTART ((ptr_t)GC_DATASTART)  /* From gc.h */
1222 #       define DATAEND   ((ptr_t)GC_DATAEND)
1223 #       undef STACK_GRAN
1224 #       define STACK_GRAN 0x10000
1225 #       define HEURISTIC1
1226 #       ifdef USE_MMAP
1227 #         define NEED_FIND_LIMIT
1228 #         define USE_MMAP_ANON
1229 #       endif
1230 #   endif
1231 #   ifdef OS2
1232 #       define OS_TYPE "OS2"
1233                 /* STACKBOTTOM and DATASTART are handled specially in   */
1234                 /* os_dep.c. OS2 actually has the right                 */
1235                 /* system call!                                         */
1236 #       define DATAEND  /* not needed */
1237 #   endif
1238 #   ifdef MSWIN32
1239 #       define OS_TYPE "MSWIN32"
1240                 /* STACKBOTTOM and DATASTART are handled specially in   */
1241                 /* os_dep.c.                                            */
1242 #       define MPROTECT_VDB
1243 #       define GWW_VDB
1244 #       define DATAEND  /* not needed */
1245 #   endif
1246 #   ifdef MSWINCE
1247 #       define OS_TYPE "MSWINCE"
1248 #       define DATAEND  /* not needed */
1249 #   endif
1250 #   ifdef DJGPP
1251 #       define OS_TYPE "DJGPP"
1252 #       include "stubinfo.h"
1253         extern int etext[];
1254         extern int _stklen;
1255         extern int __djgpp_stack_limit;
1256 #       define DATASTART ((ptr_t)((((word) (etext)) + 0x1ff) & ~0x1ff))
1257 /* #       define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \
1258                                                      + _stklen)) */
1259 #       define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen))
1260                 /* This may not be right.  */
1261 #   endif
1262 #   ifdef OPENBSD
1263 #       define OS_TYPE "OPENBSD"
1264 #       ifdef GC_OPENBSD_THREADS
1265 #         define UTHREAD_SP_OFFSET 176
1266 #       else
1267 #         include <sys/param.h>
1268 #         include <uvm/uvm_extern.h>
1269 #         define STACKBOTTOM USRSTACK
1270 #       endif
1271         extern int __data_start[];
1272 #       define DATASTART ((ptr_t)__data_start)
1273         extern char _end[];
1274 #       define DATAEND ((ptr_t)(&_end))
1275 #       define DYNAMIC_LOADING
1276 #   endif
1277 #   ifdef FREEBSD
1278 #       define OS_TYPE "FREEBSD"
1279 #       ifndef GC_FREEBSD_THREADS
1280 #           define MPROTECT_VDB
1281 #       endif
1282 #       ifdef __GLIBC__
1283 #           define SIG_SUSPEND          (32+6)
1284 #           define SIG_THR_RESTART      (32+5)
1285             extern int _end[];
1286 #           define DATAEND (ptr_t)(_end)
1287 #       else
1288 #           define SIG_SUSPEND SIGUSR1
1289 #           define SIG_THR_RESTART SIGUSR2
1290 #       endif
1291 #       define FREEBSD_STACKBOTTOM
1292 #       ifdef __ELF__
1293 #           define DYNAMIC_LOADING
1294 #       endif
1295         extern char etext[];
1296         char * GC_FreeBSDGetDataStart(size_t, ptr_t);
1297 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1298 #   endif
1299 #   ifdef NETBSD
1300 #       define OS_TYPE "NETBSD"
1301 #       ifdef __ELF__
1302 #           define DYNAMIC_LOADING
1303 #       endif
1304 #   endif
1305 #   ifdef THREE86BSD
1306 #       define OS_TYPE "THREE86BSD"
1307 #   endif
1308 #   ifdef BSDI
1309 #       define OS_TYPE "BSDI"
1310 #   endif
1311 #   if defined(NETBSD) || defined(THREE86BSD) || defined(BSDI)
1312 #       define HEURISTIC2
1313         extern char etext[];
1314 #       define DATASTART ((ptr_t)(etext))
1315 #   endif
1316 #   ifdef NEXT
1317 #       define OS_TYPE "NEXT"
1318 #       define DATASTART ((ptr_t) get_etext())
1319 #       define STACKBOTTOM ((ptr_t)0xc0000000)
1320 #       define DATAEND  /* not needed */
1321 #   endif
1322 #   ifdef DOS4GW
1323 #     define OS_TYPE "DOS4GW"
1324       extern long __nullarea;
1325       extern char _end;
1326       extern char *_STACKTOP;
1327       /* Depending on calling conventions Watcom C either precedes
1328          or does not precedes with underscore names of C-variables.
1329          Make sure startup code variables always have the same names.  */
1330       #pragma aux __nullarea "*";
1331       #pragma aux _end "*";
1332 #     define STACKBOTTOM ((ptr_t) _STACKTOP)
1333                          /* confused? me too. */
1334 #     define DATASTART ((ptr_t) &__nullarea)
1335 #     define DATAEND ((ptr_t) &_end)
1336 #   endif
1337 #   ifdef HURD
1338 #     define OS_TYPE "HURD"
1339 #     define STACK_GROWS_DOWN
1340 #     define HEURISTIC2
1341 #     define SIG_SUSPEND SIGUSR1
1342 #     define SIG_THR_RESTART SIGUSR2
1343 #     define SEARCH_FOR_DATA_START
1344       extern int _end[];
1345 #     define DATAEND ((ptr_t) (_end))
1346 /* #     define MPROTECT_VDB  Not quite working yet? */
1347 #     define DYNAMIC_LOADING
1348 #   endif
1349 #   ifdef DARWIN
1350 #     define OS_TYPE "DARWIN"
1351 #     define DARWIN_DONT_PARSE_STACK
1352 #     define DYNAMIC_LOADING
1353       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
1354          These aren't used when dyld support is enabled (it is by default) */
1355 #     define DATASTART ((ptr_t) get_etext())
1356 #     define DATAEND    ((ptr_t) get_end())
1357 #     define STACKBOTTOM ((ptr_t) 0xc0000000)
1358 #     ifndef USE_MMAP
1359 #       define USE_MMAP
1360 #     endif
1361 #     define USE_MMAP_ANON
1362 #     ifdef GC_DARWIN_THREADS
1363 #       define MPROTECT_VDB
1364 #     endif
1365 #     include <unistd.h>
1366 #     define GETPAGESIZE() getpagesize()
1367       /* There seems to be some issues with trylock hanging on darwin. This
1368          should be looked into some more */
1369 #      define NO_PTHREAD_TRYLOCK
1370 #   endif /* DARWIN */
1371 # endif
1372
1373 # ifdef NS32K
1374 #   define MACH_TYPE "NS32K"
1375 #   define ALIGNMENT 4
1376     extern char **environ;
1377 #   define DATASTART ((ptr_t)(&environ))
1378                               /* hideous kludge: environ is the first   */
1379                               /* word in crt0.o, and delimits the start */
1380                               /* of the data segment, no matter which   */
1381                               /* ld options were passed through.        */
1382 #   define STACKBOTTOM ((ptr_t) 0xfffff000) /* for Encore */
1383 # endif
1384
1385 # ifdef MIPS
1386 #   define MACH_TYPE "MIPS"
1387 #   ifdef LINUX
1388 #     define OS_TYPE "LINUX"
1389 #     define DYNAMIC_LOADING
1390       extern int _end[];
1391 #     define DATAEND (ptr_t)(_end)
1392       extern int __data_start[];
1393 #     define DATASTART ((ptr_t)(__data_start))
1394 #     define CPP_WORDSZ _MIPS_SZPTR
1395 #     define ALIGNMENT (_MIPS_SZPTR/8)
1396 #     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
1397 #       define LINUX_STACKBOTTOM
1398 #     else
1399 #       define STACKBOTTOM ((ptr_t)0x7fff8000)
1400 #     endif
1401 #   endif /* Linux */
1402 #   ifdef EWS4800
1403 #      define HEURISTIC2
1404 #      if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
1405          extern int _fdata[], _end[];
1406 #        define DATASTART ((ptr_t)_fdata)
1407 #        define DATAEND ((ptr_t)_end)
1408 #        define CPP_WORDSZ _MIPS_SZPTR
1409 #        define ALIGNMENT (_MIPS_SZPTR/8)
1410 #      else
1411          extern int etext[], edata[], end[];
1412          extern int _DYNAMIC_LINKING[], _gp[];
1413 #        define DATASTART ((ptr_t)((((word)etext + 0x3ffff) & ~0x3ffff) \
1414                + ((word)etext & 0xffff)))
1415 #        define DATAEND (ptr_t)(edata)
1416 #        define DATASTART2 (_DYNAMIC_LINKING \
1417                ? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
1418                : (ptr_t)edata)
1419 #        define DATAEND2 (ptr_t)(end)
1420 #        define ALIGNMENT 4
1421 #      endif
1422 #      define OS_TYPE "EWS4800"
1423 #   endif
1424 #   ifdef ULTRIX
1425 #       define HEURISTIC2
1426 #       define DATASTART (ptr_t)0x10000000
1427                               /* Could probably be slightly higher since */
1428                               /* startup code allocates lots of stuff.   */
1429 #       define OS_TYPE "ULTRIX"
1430 #       define ALIGNMENT 4
1431 #   endif
1432 #   ifdef IRIX5
1433 #       define HEURISTIC2
1434         extern int _fdata[];
1435 #       define DATASTART ((ptr_t)(_fdata))
1436 #       ifdef USE_MMAP
1437 #         define HEAP_START (ptr_t)0x30000000
1438 #       else
1439 #         define HEAP_START DATASTART
1440 #       endif
1441                               /* Lowest plausible heap address.         */
1442                               /* In the MMAP case, we map there.        */
1443                               /* In either case it is used to identify  */
1444                               /* heap sections so they're not           */
1445                               /* considered as roots.                   */
1446 #       define OS_TYPE "IRIX5"
1447 /*#       define MPROTECT_VDB DOB: this should work, but there is evidence */
1448 /*              of recent breakage.                                        */
1449 #       ifdef _MIPS_SZPTR
1450 #         define CPP_WORDSZ _MIPS_SZPTR
1451 #         define ALIGNMENT (_MIPS_SZPTR/8)
1452 #       else
1453 #         define ALIGNMENT 4
1454 #       endif
1455 #       define DYNAMIC_LOADING
1456 #   endif
1457 #   ifdef MSWINCE
1458 #       define OS_TYPE "MSWINCE"
1459 #       define ALIGNMENT 4
1460 #       define DATAEND /* not needed */
1461 #   endif
1462 #   if defined(NETBSD)
1463 #     define OS_TYPE "NETBSD"
1464 #     define ALIGNMENT 4
1465 #     define HEURISTIC2
1466 #     ifdef __ELF__
1467         extern int etext[];
1468 #       define DATASTART GC_data_start
1469 #       define NEED_FIND_LIMIT
1470 #       define DYNAMIC_LOADING
1471 #     else
1472 #       define DATASTART ((ptr_t) 0x10000000)
1473 #       define STACKBOTTOM ((ptr_t) 0x7ffff000)
1474 #     endif /* _ELF_ */
1475 #  endif
1476 #  ifdef OPENBSD
1477 #    define OS_TYPE "OPENBSD"
1478 #    define ALIGNMENT 4
1479 #    ifdef GC_OPENBSD_THREADS
1480 #      define UTHREAD_SP_OFFSET 808
1481 #    else
1482 #      include <sys/param.h>
1483 #      include <uvm/uvm_extern.h>
1484 #      define STACKBOTTOM USRSTACK
1485 #    endif
1486      extern int _fdata[];
1487 #    define DATASTART ((ptr_t)_fdata)
1488      extern char _end[];
1489 #    define DATAEND ((ptr_t)(&_end))
1490 #    define DYNAMIC_LOADING
1491 #  endif
1492 #  if defined(NONSTOP)
1493 #    define CPP_WORDSZ 32
1494 #    define OS_TYPE "NONSTOP"
1495 #    define ALIGNMENT 4
1496 #    define DATASTART ((ptr_t) 0x08000000)
1497      extern char **environ;
1498 #    define DATAEND ((ptr_t)(environ - 0x10))
1499 #    define STACKBOTTOM ((ptr_t) 0x4fffffff)
1500 #   endif
1501 # endif
1502
1503 # ifdef HP_PA
1504 #   define MACH_TYPE "HP_PA"
1505 #   ifdef __LP64__
1506 #     define CPP_WORDSZ 64
1507 #     define ALIGNMENT 8
1508 #   else
1509 #     define CPP_WORDSZ 32
1510 #     define ALIGNMENT 4
1511 #   endif
1512 #   if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) \
1513        && !defined(OPENBSD)
1514 #     ifndef LINUX /* For now. */
1515 #       define MPROTECT_VDB
1516 #     endif
1517 #   else
1518 #     ifdef PARALLEL_MARK
1519 #       define USE_MARK_BYTES
1520                 /* Minimize compare-and-swap usage.             */
1521 #     endif
1522 #   endif
1523 #   define STACK_GROWS_UP
1524 #   ifdef HPUX
1525 #     define OS_TYPE "HPUX"
1526       extern int __data_start[];
1527 #     define DATASTART ((ptr_t)(__data_start))
1528 #     if 0
1529         /* The following appears to work for 7xx systems running HP/UX  */
1530         /* 9.xx Furthermore, it might result in much faster             */
1531         /* collections than HEURISTIC2, which may involve scanning      */
1532         /* segments that directly precede the stack.  It is not the     */
1533         /* default, since it may not work on older machine/OS           */
1534         /* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */
1535         /* this.)                                                       */
1536 #       define STACKBOTTOM ((ptr_t) 0x7b033000)  /* from /etc/conf/h/param.h */
1537 #     else
1538         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1539         /* to this.  Note that the GC must be initialized before the    */
1540         /* first putenv call.                                           */
1541         extern char ** environ;
1542 #       define STACKBOTTOM ((ptr_t)environ)
1543 #     endif
1544 #     define DYNAMIC_LOADING
1545 #     include <unistd.h>
1546 #     define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1547 #     ifndef __GNUC__
1548 #       define PREFETCH(x)  { \
1549                               register long addr = (long)(x); \
1550                               (void) _asm ("LDW", 0, 0, addr, 0); \
1551                             }
1552 #     endif
1553 #   endif /* HPUX */
1554 #   ifdef LINUX
1555 #     define OS_TYPE "LINUX"
1556 #     define LINUX_STACKBOTTOM
1557 #     define DYNAMIC_LOADING
1558 #     define SEARCH_FOR_DATA_START
1559       extern int _end[];
1560 #     define DATAEND (ptr_t)(&_end)
1561 #   endif /* LINUX */
1562 #  ifdef OPENBSD
1563 #     define OS_TYPE "OPENBSD"
1564 #     ifdef GC_OPENBSD_THREADS
1565 #       define UTHREAD_SP_OFFSET 520
1566 #     else
1567 #       include <sys/param.h>
1568 #       include <uvm/uvm_extern.h>
1569 #       define STACKBOTTOM USRSTACK
1570 #     endif
1571       extern int __data_start[];
1572 #     define DATASTART ((ptr_t)__data_start)
1573       extern char _end[];
1574 #     define DATAEND ((ptr_t)(&_end))
1575 #     define DYNAMIC_LOADING
1576 #  endif
1577 # endif /* HP_PA */
1578
1579 # ifdef ALPHA
1580 #   define MACH_TYPE "ALPHA"
1581 #   define ALIGNMENT 8
1582 #   define CPP_WORDSZ 64
1583 #   ifdef NETBSD
1584 #       define OS_TYPE "NETBSD"
1585 #       define HEURISTIC2
1586 #       define DATASTART GC_data_start
1587 #       define ELFCLASS32 32
1588 #       define ELFCLASS64 64
1589 #       define ELF_CLASS ELFCLASS64
1590 #       define DYNAMIC_LOADING
1591 #   endif
1592 #   ifdef OPENBSD
1593 #       define OS_TYPE "OPENBSD"
1594 #       define ELF_CLASS ELFCLASS64
1595 #       ifdef GC_OPENBSD_THREADS
1596 #         define UTHREAD_SP_OFFSET 816
1597 #       else
1598 #         include <sys/param.h>
1599 #         include <uvm/uvm_extern.h>
1600 #         define STACKBOTTOM USRSTACK
1601 #       endif
1602         extern int __data_start[];
1603 #       define DATASTART ((ptr_t)__data_start)
1604         extern char _end[];
1605 #       define DATAEND ((ptr_t)(&_end))
1606 #       define DYNAMIC_LOADING
1607 #   endif
1608 #   ifdef FREEBSD
1609 #       define OS_TYPE "FREEBSD"
1610 /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */
1611 #       define SIG_SUSPEND SIGUSR1
1612 #       define SIG_THR_RESTART SIGUSR2
1613 #       define FREEBSD_STACKBOTTOM
1614 #       ifdef __ELF__
1615 #           define DYNAMIC_LOADING
1616 #       endif
1617 /* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */
1618         extern char etext[];
1619         extern char edata[];
1620         extern char end[];
1621 #       define NEED_FIND_LIMIT
1622 #       define DATASTART ((ptr_t)(&etext))
1623 #       define DATAEND (GC_find_limit (DATASTART, TRUE))
1624 #       define DATASTART2 ((ptr_t)(&edata))
1625 #       define DATAEND2 ((ptr_t)(&end))
1626 #   endif
1627 #   ifdef OSF1
1628 #       define OS_TYPE "OSF1"
1629 #       define DATASTART ((ptr_t) 0x140000000)
1630         extern int _end[];
1631 #       define DATAEND ((ptr_t) &_end)
1632         extern char ** environ;
1633         /* round up from the value of environ to the nearest page boundary */
1634         /* Probably breaks if putenv is called before collector            */
1635         /* initialization.                                                 */
1636 #       define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1))
1637 /* #    define HEURISTIC2 */
1638         /* Normally HEURISTIC2 is too conservative, since               */
1639         /* the text segment immediately follows the stack.              */
1640         /* Hence we give an upper pound.                                */
1641         /* This is currently unused, since we disabled HEURISTIC2       */
1642         extern int __start[];
1643 #       define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
1644 #       ifndef GC_OSF1_THREADS
1645           /* Unresolved signal issues with threads.     */
1646 #         define MPROTECT_VDB
1647 #       endif
1648 #       define DYNAMIC_LOADING
1649 #   endif
1650 #   ifdef LINUX
1651 #       define OS_TYPE "LINUX"
1652 #       define LINUX_STACKBOTTOM
1653 #       ifdef __ELF__
1654 #         define SEARCH_FOR_DATA_START
1655 #         define DYNAMIC_LOADING
1656 #       else
1657 #           define DATASTART ((ptr_t) 0x140000000)
1658 #       endif
1659         extern int _end[];
1660 #       define DATAEND (ptr_t)(_end)
1661 #       define MPROTECT_VDB
1662                 /* Has only been superficially tested.  May not */
1663                 /* work on all versions.                        */
1664 #   endif
1665 # endif
1666
1667 # ifdef IA64
1668 #   define MACH_TYPE "IA64"
1669 #   ifdef HPUX
1670 #       ifdef _ILP32
1671 #         define CPP_WORDSZ 32
1672             /* Requires 8 byte alignment for malloc */
1673 #         define ALIGNMENT 4
1674 #       else
1675 #         ifndef _LP64
1676                 ---> unknown ABI
1677 #         endif
1678 #         define CPP_WORDSZ 64
1679             /* Requires 16 byte alignment for malloc */
1680 #         define ALIGNMENT 8
1681 #       endif
1682 #       define OS_TYPE "HPUX"
1683         extern int __data_start[];
1684 #       define DATASTART ((ptr_t)(__data_start))
1685         /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2       */
1686         /* to this.  Note that the GC must be initialized before the    */
1687         /* first putenv call.                                           */
1688         extern char ** environ;
1689 #       define STACKBOTTOM ((ptr_t)environ)
1690 #       define HPUX_STACKBOTTOM
1691 #       define DYNAMIC_LOADING
1692 #       include <unistd.h>
1693 #       define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
1694         /* The following was empirically determined, and is probably    */
1695         /* not very robust.                                             */
1696         /* Note that the backing store base seems to be at a nice       */
1697         /* address minus one page.                                      */
1698 #       define BACKING_STORE_DISPLACEMENT 0x1000000
1699 #       define BACKING_STORE_ALIGNMENT 0x1000
1700         extern ptr_t GC_register_stackbottom;
1701 #       define BACKING_STORE_BASE GC_register_stackbottom
1702         /* Known to be wrong for recent HP/UX versions!!!       */
1703 #   endif
1704 #   ifdef LINUX
1705 #       define CPP_WORDSZ 64
1706 #       define ALIGNMENT 8
1707 #       define OS_TYPE "LINUX"
1708         /* The following works on NUE and older kernels:        */
1709 /* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)     */
1710         /* This does not work on NUE:                           */
1711 #       define LINUX_STACKBOTTOM
1712         /* We also need the base address of the register stack  */
1713         /* backing store.  This is computed in                  */
1714         /* GC_linux_register_stack_base based on the following  */
1715         /* constants:                                           */
1716 #       define BACKING_STORE_ALIGNMENT 0x100000
1717 #       define BACKING_STORE_DISPLACEMENT 0x80000000
1718         extern ptr_t GC_register_stackbottom;
1719 #       define BACKING_STORE_BASE GC_register_stackbottom
1720 #       define SEARCH_FOR_DATA_START
1721 #       ifdef __GNUC__
1722 #         define DYNAMIC_LOADING
1723 #       else
1724           /* In the Intel compiler environment, we seem to end up with  */
1725           /* statically linked executables and an undefined reference   */
1726           /* to _DYNAMIC                                                */
1727 #       endif
1728 #       define MPROTECT_VDB
1729                 /* Requires Linux 2.3.47 or later.      */
1730         extern int _end[];
1731 #       define DATAEND (ptr_t)(_end)
1732 #       ifdef __GNUC__
1733 #         ifndef __INTEL_COMPILER
1734 #           define PREFETCH(x) \
1735               __asm__ ("        lfetch  [%0]": : "r"(x))
1736 #           define PREFETCH_FOR_WRITE(x) \
1737               __asm__ ("        lfetch.excl     [%0]": : "r"(x))
1738 #           define CLEAR_DOUBLE(x) \
1739               __asm__ ("        stf.spill       [%0]=f0": : "r"((void *)(x)))
1740 #         else
1741 #           include <ia64intrin.h>
1742 #           define PREFETCH(x) \
1743               __lfetch(__lfhint_none, (x))
1744 #           define PREFETCH_FOR_WRITE(x) \
1745               __lfetch(__lfhint_nta,  (x))
1746 #           define CLEAR_DOUBLE(x) \
1747               __stf_spill((void *)(x), 0)
1748 #         endif /* __INTEL_COMPILER */
1749 #       endif
1750 #   endif
1751 #   ifdef MSWIN32
1752       /* FIXME: This is a very partial guess.  There is no port, yet.   */
1753 #     define OS_TYPE "MSWIN32"
1754                 /* STACKBOTTOM and DATASTART are handled specially in   */
1755                 /* os_dep.c.                                            */
1756 #     define DATAEND  /* not needed */
1757 #     if defined(_WIN64)
1758 #       define CPP_WORDSZ 64
1759 #     else
1760 #       define CPP_WORDSZ 32   /* Is this possible?     */
1761 #     endif
1762 #     define ALIGNMENT 8
1763 #   endif
1764 # endif
1765
1766 # ifdef M88K
1767 #   define MACH_TYPE "M88K"
1768 #   define ALIGNMENT 4
1769     extern int etext[];
1770 #   ifdef CX_UX
1771 #       define OS_TYPE "CX_UX"
1772 #       define DATASTART ((((word)etext + 0x3fffff) & ~0x3fffff) + 0x10000)
1773 #   endif
1774 #   ifdef  DGUX
1775 #       define OS_TYPE "DGUX"
1776         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1777 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
1778 #   endif
1779 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
1780 # endif
1781
1782 # ifdef S370
1783     /* If this still works, and if anyone cares, this should probably   */
1784     /* be moved to the S390 category.                                   */
1785 #   define MACH_TYPE "S370"
1786 #   define ALIGNMENT 4  /* Required by hardware */
1787 #   ifdef UTS4
1788 #       define OS_TYPE "UTS4"
1789         extern int etext[];
1790         extern int _etext[];
1791         extern int _end[];
1792         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1793 #       define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1794 #       define DATAEND (ptr_t)(_end)
1795 #       define HEURISTIC2
1796 #   endif
1797 # endif
1798
1799 # ifdef S390
1800 #   define MACH_TYPE "S390"
1801 #   ifndef __s390x__
1802 #   define ALIGNMENT 4
1803 #   define CPP_WORDSZ 32
1804 #   else
1805 #   define ALIGNMENT 8
1806 #   define CPP_WORDSZ 64
1807 #   ifndef HBLKSIZE
1808 #     define HBLKSIZE 4096
1809 #   endif
1810 #   endif
1811 #   ifdef LINUX
1812 #       define OS_TYPE "LINUX"
1813 #       define LINUX_STACKBOTTOM
1814 #       define DYNAMIC_LOADING
1815         extern int __data_start[];
1816 #       define DATASTART ((ptr_t)(__data_start))
1817     extern int _end[];
1818 #   define DATAEND (ptr_t)(_end)
1819 #   define CACHE_LINE_SIZE 256
1820 #   define GETPAGESIZE() 4096
1821 #   endif
1822 # endif
1823
1824 # ifdef ARM32
1825 #   define CPP_WORDSZ 32
1826 #   define MACH_TYPE "ARM32"
1827 #   define ALIGNMENT 4
1828 #   ifdef NETBSD
1829 #       define OS_TYPE "NETBSD"
1830 #       define HEURISTIC2
1831 #       ifdef __ELF__
1832 #          define DATASTART GC_data_start
1833 #          define DYNAMIC_LOADING
1834 #       else
1835            extern char etext[];
1836 #          define DATASTART ((ptr_t)(etext))
1837 #       endif
1838 #   endif
1839 #   ifdef LINUX
1840 #       define OS_TYPE "LINUX"
1841 #       define LINUX_STACKBOTTOM
1842 #       undef STACK_GRAN
1843 #       define STACK_GRAN 0x10000000
1844 #       ifdef __ELF__
1845 #            define DYNAMIC_LOADING
1846 #            include <features.h>
1847 #            if defined(__GLIBC__) && __GLIBC__ >= 2 \
1848                 || defined(PLATFORM_ANDROID)
1849 #                define SEARCH_FOR_DATA_START
1850 #            else
1851                  extern char **__environ;
1852 #                define DATASTART ((ptr_t)(&__environ))
1853                               /* hideous kludge: __environ is the first */
1854                               /* word in crt0.o, and delimits the start */
1855                               /* of the data segment, no matter which   */
1856                               /* ld options were passed through.        */
1857                               /* We could use _etext instead, but that  */
1858                               /* would include .rodata, which may       */
1859                               /* contain large read-only data tables    */
1860                               /* that we'd rather not scan.             */
1861 #            endif
1862              extern int _end[];
1863 #            define DATAEND (ptr_t)(_end)
1864 #       else
1865              extern int etext[];
1866 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
1867 #       endif
1868 #   endif
1869 #   ifdef MSWINCE
1870 #     define OS_TYPE "MSWINCE"
1871 #     define DATAEND /* not needed */
1872 #   endif
1873 #   ifdef DARWIN
1874       /* iPhone */
1875 #     define OS_TYPE "DARWIN"
1876 #     define DATASTART ((ptr_t) get_etext())
1877 #     define DATAEND    ((ptr_t) get_end())
1878 /* #define STACKBOTTOM ((ptr_t) 0x30000000) */ /* FIXME: Is this needed? */
1879 #     define HEURISTIC1
1880 #     ifndef USE_MMAP
1881 #       define USE_MMAP
1882 #     endif
1883 #     define USE_MMAP_ANON
1884 #   endif
1885 #   ifdef OPENBSD
1886 #     define ALIGNMENT 4
1887 #     define OS_TYPE "OPENBSD"
1888 #     ifdef GC_OPENBSD_THREADS
1889 #       define UTHREAD_SP_OFFSET 176
1890 #     else
1891 #       include <sys/param.h>
1892 #       include <uvm/uvm_extern.h>
1893 #       define STACKBOTTOM USRSTACK
1894 #     endif
1895       extern int __data_start[];
1896 #     define DATASTART ((ptr_t)__data_start)
1897       extern char _end[];
1898 #     define DATAEND ((ptr_t)(&_end))
1899 #     define DYNAMIC_LOADING
1900 #   endif
1901 #   ifdef NOSYS
1902       /* __data_start is usually defined in the target linker script.  */
1903       extern int __data_start[];
1904 #     define DATASTART (ptr_t)(__data_start)
1905       /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S  */
1906       extern void *__stack_base__;
1907 #     define STACKBOTTOM ((ptr_t) (__stack_base__))
1908 #   endif
1909 #endif
1910
1911 # ifdef CRIS
1912 #   define MACH_TYPE "CRIS"
1913 #   define CPP_WORDSZ 32
1914 #   define ALIGNMENT 1
1915 #   define OS_TYPE "LINUX"
1916 #   define DYNAMIC_LOADING
1917 #   define LINUX_STACKBOTTOM
1918 #   define SEARCH_FOR_DATA_START
1919       extern int _end[];
1920 #   define DATAEND (ptr_t)(_end)
1921 # endif
1922
1923 # if defined(SH) && !defined(SH4)
1924 #   define MACH_TYPE "SH"
1925 #   define ALIGNMENT 4
1926 #   ifdef MSWINCE
1927 #     define OS_TYPE "MSWINCE"
1928 #     define DATAEND /* not needed */
1929 #   endif
1930 #   ifdef LINUX
1931 #     define OS_TYPE "LINUX"
1932 #     define LINUX_STACKBOTTOM
1933 #     define DYNAMIC_LOADING
1934 #     define SEARCH_FOR_DATA_START
1935       extern int _end[];
1936 #     define DATAEND (ptr_t)(_end)
1937 #   endif
1938 #   ifdef NETBSD
1939 #      define OS_TYPE "NETBSD"
1940 #      define HEURISTIC2
1941 #      define DATASTART GC_data_start
1942 #      define DYNAMIC_LOADING
1943 #   endif
1944 #   ifdef OPENBSD
1945 #      define OS_TYPE "OPENBSD"
1946 #      ifdef GC_OPENBSD_THREADS
1947 #        define UTHREAD_SP_OFFSET 332
1948 #      else
1949 #        include <sys/param.h>
1950 #        include <uvm/uvm_extern.h>
1951 #        define STACKBOTTOM USRSTACK
1952 #      endif
1953        extern int __data_start[];
1954 #      define DATASTART ((ptr_t)__data_start)
1955        extern char _end[];
1956 #      define DATAEND ((ptr_t)(&_end))
1957 #      define DYNAMIC_LOADING
1958 #   endif
1959 # endif
1960
1961 # ifdef SH4
1962 #   define MACH_TYPE "SH4"
1963 #   define OS_TYPE "MSWINCE"
1964 #   define ALIGNMENT 4
1965 #   define DATAEND /* not needed */
1966 # endif
1967
1968 # ifdef M32R
1969 #   define CPP_WORDSZ 32
1970 #   define MACH_TYPE "M32R"
1971 #   define ALIGNMENT 4
1972 #   ifdef LINUX
1973 #     define OS_TYPE "LINUX"
1974 #     define LINUX_STACKBOTTOM
1975 #     undef STACK_GRAN
1976 #     define STACK_GRAN 0x10000000
1977 #     define DYNAMIC_LOADING
1978 #     define SEARCH_FOR_DATA_START
1979       extern int _end[];
1980 #     define DATAEND (ptr_t)(_end)
1981 #   endif
1982 # endif
1983
1984 # ifdef X86_64
1985 #   define MACH_TYPE "X86_64"
1986 #   define ALIGNMENT 8
1987 #   define CPP_WORDSZ 64
1988 #   ifndef HBLKSIZE
1989 #     define HBLKSIZE 4096
1990 #   endif
1991 #   define CACHE_LINE_SIZE 64
1992 #   ifdef OPENBSD
1993 #       define OS_TYPE "OPENBSD"
1994 #       define ELF_CLASS ELFCLASS64
1995 #       ifdef GC_OPENBSD_THREADS
1996 #         define UTHREAD_SP_OFFSET 400
1997 #       else
1998 #         include <sys/param.h>
1999 #         include <uvm/uvm_extern.h>
2000 #         define STACKBOTTOM USRSTACK
2001 #       endif
2002         extern int __data_start[];
2003 #       define DATASTART ((ptr_t)__data_start)
2004         extern char _end[];
2005 #       define DATAEND ((ptr_t)(&_end))
2006 #       define DYNAMIC_LOADING
2007 #   endif
2008 #   ifdef LINUX
2009 #       define OS_TYPE "LINUX"
2010 #       define LINUX_STACKBOTTOM
2011 #       if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
2012 #           define MPROTECT_VDB
2013 #       else
2014             /* We seem to get random errors in incremental mode,        */
2015             /* possibly because Linux threads is itself a malloc client */
2016             /* and can't deal with the signals.                         */
2017 #       endif
2018 #       ifdef __ELF__
2019 #            define DYNAMIC_LOADING
2020 #            ifdef UNDEFINED    /* includes ro data */
2021                extern int _etext[];
2022 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
2023 #            endif
2024 #            include <features.h>
2025 #            define SEARCH_FOR_DATA_START
2026              extern int _end[];
2027 #            define DATAEND (ptr_t)(_end)
2028 #       else
2029              extern int etext[];
2030 #            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
2031 #       endif
2032 #       if defined(__GNUC__) && __GNUC__ >= 3
2033 #           define PREFETCH(x) __builtin_prefetch((x), 0, 0)
2034 #           define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
2035 #       endif
2036 #   endif
2037 #   ifdef DARWIN
2038 #     define OS_TYPE "DARWIN"
2039 #     define DARWIN_DONT_PARSE_STACK
2040 #     define DYNAMIC_LOADING
2041       /* XXX: see get_end(3), get_etext() and get_end() should not be used.
2042          These aren't used when dyld support is enabled (it is by default) */
2043 #     define DATASTART ((ptr_t) get_etext())
2044 #     define DATAEND    ((ptr_t) get_end())
2045 #     define STACKBOTTOM ((ptr_t) 0x7fff5fc00000)
2046 #     ifndef USE_MMAP
2047 #       define USE_MMAP
2048 #     endif
2049 #     define USE_MMAP_ANON
2050 #     ifdef GC_DARWIN_THREADS
2051 #       define MPROTECT_VDB
2052 #     endif
2053 #     include <unistd.h>
2054 #     define GETPAGESIZE() getpagesize()
2055       /* There seems to be some issues with trylock hanging on darwin. This
2056          should be looked into some more */
2057 #     define NO_PTHREAD_TRYLOCK
2058 #   endif
2059 #   ifdef FREEBSD
2060 #       define OS_TYPE "FREEBSD"
2061 #       ifndef GC_FREEBSD_THREADS
2062 #           define MPROTECT_VDB
2063 #       endif
2064 #       ifdef __GLIBC__
2065 #           define SIG_SUSPEND          (32+6)
2066 #           define SIG_THR_RESTART      (32+5)
2067             extern int _end[];
2068 #           define DATAEND (ptr_t)(_end)
2069 #       else
2070 #           define SIG_SUSPEND SIGUSR1
2071 #           define SIG_THR_RESTART SIGUSR2
2072 #       endif
2073 #       define FREEBSD_STACKBOTTOM
2074 #       ifdef __ELF__
2075 #           define DYNAMIC_LOADING
2076 #       endif
2077         extern char etext[];
2078         ptr_t GC_FreeBSDGetDataStart(size_t max_page_size, ptr_t etext_addr);
2079 #       define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
2080 #   endif
2081 #   ifdef NETBSD
2082 #       define OS_TYPE "NETBSD"
2083 #       ifdef __ELF__
2084 #           define DYNAMIC_LOADING
2085 #       endif
2086 #       define HEURISTIC2
2087         extern char etext[];
2088 #       define SEARCH_FOR_DATA_START
2089 #   endif
2090 #   ifdef SOLARIS
2091 #       define OS_TYPE "SOLARIS"
2092 #       define ELF_CLASS ELFCLASS64
2093         extern int _etext[], _end[];
2094         ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2095 #       define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
2096 #       define DATAEND (ptr_t)(_end)
2097 /*      # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,      */
2098 /*      but reportedly breaks under 2.8.  It appears that the stack     */
2099 /*      base is a property of the executable, so this should not break  */
2100 /*      old executables.                                                */
2101 /*      HEURISTIC2 probably works, but this appears to be preferable.   */
2102 /*      Apparently USRSTACK is defined to be USERLIMIT, but in some     */
2103 /*      installations that's undefined.  We work around this with a     */
2104 /*      gross hack:                                                     */
2105 #       include <sys/vmparam.h>
2106 #       ifdef USERLIMIT
2107           /* This should work everywhere, but doesn't.  */
2108 #         define STACKBOTTOM ((ptr_t) USRSTACK)
2109 #       else
2110 #         define HEURISTIC2
2111 #       endif
2112 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
2113 /* It appears to be fixed in 2.8 and 2.9.                               */
2114 #       ifdef SOLARIS25_PROC_VDB_BUG_FIXED
2115 #         define PROC_VDB
2116 #       endif
2117 #       define DYNAMIC_LOADING
2118 #       if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
2119 #         define USE_MMAP
2120             /* Otherwise we now use calloc.  Mmap may result in the     */
2121             /* heap interleaved with thread stacks, which can result in */
2122             /* excessive blacklisting.  Sbrk is unusable since it       */
2123             /* doesn't interact correctly with the system malloc.       */
2124 #       endif
2125 #       ifdef USE_MMAP
2126 #         define HEAP_START (ptr_t)0x40000000
2127 #       else
2128 #         define HEAP_START DATAEND
2129 #       endif
2130 #   endif
2131 #   ifdef MSWIN32
2132 #       define OS_TYPE "MSWIN32"
2133                 /* STACKBOTTOM and DATASTART are handled specially in   */
2134                 /* os_dep.c.                                            */
2135 #       define MPROTECT_VDB
2136 #       define GWW_VDB
2137 #       define DATAEND  /* not needed */
2138 #   endif
2139 # endif
2140
2141 #if defined(LINUX_STACKBOTTOM) && defined(NO_PROC_STAT) \
2142     && !defined(USE_LIBC_PRIVATES)
2143     /* This combination will fail, since we have no way to get  */
2144     /* the stack base.  Use HEURISTIC2 instead.                 */
2145 #   undef LINUX_STACKBOTTOM
2146 #   define HEURISTIC2
2147     /* This may still fail on some architectures like IA64.     */
2148     /* We tried ...                                             */
2149 #endif
2150
2151 #if defined(LINUX) && defined(USE_MMAP)
2152     /* The kernel may do a somewhat better job merging mappings etc.    */
2153     /* with anonymous mappings.                                         */
2154 #   define USE_MMAP_ANON
2155 #endif
2156
2157 #if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC)
2158     /* Nptl allocates thread stacks with mmap, which is fine.  But it   */
2159     /* keeps a cache of thread stacks.  Thread stacks contain the       */
2160     /* thread control blocks.  These in turn contain a pointer to       */
2161     /* (sizeof (void *) from the beginning of) the dtv for thread-local */
2162     /* storage, which is calloc allocated.  If we don't scan the cached */
2163     /* thread stacks, we appear to lose the dtv.  This tends to         */
2164     /* result in something that looks like a bogus dtv count, which     */
2165     /* tends to result in a memset call on a block that is way too      */
2166     /* large.  Sometimes we're lucky and the process just dies ...      */
2167     /* There seems to be a similar issue with some other memory         */
2168     /* allocated by the dynamic loader.                                 */
2169     /* This should be avoidable by either:                              */
2170     /* - Defining USE_PROC_FOR_LIBRARIES here.                          */
2171     /*   That performs very poorly, precisely because we end up         */
2172     /*   scanning cached stacks.                                        */
2173     /* - Have calloc look at its callers.                               */
2174     /*   In spite of the fact that it is gross and disgusting.          */
2175     /* In fact neither seems to suffice, probably in part because       */
2176     /* even with USE_PROC_FOR_LIBRARIES, we don't scan parts of stack   */
2177     /* segments that appear to be out of bounds.  Thus we actually      */
2178     /* do both, which seems to yield the best results.                  */
2179
2180 #   define USE_PROC_FOR_LIBRARIES
2181 #endif
2182
2183 # ifndef STACK_GROWS_UP
2184 #   define STACK_GROWS_DOWN
2185 # endif
2186
2187 # ifndef CPP_WORDSZ
2188 #   define CPP_WORDSZ 32
2189 # endif
2190
2191 # ifndef OS_TYPE
2192 #   define OS_TYPE ""
2193 # endif
2194
2195 # ifndef DATAEND
2196     extern int end[];
2197 #   define DATAEND (ptr_t)(end)
2198 # endif
2199
2200 # if defined(SVR4) && !defined(GETPAGESIZE)
2201 #    include <unistd.h>
2202 #    define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
2203 # endif
2204
2205 # ifndef GETPAGESIZE
2206 #   if defined(SOLARIS) || defined(IRIX5) || defined(LINUX) \
2207        || defined(NETBSD) || defined(FREEBSD) || defined(HPUX)
2208 #       include <unistd.h>
2209 #   endif
2210 #   define GETPAGESIZE() getpagesize()
2211 # endif
2212
2213 # if defined(SOLARIS) || defined(DRSNX) || defined(UTS4)
2214             /* OS has SVR4 generic features.            */
2215             /* Probably others also qualify.            */
2216 #   define SVR4
2217 # endif
2218
2219 # if defined(SOLARIS) || defined(DRSNX)
2220             /* OS has SOLARIS style semi-undocumented interface */
2221             /* to dynamic loader.                               */
2222 #   define SOLARISDL
2223             /* OS has SOLARIS style signal handlers.            */
2224 #   define SUNOS5SIGS
2225 # endif
2226
2227 # if defined(HPUX)
2228 #   define SUNOS5SIGS
2229 # endif
2230
2231 # if defined(FREEBSD) && \
2232      (defined(__DragonFly__) || __FreeBSD__ >= 4 || (__FreeBSD_kernel__ >= 4))
2233 #   define SUNOS5SIGS
2234 # endif
2235
2236 # ifdef GC_NETBSD_THREADS
2237 #   define SIGRTMIN 33
2238 #   define SIGRTMAX 63
2239 # endif
2240
2241 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
2242             || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
2243             || defined(DGUX) || defined(BSD) \
2244             || defined(AIX) || defined(DARWIN) || defined(OSF1) \
2245             || defined(HURD)
2246 #   define UNIX_LIKE   /* Basic Unix-like system calls work.    */
2247 # endif
2248
2249 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
2250            -> bad word size
2251 # endif
2252
2253 # ifndef ALIGNMENT
2254     --> undefined ALIGNMENT
2255 # endif
2256
2257 # ifdef PCR
2258 #   undef DYNAMIC_LOADING
2259 #   undef STACKBOTTOM
2260 #   undef HEURISTIC1
2261 #   undef HEURISTIC2
2262 #   undef PROC_VDB
2263 #   undef MPROTECT_VDB
2264 #   define PCR_VDB
2265 # endif
2266
2267 # if !defined(STACKBOTTOM) && (defined(ECOS) || defined(NOSYS))
2268 #   error --> undefined STACKBOTTOM
2269 # endif
2270
2271 # if defined(SMALL_CONFIG) && !defined(GC_DISABLE_INCREMENTAL)
2272         /* Presumably not worth the space it takes. */
2273 #   define GC_DISABLE_INCREMENTAL
2274 # endif
2275
2276 # ifdef GC_DISABLE_INCREMENTAL
2277 #   undef GWW_VDB
2278 #   undef MPROTECT_VDB
2279 #   undef PCR_VDB
2280 #   undef PROC_VDB
2281 # endif
2282
2283 # ifdef USE_GLOBAL_ALLOC
2284     /* Cannot pass MEM_WRITE_WATCH to GlobalAlloc().    */
2285 #   undef GWW_VDB
2286 # endif
2287
2288 # ifdef USE_MUNMAP
2289     /* FIXME: Remove this undef if possible.    */
2290 #   undef MPROTECT_VDB  /* Can't deal with address space holes. */
2291 # endif
2292
2293 # if defined(PARALLEL_MARK)
2294     /* FIXME: Remove this undef if possible.    */
2295 #   undef MPROTECT_VDB  /* For now.     */
2296 # endif
2297
2298 # if defined(MPROTECT_VDB) && defined(GC_PREFER_MPROTECT_VDB)
2299     /* Choose MPROTECT_VDB manually (if multiple strategies available). */
2300 #   undef PCR_VDB
2301 #   undef PROC_VDB
2302     /* #undef GWW_VDB - handled in os_dep.c */
2303 # endif
2304
2305 # if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) \
2306     && !defined(GWW_VDB)
2307 #   define DEFAULT_VDB
2308 # endif
2309
2310 # ifndef PREFETCH
2311 #   define PREFETCH(x)
2312 #   define NO_PREFETCH
2313 # endif
2314
2315 # ifndef PREFETCH_FOR_WRITE
2316 #   define PREFETCH_FOR_WRITE(x)
2317 #   define NO_PREFETCH_FOR_WRITE
2318 # endif
2319
2320 # ifndef CACHE_LINE_SIZE
2321 #   define CACHE_LINE_SIZE 32   /* Wild guess   */
2322 # endif
2323
2324 # ifndef STATIC
2325 #   ifndef NO_DEBUGGING
2326 #     define STATIC /* ignore to aid profiling and possibly debugging */
2327 #   else
2328 #     define STATIC static
2329 #   endif
2330 # endif
2331
2332 # if defined(LINUX) || defined(HURD) || defined(__GLIBC__)
2333 #   define REGISTER_LIBRARIES_EARLY
2334     /* We sometimes use dl_iterate_phdr, which may acquire an internal  */
2335     /* lock.  This isn't safe after the world has stopped.  So we must  */
2336     /* call GC_register_dynamic_libraries before stopping the world.    */
2337     /* For performance reasons, this may be beneficial on other         */
2338     /* platforms as well, though it should be avoided in win32.         */
2339 # endif /* LINUX */
2340
2341 # if defined(SEARCH_FOR_DATA_START)
2342     extern ptr_t GC_data_start;
2343 #   define DATASTART GC_data_start
2344 # endif
2345
2346 # ifndef CLEAR_DOUBLE
2347 #   define CLEAR_DOUBLE(x) \
2348                 ((word*)x)[0] = 0; \
2349                 ((word*)x)[1] = 0;
2350 # endif /* CLEAR_DOUBLE */
2351
2352 # if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
2353      && !defined(INCLUDE_LINUX_THREAD_DESCR)
2354     /* Will not work, since libc and the dynamic loader use thread      */
2355     /* locals, sometimes as the only reference.                         */
2356 #   define INCLUDE_LINUX_THREAD_DESCR
2357 # endif
2358
2359 # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
2360         --> inconsistent configuration
2361 # endif
2362 # if defined(GC_LINUX_THREADS) && !defined(LINUX)
2363         --> inconsistent configuration
2364 # endif
2365 # if defined(GC_NETBSD_THREADS) && !defined(NETBSD)
2366         --> inconsistent configuration
2367 # endif
2368 # if defined(GC_FREEBSD_THREADS) && !defined(FREEBSD)
2369         --> inconsistent configuration
2370 # endif
2371 # if defined(GC_SOLARIS_THREADS) && !defined(SOLARIS)
2372         --> inconsistent configuration
2373 # endif
2374 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
2375         --> inconsistent configuration
2376 # endif
2377 # if defined(GC_AIX_THREADS) && !defined(_AIX)
2378         --> inconsistent configuration
2379 # endif
2380 # if defined(GC_GNU_THREADS) && !defined(HURD)
2381         --> inconsistent configuration
2382 # endif
2383 # if defined(GC_WIN32_THREADS) && !defined(MSWIN32) && !defined(CYGWIN32) \
2384         && !defined(MSWINCE)
2385         --> inconsistent configuration
2386 # endif
2387
2388 # if defined(PCR) || defined(GC_WIN32_THREADS) || defined(GC_PTHREADS)
2389 #   define THREADS
2390 # endif
2391
2392 # if defined(UNIX_LIKE) && defined(THREADS) && !defined(NO_CANCEL_SAFE)
2393     /* Make the code cancellation-safe.  This basically means that we   */
2394     /* ensure that cancellation requests are ignored while we are in    */
2395     /* the collector.  This applies only to Posix deferred cancellation;*/
2396     /* we don't handle Posix asynchronous cancellation.                 */
2397     /* Note that this only works if pthread_setcancelstate is           */
2398     /* async-signal-safe, at least in the absence of asynchronous       */
2399     /* cancellation.  This appears to be true for the glibc version,    */
2400     /* though it is not documented.  Without that assumption, there     */
2401     /* seems to be no way to safely wait in a signal handler, which     */
2402     /* we need to do for thread suspension.                             */
2403     /* Also note that little other code appears to be cancellation-safe.*/
2404     /* Hence it may make sense to turn this off for performance.        */
2405 #   define CANCEL_SAFE
2406 #   define IF_CANCEL(x) x
2407 # else
2408 #   define IF_CANCEL(x)
2409 # endif
2410
2411 # if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES)
2412 #   if defined(THREADS) && defined(PARALLEL_MARK)
2413 #     define USE_MARK_BYTES
2414 #   else
2415 #     define USE_MARK_BITS
2416 #   endif
2417 # endif
2418
2419 # if defined(MSWINCE) && !defined(__CEGCC__) && !defined(NO_GETENV)
2420 #   define NO_GETENV
2421 # endif
2422
2423 # if (defined(NO_GETENV) || defined(MSWINCE)) && !defined(NO_GETENV_WIN32)
2424 #   define NO_GETENV_WIN32
2425 # endif
2426
2427 # ifndef STRTOULL
2428 #   if defined(_WIN64) && !defined(__GNUC__)
2429 #     define STRTOULL _strtoui64
2430 #   elif defined(_LLP64) || defined(__LLP64__) || defined(_WIN64)
2431 #     define STRTOULL strtoull
2432 #   else
2433         /* strtoul() fits since sizeof(long) >= sizeof(word).           */
2434 #     define STRTOULL strtoul
2435 #   endif
2436 # endif
2437
2438 # if defined(SPARC)
2439 #   define ASM_CLEAR_CODE       /* Stack clearing is crucial, and we    */
2440                                 /* include assembly code to do it well. */
2441 # endif
2442
2443   /* Can we save call chain in objects for debugging?                   */
2444   /* SET NFRAMES (# of saved frames) and NARGS (#of args for each       */
2445   /* frame) to reasonable values for the platform.                      */
2446   /* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified   */
2447   /* at build time, though we feel free to adjust it slightly.          */
2448   /* Define NEED_CALLINFO if we either save the call stack or           */
2449   /* GC_ADD_CALLER is defined.                                          */
2450   /* GC_CAN_SAVE_CALL_STACKS is set in gc.h.                            */
2451
2452 #if defined(SPARC)
2453 # define CAN_SAVE_CALL_ARGS
2454 #endif
2455 #if (defined(I386) || defined(X86_64)) && (defined(LINUX) || defined(__GLIBC__))
2456             /* SAVE_CALL_CHAIN is supported if the code is compiled to save     */
2457             /* frame pointers by default, i.e. no -fomit-frame-pointer flag.    */
2458 # define CAN_SAVE_CALL_ARGS
2459 #endif
2460
2461 # if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
2462              && defined(GC_CAN_SAVE_CALL_STACKS)
2463 #   define SAVE_CALL_CHAIN
2464 # endif
2465 # ifdef SAVE_CALL_CHAIN
2466 #   if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS)
2467 #     define NARGS SAVE_CALL_NARGS
2468 #   else
2469 #     define NARGS 0    /* Number of arguments to save for each call.   */
2470 #   endif
2471 # endif
2472 # ifdef SAVE_CALL_CHAIN
2473 #   ifndef SAVE_CALL_COUNT
2474 #     define NFRAMES 6  /* Number of frames to save. Even for           */
2475                         /* alignment reasons.                           */
2476 #   else
2477 #     define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1)
2478 #   endif
2479 #   define NEED_CALLINFO
2480 # endif /* SAVE_CALL_CHAIN */
2481 # ifdef GC_ADD_CALLER
2482 #   define NFRAMES 1
2483 #   define NARGS 0
2484 #   define NEED_CALLINFO
2485 # endif
2486
2487 # if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
2488 #   define DBG_HDRS_ALL
2489 # endif
2490
2491 # if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
2492 #   define POINTER_SHIFT 0
2493 # endif
2494
2495 # if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
2496 #   define POINTER_MASK ((GC_word)(-1))
2497 # endif
2498
2499 # if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
2500 #   define FIXUP_POINTER(p) (p = ((p) & POINTER_MASK) << POINTER_SHIFT)
2501 # endif
2502
2503 # if defined(FIXUP_POINTER)
2504 #   define NEED_FIXUP_POINTER 1
2505 # else
2506 #   define NEED_FIXUP_POINTER 0
2507 #   define FIXUP_POINTER(p)
2508 # endif
2509
2510 # if !defined(MARK_BIT_PER_GRANULE) && !defined(MARK_BIT_PER_OBJ)
2511 #   define MARK_BIT_PER_GRANULE /* Usually faster */
2512 # endif
2513
2514 /* Some static sanity tests.    */
2515 # if defined(MARK_BIT_PER_GRANULE) && defined(MARK_BIT_PER_OBJ)
2516 #   error Define only one of MARK_BIT_PER_GRANULE and MARK_BIT_PER_OBJ.
2517 # endif
2518
2519 # if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
2520 #   error "Only one of STACK_GROWS_UP and STACK_GROWS_DOWN should be defd."
2521 # endif
2522 # if !defined(STACK_GROWS_UP) && !defined(STACK_GROWS_DOWN)
2523 #   error "One of STACK_GROWS_UP and STACK_GROWS_DOWN should be defd."
2524 # endif
2525
2526 # if defined(REDIRECT_MALLOC) && defined(THREADS) && !defined(LINUX)
2527 #   error "REDIRECT_MALLOC with THREADS works at most on Linux."
2528 # endif
2529
2530 #ifdef GC_PRIVATE_H
2531         /* This relies on some type definitions from gc_priv.h, from    */
2532         /* where it's normally included.                                */
2533         /*                                                              */
2534         /* How to get heap memory from the OS:                          */
2535         /* Note that sbrk()-like allocation is preferred, since it      */
2536         /* usually makes it possible to merge consecutively allocated   */
2537         /* chunks.  It also avoids unintended recursion with            */
2538         /* REDIRECT_MALLOC macro defined.                               */
2539         /* GET_MEM() returns a HLKSIZE aligned chunk.                   */
2540         /* 0 is taken to mean failure.                                  */
2541         /* In the case os USE_MMAP, the argument must also be a         */
2542         /* physical page size.                                          */
2543         /* GET_MEM is currently not assumed to retrieve 0 filled space, */
2544         /* though we should perhaps take advantage of the case in which */
2545         /* does.                                                        */
2546         struct hblk;    /* See gc_priv.h.       */
2547 # if defined(PCR)
2548     char * real_malloc(size_t bytes);
2549 #   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
2550                                           + GC_page_size-1)
2551 # elif defined(OS2)
2552     void * os2_alloc(size_t bytes);
2553 #   define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
2554                                             + GC_page_size) \
2555                                             + GC_page_size-1)
2556 # elif defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) || \
2557                  (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
2558                  (defined(SOLARIS) && !defined(USE_MMAP))
2559 #   define GET_MEM(bytes) HBLKPTR((size_t) calloc(1, (size_t)bytes + GC_page_size) \
2560                                                      + GC_page_size-1)
2561 # elif defined(MSWIN32)
2562     ptr_t GC_win32_get_mem(GC_word bytes);
2563 #   define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
2564 # elif defined(MACOS)
2565 #   if defined(USE_TEMPORARY_MEMORY)
2566       Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory);
2567 #     define GET_MEM(bytes) HBLKPTR( \
2568                             GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
2569                             + GC_page_size-1)
2570 #   else
2571 #     define GET_MEM(bytes) HBLKPTR( \
2572                                 NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
2573 #   endif
2574 # elif defined(MSWINCE)
2575     ptr_t GC_wince_get_mem(GC_word bytes);
2576 #   define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
2577 # elif defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
2578     void *GC_amiga_get_mem(size_t size);
2579 #   define GET_MEM(bytes) HBLKPTR((size_t) \
2580                           GC_amiga_get_mem((size_t)bytes + GC_page_size) \
2581                           + GC_page_size-1)
2582 # else
2583     ptr_t GC_unix_get_mem(GC_word bytes);
2584 #   define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
2585 # endif
2586
2587 #endif /* GC_PRIVATE_H */
2588
2589 # endif /* GCCONFIG_H */