version 1.1.1.2, 2000/04/14 11:08:00 |
version 1.1.1.3, 2000/12/01 14:48:26 |
|
|
* 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. */ |
|
|
# 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 |
# endif |
# define RISCOS /* or IRIX 4.X */ |
|
# endif |
|
# endif |
|
# endif /* !LINUX */ |
# define mach_type_known |
# define mach_type_known |
# endif |
# endif |
# if defined(sequent) && defined(i386) |
# if defined(sequent) && defined(i386) |
|
|
# 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(__alpha) || defined(__alpha__) |
# if defined(__alpha) || defined(__alpha__) |
# define ALPHA |
# define ALPHA |
# if !defined(LINUX) |
# if !defined(LINUX) |
|
|
# 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 |
|
|
/* (CX_UX and DGUX) */ |
/* (CX_UX and DGUX) */ |
/* S370 ==> 370-like machine */ |
/* S370 ==> 370-like machine */ |
/* running Amdahl UTS4 */ |
/* running Amdahl UTS4 */ |
|
/* ARM32 ==> Intel StrongARM */ |
|
/* IA64 ==> Intel IA64 */ |
|
/* (e.g. Itanium) */ |
|
|
|
|
/* |
/* |
|
|
* 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. |
|
* |
* 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. |
*/ |
*/ |
|
|
|
|
|
|
/* 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 |
/* Others have reported better success with */ |
|
/* extern int __data_start; */ |
|
/*# define DATASTART (&__data_start) */ |
|
/* and disabling the GC_data_start */ |
|
/* initialization code. */ |
|
extern int _end; |
extern int _end; |
# define DATAEND (&_end) |
# define DATAEND (&_end) |
# endif |
# endif |
|
|
# ifdef LINUX |
# ifdef LINUX |
# define OS_TYPE "LINUX" |
# define OS_TYPE "LINUX" |
# ifdef __ELF__ |
# ifdef __ELF__ |
# define DATASTART GC_data_start |
# define LINUX_DATA_START |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
# else |
# else |
Linux Sparc non elf ? |
Linux Sparc non elf ? |
# endif |
# endif |
|
|
# 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" |
|
|
|
|
# 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 |
|
|
/* 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 */ |
|
/* to this. We'll probably do this on other platforms, too. */ |
|
/* For now I'll use it where I can test it. */ |
|
extern char ** environ; |
|
# define STACKBOTTOM ((ptr_t)environ) |
# endif |
# endif |
# define STACK_GROWS_UP |
# define STACK_GROWS_UP |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
|
|
# endif |
# endif |
# include <unistd.h> |
# include <unistd.h> |
# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) |
# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) |
/* They misspelled the Posix macro? */ |
|
# endif |
# endif |
|
|
# 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 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 |
# define HEURISTIC2 |
/* Normally HEURISTIC2 is too conervative, since */ |
/* Normally HEURISTIC2 is too conervative, since */ |
|
|
# 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 LINUX_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 |
|
/* This doesn't work if the collector is in a dynamic library. */ |
# else |
# else |
# define DATASTART ((ptr_t) 0x140000000) |
# define DATASTART ((ptr_t) 0x140000000) |
# endif |
# endif |
|
|
# define ALIGN_DOUBLE |
# define ALIGN_DOUBLE |
/* Requires 16 byte alignment for malloc */ |
/* Requires 16 byte alignment for malloc */ |
# define ALIGNMENT 8 |
# 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 HPUX |
# ifdef HPUX |
--> needs work |
--> needs work |
# endif |
# endif |
|
|
/* backing store. There is probably a better way to */ |
/* backing store. There is probably a better way to */ |
/* get that, too ... */ |
/* get that, too ... */ |
# define BACKING_STORE_BASE ((ptr_t) 0x9fffffff80000000l) |
# define BACKING_STORE_BASE ((ptr_t) 0x9fffffff80000000l) |
# define DATASTART GC_data_start |
# if 1 |
|
# define SEARCH_FOR_DATA_START |
|
# define DATASTART GC_data_start |
|
# else |
|
extern int data_start; |
|
# define DATASTART ((ptr_t)(&data_start)) |
|
# endif |
# define DYNAMIC_LOADING |
# define DYNAMIC_LOADING |
|
# define MPROTECT_VDB |
|
/* Requires Linux 2.3.47 or later. */ |
extern int _end; |
extern int _end; |
# define DATAEND (&_end) |
# define DATAEND (&_end) |
|
# 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 |
# endif |
|
|
|
|
# define DATASTART ((ptr_t)(&etext)) |
# define DATASTART ((ptr_t)(&etext)) |
# define USE_GENERIC_PUSH_REGS |
# define USE_GENERIC_PUSH_REGS |
# endif |
# 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 |
#endif |
#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 |
|
|
# ifndef STACK_GROWS_UP |
# ifndef STACK_GROWS_UP |
# define STACK_GROWS_DOWN |
# define STACK_GROWS_DOWN |
# endif |
# endif |
|
|
# 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 */ |
|
|
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
# define SOLARIS_THREADS |
# define SOLARIS_THREADS |
# endif |
# endif |
|
|
/* include assembly code to do it well. */ |
/* include assembly code to do it well. */ |
# endif |
# endif |
|
|
# endif |
# endif /* GCCONFIG_H */ |