version 1.1, 1999/12/03 07:39:11 |
version 1.7, 2002/10/03 08:13:31 |
|
|
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. |
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. |
* Copyright (c) 1996 by Silicon Graphics. All rights reserved. |
* Copyright (c) 1996 by Silicon Graphics. All rights reserved. |
|
* Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. |
* |
* |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
|
|
* modified is included with the above copyright notice. |
* modified is included with the above copyright notice. |
*/ |
*/ |
|
|
#ifndef CONFIG_H |
#ifndef GCCONFIG_H |
|
|
# define CONFIG_H |
# define GCCONFIG_H |
|
|
/* Machine dependent parameters. Some tuning parameters can be found */ |
/* Machine dependent parameters. Some tuning parameters can be found */ |
/* near the top of gc_private.h. */ |
/* near the top of gc_private.h. */ |
|
|
# define LINUX |
# define LINUX |
# endif |
# endif |
|
|
|
/* And one for NetBSD: */ |
|
# if defined(__NetBSD__) |
|
# define NETBSD |
|
# endif |
|
|
|
/* And one for OpenBSD: */ |
|
# if defined(__OpenBSD__) |
|
# define OPENBSD |
|
# endif |
|
|
|
/* And one for FreeBSD: */ |
|
# if defined(__FreeBSD__) |
|
# define FREEBSD |
|
# endif |
|
|
/* Determine the machine type: */ |
/* Determine the machine type: */ |
|
# if defined(__XSCALE__) |
|
# define ARM32 |
|
# if !defined(LINUX) |
|
# define NOSYS |
|
# define mach_type_known |
|
# endif |
|
# endif |
# if defined(sun) && defined(mc68000) |
# if defined(sun) && defined(mc68000) |
# define M68K |
# define M68K |
# define SUNOS4 |
# define SUNOS4 |
|
|
# define HP |
# define HP |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__OpenBSD__) && defined(m68k) |
# if defined(OPENBSD) && defined(m68k) |
# define M68K |
# define M68K |
# define OPENBSD |
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__OpenBSD__) && defined(__sparc__) |
# if defined(OPENBSD) && defined(__sparc__) |
# define SPARC |
# define SPARC |
# define OPENBSD |
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__NetBSD__) && defined(m68k) |
# if defined(NETBSD) && defined(m68k) |
# define M68K |
# define M68K |
# define NETBSD |
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(NETBSD) && defined(__powerpc__) |
|
# define POWERPC |
|
# define mach_type_known |
|
# endif |
|
# if defined(NETBSD) && defined(__arm32__) |
|
# define ARM32 |
|
# define mach_type_known |
|
# endif |
# if defined(vax) |
# if defined(vax) |
# define VAX |
# define VAX |
# ifdef ultrix |
# ifdef ultrix |
|
|
# endif |
# endif |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(mips) || defined(__mips) |
# if defined(mips) || defined(__mips) || defined(_mips) |
# define MIPS |
# define MIPS |
# if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__) |
# if defined(nec_ews) || defined(_nec_ews) |
# define ULTRIX |
# define EWS4800 |
# else |
|
# if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) || defined(__SYSTYPE_SVR4__) |
|
# define IRIX5 /* or IRIX 6.X */ |
|
# else |
|
# define RISCOS /* or IRIX 4.X */ |
|
# endif |
|
# endif |
# endif |
|
# if !defined(LINUX) && !defined(EWS4800) |
|
# if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__) |
|
# define ULTRIX |
|
# else |
|
# if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) \ |
|
|| defined(__SYSTYPE_SVR4__) |
|
# define IRIX5 /* or IRIX 6.X */ |
|
# else |
|
# define RISCOS /* or IRIX 4.X */ |
|
# endif |
|
# endif |
|
# endif /* !LINUX */ |
|
# if defined(__NetBSD__) && defined(__MIPSEL__) |
|
# undef ULTRIX |
|
# endif |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(sequent) && defined(i386) |
# if defined(DGUX) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
|
# ifndef _USING_DGUX |
|
# define _USING_DGUX |
|
# endif |
|
# define mach_type_known |
|
# endif |
|
# if defined(sequent) && (defined(i386) || defined(__i386__)) |
|
# define I386 |
# define SEQUENT |
# define SEQUENT |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(sun) && defined(i386) |
# if defined(sun) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define SUNOS5 |
# define SUNOS5 |
# define mach_type_known |
# define mach_type_known |
|
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \ |
# if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \ |
&& !defined(__OpenBSD__) |
&& !defined(__OpenBSD__) && !(__NetBSD__) |
# define SPARC |
# define SPARC |
# define DRSNX |
# define DRSNX |
# define mach_type_known |
# define mach_type_known |
|
|
# define RS6000 |
# define RS6000 |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(__NetBSD__) && defined(__sparc__) |
|
# define SPARC |
|
# define mach_type_known |
|
# endif |
# if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386) |
# if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386) |
/* The above test may need refinement */ |
/* The above test may need refinement */ |
# define I386 |
# define I386 |
|
|
# define SYSV |
# define SYSV |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) \ |
# if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \ |
|| defined(hppa) || defined(__hppa__) |
|| defined(hppa) || defined(__hppa__) |
# define HP_PA |
# define HP_PA |
|
# ifndef LINUX |
|
# define HPUX |
|
# endif |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(__ia64) && defined(_HPUX_SOURCE) |
|
# define IA64 |
|
# define HPUX |
|
# define mach_type_known |
|
# endif |
|
# if defined(__BEOS__) && defined(_X86_) |
|
# define I386 |
|
# define BEOS |
|
# define mach_type_known |
|
# endif |
# if defined(LINUX) && (defined(i386) || defined(__i386__)) |
# if defined(LINUX) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(LINUX) && defined(powerpc) |
# if defined(LINUX) && (defined(__ia64__) || defined(__ia64)) |
|
# define IA64 |
|
# define mach_type_known |
|
# endif |
|
# if defined(LINUX) && defined(__arm__) |
|
# define ARM32 |
|
# define mach_type_known |
|
# endif |
|
# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__)) |
# define POWERPC |
# define POWERPC |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
|
# define M68K |
# define M68K |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(linux) && defined(sparc) |
# if defined(LINUX) && (defined(sparc) || defined(__sparc__)) |
# define SPARC |
# define SPARC |
# define LINUX |
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(LINUX) && defined(__arm__) |
|
# define ARM32 |
|
# define mach_type_known |
|
# endif |
|
# if defined(LINUX) && defined(__sh__) |
|
# define SH |
|
# define mach_type_known |
|
# endif |
# if defined(__alpha) || defined(__alpha__) |
# if defined(__alpha) || defined(__alpha__) |
# define ALPHA |
# define ALPHA |
# if !defined(LINUX) |
# if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) && !defined(FREEBSD) |
# define OSF1 /* a.k.a Digital Unix */ |
# define OSF1 /* a.k.a Digital Unix */ |
# endif |
# endif |
# define mach_type_known |
# define mach_type_known |
|
|
# define MACOS |
# define MACOS |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__MWERKS__) && defined(__powerc) |
# if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__) |
# define POWERPC |
# define POWERPC |
# define MACOS |
# define MACOS |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(macosx) |
# if defined(macosx) || \ |
|
defined(__APPLE__) && defined(__MACH__) && defined(__ppc__) |
# define MACOSX |
# define MACOSX |
# define POWERPC |
# define POWERPC |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(__APPLE__) && defined(__MACH__) && defined(__i386__) |
|
# define MACOSX |
|
# define I386 |
|
--> Not really supported, but at least we recognize it. |
|
# endif |
# if defined(NeXT) && defined(mc68000) |
# if defined(NeXT) && defined(mc68000) |
# define M68K |
# define M68K |
# define NEXT |
# define NEXT |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(NeXT) && defined(i386) |
# if defined(NeXT) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define NEXT |
# define NEXT |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__OpenBSD__) && defined(i386) |
# if defined(__OpenBSD__) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define OPENBSD |
# define OPENBSD |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__FreeBSD__) && defined(i386) |
# if defined(FREEBSD) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define FREEBSD |
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(__NetBSD__) && defined(i386) |
# if defined(__NetBSD__) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define NETBSD |
|
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(bsdi) && defined(i386) |
# if defined(bsdi) && (defined(i386) || defined(__i386__)) |
# define I386 |
# define I386 |
# define BSDI |
# define BSDI |
# define mach_type_known |
# define mach_type_known |
|
|
# define CX_UX |
# define CX_UX |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(DGUX) |
# if defined(DGUX) && defined(m88k) |
# define M88K |
# define M88K |
/* DGUX defined */ |
/* DGUX defined */ |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ |
# if defined(_WIN32_WCE) |
|| defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) |
/* SH3, SH4, MIPS already defined for corresponding architectures */ |
# define I386 |
# if defined(SH3) || defined(SH4) |
# define MSWIN32 /* or Win32s */ |
# define SH |
|
# endif |
|
# if defined(x86) |
|
# define I386 |
|
# endif |
|
# if defined(ARM) |
|
# define ARM32 |
|
# endif |
|
# define MSWINCE |
# define mach_type_known |
# define mach_type_known |
|
# else |
|
# if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ |
|
|| defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) |
|
# define I386 |
|
# define MSWIN32 /* or Win32s */ |
|
# define mach_type_known |
|
# endif |
# endif |
# endif |
# if defined(__DJGPP__) |
# if defined(__DJGPP__) |
# define I386 |
# define I386 |
|
|
# define CYGWIN32 |
# define CYGWIN32 |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(__MINGW32__) |
|
# define I386 |
|
# define MSWIN32 |
|
# define mach_type_known |
|
# endif |
# if defined(__BORLANDC__) |
# if defined(__BORLANDC__) |
# define I386 |
# define I386 |
# define MSWIN32 |
# define MSWIN32 |
|
|
# define UTS4 |
# define UTS4 |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(__pj__) |
|
# define PJ |
|
# define mach_type_known |
|
# endif |
|
# if defined(__embedded__) && defined(PPC) |
|
# define POWERPC |
|
# define NOSYS |
|
# define mach_type_known |
|
# endif |
/* Ivan Demakov */ |
/* Ivan Demakov */ |
# if defined(__WATCOMC__) && defined(__386__) |
# if defined(__WATCOMC__) && defined(__386__) |
# define I386 |
# define I386 |
|
|
# endif |
# endif |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
|
# if defined(__s390__) && defined(LINUX) |
|
# define S370 |
|
# define mach_type_known |
|
# endif |
|
# if defined(__GNU__) |
|
# if defined(__i386__) |
|
/* The Debian Hurd running on generic PC */ |
|
# define HURD |
|
# define I386 |
|
# define mach_type_known |
|
# endif |
|
# endif |
|
|
/* Feel free to add more clauses here */ |
/* Feel free to add more clauses here */ |
|
|
|
|
/* RS6000 ==> IBM RS/6000 AIX3.X */ |
/* RS6000 ==> IBM RS/6000 AIX3.X */ |
/* RT ==> IBM PC/RT */ |
/* RT ==> IBM PC/RT */ |
/* HP_PA ==> HP9000/700 & /800 */ |
/* HP_PA ==> HP9000/700 & /800 */ |
/* HP/UX */ |
/* HP/UX, LINUX */ |
/* SPARC ==> SPARC under SunOS */ |
/* SPARC ==> SPARC v7/v8/v9 */ |
/* (SUNOS4, SUNOS5, */ |
/* (SUNOS4, SUNOS5, LINUX, */ |
/* DRSNX variants) */ |
/* DRSNX variants) */ |
/* ALPHA ==> DEC Alpha */ |
/* ALPHA ==> DEC Alpha */ |
/* (OSF1 and LINUX variants) */ |
/* (OSF1 and LINUX variants) */ |
|
|
/* (CX_UX and DGUX) */ |
/* (CX_UX and DGUX) */ |
/* S370 ==> 370-like machine */ |
/* S370 ==> 370-like machine */ |
/* running Amdahl UTS4 */ |
/* running Amdahl UTS4 */ |
|
/* or a 390 running LINUX */ |
|
/* ARM32 ==> Intel StrongARM */ |
|
/* IA64 ==> Intel IPF */ |
|
/* (e.g. Itanium) */ |
|
/* (LINUX and HPUX) */ |
|
/* IA64_32 ==> IA64 w/32 bit ABI */ |
|
/* (HPUX) */ |
|
/* SH ==> Hitachi SuperH */ |
|
/* (LINUX & MSWINCE) */ |
|
|
|
|
/* |
/* |
|
|
* defining it to be 1 will always work, but perform poorly. |
* defining it to be 1 will always work, but perform poorly. |
* |
* |
* DATASTART is the beginning of the data segment. |
* DATASTART is the beginning of the data segment. |
* On UNIX systems, the collector will scan the area between DATASTART |
* On some platforms SEARCH_FOR_DATA_START is defined. |
|
* SEARCH_FOR_DATASTART will cause GC_data_start to |
|
* be set to an address determined by accessing data backwards from _end |
|
* until an unmapped page is found. DATASTART will be defined to be |
|
* GC_data_start. |
|
* On UNIX-like systems, the collector will scan the area between DATASTART |
* and DATAEND for root pointers. |
* and DATAEND for root pointers. |
* |
* |
* DATAEND, if not &end. |
* DATAEND, if not `end' where `end' is defined as ``extern int end[];''. |
|
* RTH suggests gaining access to linker script synth'd values with |
|
* this idiom instead of `&end' where `end' is defined as ``extern int end;'' . |
* |
* |
* ALIGN_DOUBLE of GC_malloc should return blocks aligned to twice |
* ALIGN_DOUBLE of GC_malloc should return blocks aligned to twice |
* the pointer size. |
* the pointer size. |
|
|
* 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and |
* 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and |
* 2) define exactly one of |
* 2) define exactly one of |
* STACKBOTTOM (should be defined to be an expression) |
* STACKBOTTOM (should be defined to be an expression) |
|
* LINUX_STACKBOTTOM |
* HEURISTIC1 |
* HEURISTIC1 |
* HEURISTIC2 |
* HEURISTIC2 |
|
* If STACKBOTTOM is defined, then it's value will be used directly as the |
|
* stack base. If LINUX_STACKBOTTOM is defined, then it will be determined |
|
* with a method appropriate for most Linux systems. Currently we look |
|
* first for __libc_stack_end, and if that fails read it from /proc. |
* If either of the last two macros are defined, then STACKBOTTOM is computed |
* If either of the last two macros are defined, then STACKBOTTOM is computed |
* during collector startup using one of the following two heuristics: |
* during collector startup using one of the following two heuristics: |
* HEURISTIC1: Take an address inside GC_init's frame, and round it up to |
* HEURISTIC1: Take an address inside GC_init's frame, and round it up to |
|
|
* to the nearest plausible page boundary, and use that instead |
* to the nearest plausible page boundary, and use that instead |
* of STACKBOTTOM. |
* of STACKBOTTOM. |
* |
* |
|
* Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines, |
|
* the value of environ is a pointer that can serve as STACKBOTTOM. |
|
* I expect that HEURISTIC2 can be replaced by this approach, which |
|
* interferes far less with debugging. However it has the disadvantage |
|
* that it's confused by a putenv call before the collector is initialized. |
|
* This could be dealt with by intercepting putenv ... |
|
* |
* If no expression for STACKBOTTOM can be found, and neither of the above |
* If no expression for STACKBOTTOM can be found, and neither of the above |
* heuristics are usable, the collector can still be used with all of the above |
* heuristics are usable, the collector can still be used with all of the above |
* undefined, provided one of the following is done: |
* undefined, provided one of the following is done: |
|
|
* |
* |
* An architecture may define DYNAMIC_LOADING if dynamic_load.c |
* An architecture may define DYNAMIC_LOADING if dynamic_load.c |
* defined GC_register_dynamic_libraries() for the architecture. |
* defined GC_register_dynamic_libraries() for the architecture. |
|
* |
|
* An architecture may define PREFETCH(x) to preload the cache with *x. |
|
* This defaults to a no-op. |
|
* |
|
* PREFETCH_FOR_WRITE(x) is used if *x is about to be written. |
|
* |
|
* An architecture may also define CLEAR_DOUBLE(x) to be a fast way to |
|
* clear the two words at GC_malloc-aligned address x. By default, |
|
* word stores of 0 are used instead. |
|
* |
|
* HEAP_START may be defined as the initial address hint for mmap-based |
|
* allocation. |
*/ |
*/ |
|
|
|
/* If we are using a recent version of gcc, we can use __builtin_unwind_init() |
|
* to push the relevant registers onto the stack. This generally makes |
|
* USE_GENERIC_PUSH_REGS the preferred approach for marking from registers. |
|
*/ |
|
# if defined(__GNUC__) && ((__GNUC__ >= 3) || \ |
|
(__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) |
|
# define HAVE_BUILTIN_UNWIND_INIT |
|
# endif |
|
|
# define STACK_GRAN 0x1000000 |
# define STACK_GRAN 0x1000000 |
# ifdef M68K |
# ifdef M68K |
|
|
# ifdef OPENBSD |
# ifdef OPENBSD |
# define OS_TYPE "OPENBSD" |
# define OS_TYPE "OPENBSD" |
# define HEURISTIC2 |
# define HEURISTIC2 |
extern char etext; |
extern char etext[]; |
# define DATASTART ((ptr_t)(&etext)) |
# define DATASTART ((ptr_t)(etext)) |
# endif |
# endif |
# ifdef NETBSD |
# ifdef NETBSD |
# define OS_TYPE "NETBSD" |
# define OS_TYPE "NETBSD" |
# define HEURISTIC2 |
# define HEURISTIC2 |
extern char etext; |
extern char etext[]; |
# define DATASTART ((ptr_t)(&etext)) |
# define DATASTART ((ptr_t)(etext)) |
# endif |
# endif |
# ifdef LINUX |
# ifdef LINUX |
# define OS_TYPE "LINUX" |
# define OS_TYPE "LINUX" |
# define STACKBOTTOM ((ptr_t)0xf0000000) |
# define STACKBOTTOM ((ptr_t)0xf0000000) |
# define MPROTECT_VDB |
/* # define MPROTECT_VDB - Reported to not work 9/17/01 */ |
# ifdef __ELF__ |
# ifdef __ELF__ |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
extern char **__environ; |
# include <features.h> |
# define DATASTART ((ptr_t)(&__environ)) |
# if defined(__GLIBC__)&& __GLIBC__>=2 |
|
# define LINUX_DATA_START |
|
# else /* !GLIBC2 */ |
|
extern char **__environ; |
|
# define DATASTART ((ptr_t)(&__environ)) |
/* hideous kludge: __environ is the first */ |
/* hideous kludge: __environ is the first */ |
/* word in crt0.o, and delimits the start */ |
/* word in crt0.o, and delimits the start */ |
/* of the data segment, no matter which */ |
/* of the data segment, no matter which */ |
|
|
/* would include .rodata, which may */ |
/* would include .rodata, which may */ |
/* contain large read-only data tables */ |
/* contain large read-only data tables */ |
/* that we'd rather not scan. */ |
/* that we'd rather not scan. */ |
extern int _end; |
# endif /* !GLIBC2 */ |
# define DATAEND (&_end) |
extern int _end[]; |
|
# define DATAEND (_end) |
# else |
# else |
extern int etext; |
extern int etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff)) |
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) |
# endif |
# endif |
# endif |
# endif |
# ifdef SUNOS4 |
# ifdef SUNOS4 |
# define OS_TYPE "SUNOS4" |
# define OS_TYPE "SUNOS4" |
extern char etext; |
extern char etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0x1ffff) & ~0x1ffff)) |
# define DATASTART ((ptr_t)((((word) (etext)) + 0x1ffff) & ~0x1ffff)) |
# define HEURISTIC1 /* differs */ |
# define HEURISTIC1 /* differs */ |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# endif |
# endif |
# ifdef HP |
# ifdef HP |
# define OS_TYPE "HP" |
# define OS_TYPE "HP" |
extern char etext; |
extern char etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff)) |
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) |
# define STACKBOTTOM ((ptr_t) 0xffeffffc) |
# define STACKBOTTOM ((ptr_t) 0xffeffffc) |
/* empirically determined. seems to work. */ |
/* empirically determined. seems to work. */ |
# include <unistd.h> |
# include <unistd.h> |
|
|
# endif |
# endif |
# ifdef SYSV |
# ifdef SYSV |
# define OS_TYPE "SYSV" |
# define OS_TYPE "SYSV" |
extern etext; |
extern etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0x3fffff) \ |
# define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \ |
& ~0x3fffff) \ |
& ~0x3fffff) \ |
+((word)&etext & 0x1fff)) |
+((word)etext & 0x1fff)) |
/* This only works for shared-text binaries with magic number 0413. |
/* This only works for shared-text binaries with magic number 0413. |
The other sorts of SysV binaries put the data at the end of the text, |
The other sorts of SysV binaries put the data at the end of the text, |
in which case the default of &etext would work. Unfortunately, |
in which case the default of etext would work. Unfortunately, |
handling both would require having the magic-number available. |
handling both would require having the magic-number available. |
-- Parag |
-- Parag |
*/ |
*/ |
|
|
/* This was 2, but that didn't sound right. */ |
/* This was 2, but that didn't sound right. */ |
# define OS_TYPE "LINUX" |
# define OS_TYPE "LINUX" |
# define HEURISTIC1 |
# define HEURISTIC1 |
|
# define DYNAMIC_LOADING |
# undef STACK_GRAN |
# undef STACK_GRAN |
# define STACK_GRAN 0x10000000 |
# define STACK_GRAN 0x10000000 |
/* Stack usually starts at 0x80000000 */ |
/* Stack usually starts at 0x80000000 */ |
# define DATASTART GC_data_start |
# define LINUX_DATA_START |
extern int _end; |
extern int _end[]; |
# define DATAEND (&_end) |
# define DATAEND (_end) |
# endif |
# endif |
# ifdef MACOSX |
# ifdef MACOSX |
|
/* There are reasons to suspect this may not be reliable. */ |
# define ALIGNMENT 4 |
# define ALIGNMENT 4 |
# define OS_TYPE "MACOSX" |
# define OS_TYPE "MACOSX" |
# define DATASTART ((ptr_t) get_etext()) |
# define DATASTART ((ptr_t) get_etext()) |
# define STACKBOTTOM ((ptr_t) 0xc0000000) |
# define STACKBOTTOM ((ptr_t) 0xc0000000) |
# define DATAEND /* not needed */ |
# define DATAEND /* not needed */ |
|
# define MPROTECT_VDB |
|
# include <unistd.h> |
|
# define GETPAGESIZE() getpagesize() |
# endif |
# endif |
|
# ifdef NETBSD |
|
# define ALIGNMENT 4 |
|
# define OS_TYPE "NETBSD" |
|
# define HEURISTIC2 |
|
extern char etext[]; |
|
# define DATASTART GC_data_start |
|
# define DYNAMIC_LOADING |
|
# endif |
|
# ifdef NOSYS |
|
# define ALIGNMENT 4 |
|
# define OS_TYPE "NOSYS" |
|
extern void __end[], __dso_handle[]; |
|
# define DATASTART (__dso_handle) /* OK, that's ugly. */ |
|
# define DATAEND (__end) |
|
/* Stack starts at 0xE0000000 for the simulator. */ |
|
# undef STACK_GRAN |
|
# define STACK_GRAN 0x10000000 |
|
# define HEURISTIC1 |
|
# endif |
# endif |
# endif |
|
|
# ifdef VAX |
# ifdef VAX |
# define MACH_TYPE "VAX" |
# define MACH_TYPE "VAX" |
# define ALIGNMENT 4 /* Pointers are longword aligned by 4.2 C compiler */ |
# define ALIGNMENT 4 /* Pointers are longword aligned by 4.2 C compiler */ |
extern char etext; |
extern char etext[]; |
# define DATASTART ((ptr_t)(&etext)) |
# define DATASTART ((ptr_t)(etext)) |
# ifdef BSD |
# ifdef BSD |
# define OS_TYPE "BSD" |
# define OS_TYPE "BSD" |
# define HEURISTIC1 |
# define HEURISTIC1 |
|
|
|
|
# ifdef SPARC |
# ifdef SPARC |
# define MACH_TYPE "SPARC" |
# define MACH_TYPE "SPARC" |
# define ALIGNMENT 4 /* Required by hardware */ |
# if defined(__arch64__) || defined(__sparcv9) |
|
# define ALIGNMENT 8 |
|
# define CPP_WORDSZ 64 |
|
# define ELF_CLASS ELFCLASS64 |
|
# else |
|
# define ALIGNMENT 4 /* Required by hardware */ |
|
# define CPP_WORDSZ 32 |
|
# endif |
# define ALIGN_DOUBLE |
# define ALIGN_DOUBLE |
extern int etext; |
|
# ifdef SUNOS5 |
# ifdef SUNOS5 |
# define OS_TYPE "SUNOS5" |
# define OS_TYPE "SUNOS5" |
extern int _etext; |
extern int _etext[]; |
extern int _end; |
extern int _end[]; |
extern char * GC_SysVGetDataStart(); |
extern char * GC_SysVGetDataStart(); |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext) |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext) |
# define DATAEND (&_end) |
# define DATAEND (_end) |
# ifndef USE_MMAP |
# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) |
# define USE_MMAP |
# define USE_MMAP |
|
/* Otherwise we now use calloc. Mmap may result in the */ |
|
/* heap interleaved with thread stacks, which can result in */ |
|
/* excessive blacklisting. Sbrk is unusable since it */ |
|
/* doesn't interact correctly with the system malloc. */ |
# endif |
# endif |
# ifdef USE_MMAP |
# ifdef USE_MMAP |
# define HEAP_START (ptr_t)0x40000000 |
# define HEAP_START (ptr_t)0x40000000 |
|
|
# define HEAP_START DATAEND |
# define HEAP_START DATAEND |
# endif |
# endif |
# define PROC_VDB |
# define PROC_VDB |
/* HEURISTIC1 reportedly no longer works under 2.7. Thus we */ |
/* HEURISTIC1 reportedly no longer works under 2.7. */ |
/* switched to HEURISTIC2, eventhough it creates some debugging */ |
/* HEURISTIC2 probably works, but this appears to be preferable. */ |
/* issues. */ |
/* Apparently USRSTACK is defined to be USERLIMIT, but in some */ |
#if MPI |
/* installations that's undefined. We work around this with a */ |
extern int *StackBottom; |
/* gross hack: */ |
# define STACKBOTTOM (ptr_t)(StackBottom) |
# include <sys/vmparam.h> |
#else |
# ifdef USERLIMIT |
# define HEURISTIC2 |
/* This should work everywhere, but doesn't. */ |
#endif |
# define STACKBOTTOM USRSTACK |
|
# else |
|
# define HEURISTIC2 |
|
# endif |
# include <unistd.h> |
# include <unistd.h> |
# define GETPAGESIZE() sysconf(_SC_PAGESIZE) |
# define GETPAGESIZE() sysconf(_SC_PAGESIZE) |
/* getpagesize() appeared to be missing from at least one */ |
/* getpagesize() appeared to be missing from at least one */ |
|
|
# define OS_TYPE "SUNOS4" |
# define OS_TYPE "SUNOS4" |
/* [If you have a weak stomach, don't read this.] */ |
/* [If you have a weak stomach, don't read this.] */ |
/* We would like to use: */ |
/* We would like to use: */ |
/* # define DATASTART ((ptr_t)((((word) (&etext)) + 0x1fff) & ~0x1fff)) */ |
/* # define DATASTART ((ptr_t)((((word) (etext)) + 0x1fff) & ~0x1fff)) */ |
/* This fails occasionally, due to an ancient, but very */ |
/* This fails occasionally, due to an ancient, but very */ |
/* persistent ld bug. &etext is set 32 bytes too high. */ |
/* persistent ld bug. etext is set 32 bytes too high. */ |
/* We instead read the text segment size from the a.out */ |
/* We instead read the text segment size from the a.out */ |
/* header, which happens to be mapped into our address space */ |
/* header, which happens to be mapped into our address space */ |
/* at the start of the text segment. The detective work here */ |
/* at the start of the text segment. The detective work here */ |
|
|
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# endif |
# endif |
# ifdef DRSNX |
# ifdef DRSNX |
# define CPP_WORDSZ 32 |
|
# define OS_TYPE "DRSNX" |
# define OS_TYPE "DRSNX" |
extern char * GC_SysVGetDataStart(); |
extern char * GC_SysVGetDataStart(); |
extern int etext; |
extern int etext[]; |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &etext) |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext) |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
# define STACKBOTTOM ((ptr_t) 0xdfff0000) |
# define STACKBOTTOM ((ptr_t) 0xdfff0000) |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
|
|
# ifdef LINUX |
# ifdef LINUX |
# define OS_TYPE "LINUX" |
# define OS_TYPE "LINUX" |
# ifdef __ELF__ |
# ifdef __ELF__ |
# define DATASTART GC_data_start |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
|
# else |
# else |
Linux Sparc non elf ? |
Linux Sparc/a.out not supported |
# endif |
# endif |
extern int _end; |
extern int _end[]; |
# define DATAEND (&_end) |
extern int _etext[]; |
|
# define DATAEND (_end) |
# define SVR4 |
# define SVR4 |
# define STACKBOTTOM ((ptr_t) 0xf0000000) |
# ifdef __arch64__ |
|
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, _etext) |
|
/* libc_stack_end is not set reliably for sparc64 */ |
|
# define STACKBOTTOM ((ptr_t) 0x80000000000ULL) |
|
# else |
|
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext) |
|
# define LINUX_STACKBOTTOM |
|
# endif |
# endif |
# endif |
# ifdef OPENBSD |
# ifdef OPENBSD |
# define OS_TYPE "OPENBSD" |
# define OS_TYPE "OPENBSD" |
# define STACKBOTTOM ((ptr_t) 0xf8000000) |
# define STACKBOTTOM ((ptr_t) 0xf8000000) |
# define DATASTART ((ptr_t)(&etext)) |
extern int etext[]; |
|
# define DATASTART ((ptr_t)(etext)) |
# endif |
# endif |
|
# ifdef NETBSD |
|
# define OS_TYPE "NETBSD" |
|
# define HEURISTIC2 |
|
# ifdef __ELF__ |
|
# define DATASTART GC_data_start |
|
# define DYNAMIC_LOADING |
|
# else |
|
extern char etext[]; |
|
# define DATASTART ((ptr_t)(etext)) |
|
# endif |
|
# endif |
# endif |
# endif |
|
|
# ifdef I386 |
# ifdef I386 |
|
|
# define ALIGN_DOUBLE /* Not strictly necessary, but may give speed */ |
# define ALIGN_DOUBLE /* Not strictly necessary, but may give speed */ |
/* improvement on Pentiums. */ |
/* improvement on Pentiums. */ |
# endif |
# endif |
|
# ifdef HAVE_BUILTIN_UNWIND_INIT |
|
# define USE_GENERIC_PUSH_REGS |
|
# endif |
# ifdef SEQUENT |
# ifdef SEQUENT |
# define OS_TYPE "SEQUENT" |
# define OS_TYPE "SEQUENT" |
extern int etext; |
extern int etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff)) |
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) |
# define STACKBOTTOM ((ptr_t) 0x3ffff000) |
# define STACKBOTTOM ((ptr_t) 0x3ffff000) |
# endif |
# endif |
|
# ifdef BEOS |
|
# define OS_TYPE "BEOS" |
|
# include <OS.h> |
|
# define GETPAGESIZE() B_PAGE_SIZE |
|
extern int etext[]; |
|
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) |
|
# endif |
# ifdef SUNOS5 |
# ifdef SUNOS5 |
# define OS_TYPE "SUNOS5" |
# define OS_TYPE "SUNOS5" |
extern int etext, _start; |
extern int _etext[], _end[]; |
extern char * GC_SysVGetDataStart(); |
extern char * GC_SysVGetDataStart(); |
# define DATASTART GC_SysVGetDataStart(0x1000, &etext) |
# define DATASTART GC_SysVGetDataStart(0x1000, _etext) |
# define STACKBOTTOM ((ptr_t)(&_start)) |
# define DATAEND (_end) |
/** At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ |
/* # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7, */ |
/*# define PROC_VDB*/ |
/* but reportedly breaks under 2.8. It appears that the stack */ |
|
/* base is a property of the executable, so this should not break */ |
|
/* old executables. */ |
|
/* HEURISTIC2 probably works, but this appears to be preferable. */ |
|
# include <sys/vm.h> |
|
# define STACKBOTTOM USRSTACK |
|
/* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ |
|
/* It appears to be fixed in 2.8 and 2.9. */ |
|
# ifdef SOLARIS25_PROC_VDB_BUG_FIXED |
|
# define PROC_VDB |
|
# endif |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# ifndef USE_MMAP |
# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) |
# define USE_MMAP |
# define USE_MMAP |
|
/* Otherwise we now use calloc. Mmap may result in the */ |
|
/* heap interleaved with thread stacks, which can result in */ |
|
/* excessive blacklisting. Sbrk is unusable since it */ |
|
/* doesn't interact correctly with the system malloc. */ |
# endif |
# endif |
# ifdef USE_MMAP |
# ifdef USE_MMAP |
# define HEAP_START (ptr_t)0x40000000 |
# define HEAP_START (ptr_t)0x40000000 |
|
|
# endif |
# endif |
# ifdef SCO |
# ifdef SCO |
# define OS_TYPE "SCO" |
# define OS_TYPE "SCO" |
extern int etext; |
extern int etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0x3fffff) \ |
# define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \ |
& ~0x3fffff) \ |
& ~0x3fffff) \ |
+((word)&etext & 0xfff)) |
+((word)etext & 0xfff)) |
# define STACKBOTTOM ((ptr_t) 0x7ffffffc) |
# define STACKBOTTOM ((ptr_t) 0x7ffffffc) |
# endif |
# endif |
# ifdef SCO_ELF |
# ifdef SCO_ELF |
# define OS_TYPE "SCO_ELF" |
# define OS_TYPE "SCO_ELF" |
extern int etext; |
extern int etext[]; |
# define DATASTART ((ptr_t)(&etext)) |
# define DATASTART ((ptr_t)(etext)) |
# define STACKBOTTOM ((ptr_t) 0x08048000) |
# define STACKBOTTOM ((ptr_t) 0x08048000) |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# define ELF_CLASS ELFCLASS32 |
# define ELF_CLASS ELFCLASS32 |
# endif |
# endif |
|
# ifdef DGUX |
|
# define OS_TYPE "DGUX" |
|
extern int _etext, _end; |
|
extern char * GC_SysVGetDataStart(); |
|
# define DATASTART GC_SysVGetDataStart(0x1000, &_etext) |
|
# define DATAEND (&_end) |
|
# define STACK_GROWS_DOWN |
|
# define HEURISTIC2 |
|
# include <unistd.h> |
|
# define GETPAGESIZE() sysconf(_SC_PAGESIZE) |
|
# define DYNAMIC_LOADING |
|
# ifndef USE_MMAP |
|
# define USE_MMAP |
|
# endif /* USE_MMAP */ |
|
# define MAP_FAILED (void *) -1 |
|
# ifdef USE_MMAP |
|
# define HEAP_START (ptr_t)0x40000000 |
|
# else /* USE_MMAP */ |
|
# define HEAP_START DATAEND |
|
# endif /* USE_MMAP */ |
|
# endif /* DGUX */ |
|
|
# ifdef LINUX |
# ifdef LINUX |
|
# ifndef __GNUC__ |
|
/* The Intel compiler doesn't like inline assembly */ |
|
# define USE_GENERIC_PUSH_REGS |
|
# endif |
# define OS_TYPE "LINUX" |
# define OS_TYPE "LINUX" |
# define STACKBOTTOM ((ptr_t)0xc0000000) |
# define LINUX_STACKBOTTOM |
/* Appears to be 0xe0000000 for at least one 2.1.91 kernel. */ |
# define USE_MMAP |
/* Probably needs to be more flexible, but I don't yet */ |
# if 0 |
/* fully understand how flexible. */ |
# define HEURISTIC1 |
# if !defined(LINUX_THREADS) || !defined(REDIRECT_MALLOC) |
# undef STACK_GRAN |
|
# define STACK_GRAN 0x10000000 |
|
/* STACKBOTTOM is usually 0xc0000000, but this changes with */ |
|
/* different kernel configurations. In particular, systems */ |
|
/* with 2GB physical memory will usually move the user */ |
|
/* address space limit, and hence initial SP to 0x80000000. */ |
|
# endif |
|
# if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC) |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
# else |
# else |
/* We seem to get random errors in incremental mode, */ |
/* We seem to get random errors in incremental mode, */ |
/* possibly because Linux threads is itself a malloc client */ |
/* possibly because Linux threads is itself a malloc client */ |
/* and can't deal with the signals. */ |
/* and can't deal with the signals. */ |
# endif |
# endif |
|
# define HEAP_START 0x1000 |
|
/* This encourages mmap to give us low addresses, */ |
|
/* thus allowing the heap to grow to ~3GB */ |
# ifdef __ELF__ |
# ifdef __ELF__ |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# ifdef UNDEFINED /* includes ro data */ |
# ifdef UNDEFINED /* includes ro data */ |
extern int _etext; |
extern int _etext[]; |
# define DATASTART ((ptr_t)((((word) (&_etext)) + 0xfff) & ~0xfff)) |
# define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff)) |
# endif |
# endif |
# include <features.h> |
# include <features.h> |
# if defined(__GLIBC__) && __GLIBC__ >= 2 |
# if defined(__GLIBC__) && __GLIBC__ >= 2 |
extern int __data_start; |
# define LINUX_DATA_START |
# define DATASTART ((ptr_t)(&__data_start)) |
|
# else |
# else |
extern char **__environ; |
extern char **__environ; |
# define DATASTART ((ptr_t)(&__environ)) |
# define DATASTART ((ptr_t)(&__environ)) |
|
|
/* contain large read-only data tables */ |
/* contain large read-only data tables */ |
/* that we'd rather not scan. */ |
/* that we'd rather not scan. */ |
# endif |
# endif |
extern int _end; |
extern int _end[]; |
# define DATAEND (&_end) |
# define DATAEND (_end) |
# else |
# else |
extern int etext; |
extern int etext[]; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff)) |
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) |
# endif |
# endif |
|
# ifdef USE_I686_PREFETCH |
|
# define PREFETCH(x) \ |
|
__asm__ __volatile__ (" prefetchnta %0": : "m"(*(char *)(x))) |
|
/* Empirically prefetcht0 is much more effective at reducing */ |
|
/* cache miss stalls for the targetted load instructions. But it */ |
|
/* seems to interfere enough with other cache traffic that the net */ |
|
/* result is worse than prefetchnta. */ |
|
# if 0 |
|
/* Using prefetches for write seems to have a slight negative */ |
|
/* impact on performance, at least for a PIII/500. */ |
|
# define PREFETCH_FOR_WRITE(x) \ |
|
__asm__ __volatile__ (" prefetcht0 %0": : "m"(*(char *)(x))) |
|
# endif |
|
# endif |
|
# ifdef USE_3DNOW_PREFETCH |
|
# define PREFETCH(x) \ |
|
__asm__ __volatile__ (" prefetch %0": : "m"(*(char *)(x))) |
|
# define PREFETCH_FOR_WRITE(x) \ |
|
__asm__ __volatile__ (" prefetchw %0": : "m"(*(char *)(x))) |
|
# endif |
# endif |
# endif |
# ifdef CYGWIN32 |
# ifdef CYGWIN32 |
# define OS_TYPE "CYGWIN32" |
# define OS_TYPE "CYGWIN32" |
extern int _data_start__; |
extern int _data_start__[]; |
extern int _data_end__; |
extern int _data_end__[]; |
extern int _bss_start__; |
extern int _bss_start__[]; |
extern int _bss_end__; |
extern int _bss_end__[]; |
/* For binutils 2.9.1, we have */ |
/* For binutils 2.9.1, we have */ |
/* DATASTART = _data_start__ */ |
/* DATASTART = _data_start__ */ |
/* DATAEND = _bss_end__ */ |
/* DATAEND = _bss_end__ */ |
|
|
/* minumum/maximum of the two. */ |
/* minumum/maximum of the two. */ |
# define MAX(x,y) ((x) > (y) ? (x) : (y)) |
# define MAX(x,y) ((x) > (y) ? (x) : (y)) |
# define MIN(x,y) ((x) < (y) ? (x) : (y)) |
# define MIN(x,y) ((x) < (y) ? (x) : (y)) |
# define DATASTART ((ptr_t) MIN(&_data_start__, &_bss_start__)) |
# define DATASTART ((ptr_t) MIN(_data_start__, _bss_start__)) |
# define DATAEND ((ptr_t) MAX(&_data_end__, &_bss_end__)) |
# define DATAEND ((ptr_t) MAX(_data_end__, _bss_end__)) |
# undef STACK_GRAN |
# undef STACK_GRAN |
# define STACK_GRAN 0x10000 |
# define STACK_GRAN 0x10000 |
# define HEURISTIC1 |
# define HEURISTIC1 |
|
|
/* os_dep.c. OS2 actually has the right */ |
/* os_dep.c. OS2 actually has the right */ |
/* system call! */ |
/* system call! */ |
# define DATAEND /* not needed */ |
# define DATAEND /* not needed */ |
|
# define USE_GENERIC_PUSH_REGS |
# endif |
# endif |
# ifdef MSWIN32 |
# ifdef MSWIN32 |
# define OS_TYPE "MSWIN32" |
# define OS_TYPE "MSWIN32" |
|
|
# endif |
# endif |
# define DATAEND /* not needed */ |
# define DATAEND /* not needed */ |
# endif |
# endif |
|
# ifdef MSWINCE |
|
# define OS_TYPE "MSWINCE" |
|
# define DATAEND /* not needed */ |
|
# endif |
# ifdef DJGPP |
# ifdef DJGPP |
# define OS_TYPE "DJGPP" |
# define OS_TYPE "DJGPP" |
# include "stubinfo.h" |
# include "stubinfo.h" |
extern int etext; |
extern int etext[]; |
extern int _stklen; |
extern int _stklen; |
extern int __djgpp_stack_limit; |
extern int __djgpp_stack_limit; |
# define DATASTART ((ptr_t)((((word) (&etext)) + 0x1ff) & ~0x1ff)) |
# define DATASTART ((ptr_t)((((word) (etext)) + 0x1ff) & ~0x1ff)) |
/* # define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \ |
/* # define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \ |
+ _stklen)) */ |
+ _stklen)) */ |
# define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen)) |
# define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen)) |
|
|
# endif |
# endif |
# ifdef FREEBSD |
# ifdef FREEBSD |
# define OS_TYPE "FREEBSD" |
# define OS_TYPE "FREEBSD" |
# define MPROTECT_VDB |
# ifndef GC_FREEBSD_THREADS |
|
# define MPROTECT_VDB |
|
# endif |
|
# define SIG_SUSPEND SIGUSR1 |
|
# define SIG_THR_RESTART SIGUSR2 |
|
# define FREEBSD_STACKBOTTOM |
|
# ifdef __ELF__ |
|
# define DYNAMIC_LOADING |
|
# endif |
|
extern char etext[]; |
|
# define DATASTART ((ptr_t)(etext)) |
# endif |
# endif |
# ifdef NETBSD |
# ifdef NETBSD |
# define OS_TYPE "NETBSD" |
# define OS_TYPE "NETBSD" |
|
# ifdef __ELF__ |
|
# define DYNAMIC_LOADING |
|
# endif |
# endif |
# endif |
# ifdef THREE86BSD |
# ifdef THREE86BSD |
# define OS_TYPE "THREE86BSD" |
# define OS_TYPE "THREE86BSD" |
|
|
# ifdef BSDI |
# ifdef BSDI |
# define OS_TYPE "BSDI" |
# define OS_TYPE "BSDI" |
# endif |
# endif |
# if defined(OPENBSD) || defined(FREEBSD) || defined(NETBSD) \ |
# if defined(OPENBSD) || defined(NETBSD) \ |
|| defined(THREE86BSD) || defined(BSDI) |
|| defined(THREE86BSD) || defined(BSDI) |
# define HEURISTIC2 |
# define HEURISTIC2 |
extern char etext; |
extern char etext[]; |
# define DATASTART ((ptr_t)(&etext)) |
# define DATASTART ((ptr_t)(etext)) |
# endif |
# endif |
# ifdef NEXT |
# ifdef NEXT |
# define OS_TYPE "NEXT" |
# define OS_TYPE "NEXT" |
|
|
# define DATASTART ((ptr_t) &__nullarea) |
# define DATASTART ((ptr_t) &__nullarea) |
# define DATAEND ((ptr_t) &_end) |
# define DATAEND ((ptr_t) &_end) |
# endif |
# endif |
|
# ifdef HURD |
|
# define OS_TYPE "HURD" |
|
# define STACK_GROWS_DOWN |
|
# define HEURISTIC2 |
|
extern int __data_start[]; |
|
# define DATASTART ( (ptr_t) (__data_start)) |
|
extern int _end[]; |
|
# define DATAEND ( (ptr_t) (_end)) |
|
/* # define MPROTECT_VDB Not quite working yet? */ |
|
# define DYNAMIC_LOADING |
|
# endif |
# endif |
# endif |
|
|
# ifdef NS32K |
# ifdef NS32K |
|
|
|
|
# ifdef MIPS |
# ifdef MIPS |
# define MACH_TYPE "MIPS" |
# define MACH_TYPE "MIPS" |
# ifndef IRIX5 |
# ifdef LINUX |
# define DATASTART (ptr_t)0x10000000 |
/* This was developed for a linuxce style platform. Probably */ |
|
/* needs to be tweaked for workstation class machines. */ |
|
# define OS_TYPE "LINUX" |
|
# define DYNAMIC_LOADING |
|
extern int _end[]; |
|
# define DATAEND (_end) |
|
extern int __data_start[]; |
|
# define DATASTART ((ptr_t)(__data_start)) |
|
# define ALIGNMENT 4 |
|
# define USE_GENERIC_PUSH_REGS |
|
# define LINUX_STACKBOTTOM |
|
# endif /* Linux */ |
|
# ifdef EWS4800 |
|
# define HEURISTIC2 |
|
# if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64) |
|
extern int _fdata[], _end[]; |
|
# define DATASTART ((ptr_t)_fdata) |
|
# define DATAEND ((ptr_t)_end) |
|
# define CPP_WORDSZ _MIPS_SZPTR |
|
# define ALIGNMENT (_MIPS_SZPTR/8) |
|
# else |
|
extern int etext[], edata[], end[]; |
|
extern int _DYNAMIC_LINKING[], _gp[]; |
|
# define DATASTART ((ptr_t)((((word)etext + 0x3ffff) & ~0x3ffff) \ |
|
+ ((word)etext & 0xffff))) |
|
# define DATAEND (edata) |
|
# define DATASTART2 (_DYNAMIC_LINKING \ |
|
? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \ |
|
: (ptr_t)edata) |
|
# define DATAEND2 (end) |
|
# define ALIGNMENT 4 |
|
# endif |
|
# define OS_TYPE "EWS4800" |
|
# define USE_GENERIC_PUSH_REGS 1 |
|
# endif |
|
# ifdef ULTRIX |
|
# define HEURISTIC2 |
|
# define DATASTART (ptr_t)0x10000000 |
/* Could probably be slightly higher since */ |
/* Could probably be slightly higher since */ |
/* startup code allocates lots of stuff. */ |
/* startup code allocates lots of stuff. */ |
# else |
|
extern int _fdata; |
|
# define DATASTART ((ptr_t)(&_fdata)) |
|
# ifdef USE_MMAP |
|
# define HEAP_START (ptr_t)0x30000000 |
|
# else |
|
# define HEAP_START DATASTART |
|
# endif |
|
/* Lowest plausible heap address. */ |
|
/* In the MMAP case, we map there. */ |
|
/* In either case it is used to identify */ |
|
/* heap sections so they're not */ |
|
/* considered as roots. */ |
|
# endif /* IRIX5 */ |
|
# define HEURISTIC2 |
|
/* # define STACKBOTTOM ((ptr_t)0x7fff8000) sometimes also works. */ |
|
# ifdef ULTRIX |
|
# define OS_TYPE "ULTRIX" |
# define OS_TYPE "ULTRIX" |
# define ALIGNMENT 4 |
# define ALIGNMENT 4 |
# endif |
# endif |
# ifdef RISCOS |
# ifdef RISCOS |
|
# define HEURISTIC2 |
|
# define DATASTART (ptr_t)0x10000000 |
# define OS_TYPE "RISCOS" |
# define OS_TYPE "RISCOS" |
# define ALIGNMENT 4 /* Required by hardware */ |
# define ALIGNMENT 4 /* Required by hardware */ |
# endif |
# endif |
# ifdef IRIX5 |
# ifdef IRIX5 |
|
# define HEURISTIC2 |
|
extern int _fdata[]; |
|
# define DATASTART ((ptr_t)(_fdata)) |
|
# ifdef USE_MMAP |
|
# define HEAP_START (ptr_t)0x30000000 |
|
# else |
|
# define HEAP_START DATASTART |
|
# endif |
|
/* Lowest plausible heap address. */ |
|
/* In the MMAP case, we map there. */ |
|
/* In either case it is used to identify */ |
|
/* heap sections so they're not */ |
|
/* considered as roots. */ |
# define OS_TYPE "IRIX5" |
# define OS_TYPE "IRIX5" |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
# ifdef _MIPS_SZPTR |
# ifdef _MIPS_SZPTR |
|
|
# endif |
# endif |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# endif |
# endif |
|
# ifdef MSWINCE |
|
# define OS_TYPE "MSWINCE" |
|
# define ALIGNMENT 4 |
|
# define DATAEND /* not needed */ |
|
# endif |
|
# if defined(NETBSD) |
|
/* This also checked for __MIPSEL__ . Why? NETBSD recognition */ |
|
/* should be handled at the top of the file. */ |
|
# define ALIGNMENT 4 |
|
# define OS_TYPE "NETBSD" |
|
# define HEURISTIC2 |
|
# define USE_GENERIC_PUSH_REGS |
|
# ifdef __ELF__ |
|
extern int etext[]; |
|
# define DATASTART GC_data_start |
|
# define NEED_FIND_LIMIT |
|
# define DYNAMIC_LOADING |
|
# else |
|
# define DATASTART ((ptr_t) 0x10000000) |
|
# define STACKBOTTOM ((ptr_t) 0x7ffff000) |
|
# endif /* _ELF_ */ |
|
# endif |
# endif |
# endif |
|
|
# ifdef RS6000 |
# ifdef RS6000 |
# define MACH_TYPE "RS6000" |
# define MACH_TYPE "RS6000" |
# define ALIGNMENT 4 |
# ifdef __64BIT__ |
# define DATASTART ((ptr_t)0x20000000) |
# define ALIGNMENT 8 |
|
# define CPP_WORDSZ 64 |
|
# define STACKBOTTOM 0x1000000000000000 |
|
# else |
|
# define ALIGNMENT 4 |
|
# define CPP_WORDSZ 32 |
|
# define STACKBOTTOM ((ptr_t)((ulong)&errno)) |
|
# endif |
|
extern int _data[], _end[]; |
|
# define DATASTART ((ptr_t)((ulong)_data)) |
|
# define DATAEND ((ptr_t)((ulong)_end)) |
extern int errno; |
extern int errno; |
# define STACKBOTTOM ((ptr_t)((ulong)&errno)) |
# define USE_GENERIC_PUSH_REGS |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
/* For really old versions of AIX, this may have to be removed. */ |
/* For really old versions of AIX, this may have to be removed. */ |
# endif |
# endif |
|
|
# ifdef HP_PA |
# ifdef HP_PA |
# define MACH_TYPE "HP_PA" |
# define MACH_TYPE "HP_PA" |
# define ALIGNMENT 4 |
# ifdef __LP64__ |
# define ALIGN_DOUBLE |
# define CPP_WORDSZ 64 |
extern int __data_start; |
# define ALIGNMENT 8 |
# define DATASTART ((ptr_t)(&__data_start)) |
# else |
# if 0 |
# define CPP_WORDSZ 32 |
|
# define ALIGNMENT 4 |
|
# define ALIGN_DOUBLE |
|
# endif |
|
# if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) |
|
# ifndef LINUX /* For now. */ |
|
# define MPROTECT_VDB |
|
# endif |
|
# else |
|
# define GENERIC_COMPARE_AND_SWAP |
|
/* No compare-and-swap instruction. Use pthread mutexes */ |
|
/* when we absolutely have to. */ |
|
# ifdef PARALLEL_MARK |
|
# define USE_MARK_BYTES |
|
/* Minimize compare-and-swap usage. */ |
|
# endif |
|
# endif |
|
# define STACK_GROWS_UP |
|
# ifdef HPUX |
|
# define OS_TYPE "HPUX" |
|
extern int __data_start[]; |
|
# define DATASTART ((ptr_t)(__data_start)) |
|
# if 0 |
/* The following appears to work for 7xx systems running HP/UX */ |
/* The following appears to work for 7xx systems running HP/UX */ |
/* 9.xx Furthermore, it might result in much faster */ |
/* 9.xx Furthermore, it might result in much faster */ |
/* collections than HEURISTIC2, which may involve scanning */ |
/* collections than HEURISTIC2, which may involve scanning */ |
|
|
/* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */ |
/* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */ |
/* this.) */ |
/* this.) */ |
# define STACKBOTTOM ((ptr_t) 0x7b033000) /* from /etc/conf/h/param.h */ |
# define STACKBOTTOM ((ptr_t) 0x7b033000) /* from /etc/conf/h/param.h */ |
# else |
# else |
# define HEURISTIC2 |
/* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */ |
# endif |
/* to this. Note that the GC must be initialized before the */ |
# define STACK_GROWS_UP |
/* first putenv call. */ |
# define DYNAMIC_LOADING |
extern char ** environ; |
# include <unistd.h> |
# define STACKBOTTOM ((ptr_t)environ) |
# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) |
# endif |
/* They misspelled the Posix macro? */ |
# define DYNAMIC_LOADING |
# endif |
# include <unistd.h> |
|
# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) |
|
# ifndef __GNUC__ |
|
# define PREFETCH(x) { \ |
|
register long addr = (long)(x); \ |
|
(void) _asm ("LDW", 0, 0, addr, 0); \ |
|
} |
|
# endif |
|
# endif /* HPUX */ |
|
# ifdef LINUX |
|
# define OS_TYPE "LINUX" |
|
# define LINUX_STACKBOTTOM |
|
# define DYNAMIC_LOADING |
|
# define SEARCH_FOR_DATA_START |
|
extern int _end[]; |
|
# define DATAEND (&_end) |
|
# endif /* LINUX */ |
|
# endif /* HP_PA */ |
|
|
# ifdef ALPHA |
# ifdef ALPHA |
# define MACH_TYPE "ALPHA" |
# define MACH_TYPE "ALPHA" |
# define ALIGNMENT 8 |
# define ALIGNMENT 8 |
|
# ifndef LINUX |
|
# define USE_GENERIC_PUSH_REGS |
|
/* Gcc and probably the DEC/Compaq compiler spill pointers to preserved */ |
|
/* fp registers in some cases when the target is a 21264. The assembly */ |
|
/* code doesn't handle that yet, and version dependencies make that a */ |
|
/* bit tricky. Do the easy thing for now. */ |
|
# endif |
|
# ifdef NETBSD |
|
# define OS_TYPE "NETBSD" |
|
# define HEURISTIC2 |
|
# define DATASTART GC_data_start |
|
# define ELFCLASS32 32 |
|
# define ELFCLASS64 64 |
|
# define ELF_CLASS ELFCLASS64 |
|
# define CPP_WORDSZ 64 |
|
# define DYNAMIC_LOADING |
|
# endif |
|
# ifdef OPENBSD |
|
# define OS_TYPE "OPENBSD" |
|
# define HEURISTIC2 |
|
# define CPP_WORDSZ 64 |
|
# ifdef __ELF__ /* since OpenBSD/Alpha 2.9 */ |
|
# define DATASTART GC_data_start |
|
# define ELFCLASS32 32 |
|
# define ELFCLASS64 64 |
|
# define ELF_CLASS ELFCLASS64 |
|
# else /* ECOFF, until OpenBSD/Alpha 2.7 */ |
|
# define DATASTART ((ptr_t) 0x140000000) |
|
# endif |
|
# endif |
|
# ifdef FREEBSD |
|
# define OS_TYPE "FREEBSD" |
|
/* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */ |
|
# define SIG_SUSPEND SIGUSR1 |
|
# define SIG_THR_RESTART SIGUSR2 |
|
# define FREEBSD_STACKBOTTOM |
|
# ifdef __ELF__ |
|
# define DYNAMIC_LOADING |
|
# endif |
|
/* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */ |
|
extern char etext[]; |
|
extern char edata[]; |
|
extern char end[]; |
|
# define NEED_FIND_LIMIT |
|
# define DATASTART ((ptr_t)(&etext)) |
|
# define DATAEND (GC_find_limit (DATASTART, TRUE)) |
|
# define DATASTART2 ((ptr_t)(&edata)) |
|
# define DATAEND2 ((ptr_t)(&end)) |
|
# define CPP_WORDSZ 64 |
|
# endif |
# ifdef OSF1 |
# ifdef OSF1 |
# define OS_TYPE "OSF1" |
# define OS_TYPE "OSF1" |
# define DATASTART ((ptr_t) 0x140000000) |
# define DATASTART ((ptr_t) 0x140000000) |
extern _end; |
extern int _end[]; |
# define DATAEND ((ptr_t) &_end) |
# define DATAEND ((ptr_t) &_end) |
# define HEURISTIC2 |
extern char ** environ; |
|
/* round up from the value of environ to the nearest page boundary */ |
|
/* Probably breaks if putenv is called before collector */ |
|
/* initialization. */ |
|
# define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1)) |
|
/* # define HEURISTIC2 */ |
/* Normally HEURISTIC2 is too conervative, since */ |
/* Normally HEURISTIC2 is too conervative, since */ |
/* the text segment immediately follows the stack. */ |
/* the text segment immediately follows the stack. */ |
/* Hence we give an upper pound. */ |
/* Hence we give an upper pound. */ |
extern int __start; |
/* This is currently unused, since we disabled HEURISTIC2 */ |
# define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1))) |
extern int __start[]; |
|
# define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1))) |
# define CPP_WORDSZ 64 |
# define CPP_WORDSZ 64 |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
|
|
# define CPP_WORDSZ 64 |
# define CPP_WORDSZ 64 |
# define STACKBOTTOM ((ptr_t) 0x120000000) |
# define STACKBOTTOM ((ptr_t) 0x120000000) |
# ifdef __ELF__ |
# ifdef __ELF__ |
# if 0 |
# define SEARCH_FOR_DATA_START |
/* __data_start apparently disappeared in some recent releases. */ |
|
extern int __data_start; |
|
# define DATASTART &__data_start |
|
# endif |
|
# define DATASTART GC_data_start |
|
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# else |
# else |
# define DATASTART ((ptr_t) 0x140000000) |
# define DATASTART ((ptr_t) 0x140000000) |
# endif |
# endif |
extern int _end; |
extern int _end[]; |
# define DATAEND (&_end) |
# define DATAEND (_end) |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
/* Has only been superficially tested. May not */ |
/* Has only been superficially tested. May not */ |
/* work on all versions. */ |
/* work on all versions. */ |
# endif |
# endif |
# endif |
# endif |
|
|
|
# ifdef IA64 |
|
# define MACH_TYPE "IA64" |
|
# define USE_GENERIC_PUSH_REGS |
|
/* We need to get preserved registers in addition to register */ |
|
/* windows. That's easiest to do with setjmp. */ |
|
# ifdef PARALLEL_MARK |
|
# define USE_MARK_BYTES |
|
/* Compare-and-exchange is too expensive to use for */ |
|
/* setting mark bits. */ |
|
# endif |
|
# ifdef HPUX |
|
# ifdef _ILP32 |
|
# define CPP_WORDSZ 32 |
|
# define ALIGN_DOUBLE |
|
/* Requires 8 byte alignment for malloc */ |
|
# define ALIGNMENT 4 |
|
# else |
|
# ifndef _LP64 |
|
---> unknown ABI |
|
# endif |
|
# define CPP_WORDSZ 64 |
|
# define ALIGN_DOUBLE |
|
/* Requires 16 byte alignment for malloc */ |
|
# define ALIGNMENT 8 |
|
# endif |
|
# define OS_TYPE "HPUX" |
|
extern int __data_start[]; |
|
# define DATASTART ((ptr_t)(__data_start)) |
|
/* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */ |
|
/* to this. Note that the GC must be initialized before the */ |
|
/* first putenv call. */ |
|
extern char ** environ; |
|
# define STACKBOTTOM ((ptr_t)environ) |
|
# define DYNAMIC_LOADING |
|
# include <unistd.h> |
|
# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) |
|
/* The following was empirically determined, and is probably */ |
|
/* not very robust. */ |
|
/* Note that the backing store base seems to be at a nice */ |
|
/* address minus one page. */ |
|
# define BACKING_STORE_DISPLACEMENT 0x1000000 |
|
# define BACKING_STORE_ALIGNMENT 0x1000 |
|
# define BACKING_STORE_BASE \ |
|
(ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1) \ |
|
& ~(BACKING_STORE_ALIGNMENT - 1)) |
|
# endif |
|
# ifdef LINUX |
|
# define CPP_WORDSZ 64 |
|
# define ALIGN_DOUBLE |
|
/* Requires 16 byte alignment for malloc */ |
|
# define ALIGNMENT 8 |
|
# define OS_TYPE "LINUX" |
|
/* The following works on NUE and older kernels: */ |
|
/* # define STACKBOTTOM ((ptr_t) 0xa000000000000000l) */ |
|
/* This does not work on NUE: */ |
|
# define LINUX_STACKBOTTOM |
|
/* We also need the base address of the register stack */ |
|
/* backing store. This is computed in */ |
|
/* GC_linux_register_stack_base based on the following */ |
|
/* constants: */ |
|
# define BACKING_STORE_ALIGNMENT 0x100000 |
|
# define BACKING_STORE_DISPLACEMENT 0x80000000 |
|
extern char * GC_register_stackbottom; |
|
# define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom) |
|
# define SEARCH_FOR_DATA_START |
|
# ifdef __GNUC__ |
|
# define DYNAMIC_LOADING |
|
# else |
|
/* In the Intel compiler environment, we seem to end up with */ |
|
/* statically linked executables and an undefined reference */ |
|
/* to _DYNAMIC */ |
|
# endif |
|
# define MPROTECT_VDB |
|
/* Requires Linux 2.3.47 or later. */ |
|
extern int _end[]; |
|
# define DATAEND (_end) |
|
# ifdef __GNUC__ |
|
# define PREFETCH(x) \ |
|
__asm__ (" lfetch [%0]": : "r"((void *)(x))) |
|
# define PREFETCH_FOR_WRITE(x) \ |
|
__asm__ (" lfetch.excl [%0]": : "r"((void *)(x))) |
|
# define CLEAR_DOUBLE(x) \ |
|
__asm__ (" stf.spill [%0]=f0": : "r"((void *)(x))) |
|
# endif |
|
# endif |
|
# endif |
|
|
# ifdef M88K |
# ifdef M88K |
# define MACH_TYPE "M88K" |
# define MACH_TYPE "M88K" |
# define ALIGNMENT 4 |
# define ALIGNMENT 4 |
# define ALIGN_DOUBLE |
# define ALIGN_DOUBLE |
extern int etext; |
extern int etext[]; |
# ifdef CX_UX |
# ifdef CX_UX |
# define OS_TYPE "CX_UX" |
# define OS_TYPE "CX_UX" |
# define DATASTART ((((word)&etext + 0x3fffff) & ~0x3fffff) + 0x10000) |
# define DATASTART ((((word)etext + 0x3fffff) & ~0x3fffff) + 0x10000) |
# endif |
# endif |
# ifdef DGUX |
# ifdef DGUX |
# define OS_TYPE "DGUX" |
# define OS_TYPE "DGUX" |
extern char * GC_SysVGetDataStart(); |
extern char * GC_SysVGetDataStart(); |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &etext) |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext) |
# endif |
# endif |
# define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */ |
# define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */ |
# endif |
# endif |
|
|
# ifdef S370 |
# ifdef S370 |
# define MACH_TYPE "S370" |
# define MACH_TYPE "S370" |
# define OS_TYPE "UTS4" |
|
# define ALIGNMENT 4 /* Required by hardware */ |
# define ALIGNMENT 4 /* Required by hardware */ |
extern int etext; |
# define USE_GENERIC_PUSH_REGS |
extern int _etext; |
# ifdef UTS4 |
extern int _end; |
# define OS_TYPE "UTS4" |
|
extern int etext[]; |
|
extern int _etext[]; |
|
extern int _end[]; |
extern char * GC_SysVGetDataStart(); |
extern char * GC_SysVGetDataStart(); |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext) |
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext) |
# define DATAEND (&_end) |
# define DATAEND (_end) |
# define HEURISTIC2 |
# define HEURISTIC2 |
|
# endif |
|
# ifdef LINUX |
|
# define OS_TYPE "LINUX" |
|
# define HEURISTIC1 |
|
# define DYNAMIC_LOADING |
|
extern int __data_start[]; |
|
# define DATASTART ((ptr_t)(__data_start)) |
|
# endif |
# endif |
# endif |
|
|
|
# if defined(PJ) |
|
# define ALIGNMENT 4 |
|
extern int _etext[]; |
|
# define DATASTART ((ptr_t)(_etext)) |
|
# define HEURISTIC1 |
|
# endif |
|
|
|
# ifdef ARM32 |
|
# define CPP_WORDSZ 32 |
|
# define MACH_TYPE "ARM32" |
|
# define ALIGNMENT 4 |
|
# ifdef NETBSD |
|
# define OS_TYPE "NETBSD" |
|
# define HEURISTIC2 |
|
extern char etext[]; |
|
# define DATASTART ((ptr_t)(etext)) |
|
# define USE_GENERIC_PUSH_REGS |
|
# endif |
|
# ifdef LINUX |
|
# define OS_TYPE "LINUX" |
|
# define HEURISTIC1 |
|
# undef STACK_GRAN |
|
# define STACK_GRAN 0x10000000 |
|
# define USE_GENERIC_PUSH_REGS |
|
# ifdef __ELF__ |
|
# define DYNAMIC_LOADING |
|
# include <features.h> |
|
# if defined(__GLIBC__) && __GLIBC__ >= 2 |
|
# define LINUX_DATA_START |
|
# else |
|
extern char **__environ; |
|
# define DATASTART ((ptr_t)(&__environ)) |
|
/* hideous kludge: __environ is the first */ |
|
/* word in crt0.o, and delimits the start */ |
|
/* of the data segment, no matter which */ |
|
/* ld options were passed through. */ |
|
/* We could use _etext instead, but that */ |
|
/* would include .rodata, which may */ |
|
/* contain large read-only data tables */ |
|
/* that we'd rather not scan. */ |
|
# endif |
|
extern int _end[]; |
|
# define DATAEND (_end) |
|
# else |
|
extern int etext[]; |
|
# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) |
|
# endif |
|
# endif |
|
# ifdef MSWINCE |
|
# define OS_TYPE "MSWINCE" |
|
# define DATAEND /* not needed */ |
|
# endif |
|
# ifdef NOSYS |
|
/* __data_start is usually defined in the target linker script. */ |
|
extern int __data_start[]; |
|
# define DATASTART (ptr_t)(__data_start) |
|
# define USE_GENERIC_PUSH_REGS |
|
/* __stack_base__ is set in newlib/libc/sys/arm/crt0.S */ |
|
extern void *__stack_base__; |
|
# define STACKBOTTOM ((ptr_t) (__stack_base__)) |
|
# endif |
|
#endif |
|
|
|
# ifdef SH |
|
# define MACH_TYPE "SH" |
|
# define ALIGNMENT 4 |
|
# ifdef MSWINCE |
|
# define OS_TYPE "MSWINCE" |
|
# define DATAEND /* not needed */ |
|
# endif |
|
# ifdef LINUX |
|
# define OS_TYPE "LINUX" |
|
# define STACKBOTTOM ((ptr_t) 0x7c000000) |
|
# define USE_GENERIC_PUSH_REGS |
|
# define DYNAMIC_LOADING |
|
# define LINUX_DATA_START |
|
extern int _end[]; |
|
# define DATAEND (_end) |
|
# endif |
|
# endif |
|
|
|
# ifdef SH4 |
|
# define MACH_TYPE "SH4" |
|
# define OS_TYPE "MSWINCE" |
|
# define ALIGNMENT 4 |
|
# define DATAEND /* not needed */ |
|
# endif |
|
|
|
#ifdef LINUX_DATA_START |
|
/* Some Linux distributions arrange to define __data_start. Some */ |
|
/* define data_start as a weak symbol. The latter is technically */ |
|
/* broken, since the user program may define data_start, in which */ |
|
/* case we lose. Nonetheless, we try both, prefering __data_start. */ |
|
/* We assume gcc. */ |
|
# pragma weak __data_start |
|
extern int __data_start[]; |
|
# pragma weak data_start |
|
extern int data_start[]; |
|
# define DATASTART ((ptr_t)(__data_start != 0? __data_start : data_start)) |
|
#endif |
|
|
|
#if defined(LINUX) && defined(REDIRECT_MALLOC) |
|
/* Rld appears to allocate some memory with its own allocator, and */ |
|
/* some through malloc, which might be redirected. To make this */ |
|
/* work with collectable memory, we have to scan memory allocated */ |
|
/* by rld's internal malloc. */ |
|
# define USE_PROC_FOR_LIBRARIES |
|
#endif |
|
|
# ifndef STACK_GROWS_UP |
# ifndef STACK_GROWS_UP |
# define STACK_GROWS_DOWN |
# define STACK_GROWS_DOWN |
# endif |
# endif |
|
|
# endif |
# endif |
|
|
# ifndef DATAEND |
# ifndef DATAEND |
extern int end; |
extern int end[]; |
# define DATAEND (&end) |
# define DATAEND (end) |
# endif |
# endif |
|
|
# if defined(SVR4) && !defined(GETPAGESIZE) |
# if defined(SVR4) && !defined(GETPAGESIZE) |
|
|
# endif |
# endif |
|
|
# if defined(SUNOS5) || defined(DRSNX) || defined(UTS4) |
# if defined(SUNOS5) || defined(DRSNX) || defined(UTS4) |
/* OS has SVR4 generic features. Probably others also qualify. */ |
/* OS has SVR4 generic features. Probably others also qualify. */ |
# define SVR4 |
# define SVR4 |
# endif |
# endif |
|
|
# if defined(SUNOS5) || defined(DRSNX) |
# if defined(SUNOS5) || defined(DRSNX) |
/* OS has SUNOS5 style semi-undocumented interface to dynamic */ |
/* OS has SUNOS5 style semi-undocumented interface to dynamic */ |
/* loader. */ |
/* loader. */ |
# define SUNOS5DL |
# define SUNOS5DL |
/* OS has SUNOS5 style signal handlers. */ |
/* OS has SUNOS5 style signal handlers. */ |
# define SUNOS5SIGS |
# define SUNOS5SIGS |
# endif |
# endif |
|
|
|
# if defined(HPUX) |
|
# define SUNOS5SIGS |
|
# endif |
|
|
|
# if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \ |
|
|| defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) || defined(DGUX) \ |
|
|| defined(BSD) || defined(AIX) || defined(MACOSX) || defined(OSF1) |
|
# define UNIX_LIKE /* Basic Unix-like system calls work. */ |
|
# endif |
|
|
# if CPP_WORDSZ != 32 && CPP_WORDSZ != 64 |
# if CPP_WORDSZ != 32 && CPP_WORDSZ != 64 |
-> bad word size |
-> bad word size |
# endif |
# endif |
|
|
# ifdef PCR |
# ifdef PCR |
|
|
# endif |
# endif |
|
|
# ifdef SRC_M3 |
# ifdef SRC_M3 |
/* Postponed for now. */ |
/* Postponed for now. */ |
# undef PROC_VDB |
# undef PROC_VDB |
# undef MPROTECT_VDB |
# undef MPROTECT_VDB |
# endif |
# endif |
|
|
# ifdef SMALL_CONFIG |
# ifdef SMALL_CONFIG |
/* Presumably not worth the space it takes. */ |
/* Presumably not worth the space it takes. */ |
# undef PROC_VDB |
# undef PROC_VDB |
# undef MPROTECT_VDB |
# undef MPROTECT_VDB |
# endif |
# endif |
|
|
# undef MPROTECT_VDB /* Can't deal with address space holes. */ |
# undef MPROTECT_VDB /* Can't deal with address space holes. */ |
# endif |
# endif |
|
|
|
# ifdef PARALLEL_MARK |
|
# undef MPROTECT_VDB /* For now. */ |
|
# endif |
|
|
# if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) |
# if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) |
# define DEFAULT_VDB |
# define DEFAULT_VDB |
# endif |
# endif |
|
|
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
# ifndef PREFETCH |
# define SOLARIS_THREADS |
# define PREFETCH(x) |
|
# define NO_PREFETCH |
# endif |
# endif |
# if defined(IRIX_THREADS) && !defined(IRIX5) |
|
--> inconsistent configuration |
# ifndef PREFETCH_FOR_WRITE |
|
# define PREFETCH_FOR_WRITE(x) |
|
# define NO_PREFETCH_FOR_WRITE |
# endif |
# endif |
# if defined(IRIX_JDK_THREADS) && !defined(IRIX5) |
|
--> inconsistent configuration |
# ifndef CACHE_LINE_SIZE |
|
# define CACHE_LINE_SIZE 32 /* Wild guess */ |
# endif |
# endif |
# if defined(LINUX_THREADS) && !defined(LINUX) |
|
--> inconsistent configuration |
# if defined(SEARCH_FOR_DATA_START) |
|
extern ptr_t GC_data_start; |
|
# define DATASTART GC_data_start |
# endif |
# endif |
# if defined(SOLARIS_THREADS) && !defined(SUNOS5) |
|
--> inconsistent configuration |
# ifndef CLEAR_DOUBLE |
|
# define CLEAR_DOUBLE(x) \ |
|
((word*)x)[0] = 0; \ |
|
((word*)x)[1] = 0; |
|
# endif /* CLEAR_DOUBLE */ |
|
|
|
/* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */ |
|
# if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS) |
|
# define GC_SOLARIS_THREADS |
# endif |
# endif |
|
|
|
# if defined(GC_IRIX_THREADS) && !defined(IRIX5) |
|
--> inconsistent configuration |
|
# endif |
|
# if defined(GC_LINUX_THREADS) && !defined(LINUX) |
|
--> inconsistent configuration |
|
# endif |
|
# if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5) |
|
--> inconsistent configuration |
|
# endif |
|
# if defined(GC_HPUX_THREADS) && !defined(HPUX) |
|
--> inconsistent configuration |
|
# endif |
|
# if defined(GC_WIN32_THREADS) && !defined(MSWIN32) |
|
/* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect */ |
|
/* the necessary code is mostly there, but nobody has actually made */ |
|
/* sure the right combination of pieces is compiled in, etc. */ |
|
--> inconsistent configuration |
|
# endif |
|
|
# if defined(PCR) || defined(SRC_M3) || \ |
# if defined(PCR) || defined(SRC_M3) || \ |
defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \ |
defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) || \ |
defined(IRIX_THREADS) || defined(LINUX_THREADS) || \ |
defined(GC_PTHREADS) |
defined(IRIX_JDK_THREADS) |
|
# define THREADS |
# define THREADS |
# endif |
# endif |
|
|
# if defined(HP_PA) || defined(M88K) || defined(POWERPC) \ |
# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \ |
|| (defined(I386) && defined(OS2)) || defined(UTS4) || defined(LINT) |
|| defined(LINT) || defined(MSWINCE) || defined(ARM32) \ |
/* Use setjmp based hack to mark from callee-save registers. */ |
|| (defined(I386) && defined(__LCC__)) |
|
/* Use setjmp based hack to mark from callee-save registers. */ |
|
/* The define should move to the individual platform */ |
|
/* descriptions. */ |
# define USE_GENERIC_PUSH_REGS |
# define USE_GENERIC_PUSH_REGS |
# endif |
# endif |
# if defined(SPARC) && !defined(LINUX) |
|
# define SAVE_CALL_CHAIN |
# if defined(SPARC) |
# define ASM_CLEAR_CODE /* Stack clearing is crucial, and we */ |
# define ASM_CLEAR_CODE /* Stack clearing is crucial, and we */ |
/* include assembly code to do it well. */ |
/* include assembly code to do it well. */ |
# endif |
# endif |
|
|
|
/* Can we save call chain in objects for debugging? */ |
|
/* SET NFRAMES (# of saved frames) and NARGS (#of args for each frame) */ |
|
/* to reasonable values for the platform. */ |
|
/* Set SAVE_CALL_CHAIN if we can. SAVE_CALL_COUNT can be specified at */ |
|
/* build time, though we feel free to adjust it slightly. */ |
|
/* Define NEED_CALLINFO if we either save the call stack or */ |
|
/* GC_ADD_CALLER is defined. */ |
|
#ifdef LINUX |
|
# include <features.h> |
|
# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2 |
|
# define HAVE_BUILTIN_BACKTRACE |
# endif |
# endif |
|
#endif |
|
|
|
#if defined(SPARC) |
|
# define CAN_SAVE_CALL_STACKS |
|
# define CAN_SAVE_CALL_ARGS |
|
#endif |
|
#if defined(I386) && defined(LINUX) |
|
/* SAVE_CALL_CHAIN is supported if the code is compiled to save */ |
|
/* frame pointers by default, i.e. no -fomit-frame-pointer flag. */ |
|
# define CAN_SAVE_CALL_STACKS |
|
# define CAN_SAVE_CALL_ARGS |
|
#endif |
|
#if defined(HAVE_BUILTIN_BACKTRACE) && !defined(CAN_SAVE_CALL_STACKS) |
|
# define CAN_SAVE_CALL_STACKS |
|
#endif |
|
|
|
# if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \ |
|
&& defined(CAN_SAVE_CALL_STACKS) |
|
# define SAVE_CALL_CHAIN |
|
# endif |
|
# ifdef SAVE_CALL_CHAIN |
|
# if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS) |
|
# define NARGS SAVE_CALL_NARGS |
|
# else |
|
# define NARGS 0 /* Number of arguments to save for each call. */ |
|
# endif |
|
# endif |
|
# ifdef SAVE_CALL_CHAIN |
|
# ifndef SAVE_CALL_COUNT |
|
# define NFRAMES 6 /* Number of frames to save. Even for */ |
|
/* alignment reasons. */ |
|
# else |
|
# define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1) |
|
# endif |
|
# define NEED_CALLINFO |
|
# endif /* SAVE_CALL_CHAIN */ |
|
# ifdef GC_ADD_CALLER |
|
# define NFRAMES 1 |
|
# define NARGS 0 |
|
# define NEED_CALLINFO |
|
# endif |
|
|
|
# if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL) |
|
# define DBG_HDRS_ALL |
|
# endif |
|
|
|
#ifdef GC_PRIVATE_H |
|
/* This relies on some type definitions from gc_priv.h, from */ |
|
/* where it's normally included. */ |
|
/* */ |
|
/* How to get heap memory from the OS: */ |
|
/* Note that sbrk()-like allocation is preferred, since it */ |
|
/* usually makes it possible to merge consecutively allocated */ |
|
/* chunks. It also avoids unintented recursion with */ |
|
/* -DREDIRECT_MALLOC. */ |
|
/* GET_MEM() returns a HLKSIZE aligned chunk. */ |
|
/* 0 is taken to mean failure. */ |
|
/* In the case os USE_MMAP, the argument must also be a */ |
|
/* physical page size. */ |
|
/* GET_MEM is currently not assumed to retrieve 0 filled space, */ |
|
/* though we should perhaps take advantage of the case in which */ |
|
/* does. */ |
|
struct hblk; /* See gc_priv.h. */ |
|
# ifdef PCR |
|
char * real_malloc(); |
|
# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \ |
|
+ GC_page_size-1) |
|
# else |
|
# ifdef OS2 |
|
void * os2_alloc(size_t bytes); |
|
# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \ |
|
+ GC_page_size) \ |
|
+ GC_page_size-1) |
|
# else |
|
# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \ |
|
(defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \ |
|
(defined(SUNOS5) && !defined(USE_MMAP)) |
|
# define GET_MEM(bytes) HBLKPTR((size_t) \ |
|
calloc(1, (size_t)bytes + GC_page_size) \ |
|
+ GC_page_size-1) |
|
# else |
|
# ifdef MSWIN32 |
|
extern ptr_t GC_win32_get_mem(); |
|
# define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes) |
|
# else |
|
# ifdef MACOS |
|
# if defined(USE_TEMPORARY_MEMORY) |
|
extern Ptr GC_MacTemporaryNewPtr(size_t size, |
|
Boolean clearMemory); |
|
# define GET_MEM(bytes) HBLKPTR( \ |
|
GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \ |
|
+ GC_page_size-1) |
|
# else |
|
# define GET_MEM(bytes) HBLKPTR( \ |
|
NewPtrClear(bytes + GC_page_size) + GC_page_size-1) |
|
# endif |
|
# else |
|
# ifdef MSWINCE |
|
extern ptr_t GC_wince_get_mem(); |
|
# define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes) |
|
# else |
|
# if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC) |
|
extern void *GC_amiga_get_mem(size_t size); |
|
define GET_MEM(bytes) HBLKPTR((size_t) \ |
|
GC_amiga_get_mem((size_t)bytes + GC_page_size) \ |
|
+ GC_page_size-1) |
|
# else |
|
extern ptr_t GC_unix_get_mem(); |
|
# define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes) |
|
# endif |
|
# endif |
|
# endif |
|
# endif |
|
# endif |
|
# endif |
|
# endif |
|
|
|
#endif /* GC_PRIVATE_H */ |
|
|
|
# endif /* GCCONFIG_H */ |