version 1.2, 2000/04/10 08:31:36 |
version 1.3, 2001/04/20 07:39:26 |
|
|
* 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 |
|
|
/* Determine the machine type: */ |
/* Determine the machine type: */ |
# if defined(sun) && defined(mc68000) |
# if defined(sun) && defined(mc68000) |
# define M68K |
# define M68K |
|
|
# 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 |
# if defined(mips) || defined(__mips) |
# if defined(mips) || defined(__mips) |
# define MIPS |
# define MIPS |
# if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__) |
# if !defined(LINUX) |
# define ULTRIX |
# if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__) |
# else |
# define ULTRIX |
# if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) || defined(__SYSTYPE_SVR4__) |
# else |
# define IRIX5 /* or IRIX 6.X */ |
# if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) \ |
# else |
|| defined(__SYSTYPE_SVR4__) |
# define RISCOS /* or IRIX 4.X */ |
# define IRIX5 /* or IRIX 6.X */ |
# endif |
# else |
|
# define RISCOS /* or IRIX 4.X */ |
|
# endif |
|
# endif |
|
# endif /* !LINUX */ |
|
# if defined(__NetBSD__) && defined(__MIPSEL__) |
|
# undef ULTRIX |
# endif |
# endif |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(sequent) && defined(i386) |
# if defined(sequent) && (defined(i386) || defined(__i386__)) |
# define 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(__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(__ia64__) || defined(__ia64)) |
|
# define IA64 |
|
# define mach_type_known |
|
# endif |
# if defined(LINUX) && defined(powerpc) |
# if defined(LINUX) && defined(powerpc) |
# define POWERPC |
# define POWERPC |
# define mach_type_known |
# define mach_type_known |
|
|
# 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 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) |
# 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(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 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 |
|
|
/* 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 |
|
|
/* 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 IA64 */ |
|
/* (e.g. Itanium) */ |
|
/* SH ==> Hitachi SuperH */ |
|
/* (LINUX & MSWINCE) */ |
|
|
|
|
/* |
/* |
|
|
* 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. |
*/ |
*/ |
|
|
|
|
|
|
# define MPROTECT_VDB |
# define MPROTECT_VDB |
# 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. */ |
|
# endif /* !GLIBC2 */ |
extern int _end; |
extern int _end; |
# define DATAEND (&_end) |
# define DATAEND (&_end) |
# else |
# else |
|
|
/* 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 |
|
|
|
|
# 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 |
|
# else |
|
# define ALIGNMENT 4 /* Required by hardware */ |
|
# 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; |
|
|
# 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 |
|
# if MPI |
|
extern int *StackBottom; |
|
# define STACKBOTTOM (ptr_t)(StackBottom) |
|
# else |
|
# define HEURISTIC2 |
|
# endif |
|
# 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 */ |
|
|
# 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; |
|
extern int _etext; |
# define DATAEND (&_end) |
# define DATAEND (&_end) |
# define SVR4 |
# define SVR4 |
# define STACKBOTTOM ((ptr_t) 0xf0000000) |
# ifdef __arch64__ |
|
# define STACKBOTTOM ((ptr_t) 0x80000000000ULL) |
|
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, &_etext) |
|
# define CPP_WORDSZ 64 |
|
# else |
|
# define STACKBOTTOM ((ptr_t) 0xf0000000) |
|
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext) |
|
# 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) |
|
extern int etext; |
# define DATASTART ((ptr_t)(&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 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, _start; |
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 STACKBOTTOM ((ptr_t)(&_start)) worked through 2.7, */ |
|
/* 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/vmparam.h> |
|
# define STACKBOTTOM USRSTACK |
/** At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ |
/** At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ |
/*# define PROC_VDB*/ |
/*# define PROC_VDB*/ |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
|
|
# endif |
# endif |
# ifdef LINUX |
# ifdef LINUX |
# define OS_TYPE "LINUX" |
# define OS_TYPE "LINUX" |
# define HEURISTIC1 |
# define LINUX_STACKBOTTOM |
# undef STACK_GRAN |
# if 0 |
# define STACK_GRAN 0x10000000 |
# define HEURISTIC1 |
/* STACKBOTTOM is usually 0xc0000000, but this changes with */ |
# undef STACK_GRAN |
/* different kernel configurations. In particular, systems */ |
# define STACK_GRAN 0x10000000 |
/* with 2GB physical memory will usually move the user */ |
/* STACKBOTTOM is usually 0xc0000000, but this changes with */ |
/* address space limit, and hence initial SP to 0x80000000. */ |
/* 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(LINUX_THREADS) || !defined(REDIRECT_MALLOC) |
# if !defined(LINUX_THREADS) || !defined(REDIRECT_MALLOC) |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
# else |
# else |
|
|
# 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)) |
|
|
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" |
|
|
/* 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" |
|
|
# ifdef FREEBSD |
# ifdef FREEBSD |
# define OS_TYPE "FREEBSD" |
# define OS_TYPE "FREEBSD" |
# define MPROTECT_VDB |
# define MPROTECT_VDB |
|
# define FREEBSD_STACKBOTTOM |
# endif |
# endif |
# ifdef NETBSD |
# ifdef NETBSD |
# define OS_TYPE "NETBSD" |
# define OS_TYPE "NETBSD" |
|
|
# 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(FREEBSD) \ |
|| defined(THREE86BSD) || defined(BSDI) |
|| defined(THREE86BSD) || defined(BSDI) |
# define HEURISTIC2 |
# define HEURISTIC2 |
extern char etext; |
extern char etext; |
|
|
|
|
# ifdef MIPS |
# ifdef MIPS |
# define MACH_TYPE "MIPS" |
# define MACH_TYPE "MIPS" |
# ifndef IRIX5 |
|
# define DATASTART (ptr_t)0x10000000 |
|
/* Could probably be slightly higher since */ |
|
/* 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. */ |
/* # define STACKBOTTOM ((ptr_t)0x7fff8000) sometimes also works. */ |
|
# ifdef LINUX |
|
/* This was developed for a linuxce style platform. Probably */ |
|
/* needs to be tweaked for workstation class machines. */ |
|
# define OS_TYPE "LINUX" |
|
extern int __data_start; |
|
# define DATASTART ((ptr_t)(&__data_start)) |
|
# define ALIGNMENT 4 |
|
# define USE_GENERIC_PUSH_REGS 1 |
|
# define STACKBOTTOM 0x80000000 |
|
/* In many cases, this should probably use LINUX_STACKBOTTOM */ |
|
/* instead. But some kernel versions seem to give the wrong */ |
|
/* value from /proc. */ |
|
# endif /* Linux */ |
# ifdef ULTRIX |
# ifdef ULTRIX |
|
# define HEURISTIC2 |
|
# define DATASTART (ptr_t)0x10000000 |
|
/* Could probably be slightly higher since */ |
|
/* startup code allocates lots of stuff. */ |
# 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 1 |
|
# 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 |
|
|
|
|
# ifdef HP_PA |
# ifdef HP_PA |
# define MACH_TYPE "HP_PA" |
# define MACH_TYPE "HP_PA" |
# define ALIGNMENT 4 |
# define OS_TYPE "HPUX" |
# define ALIGN_DOUBLE |
# ifdef __LP64__ |
extern int __data_start; |
# define CPP_WORDSZ 64 |
# define DATASTART ((ptr_t)(&__data_start)) |
# define ALIGNMENT 8 |
# if 0 |
# else |
|
# define CPP_WORDSZ 32 |
|
# define ALIGNMENT 4 |
|
# define ALIGN_DOUBLE |
|
# endif |
|
# if !defined(GC_HPUX_THREADS) && !defined(HPUX_THREADS) \ |
|
&& !defined(GC_LINUX_THREADS) && !defined(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 |
|
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 LINUX_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 |
|
# 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. */ |
|
# 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 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. */ |
|
/* This is currently unused, since we disabled HEURISTIC2 */ |
extern int __start; |
extern int __start; |
# define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1))) |
# define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1))) |
# define CPP_WORDSZ 64 |
# define CPP_WORDSZ 64 |
|
|
# 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. */ |
# define DATASTART GC_data_start |
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 |
# endif |
# endif |
|
|
|
# ifdef IA64 |
|
# define MACH_TYPE "IA64" |
|
# define ALIGN_DOUBLE |
|
/* Requires 16 byte alignment for malloc */ |
|
# define ALIGNMENT 8 |
|
# 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 |
|
--> needs work |
|
# endif |
|
# ifdef LINUX |
|
# define OS_TYPE "LINUX" |
|
# define CPP_WORDSZ 64 |
|
/* 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 |
|
# define DATASTART GC_data_start |
|
# define DYNAMIC_LOADING |
|
# 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 |
|
|
|
|
# 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 |
|
# ifdef UTS4 |
|
# define OS_TYPE "UTS4" |
|
extern int etext; |
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) |
# 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 |
|
#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 |
|
|
# 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(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 |
|
|
# 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 |
|
|
|
# ifndef PREFETCH |
|
# define PREFETCH(x) |
|
# define NO_PREFETCH |
|
# endif |
|
|
|
# ifndef PREFETCH_FOR_WRITE |
|
# define PREFETCH_FOR_WRITE(x) |
|
# define NO_PREFETCH_FOR_WRITE |
|
# endif |
|
|
|
# ifndef CACHE_LINE_SIZE |
|
# define CACHE_LINE_SIZE 32 /* Wild guess */ |
|
# endif |
|
|
|
# ifndef CLEAR_DOUBLE |
|
# define CLEAR_DOUBLE(x) \ |
|
((word*)x)[0] = 0; \ |
|
((word*)x)[1] = 0; |
|
# endif /* CLEAR_DOUBLE */ |
|
|
|
/* Internally to the collector we test only the XXX_THREADS macros */ |
|
/* not the GC_XXX_THREADS versions. Here we make sure the latter */ |
|
/* are treated as equivalent. */ |
|
#if defined(GC_SOLARIS_THREADS) && !defined(_SOLARIS_THREADS) |
|
# define _SOLARIS_THREADS |
|
#endif |
|
#if defined(GC_SOLARIS_THREADS) && !defined(_SOLARIS_PTHREADS) |
|
# define _SOLARIS_PTHREADS |
|
#endif |
|
#if defined(GC_IRIX_THREADS) && !defined(IRIX_THREADS) |
|
# define IRIX_THREADS |
|
#endif |
|
#if defined(GC_LINUX_THREADS) && !defined(LINUX_THREADS) |
|
# define LINUX_THREADS |
|
#endif |
|
#if defined(GC_WIN32_THREADS) && !defined(WIN32_THREADS) |
|
# define WIN32_THREADS |
|
#endif |
|
#if defined(GC_HPUX_THREADS) && !defined(HPUX_THREADS) |
|
# define HPUX_THREADS |
|
#endif |
|
#if defined(GC_OSF1_THREADS) && !defined(OSF1_THREADS) |
|
# define OSF1_THREADS |
|
#endif |
|
|
|
/* Internally we use SOLARIS_THREADS to test for either old or pthreads. */ |
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
# define SOLARIS_THREADS |
# define SOLARIS_THREADS |
# endif |
# endif |
# if defined(IRIX_THREADS) && !defined(IRIX5) |
# if defined(IRIX_THREADS) && !defined(IRIX5) |
--> inconsistent configuration |
--> inconsistent configuration |
# endif |
# endif |
# if defined(IRIX_JDK_THREADS) && !defined(IRIX5) |
|
--> inconsistent configuration |
|
# endif |
|
# if defined(LINUX_THREADS) && !defined(LINUX) |
# if defined(LINUX_THREADS) && !defined(LINUX) |
--> inconsistent configuration |
--> inconsistent configuration |
# endif |
# endif |
# if defined(SOLARIS_THREADS) && !defined(SUNOS5) |
# if defined(SOLARIS_THREADS) && !defined(SUNOS5) |
--> inconsistent configuration |
--> inconsistent configuration |
# endif |
# endif |
|
# if defined(HPUX_THREADS) && !defined(HPUX) |
|
--> inconsistent configuration |
|
# endif |
# if defined(PCR) || defined(SRC_M3) || \ |
# if defined(PCR) || defined(SRC_M3) || \ |
defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \ |
defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \ |
defined(IRIX_THREADS) || defined(LINUX_THREADS) || \ |
defined(IRIX_THREADS) || defined(LINUX_THREADS) || \ |
defined(IRIX_JDK_THREADS) |
defined(HPUX_THREADS) || defined(OSF1_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) \ |
/* 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) |
# 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. */ |
|
# ifdef SAVE_CALL_COUNT |
|
# define SAVE_CALL_CHAIN |
|
# endif |
|
# endif |
|
# if defined(SPARC) |
# define SAVE_CALL_CHAIN |
# define SAVE_CALL_CHAIN |
# 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 |
|
|
# endif |
# endif /* GCCONFIG_H */ |