From 4109fe8594fef15d5cb36d1019e5b7c95dbc45f6 Mon Sep 17 00:00:00 2001 From: Bryce McKinlay Date: Fri, 13 Aug 2004 23:05:36 +0000 Subject: [PATCH] configure.in (GCINCS): Don't use "boehm-cflags". libjava: 2004-08-13 Bryce McKinlay * configure.in (GCINCS): Don't use "boehm-cflags". Instead, -I boehm-gc's include dirs. * configure: Rebuilt. * include/boehm-gc.h: Include gc_config.h. boehm-gc: 2004-08-13 Bryce McKinlay * configure.ac (gc_cflags): Add -Iinclude. (AC_CONFIG_HEADERS): New. Configure gc_config.h header. Don't write DEFS to boehm-cflags file. * configure: Rebuilt. * gcj_mlc.c: Check #ifdef GC_GCJ_SUPPORT after including headers. * specific.c: Check #ifdef GC_LINUX_THREADS after including headers. * include/gc_config_macros.h: Remove backward-compatibility redefinitions of GC_ names. * include/gc.h: Include . 2004-08-13 Bryce McKinlay Import Boehm GC version 6.3. From-SVN: r85972 --- boehm-gc/BCC_MAKEFILE | 2 +- boehm-gc/ChangeLog | 16 + boehm-gc/Makefile.direct | 26 +- boehm-gc/Makefile.dist | 217 ++++++++--- boehm-gc/Makefile.dj | 28 +- boehm-gc/Makefile.in | 50 +-- boehm-gc/NT_MAKEFILE | 9 +- boehm-gc/aclocal.m4 | 178 +++++++-- boehm-gc/allchblk.c | 31 +- boehm-gc/alloc.c | 37 +- boehm-gc/checksums.c | 34 +- boehm-gc/configure | 424 ++++++++++++++++----- boehm-gc/configure.ac | 11 +- boehm-gc/cord/cordprnt.c | 2 +- boehm-gc/cord/cordtest.c | 8 +- boehm-gc/cord/cordxtra.c | 6 +- boehm-gc/cord/de.c | 2 +- boehm-gc/dbg_mlc.c | 98 ++++- boehm-gc/doc/README | 4 +- boehm-gc/doc/README.changes | 214 ++++++++++- boehm-gc/doc/README.environment | 32 +- boehm-gc/doc/README.macros | 5 + boehm-gc/doc/README.win32 | 115 ++++-- boehm-gc/doc/debugging.html | 13 +- boehm-gc/doc/gc.man | 27 +- boehm-gc/doc/gcdescr.html | 60 ++- boehm-gc/dyn_load.c | 114 +++++- boehm-gc/finalize.c | 29 ++ boehm-gc/gcj_mlc.c | 82 ++-- boehm-gc/headers.c | 2 +- boehm-gc/if_not_there.c | 12 + boehm-gc/include/Makefile.in | 6 +- boehm-gc/include/gc.h | 61 ++- boehm-gc/include/gc_config.h.in | 34 ++ boehm-gc/include/gc_config_macros.h | 36 -- boehm-gc/include/gc_cpp.h | 13 +- boehm-gc/include/gc_gcj.h | 13 +- boehm-gc/include/gc_local_alloc.h | 1 + boehm-gc/include/gc_mark.h | 64 +++- boehm-gc/include/javaxfc.h | 20 - boehm-gc/include/new_gc_alloc.h | 32 +- boehm-gc/include/private/dbg_mlc.h | 1 - boehm-gc/include/private/gc_pmark.h | 7 +- boehm-gc/include/private/gc_priv.h | 22 +- boehm-gc/include/private/gcconfig.h | 117 ++++-- boehm-gc/include/private/solaris_threads.h | 2 + boehm-gc/include/private/specific.h | 2 +- boehm-gc/mach_dep.c | 3 + boehm-gc/malloc.c | 23 +- boehm-gc/mallocx.c | 12 + boehm-gc/mark.c | 6 +- boehm-gc/misc.c | 108 +++++- boehm-gc/new_hblk.c | 12 +- boehm-gc/os_dep.c | 395 ++++++++++++------- boehm-gc/pthread_support.c | 1 + boehm-gc/solaris_pthreads.c | 4 +- boehm-gc/solaris_threads.c | 16 +- boehm-gc/specific.c | 4 +- boehm-gc/tests/test.c | 17 +- boehm-gc/tests/test_cpp.cc | 2 +- boehm-gc/tests/trace_test.c | 1 + boehm-gc/threadlibs.c | 1 + boehm-gc/typd_mlc.c | 48 +-- boehm-gc/version.h | 4 +- boehm-gc/win32_threads.c | 2 +- libjava/ChangeLog | 7 + libjava/configure | 5 +- libjava/configure.in | 7 +- libjava/include/boehm-gc.h | 2 + 69 files changed, 2220 insertions(+), 779 deletions(-) create mode 100644 boehm-gc/include/gc_config.h.in diff --git a/boehm-gc/BCC_MAKEFILE b/boehm-gc/BCC_MAKEFILE index 3f86ed56fc4..e21bc3d8dfe 100644 --- a/boehm-gc/BCC_MAKEFILE +++ b/boehm-gc/BCC_MAKEFILE @@ -16,7 +16,7 @@ link= $(bcbin)\ilink32 cflags= -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude1);$(gcinclude2) -L$(bclib) \ -w-pro -w-aus -w-par -w-ccc -w-rch -a4 -D__STDC__=0 #defines= -DSILENT -defines= -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS -DUSE_GENERIC -DNO_GETENV -DJAVA_FINALIZATION -DGC_OPERATOR_NEW_ARRAY +defines= -DSILENT -DALL_INTERIOR_POINTERS -DUSE_GENERIC -DNO_GETENV -DJAVA_FINALIZATION -DGC_OPERATOR_NEW_ARRAY .c.obj: $(cc) @&&| diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index e7994f76eea..9ed4d720b23 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,19 @@ +2004-08-13 Bryce McKinlay + + * configure.ac (gc_cflags): Add -Iinclude. + (AC_CONFIG_HEADERS): New. Configure gc_config.h header. + Don't write DEFS to boehm-cflags file. + * configure: Rebuilt. + * gcj_mlc.c: Check #ifdef GC_GCJ_SUPPORT after including headers. + * specific.c: Check #ifdef GC_LINUX_THREADS after including headers. + * include/gc_config_macros.h: Remove backward-compatibility + redefinitions of GC_ names. + * include/gc.h: Include . + +2004-08-13 Bryce McKinlay + + Import Boehm GC version 6.3. + 2004-08-12 Kelley Cook * include/Makefile.in: Regenerate diff --git a/boehm-gc/Makefile.direct b/boehm-gc/Makefile.direct index 52b9137a922..20fa40a9a08 100644 --- a/boehm-gc/Makefile.direct +++ b/boehm-gc/Makefile.direct @@ -36,7 +36,7 @@ CFLAGS= -O -I$(srcdir)/include -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DNO_EXECUTE_ # -DGC_LINUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC # To build the parallel collector in a static library on HP/UX, # add to the above: -# -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -DUSE_HPUX_TLS -D_POSIX_C_SOURCE=199506L +# -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -D_POSIX_C_SOURCE=199506L # To build the thread-safe collector on Tru64, add to the above: # -pthread -DGC_OSF1_THREADS @@ -182,7 +182,7 @@ HOSTCFLAGS=$(CFLAGS) # this facility is only used in a few places. It is intended primarily # for debugging of the garbage collector itself, but could also # -DDBG_HDRS_ALL Make sure that all objects have debug headers. Increases -# the reliability (from 99.9999% to 100%) of some of the debugging +# the reliability (from 99.9999% to 100% mod. bugs) of some of the debugging # code (especially KEEP_BACK_PTRS). Makes -DSHORT_DBG_HDRS possible. # Assumes that all client allocation is done through debugging # allocators. @@ -235,6 +235,10 @@ HOSTCFLAGS=$(CFLAGS) # in a way that usually does not involve acquisition of a global lock. # Currently requires -DGC_LINUX_THREADS, but should be easy to port to # other pthreads environments. Recommended for multiprocessors. +# -DUSE_COMPILER_TLS causes thread local allocation to use compiler-supported +# "__thread" thread-local variables. This is the default in HP/UX. It +# may help performance on recent Linux installations. (It failed for +# me on RedHat 8, but appears to work on RedHat 9.) # -DPARALLEL_MARK allows the marker to run in multiple threads. Recommended # for multiprocessors. Currently requires Linux on X86 or IA64, though # support for other Posix platforms should be fairly easy to add, @@ -316,14 +320,15 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ doc/README.environment doc/tree.html doc/gcdescr.html \ doc/README.autoconf doc/README.macros doc/README.ews4800 \ doc/README.DGUX386 doc/README.arm.cross doc/leak.html \ - doc/scale.html doc/gcinterface.html doc/README.darwin + doc/scale.html doc/gcinterface.html doc/README.darwin \ + doc/simple_example.html TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \ - tests/leak_test.c tests/thread_leak_test.c + tests/leak_test.c tests/thread_leak_test.c tests/middle.c GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \ libtool.m4 install-sh configure.host Makefile.in \ - ltconfig aclocal.m4 config.sub config.guess \ + aclocal.m4 config.sub config.guess \ include/Makefile.am include/Makefile.in \ doc/Makefile.am doc/Makefile.in \ ltmain.sh mkinstalldirs depcomp missing @@ -331,7 +336,7 @@ GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \ OTHER_MAKEFILES= OS2_MAKEFILE NT_MAKEFILE NT_THREADS_MAKEFILE gc.mak \ BCC_MAKEFILE EMX_MAKEFILE WCC_MAKEFILE Makefile.dj \ PCR-Makefile SMakefile.amiga Makefile.DLLs \ - digimars.mak Makefile.direct + digimars.mak Makefile.direct NT_STATIC_THREADS_MAKEFILE # Makefile and Makefile.direct are copies of each other. OTHER_FILES= Makefile setjmp_t.c callprocs pc_excludes \ @@ -363,16 +368,23 @@ SPECIALCFLAGS = -I$(srcdir)/include all: gc.a gctest -BSD-pkg-all: bsd-libgc.a +LEAKFLAGS=$(CFLAGS) -DFIND_LEAK + +BSD-pkg-all: bsd-libgc.a bsd-libleak.a bsd-libgc.a: $(MAKE) CFLAGS="$(CFLAGS)" clean c++-t mv gc.a bsd-libgc.a +bsd-libleak.a: + $(MAKE) -f Makefile.direct CFLAGS="$(LEAKFLAGS)" clean c++-nt + mv gc.a bsd-libleak.a + BSD-pkg-install: BSD-pkg-all ${CP} bsd-libgc.a libgc.a ${INSTALL_DATA} libgc.a ${PREFIX}/lib ${INSTALL_DATA} gc.h gc_cpp.h ${PREFIX}/include + ${INSTALL_MAN} doc/gc.man ${PREFIX}/man/man3/gc.3 pcr: PCR-Makefile include/private/gc_private.h include/private/gc_hdrs.h \ include/private/gc_locks.h include/gc.h include/private/gcconfig.h \ diff --git a/boehm-gc/Makefile.dist b/boehm-gc/Makefile.dist index 9b1aeb3c92c..20fa40a9a08 100644 --- a/boehm-gc/Makefile.dist +++ b/boehm-gc/Makefile.dist @@ -1,4 +1,4 @@ -# This is the original manually generated Makefile. It may stil be used +# This is the original manually generated Makefile. It may still be used # to build the collector. # # Primary targets: @@ -10,13 +10,20 @@ # c++ interface to gc.a # cord/de - builds dumb editor based on cords. ABI_FLAG= +# ABI_FLAG should be the cc flag that specifies the ABI. On most +# platforms this will be the empty string. Possible values: +# +DD64 for 64-bit executable on HP/UX. +# -n32, -n64, -o32 for SGI/MIPS ABIs. + +AS_ABI_FLAG=$(ABI_FLAG) +# ABI flag for assembler. On HP/UX this is +A64 for 64 bit +# executables. + CC=cc $(ABI_FLAG) CXX=g++ $(ABI_FLAG) -AS=as $(ABI_FLAG) +AS=as $(AS_ABI_FLAG) # The above doesn't work with gas, which doesn't run cpp. # Define AS as `gcc -c -x assembler-with-cpp' instead. -# Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64) -# if you use something other than the default ABI on your machine. # Redefining srcdir allows object code for the nonPCR version of the collector # to be generated in different directories. @@ -27,8 +34,11 @@ CFLAGS= -O -I$(srcdir)/include -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DNO_EXECUTE_ # To build the parallel collector on Linux, add to the above: # -DGC_LINUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -# To build the parallel collector n a static library on HP/UX, add to the above: -# -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -DUSE_HPUX_TLS -D_POSIX_C_SOURCE=199506L +# To build the parallel collector in a static library on HP/UX, +# add to the above: +# -DGC_HPUX_THREADS -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC -D_POSIX_C_SOURCE=199506L +# To build the thread-safe collector on Tru64, add to the above: +# -pthread -DGC_OSF1_THREADS # HOSTCC and HOSTCFLAGS are used to build executables that will be run as # part of the build process, i.e. on the build machine. These will usually @@ -54,12 +64,22 @@ HOSTCFLAGS=$(CFLAGS) # gc.h before performing thr_ or dl* or GC_ operations.) # Must also define -D_REENTRANT. # -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads. -# Define SOLARIS_THREADS as well. +# (Internally this define GC_SOLARIS_THREADS as well.) # -DGC_IRIX_THREADS enables support for Irix pthreads. See README.irix. # -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads. # Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp. # -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads. # see README.linux. -D_REENTRANT may also be required. +# -DGC_OSF1_THREADS enables support for Tru64 pthreads. Untested. +# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. Untested. +# Appeared to run into some underlying thread problems. +# -DGC_DARWIN_THREADS enables support for Mac OS X pthreads. Untested. +# -DGC_DGUX386_THREADS enables support for DB/UX on I386 threads. +# See README.DGUX386. +# -DGC_WIN32_THREADS enables support for win32 threads. That makes sense +# for this Makefile only under Cygwin. +# -DGC_THREADS should set the appropriate one of the above macros. +# It assumes pthreads for Solaris. # -DALL_INTERIOR_POINTERS allows all pointers to the interior # of objects to be recognized. (See gc_priv.h for consequences.) # Alternatively, GC_all_interior_pointers can be set at process @@ -88,26 +108,34 @@ HOSTCFLAGS=$(CFLAGS) # code from the heap. Currently this only affects the incremental # collector on UNIX machines. It may greatly improve its performance, # since this may avoid some expensive cache synchronization. -# -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the -# new syntax "operator new[]" for allocating and deleting arrays. +# -DGC_NO_OPERATOR_NEW_ARRAY declares that the C++ compiler does not support +# the new syntax "operator new[]" for allocating and deleting arrays. # See gc_cpp.h for details. No effect on the C part of the collector. -# This is defined implicitly in a few environments. -# -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined -# as aliases for X, GC_realloc, and GC_free, respectively. -# Calloc is redefined in terms of the new malloc. X should +# This is defined implicitly in a few environments. Must also be defined +# by clients that use gc_cpp.h. +# -DREDIRECT_MALLOC=X causes malloc to be defined as alias for X. +# Unless the following macros are defined, realloc is also redirected +# to GC_realloc, and free is redirected to GC_free. +# Calloc and strdup are redefined in terms of the new malloc. X should # be either GC_malloc or GC_malloc_uncollectable, or # GC_debug_malloc_replacement. (The latter invokes GC_debug_malloc # with dummy source location information, but still results in -# properly remembered call stacks on Linux/X86 and Solaris/SPARC.) +# properly remembered call stacks on Linux/X86 and Solaris/SPARC. +# It requires that the following two macros also be used.) # The former is occasionally useful for working around leaks in code # you don't want to (or can't) look at. It may not work for # existing code, but it often does. Neither works on all platforms, # since some ports use malloc or calloc to obtain system memory. -# (Probably works for UNIX, and win32.) +# (Probably works for UNIX, and win32.) If you build with DBG_HDRS_ALL, +# you should only use GC_debug_malloc_replacement as a malloc +# replacement. # -DREDIRECT_REALLOC=X causes GC_realloc to be redirected to X. # The canonical use is -DREDIRECT_REALLOC=GC_debug_realloc_replacement, # together with -DREDIRECT_MALLOC=GC_debug_malloc_replacement to # generate leak reports with call stacks for both malloc and realloc. +# This also requires the following: +# -DREDIRECT_FREE=X causes free to be redirected to X. The +# canonical use is -DREDIRECT_FREE=GC_debug_free. # -DIGNORE_FREE turns calls to free into a noop. Only useful with # -DREDIRECT_MALLOC. # -DNO_DEBUGGING removes GC_dump and the debugging routines it calls. @@ -135,8 +163,8 @@ HOSTCFLAGS=$(CFLAGS) # Works for Solaris and Irix. # -DUSE_MUNMAP causes memory to be returned to the OS under the right # circumstances. This currently disables VM-based incremental collection. -# This is currently experimental, and works only under some Unix and -# Linux versions. +# This is currently experimental, and works only under some Unix, +# Linux and Windows versions. # -DMMAP_STACKS (for Solaris threads) Use mmap from /dev/zero rather than # GC_scratch_alloc() to get stack memory. # -DPRINT_BLACK_LIST Whenever a black list entry is added, i.e. whenever @@ -154,7 +182,7 @@ HOSTCFLAGS=$(CFLAGS) # this facility is only used in a few places. It is intended primarily # for debugging of the garbage collector itself, but could also # -DDBG_HDRS_ALL Make sure that all objects have debug headers. Increases -# the reliability (from 99.9999% to 100%) of some of the debugging +# the reliability (from 99.9999% to 100% mod. bugs) of some of the debugging # code (especially KEEP_BACK_PTRS). Makes -DSHORT_DBG_HDRS possible. # Assumes that all client allocation is done through debugging # allocators. @@ -172,8 +200,12 @@ HOSTCFLAGS=$(CFLAGS) # allocated through the debugging interface. Affects the amount of # information generated in leak reports. Only matters on platforms # on which we can quickly generate call stacks, currently Linux/(X86 & SPARC) -# and Solaris/SPARC. Turns on call chain saving on X86. On X86, client +# and Solaris/SPARC and platforms that provide execinfo.h. +# Default is zero. On X86, client # code should NOT be compiled with -fomit-frame-pointer. +# -DSAVE_CALL_NARGS= Set the number of functions arguments to be +# saved with each call frame. Default is zero. Ignored if we +# don't know how to retrieve arguments on the platform. # -DCHECKSUMS reports on erroneously clear dirty bits, and unexpectedly # altered stubborn objects, at substantial performance cost. # Use only for debugging of the incremental collector. @@ -190,8 +222,11 @@ HOSTCFLAGS=$(CFLAGS) # 15% or so. # -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style # prefetch instructions. Same restrictions as USE_I686_PREFETCH. -# UNTESTED!! -# -DGC_USE_LD_WRAP in combination with the gld flags listed in README.linux +# Minimally tested. Didn't appear to be an obvious win on a K6-2/500. +# -DUSE_PPC_PREFETCH causes the collector to issue PowerPC style +# prefetch instructions. No effect except on PowerPC OS X platforms. +# Performance impact untested. +# -DGC_USE_LD_WRAP in combination with the old flags listed in README.linux # causes the collector some system and pthread calls in a more transparent # fashion than the usual macro-based approach. Requires GNU ld, and # currently probably works only with Linux. @@ -200,6 +235,10 @@ HOSTCFLAGS=$(CFLAGS) # in a way that usually does not involve acquisition of a global lock. # Currently requires -DGC_LINUX_THREADS, but should be easy to port to # other pthreads environments. Recommended for multiprocessors. +# -DUSE_COMPILER_TLS causes thread local allocation to use compiler-supported +# "__thread" thread-local variables. This is the default in HP/UX. It +# may help performance on recent Linux installations. (It failed for +# me on RedHat 8, but appears to work on RedHat 9.) # -DPARALLEL_MARK allows the marker to run in multiple threads. Recommended # for multiprocessors. Currently requires Linux on X86 or IA64, though # support for other Posix platforms should be fairly easy to add, @@ -208,9 +247,35 @@ HOSTCFLAGS=$(CFLAGS) # These may otherwise alter its configuration, or turn off GC altogether. # I don't know of a reason to disable this, except possibly if the # resulting process runs as a privileged user? +# -DUSE_GLOBAL_ALLOC. Win32 only. Use GlobalAlloc instead of +# VirtualAlloc to allocate the heap. May be needed to work around +# a Windows NT/2000 issue. Incompatible with USE_MUNMAP. +# See README.win32 for details. +# -DMAKE_BACK_GRAPH. Enable GC_PRINT_BACK_HEIGHT environment variable. +# See README.environment for details. Experimental. Limited platform +# support. Implies DBG_HDRS_ALL. All allocation should be done using +# the debug interface. # -DSTUBBORN_ALLOC allows allocation of "hard to change" objects, and thus # makes incremental collection easier. Was enabled by default until 6.0. # Rarely used, to my knowledge. +# -DHANDLE_FORK attempts to make GC_malloc() work in a child process fork()ed +# from a multithreaded parent. Currently only supported by pthread_support.c. +# (Similar code should work on Solaris or Irix, but it hasn't been tried.) +# -DTEST_WITH_SYSTEM_MALLOC causes gctest to allocate (and leak) large chunks +# of memory with the standard system malloc. This will cause the root +# set and collected heap to grow significantly if malloced memory is +# somehow getting traced by the collector. This has no impact on the +# generated library; it only affects the test. +# -DPOINTER_MASK=0x... causes candidate pointers to be ANDed with the +# given mask before being considered. If either this or the following +# macro is defined, it will be assumed that all pointers stored in +# the heap need to be processed this way. Stack and register pointers +# will be considered both with and without processing. +# These macros are normally needed only to support systems that use +# high-order pointer tags. EXPERIMENTAL. +# -DPOINTER_SHIFT=n causes the collector to left shift candidate pointers +# by the indicated amount before trying to interpret them. Applied +# after POINTER_MASK. EXPERIMENTAL. See also the preceding macro. # CXXFLAGS= $(CFLAGS) @@ -218,50 +283,69 @@ AR= ar RANLIB= ranlib -OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o +OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o aix_irix_threads.o pthread_support.o pthread_stop_world.o darwin_stop_world.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o backgraph.o win32_threads.o -CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c +CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c aix_irix_threads.c pthread_support.c pthread_stop_world.c darwin_stop_world.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c backgraph.c win32_threads.c CORD_SRCS= cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c include/cord.h include/ec.h include/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC CORD_OBJS= cord/cordbscs.o cord/cordxtra.o cord/cordprnt.o -SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \ - sparc_mach_dep.s include/gc.h include/gc_typed.h \ +SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.S \ + sparc_mach_dep.S include/gc.h include/gc_typed.h \ include/private/gc_hdrs.h include/private/gc_priv.h \ include/private/gcconfig.h include/private/gc_pmark.h \ include/gc_inl.h include/gc_inline.h include/gc_mark.h \ threadlibs.c if_mach.c if_not_there.c gc_cpp.cc include/gc_cpp.h \ - include/weakpointer.h include/private/gc_locks.h \ + gcname.c include/weakpointer.h include/private/gc_locks.h \ gcc_support.c mips_ultrix_mach_dep.s include/gc_alloc.h \ - include/new_gc_alloc.h include/javaxfc.h sparc_sunos4_mach_dep.s \ - sparc_netbsd_mach_dep.s \ + include/new_gc_alloc.h include/gc_allocator.h \ + include/javaxfc.h sparc_sunos4_mach_dep.s sparc_netbsd_mach_dep.s \ include/private/solaris_threads.h include/gc_backptr.h \ hpux_test_and_clear.s include/gc_gcj.h \ include/gc_local_alloc.h include/private/dbg_mlc.h \ - include/private/specific.h powerpc_macosx_mach_dep.s \ + include/private/specific.h powerpc_darwin_mach_dep.s \ include/leak_detector.h include/gc_amiga_redirects.h \ - include/gc_pthread_redirects.h $(CORD_SRCS) + include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \ + include/gc_config_macros.h include/private/pthread_support.h \ + include/private/pthread_stop_world.h include/private/darwin_semaphore.h \ + include/private/darwin_stop_world.h $(CORD_SRCS) DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ - doc/README.amiga doc/README.cords doc/README.debugging \ + doc/README.amiga doc/README.cords doc/debugging.html \ doc/README.dj doc/README.hp doc/README.linux doc/README.rs6000 \ doc/README.sgi doc/README.solaris2 doc/README.uts \ doc/README.win32 doc/barrett_diagram doc/README \ doc/README.contributors doc/README.changes doc/gc.man \ - doc/README.environment + doc/README.environment doc/tree.html doc/gcdescr.html \ + doc/README.autoconf doc/README.macros doc/README.ews4800 \ + doc/README.DGUX386 doc/README.arm.cross doc/leak.html \ + doc/scale.html doc/gcinterface.html doc/README.darwin \ + doc/simple_example.html TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \ - tests/leak_test.c tests/thread_leak_test.c -OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \ - setjmp_t.c SMakefile.amiga configure.in Makefile.am \ - callprocs pc_excludes \ - MacProjects.sit.hqx MacOS.c EMX_MAKEFILE \ + tests/leak_test.c tests/thread_leak_test.c tests/middle.c + +GNU_BUILD_FILES= configure.in Makefile.am configure acinclude.m4 \ + libtool.m4 install-sh configure.host Makefile.in \ + aclocal.m4 config.sub config.guess \ + include/Makefile.am include/Makefile.in \ + doc/Makefile.am doc/Makefile.in \ + ltmain.sh mkinstalldirs depcomp missing + +OTHER_MAKEFILES= OS2_MAKEFILE NT_MAKEFILE NT_THREADS_MAKEFILE gc.mak \ + BCC_MAKEFILE EMX_MAKEFILE WCC_MAKEFILE Makefile.dj \ + PCR-Makefile SMakefile.amiga Makefile.DLLs \ + digimars.mak Makefile.direct NT_STATIC_THREADS_MAKEFILE +# Makefile and Makefile.direct are copies of each other. + +OTHER_FILES= Makefile setjmp_t.c callprocs pc_excludes \ + MacProjects.sit.hqx MacOS.c \ Mac_files/datastart.c Mac_files/dataend.c \ Mac_files/MacOS_config.h Mac_files/MacOS_Test_config.h \ add_gc_prefix.c gc_cpp.cpp \ - win32_threads.c NT_THREADS_MAKEFILE gc.mak Makefile.dj \ - version.h Makefile.DLLs WCC_MAKEFILE AmigaOS.c $(TESTS) + version.h AmigaOS.c \ + $(TESTS) $(GNU_BUILD_FILES) $(OTHER_MAKEFILES) CORD_INCLUDE_FILES= $(srcdir)/include/gc.h $(srcdir)/include/cord.h \ $(srcdir)/include/ec.h $(srcdir)/include/private/cord_pos.h @@ -284,16 +368,23 @@ SPECIALCFLAGS = -I$(srcdir)/include all: gc.a gctest -BSD-pkg-all: bsd-libgc.a +LEAKFLAGS=$(CFLAGS) -DFIND_LEAK + +BSD-pkg-all: bsd-libgc.a bsd-libleak.a bsd-libgc.a: $(MAKE) CFLAGS="$(CFLAGS)" clean c++-t mv gc.a bsd-libgc.a +bsd-libleak.a: + $(MAKE) -f Makefile.direct CFLAGS="$(LEAKFLAGS)" clean c++-nt + mv gc.a bsd-libleak.a + BSD-pkg-install: BSD-pkg-all ${CP} bsd-libgc.a libgc.a ${INSTALL_DATA} libgc.a ${PREFIX}/lib ${INSTALL_DATA} gc.h gc_cpp.h ${PREFIX}/include + ${INSTALL_MAN} doc/gc.man ${PREFIX}/man/man3/gc.3 pcr: PCR-Makefile include/private/gc_private.h include/private/gc_hdrs.h \ include/private/gc_locks.h include/gc.h include/private/gcconfig.h \ @@ -304,16 +395,16 @@ mach_dep.o $(SRCS) $(OBJS) tests/test.o dyn_load.o dyn_load_sunos53.o: \ $(srcdir)/include/private/gc_priv.h \ $(srcdir)/include/private/gc_hdrs.h $(srcdir)/include/private/gc_locks.h \ - $(srcdir)/include/gc.h \ + $(srcdir)/include/gc.h $(srcdir)/include/gc_pthread_redirects.h \ $(srcdir)/include/private/gcconfig.h $(srcdir)/include/gc_typed.h \ - Makefile + $(srcdir)/include/gc_config_macros.h Makefile # The dependency on Makefile is needed. Changing # options such as -DSILENT affects the size of GC_arrays, # invalidating all .o files that rely on gc_priv.h mark.o typd_mlc.o finalize.o ptr_chck.o: $(srcdir)/include/gc_mark.h $(srcdir)/include/private/gc_pmark.h -specific.o linux_threads.o: $(srcdir)/include/private/specific.h +specific.o pthread_support.o: $(srcdir)/include/private/specific.h solaris_threads.o solaris_pthreads.o: $(srcdir)/include/private/solaris_threads.h @@ -408,21 +499,25 @@ liblinuxgc.so: $(OBJS) dyn_load.o # gcc -shared -Wl,-soname=libgc.so.0 -o libgc.so.0 $(LIBOBJS) dyn_load.lo # touch liblinuxgc.so -mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ultrix_mach_dep.s \ - $(srcdir)/rs6000_mach_dep.s $(srcdir)/powerpc_macosx_mach_dep.s $(UTILS) +mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s \ + $(srcdir)/mips_ultrix_mach_dep.s \ + $(srcdir)/rs6000_mach_dep.s $(srcdir)/powerpc_darwin_mach_dep.s \ + $(srcdir)/sparc_mach_dep.S $(srcdir)/sparc_sunos4_mach_dep.s \ + $(srcdir)/ia64_save_regs_in_stack.s \ + $(srcdir)/sparc_netbsd_mach_dep.s $(UTILS) rm -f mach_dep.o - ./if_mach MIPS IRIX5 $(AS) -o mach_dep.o $(srcdir)/mips_sgi_mach_dep.s + ./if_mach MIPS IRIX5 $(CC) -c -o mach_dep.o $(srcdir)/mips_sgi_mach_dep.s ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s - ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s - ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_macosx_mach_dep.s -# ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s -# alpha_mach_dep.s assumes that pointers are not saved in fp registers. -# Gcc on a 21264 can spill pointers to fp registers. Oops. - ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s + ./if_mach POWERPC DARWIN $(AS) -o mach_dep.o $(srcdir)/powerpc_darwin_mach_dep.s + ./if_mach ALPHA LINUX $(CC) -c -o mach_dep.o $(srcdir)/alpha_mach_dep.S + ./if_mach SPARC SUNOS5 $(CC) -c -o mach_dep.o $(srcdir)/sparc_mach_dep.S ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s ./if_mach SPARC OPENBSD $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s ./if_mach SPARC NETBSD $(AS) -o mach_dep.o $(srcdir)/sparc_netbsd_mach_dep.s + ./if_mach IA64 "" as $(AS_ABI_FLAG) -o ia64_save_regs_in_stack.o $(srcdir)/ia64_save_regs_in_stack.s + ./if_mach IA64 "" $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c + ./if_mach IA64 "" ld -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o ./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c mark_rts.o: $(srcdir)/mark_rts.c $(UTILS) @@ -462,7 +557,7 @@ cord/de: $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(UTILS) ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -lucb `./threadlibs` ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) -ldld `./threadlibs` ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses - ./if_mach POWERPC MACOSX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a + ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` @@ -481,7 +576,7 @@ if_not_there: $(srcdir)/if_not_there.c clean: rm -f gc.a *.o *.exe tests/*.o gctest gctest_dyn_link test_cpp \ setjmp_test mon.out gmon.out a.out core if_not_there if_mach \ - threadlibs $(CORD_OBJS) cord/cordtest cord/de + threadlibs $(CORD_OBJS) cord/cordtest cord/de -rm -f *~ gctest: tests/test.o gc.a $(UTILS) @@ -505,12 +600,22 @@ KandRtest: setjmp_test gctest ./setjmp_test ./gctest -add_gc_prefix: add_gc_prefix.c +add_gc_prefix: $(srcdir)/add_gc_prefix.c $(srcdir)/version.h $(CC) -o add_gc_prefix $(srcdir)/add_gc_prefix.c -gc.tar: $(SRCS) $(DOC_FILES) $(OTHER_FILES) add_gc_prefix +gcname: $(srcdir)/gcname.c $(srcdir)/version.h + $(CC) -o gcname $(srcdir)/gcname.c + +gc.tar: $(SRCS) $(DOC_FILES) $(OTHER_FILES) add_gc_prefix gcname + cp Makefile Makefile.old + cp Makefile.direct Makefile + rm -f `./gcname` + ln -s . `./gcname` ./add_gc_prefix $(SRCS) $(DOC_FILES) $(OTHER_FILES) > /tmp/gc.tar-files tar cvfh gc.tar `cat /tmp/gc.tar-files` + cp gc.tar `./gcname`.tar + gzip `./gcname`.tar + rm `./gcname` pc_gc.tar: $(SRCS) $(OTHER_FILES) tar cvfX pc_gc.tar pc_excludes $(SRCS) $(OTHER_FILES) diff --git a/boehm-gc/Makefile.dj b/boehm-gc/Makefile.dj index 6097293ff0e..7757f15133d 100644 --- a/boehm-gc/Makefile.dj +++ b/boehm-gc/Makefile.dj @@ -29,7 +29,7 @@ EXE_SUFFIX=.exe srcdir= . VPATH= $(srcdir) -CFLAGS= -O -I$(srcdir)/include -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION -DSILENT +CFLAGS= -gstabs+ -O2 -I$(srcdir)/include -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION -DSILENT # Setjmp_test may yield overly optimistic results when compiled # without optimization. @@ -157,9 +157,9 @@ AR= ar RANLIB= ranlib -OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o hpux_irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o +OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o -CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c hpux_irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c +CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c CORD_SRCS= cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c include/cord.h include/ec.h include/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC cord/SCOPTIONS.amiga cord/SMakefile.amiga @@ -181,7 +181,7 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.S rs6000_mach_dep.s alpha_mach_dep.S \ include/leak_detector.h $(CORD_SRCS) OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \ - README test.c test_cpp.cc setjmp_t.c SMakefile.amiga \ + README tests/test.c test_cpp.cc setjmp_t.c SMakefile.amiga \ SCoptions.amiga README.amiga README.win32 cord/README \ README.rs6000 README.QUICK callprocs pc_excludes \ barrett_diagram README.OS2 README.Mac MacProjects.sit.hqx \ @@ -206,7 +206,7 @@ CURSES= -lcurses -ltermlib # the SHELL environment variable. SHELL= /bin/sh -SPECIALCFLAGS = +SPECIALCFLAGS = -I$(srcdir)/include # Alternative flags to the C compiler for mach_dep.c. # Mach_dep.c often doesn't like optimization, and it's # not time-critical anyway. @@ -224,7 +224,7 @@ $(OBJS) test.o dyn_load.o dyn_load_sunos53.o: \ # options such as -DSILENT affects the size of GC_arrays, # invalidating all .o files that rely on gc_priv.h -mark.o typd_mlc.o finalize.o: $(srcdir)/gc_mark.h +mark.o typd_mlc.o finalize.o: $(srcdir)/include/gc_mark.h base_lib gc.a: $(OBJS) dyn_load.o $(UTILS) echo > base_lib @@ -366,11 +366,11 @@ clean: rm -f threadlibs$(EXE_SUFFIX) cord/cordtest$(EXE_SUFFIX) -rm -f *~ -gctest$(EXE_SUFFIX): test.o gc.a if_mach$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX) +gctest$(EXE_SUFFIX): tests/test.o gc.a if_mach$(EXE_SUFFIX) if_not_there$(EXE_SUFFIX) rm -f gctest gctest$(EXE_SUFFIX) - ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o gctest test.o gc.a -lucb - ./if_mach HP_PA "" $(CC) $(CFLAGS) -o gctest test.o gc.a -ldld - ./if_not_there gctest$(EXE_SUFFIX) $(CC) $(CFLAGS) -o gctest$(EXE_SUFFIX) test.o gc.a + ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o gctest tests/test.o gc.a -lucb + ./if_mach HP_PA "" $(CC) $(CFLAGS) -o gctest tests/test.o gc.a -ldld + ./if_not_there gctest$(EXE_SUFFIX) $(CC) $(CFLAGS) -o gctest$(EXE_SUFFIX) tests/test.o gc.a rm -f gctest # If an optimized setjmp_test generates a segmentation fault, @@ -407,8 +407,8 @@ gc.tar.Z: gc.tar gc.tar.gz: gc.tar gzip gc.tar -lint: $(CSRCS) test.c - lint -DLINT $(CSRCS) test.c | egrep -v "possible pointer alignment problem|abort|exit|sbrk|mprotect|syscall" +lint: $(CSRCS) tests/test.c + lint -DLINT $(CSRCS) tests/test.c | egrep -v "possible pointer alignment problem|abort|exit|sbrk|mprotect|syscall" # BTL: added to test shared library version of collector. # Currently works only under SunOS5. Requires GC_INIT call from statically @@ -417,8 +417,8 @@ ABSDIR = `pwd` gctest_dyn_link: test.o libgc.so $(CC) -L$(ABSDIR) -R$(ABSDIR) -o gctest_dyn_link test.o -lgc -ldl -lthread -test_dll.o: test.c libgc_globals.h - $(CC) $(CFLAGS) -DGC_USE_DLL -c test.c -o test_dll.o +test_dll.o: tests/test.c libgc_globals.h + $(CC) $(CFLAGS) -DGC_USE_DLL -c tests/test.c -o test_dll.o test_dll: test_dll.o libgc_dll.a libgc.dll $(CC) test_dll.o -L$(ABSDIR) -lgc_dll -o test_dll diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in index 2be4b5939a9..d73b2390d35 100644 --- a/boehm-gc/Makefile.in +++ b/boehm-gc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.8.5 from Makefile.am. +# Makefile.in generated by automake 1.9 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -81,15 +81,6 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = -am__libgcjgc_la_SOURCES_DIST = allchblk.c alloc.c blacklst.c \ - checksums.c dbg_mlc.c dyn_load.c finalize.c gc_dlopen.c \ - gcj_mlc.c headers.c aix_irix_threads.c malloc.c mallocx.c \ - mark.c mark_rts.c misc.c new_hblk.c obj_map.c os_dep.c \ - pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ - solaris_pthreads.c solaris_threads.c specific.c stubborn.c \ - typd_mlc.c backgraph.c win32_threads.c pthread_support.c \ - pthread_stop_world.c darwin_stop_world.c \ - powerpc_darwin_mach_dep.s @POWERPC_DARWIN_TRUE@am__objects_1 = powerpc_darwin_mach_dep.lo am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \ dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \ @@ -101,15 +92,6 @@ am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \ pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1) am_libgcjgc_la_OBJECTS = $(am__objects_2) libgcjgc_la_OBJECTS = $(am_libgcjgc_la_OBJECTS) -am__libgcjgc_convenience_la_SOURCES_DIST = allchblk.c alloc.c \ - blacklst.c checksums.c dbg_mlc.c dyn_load.c finalize.c \ - gc_dlopen.c gcj_mlc.c headers.c aix_irix_threads.c malloc.c \ - mallocx.c mark.c mark_rts.c misc.c new_hblk.c obj_map.c \ - os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ - solaris_pthreads.c solaris_threads.c specific.c stubborn.c \ - typd_mlc.c backgraph.c win32_threads.c pthread_support.c \ - pthread_stop_world.c darwin_stop_world.c \ - powerpc_darwin_mach_dep.s am_libgcjgc_convenience_la_OBJECTS = $(am__objects_2) libgcjgc_convenience_la_OBJECTS = \ $(am_libgcjgc_convenience_la_OBJECTS) @@ -129,8 +111,6 @@ LTCCASCOMPILE = $(LIBTOOL) --mode=compile $(CCAS) $(AM_CCASFLAGS) \ $(CCASFLAGS) SOURCES = $(libgcjgc_la_SOURCES) $(libgcjgc_convenience_la_SOURCES) \ $(gctest_SOURCES) -DIST_SOURCES = $(am__libgcjgc_la_SOURCES_DIST) \ - $(am__libgcjgc_convenience_la_SOURCES_DIST) $(gctest_SOURCES) MULTISRCTOP = MULTIBUILDTOP = MULTIDIRS = @@ -227,6 +207,8 @@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -430,15 +412,6 @@ distclean-compile: .c.lo: $(LTCOMPILE) -c -o $@ $< -tests/test.o: tests/test.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/test.o `test -f 'tests/test.c' || echo '$(srcdir)/'`tests/test.c - -tests/test.obj: tests/test.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/test.obj `if test -f 'tests/test.c'; then $(CYGPATH_W) 'tests/test.c'; else $(CYGPATH_W) '$(srcdir)/tests/test.c'; fi` - -tests/test.lo: tests/test.c - $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/test.lo `test -f 'tests/test.c' || echo '$(srcdir)/'`tests/test.c - .s.o: $(CCASCOMPILE) -c $< @@ -454,19 +427,22 @@ clean-libtool: distclean-libtool: -rm -f libtool +# GNU Make needs to see an explicit $(MAKE) variable in the command it +# runs to enable its job server during parallel builds. Hence the +# comments below. all-multi: - $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do + $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE) install-multi: - $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do + $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE) mostlyclean-multi: - $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE) clean-multi: - $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE) distclean-multi: - $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE) maintainer-clean-multi: - $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd @@ -686,7 +662,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -rm -f tests/$(am__dirstamp) maintainer-clean-generic: diff --git a/boehm-gc/NT_MAKEFILE b/boehm-gc/NT_MAKEFILE index 580e1425559..d1b6a5d6f1f 100644 --- a/boehm-gc/NT_MAKEFILE +++ b/boehm-gc/NT_MAKEFILE @@ -2,7 +2,8 @@ # DLLs are included in the root set under NT, but not under win32S. # Use "nmake nodebug=1 all" for optimized versions of library, gctest and editor. -CPU= i386 +MY_CPU=X86 +CPU=$(MY_CPU) !include OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj malloc.obj stubborn.obj dyn_load.obj typd_mlc.obj ptr_chck.obj gc_cpp.obj mallocx.obj @@ -10,10 +11,10 @@ OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_r all: gctest.exe cord\de.exe test_cpp.exe .c.obj: - $(cc) $(cdebug) $(cflags) $(cvars) -Iinclude -DSILENT -DALL_INTERIOR_POINTERS -D__STDC__ -DGC_NOT_DLL $*.c /Fo$*.obj + $(cc) $(cdebug) $(cflags) $(cvars) -Iinclude -DSILENT -DALL_INTERIOR_POINTERS -D__STDC__ -DGC_NOT_DLL -DGC_BUILD $*.c /Fo$*.obj .cpp.obj: - $(cc) $(cdebug) $(cflags) $(cvars) -Iinclude -DSILENT -DALL_INTERIOR_POINTERS -DGC_NOT_DLL $*.CPP /Fo$*.obj + $(cc) $(cdebug) $(cflags) $(cvars) -Iinclude -DSILENT -DALL_INTERIOR_POINTERS -DGC_NOT_DLL -DGC_BUILD $*.CPP /Fo$*.obj $(OBJS) tests\test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h include\private\gc_locks.h include\private\gc_pmark.h include\gc_mark.h @@ -30,7 +31,7 @@ gctest.exe: tests\test.obj gc.lib # mapsympe -n -o gctest.sym gctest.exe cord\de_win.rbj: cord\de_win.res - cvtres -$(CPU) cord\de_win.res -o cord\de_win.rbj + cvtres /MACHINE:$(MY_CPU) /OUT:cord\de_win.rbj cord\de_win.res cord\de.obj cord\de_win.obj: include\cord.h include\private\cord_pos.h cord\de_win.h cord\de_cmds.h diff --git a/boehm-gc/aclocal.m4 b/boehm-gc/aclocal.m4 index ef6dbcd3ce6..18ec86807b0 100644 --- a/boehm-gc/aclocal.m4 +++ b/boehm-gc/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.8.5 -*- Autoconf -*- +# generated automatically by aclocal 1.9 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. @@ -33,14 +33,14 @@ # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"]) +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.8.5])]) + [AM_AUTOMAKE_VERSION([1.9])]) # AM_AUX_DIR_EXPAND @@ -108,7 +108,7 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc. +# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -145,8 +145,8 @@ else fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]) + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) fi])]) # serial 7 -*- Autoconf -*- @@ -319,7 +319,8 @@ AC_SUBST([AMDEPBACKSLASH]) # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -355,27 +356,21 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], else continue fi - grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue - # Extract the definition of DEP_FILES from the Makefile without - # running `make'. + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` - test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" - # We invoke sed twice because it is the simplest approach to - # changing $(DEPDIR) to its actual value in the expansion. - for file in `sed -n ' - /^DEP_FILES = .*\\\\$/ { - s/^DEP_FILES = // - :loop - s/\\\\$// - p - n - /\\\\$/ b loop - p - } - /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue @@ -406,7 +401,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify @@ -482,7 +477,6 @@ AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) -AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl @@ -491,7 +485,9 @@ AC_REQUIRE([AM_PROG_MKDIR_P])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl - +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], @@ -814,13 +810,21 @@ fi # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # Keeping the `.' argument allows $(mkdir_p) to be used without - # argument. Indeed, we sometimes output rules like + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. - # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more - # expensive solution, as it forces Make to start a sub-shell.) - mkdir_p='mkdir -p -- .' + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as @@ -1055,4 +1059,112 @@ fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + m4_include([acinclude.m4]) diff --git a/boehm-gc/allchblk.c b/boehm-gc/allchblk.c index 2b039397e1c..793c468b928 100644 --- a/boehm-gc/allchblk.c +++ b/boehm-gc/allchblk.c @@ -111,7 +111,7 @@ void GC_print_hblkfreelist() for (i = 0; i <= N_HBLK_FLS; ++i) { h = GC_hblkfreelist[i]; # ifdef USE_MUNMAP - if (0 != h) GC_printf1("Free list %ld (Total size %ld):\n", + if (0 != h) GC_printf1("Free list %ld:\n", (unsigned long)i); # else if (0 != h) GC_printf2("Free list %ld (Total size %ld):\n", @@ -133,10 +133,12 @@ void GC_print_hblkfreelist() h = hhdr -> hb_next; } } - if (total_free != GC_large_free_bytes) { +# ifndef USE_MUNMAP + if (total_free != GC_large_free_bytes) { GC_printf1("GC_large_free_bytes = %lu (INCONSISTENT!!)\n", (unsigned long) GC_large_free_bytes); - } + } +# endif GC_printf1("Total of %lu bytes on free list\n", (unsigned long)total_free); } @@ -181,7 +183,7 @@ void GC_dump_regions() hhdr = HDR(p); GC_printf1("\t0x%lx ", (unsigned long)p); if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { - GC_printf1("Missing header!!\n", hhdr); + GC_printf1("Missing header!!(%ld)\n", hhdr); p += HBLKSIZE; continue; } @@ -375,9 +377,8 @@ void GC_unmap_old(void) if (!IS_MAPPED(hhdr)) continue; threshold = (unsigned short)(GC_gc_no - UNMAP_THRESHOLD); last_rec = hhdr -> hb_last_reclaimed; - if (last_rec > GC_gc_no - || last_rec < threshold && threshold < GC_gc_no - /* not recently wrapped */) { + if ((last_rec > GC_gc_no || last_rec < threshold) + && threshold < GC_gc_no /* not recently wrapped */) { sz = hhdr -> hb_sz; GC_unmap((ptr_t)h, sz); hhdr -> hb_flags |= WAS_UNMAPPED; @@ -422,6 +423,7 @@ void GC_merge_unmapped(void) } else { GC_remap((ptr_t)h, size); hhdr -> hb_flags &= ~WAS_UNMAPPED; + hhdr -> hb_last_reclaimed = nexthdr -> hb_last_reclaimed; } } else { /* Unmap any gap in the middle */ @@ -468,7 +470,11 @@ int index; if (total_size == bytes) return h; rest = (struct hblk *)((word)h + bytes); rest_hdr = GC_install_header(rest); - if (0 == rest_hdr) return(0); + if (0 == rest_hdr) { + /* This may be very bad news ... */ + WARN("Header allocation failed: Dropping block.\n", 0); + return(0); + } rest_hdr -> hb_sz = total_size - bytes; rest_hdr -> hb_flags = 0; # ifdef GC_ASSERTIONS @@ -784,6 +790,9 @@ signed_word size; size = HBLKSIZE * OBJ_SZ_TO_BLOCKS(size); GC_remove_counts(hbp, (word)size); hhdr->hb_sz = size; +# ifdef USE_MUNMAP + hhdr -> hb_last_reclaimed = GC_gc_no; +# endif /* Check for duplicate deallocation in the easy case */ if (HBLK_IS_FREE(hhdr)) { @@ -809,11 +818,17 @@ signed_word size; if (IS_MAPPED(prevhdr)) { GC_remove_from_fl(prevhdr, FL_UNKNOWN); prevhdr -> hb_sz += hhdr -> hb_sz; +# ifdef USE_MUNMAP + prevhdr -> hb_last_reclaimed = GC_gc_no; +# endif GC_remove_header(hbp); hbp = prev; hhdr = prevhdr; } } + /* FIXME: It is not clear we really always want to do these merges */ + /* with -DUSE_MUNMAP, since it updates ages and hence prevents */ + /* unmapping. */ GC_large_free_bytes += size; GC_add_to_fl(hbp, hhdr); diff --git a/boehm-gc/alloc.c b/boehm-gc/alloc.c index d2b874fc770..1ac6ff8111f 100644 --- a/boehm-gc/alloc.c +++ b/boehm-gc/alloc.c @@ -133,7 +133,7 @@ int GC_n_attempts = 0; /* Number of attempts at finishing */ if (GC_print_stats) { GC_printf0("Abandoning stopped marking after "); GC_printf1("%lu msecs", (unsigned long)time_diff); - GC_printf1("(attempt %d)\n", (unsigned long) GC_n_attempts); + GC_printf1("(attempt %ld)\n", (unsigned long) GC_n_attempts); } # endif return(1); @@ -228,10 +228,15 @@ void GC_clear_a_few_frames() for (i = 0; i < NWORDS; i++) frames[i] = 0; } +/* Heap size at which we need a collection to avoid expanding past */ +/* limits used by blacklisting. */ +static word GC_collect_at_heapsize = (word)(-1); + /* Have we allocated enough to amortize a collection? */ GC_bool GC_should_collect() { - return(GC_adj_words_allocd() >= min_words_allocd()); + return(GC_adj_words_allocd() >= min_words_allocd() + || GC_heapsize >= GC_collect_at_heapsize); } @@ -924,25 +929,37 @@ word n; # endif } # endif - expansion_slop = 8 * WORDS_TO_BYTES(min_words_allocd()); - if (5 * HBLKSIZE * MAXHINCR > expansion_slop) { - expansion_slop = 5 * HBLKSIZE * MAXHINCR; - } + expansion_slop = WORDS_TO_BYTES(min_words_allocd()) + 4*MAXHINCR*HBLKSIZE; if (GC_last_heap_addr == 0 && !((word)space & SIGNB) || GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space) { /* Assume the heap is growing up */ GC_greatest_plausible_heap_addr = - GC_max(GC_greatest_plausible_heap_addr, - (ptr_t)space + bytes + expansion_slop); + (GC_PTR)GC_max((ptr_t)GC_greatest_plausible_heap_addr, + (ptr_t)space + bytes + expansion_slop); } else { /* Heap is growing down */ GC_least_plausible_heap_addr = - GC_min(GC_least_plausible_heap_addr, - (ptr_t)space - expansion_slop); + (GC_PTR)GC_min((ptr_t)GC_least_plausible_heap_addr, + (ptr_t)space - expansion_slop); } +# if defined(LARGE_CONFIG) + if (((ptr_t)GC_greatest_plausible_heap_addr <= (ptr_t)space + bytes + || (ptr_t)GC_least_plausible_heap_addr >= (ptr_t)space) + && GC_heapsize > 0) { + /* GC_add_to_heap will fix this, but ... */ + WARN("Too close to address space limit: blacklisting ineffective\n", 0); + } +# endif GC_prev_heap_addr = GC_last_heap_addr; GC_last_heap_addr = (ptr_t)space; GC_add_to_heap(space, bytes); + /* Force GC before we are likely to allocate past expansion_slop */ + GC_collect_at_heapsize = + GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE; +# if defined(LARGE_CONFIG) + if (GC_collect_at_heapsize < GC_heapsize /* wrapped */) + GC_collect_at_heapsize = (word)(-1); +# endif return(TRUE); } diff --git a/boehm-gc/checksums.c b/boehm-gc/checksums.c index 121c36d4be2..57a6ebc2160 100644 --- a/boehm-gc/checksums.c +++ b/boehm-gc/checksums.c @@ -13,14 +13,14 @@ /* Boehm, March 29, 1995 12:51 pm PST */ # ifdef CHECKSUMS -# include "gc_priv.h" +# include "private/gc_priv.h" /* This is debugging code intended to verify the results of dirty bit */ /* computations. Works only in a single threaded environment. */ /* We assume that stubborn objects are changed only when they are */ /* enabled for writing. (Certain kinds of writing are actually */ /* safe under other conditions.) */ -# define NSUMS 2000 +# define NSUMS 10000 # define OFFSET 0x10000 @@ -29,7 +29,7 @@ typedef struct { word old_sum; word new_sum; struct hblk * block; /* Block to which this refers + OFFSET */ - /* to hide it from colector. */ + /* to hide it from collector. */ } page_entry; page_entry GC_sums [NSUMS]; @@ -76,12 +76,13 @@ int index; { page_entry *pe = GC_sums + index; register hdr * hhdr = HDR(h); + struct hblk *b; if (pe -> block != 0 && pe -> block != h + OFFSET) ABORT("goofed"); pe -> old_sum = pe -> new_sum; pe -> new_sum = GC_checksum(h); # if !defined(MSWIN32) && !defined(MSWINCE) - if (pe -> new_sum != 0 && !GC_page_was_ever_dirty(h)) { + if (pe -> new_sum != 0x80000000 && !GC_page_was_ever_dirty(h)) { GC_printf1("GC_page_was_ever_dirty(0x%lx) is wrong\n", (unsigned long)h); } @@ -91,13 +92,19 @@ int index; } else { GC_n_clean++; } - if (pe -> new_valid && pe -> old_sum != pe -> new_sum) { + b = h; + while (IS_FORWARDING_ADDR_OR_NIL(hhdr) && hhdr != 0) { + b -= (word)hhdr; + hhdr = HDR(b); + } + if (pe -> new_valid + && hhdr != 0 && hhdr -> hb_descr != 0 /* may contain pointers */ + && pe -> old_sum != pe -> new_sum) { if (!GC_page_was_dirty(h) || !GC_page_was_ever_dirty(h)) { /* Set breakpoint here */GC_n_dirty_errors++; } # ifdef STUBBORN_ALLOC - if (!IS_FORWARDING_ADDR_OR_NIL(hhdr) - && hhdr -> hb_map != GC_invalid_map + if ( hhdr -> hb_map != GC_invalid_map && hhdr -> hb_obj_kind == STUBBORN && !GC_page_was_changed(h) && !GC_on_free_list(h)) { @@ -120,26 +127,17 @@ word dummy; register hdr * hhdr = HDR(h); register bytes = WORDS_TO_BYTES(hhdr -> hb_sz); - bytes += HDR_BYTES + HBLKSIZE-1; + bytes += HBLKSIZE-1; bytes &= ~(HBLKSIZE-1); GC_bytes_in_used_blocks += bytes; } void GC_check_blocks() { - word bytes_in_free_blocks = 0; - struct hblk * h = GC_hblkfreelist; - hdr * hhdr = HDR(h); - word sz; + word bytes_in_free_blocks = GC_large_free_bytes; GC_bytes_in_used_blocks = 0; GC_apply_to_all_blocks(GC_add_block, (word)0); - while (h != 0) { - sz = hhdr -> hb_sz; - bytes_in_free_blocks += sz; - h = hhdr -> hb_next; - hhdr = HDR(h); - } GC_printf2("GC_bytes_in_used_blocks = %ld, bytes_in_free_blocks = %ld ", GC_bytes_in_used_blocks, bytes_in_free_blocks); GC_printf1("GC_heapsize = %ld\n", GC_heapsize); diff --git a/boehm-gc/configure b/boehm-gc/configure index 338609c6820..d2de790149c 100755 --- a/boehm-gc/configure +++ b/boehm-gc/configure @@ -309,7 +309,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os mkinstalldirs INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CFLAGS CXXFLAGS CCAS CCASFLAGS AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS LN_S LIBTOOL CXXCPP CPPFLAGS THREADLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all target_noncanonical CPLUSPLUS_TRUE CPLUSPLUS_FALSE AM_CPPFLAGS addobjs addincludes addlibs addtests CPP EGREP MY_CFLAGS toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os mkinstalldirs INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CFLAGS CXXFLAGS CCAS CCASFLAGS AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS LN_S LIBTOOL CXXCPP CPPFLAGS THREADLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all target_noncanonical CPLUSPLUS_TRUE CPLUSPLUS_FALSE AM_CPPFLAGS addobjs addincludes addlibs addtests CPP EGREP MY_CFLAGS toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -967,7 +967,7 @@ esac else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi - cd "$ac_popdir" + cd $ac_popdir done fi @@ -1483,7 +1483,7 @@ esac mkinstalldirs="`cd $ac_aux_dir && ${PWDCMD-pwd}`/mkinstalldirs" -am__api_version="1.8" +am__api_version="1.9" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: @@ -1635,13 +1635,21 @@ echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # Keeping the `.' argument allows $(mkdir_p) to be used without - # argument. Indeed, we sometimes output rules like + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. - # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more - # expensive solution, as it forces Make to start a sub-shell.) - mkdir_p='mkdir -p -- .' + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as @@ -1757,7 +1765,7 @@ fi # Define the identity of the package. PACKAGE=gc - VERSION=6.1a1 + VERSION=6.3 # Some tools Automake needs. @@ -1776,9 +1784,6 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -AMTAR=${AMTAR-"${am_missing_run}tar"} - install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user @@ -1871,6 +1876,13 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + @@ -2508,7 +2520,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2566,7 +2579,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2682,7 +2696,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2736,7 +2751,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2781,7 +2797,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2825,7 +2842,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3183,7 +3201,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3241,7 +3260,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3312,7 +3332,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3356,7 +3377,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3964,7 +3986,7 @@ case ${gc_basedir} in *) gc_flagbasedir='$(top_builddir)/'${gc_basedir} ;; esac -gc_cflags="${gc_cflags} -I"'$(top_builddir)'"/./targ-include -I${gc_flagbasedir}/libc/include" +gc_cflags="${gc_cflags} -Iinclude -I"'$(top_builddir)'"/./targ-include -I${gc_flagbasedir}/libc/include" case "${host}" in *-*-cygwin32*) gc_cflags="${gc_cflags} -I${gc_flagbasedir}/../winsup/include" @@ -4717,7 +4739,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 4720 "configure"' > conftest.$ac_ext + echo '#line 4742 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4864,7 +4886,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5562,7 +5585,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6061,7 +6085,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6231,7 +6256,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6294,7 +6320,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6566,7 +6593,8 @@ else multilib_arg= fi - ac_config_commands="$ac_config_commands boehm-cflags" + ac_config_headers="$ac_config_headers include/gc_config.h" + ac_config_files="$ac_config_files Makefile include/Makefile" @@ -6644,38 +6672,7 @@ s/^[^=]*=[ ]*$//; }' fi -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - +DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= @@ -7051,10 +7048,15 @@ Usage: $0 [OPTIONS] [FILE]... --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE Configuration files: $config_files +Configuration headers: +$config_headers + Configuration commands: $config_commands @@ -7175,9 +7177,6 @@ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} CC="$CC" AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" -DEFS="$DEFS" -AM_CPPFLAGS="$AM_CPPFLAGS" - _ACEOF @@ -7191,7 +7190,7 @@ do "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "boehm-cflags" ) CONFIG_COMMANDS="$CONFIG_COMMANDS boehm-cflags" ;; + "include/gc_config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/gc_config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; @@ -7204,6 +7203,7 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi @@ -7301,7 +7301,6 @@ s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t -s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t @@ -7310,6 +7309,9 @@ s,@mkdir_p@,$mkdir_p,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t +s,@AMTAR@,$AMTAR,;t t +s,@am__tar@,$am__tar,;t t +s,@am__untar@,$am__untar,;t t s,@CC@,$CC,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t @@ -7532,6 +7534,11 @@ esac *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ @@ -7570,12 +7577,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;} fi;; esac done` || { (exit 1); exit 1; } - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub @@ -7607,6 +7608,251 @@ done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'`/stamp-h$_am_stamp_count +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + # # CONFIG_COMMANDS section. # @@ -7752,27 +7998,21 @@ echo X"$mf" | else continue fi - grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue - # Extract the definition of DEP_FILES from the Makefile without - # running `make'. + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` - test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" - # We invoke sed twice because it is the simplest approach to - # changing $(DEPDIR) to its actual value in the expansion. - for file in `sed -n ' - /^DEP_FILES = .*\\\\$/ { - s/^DEP_FILES = // - :loop - s/\\\\$// - p - n - /\\\\$/ b loop - p - } - /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue @@ -7818,8 +8058,6 @@ echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} done done ;; - boehm-cflags ) -echo "$AM_CPPFLAGS $DEFS" > boehm-cflags ;; esac done _ACEOF diff --git a/boehm-gc/configure.ac b/boehm-gc/configure.ac index a99cb901a90..0137ff6519f 100644 --- a/boehm-gc/configure.ac +++ b/boehm-gc/configure.ac @@ -37,7 +37,7 @@ _GCC_TOPLEV_NONCANONICAL_TARGET mkinstalldirs="`cd $ac_aux_dir && ${PWDCMD-pwd}`/mkinstalldirs" AC_SUBST(mkinstalldirs) -AM_INIT_AUTOMAKE(gc, 6.1a1, no-define) +AM_INIT_AUTOMAKE(gc, 6.3, no-define) # The autoconf 2.5x version of the no-executables hack. sinclude(../config/no-executables.m4) @@ -79,7 +79,7 @@ case [$]{gc_basedir} in *) gc_flagbasedir='[$](top_builddir)/'[$]{gc_basedir} ;; esac -gc_cflags="[$]{gc_cflags} -I"'[$](top_builddir)'"/./targ-include -I[$]{gc_flagbasedir}/libc/include" +gc_cflags="[$]{gc_cflags} -Iinclude -I"'[$](top_builddir)'"/./targ-include -I[$]{gc_flagbasedir}/libc/include" case "${host}" in *-*-cygwin32*) gc_cflags="[$]{gc_cflags} -I[$]{gc_flagbasedir}/../winsup/include" @@ -480,10 +480,7 @@ else multilib_arg= fi -AC_CONFIG_COMMANDS(boehm-cflags, [ -dnl Put all the -I and -D options in a file. -echo "$AM_CPPFLAGS $DEFS" > boehm-cflags], [ -DEFS="$DEFS" -AM_CPPFLAGS="$AM_CPPFLAGS"]) +AC_CONFIG_HEADERS([include/gc_config.h]) + AC_CONFIG_FILES(Makefile include/Makefile) AC_OUTPUT diff --git a/boehm-gc/cord/cordprnt.c b/boehm-gc/cord/cordprnt.c index 6ecc00e8410..ad937b02d4e 100644 --- a/boehm-gc/cord/cordprnt.c +++ b/boehm-gc/cord/cordprnt.c @@ -261,7 +261,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args) # ifdef __va_copy __va_copy(vsprintf_args, args); # else -# if defined(__GNUC__) /* and probably in other cases */ +# if defined(__GNUC__) && !defined(__DJGPP__) /* and probably in other cases */ va_copy(vsprintf_args, args); # else vsprintf_args = args; diff --git a/boehm-gc/cord/cordtest.c b/boehm-gc/cord/cordtest.c index d54c65fe0d7..8f4836a2333 100644 --- a/boehm-gc/cord/cordtest.c +++ b/boehm-gc/cord/cordtest.c @@ -11,6 +11,7 @@ * modified is included with the above copyright notice. */ /* Boehm, August 24, 1994 11:58 am PDT */ +# include "gc.h" /* For GC_INIT() only */ # include "cord.h" # include # include @@ -116,7 +117,7 @@ void test_basics() void test_extras() { -# if defined(__OS2__) +# if defined(__OS2__) || defined(__DJGPP__) # define FNAME1 "tmp1" # define FNAME2 "tmp2" # elif defined(AMIGA) @@ -162,6 +163,10 @@ void test_extras() x = CORD_cat(x,x); } if ((f = fopen(FNAME2, "w")) == 0) ABORT("2nd open failed"); +# ifdef __DJGPP__ + /* FIXME: DJGPP workaround. Why does this help? */ + if (fflush(f) != 0) ABORT("fflush failed"); +# endif if (CORD_put(x,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); w = CORD_from_file(f2 = fopen(FNAME2, "rb")); @@ -221,6 +226,7 @@ main() # ifdef THINK_C printf("cordtest:\n"); # endif + GC_INIT(); test_basics(); test_extras(); test_printf(); diff --git a/boehm-gc/cord/cordxtra.c b/boehm-gc/cord/cordxtra.c index a5be10de58a..b0a746226cb 100644 --- a/boehm-gc/cord/cordxtra.c +++ b/boehm-gc/cord/cordxtra.c @@ -385,9 +385,9 @@ size_t CORD_str(CORD x, size_t start, CORD s) mask <<= 8; mask |= 0xff; s_buf <<= 8; - s_buf |= s_start[i]; + s_buf |= (unsigned char)s_start[i]; x_buf <<= 8; - x_buf |= CORD_pos_fetch(xpos); + x_buf |= (unsigned char)CORD_pos_fetch(xpos); CORD_next(xpos); } for (match_pos = start; ; match_pos++) { @@ -402,7 +402,7 @@ size_t CORD_str(CORD x, size_t start, CORD s) return(CORD_NOT_FOUND); } x_buf <<= 8; - x_buf |= CORD_pos_fetch(xpos); + x_buf |= (unsigned char)CORD_pos_fetch(xpos); CORD_next(xpos); } } diff --git a/boehm-gc/cord/de.c b/boehm-gc/cord/de.c index fda71424176..989e19a8881 100644 --- a/boehm-gc/cord/de.c +++ b/boehm-gc/cord/de.c @@ -569,9 +569,9 @@ char ** argv; #if defined(MACINTOSH) console_options.title = "\pDumb Editor"; cshow(stdout); - GC_init(); argc = ccommand(&argv); #endif + GC_INIT(); if (argc != 2) goto usage; arg_file_name = argv[1]; diff --git a/boehm-gc/dbg_mlc.c b/boehm-gc/dbg_mlc.c index f640930d901..aacbb7a1b63 100644 --- a/boehm-gc/dbg_mlc.c +++ b/boehm-gc/dbg_mlc.c @@ -2,7 +2,7 @@ * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. * Copyright (c) 1997 by Silicon Graphics. All rights reserved. - * Copyright (c) 1999-2000 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -195,13 +195,13 @@ ptr_t p; (unsigned long)i); switch(source) { case GC_REFD_FROM_ROOT: - GC_err_printf1("root at 0x%lx\n", (unsigned long)base); + GC_err_printf1("root at 0x%lx\n\n", (unsigned long)base); goto out; case GC_REFD_FROM_REG: - GC_err_printf0("root in register\n"); + GC_err_printf0("root in register\n\n"); goto out; case GC_FINALIZER_REFD: - GC_err_printf0("list of finalizable objects\n"); + GC_err_printf0("list of finalizable objects\n\n"); goto out; case GC_REFD_FROM_HEAP: GC_err_printf1("offset %ld in object:\n", (unsigned long)offset); @@ -217,15 +217,20 @@ ptr_t p; /* Force a garbage collection and generate a backtrace from a */ /* random heap address. */ - void GC_generate_random_backtrace(void) + void GC_generate_random_backtrace_no_gc(void) { void * current; - GC_gcollect(); current = GC_generate_random_valid_address(); - GC_printf1("Chose address 0x%lx in object\n", (unsigned long)current); + GC_printf1("\n****Chose address 0x%lx in object\n", (unsigned long)current); GC_print_backtrace(current); } + void GC_generate_random_backtrace(void) + { + GC_gcollect(); + GC_generate_random_backtrace_no_gc(); + } + #endif /* KEEP_BACK_PTRS */ # define CROSSES_HBLK(p, sz) \ @@ -325,6 +330,58 @@ register oh * ohdr; } #endif /* !SHORT_DBG_HDRS */ +static GC_describe_type_fn GC_describe_type_fns[MAXOBJKINDS] = {0}; + +void GC_register_describe_type_fn(kind, fn) +int kind; +GC_describe_type_fn fn; +{ + GC_describe_type_fns[kind] = fn; +} + +/* Print a type description for the object whose client-visible address */ +/* is p. */ +void GC_print_type(p) +ptr_t p; +{ + hdr * hhdr = GC_find_header(p); + char buffer[GC_TYPE_DESCR_LEN + 1]; + int kind = hhdr -> hb_obj_kind; + + if (0 != GC_describe_type_fns[kind] && GC_is_marked(GC_base(p))) { + /* This should preclude free list objects except with */ + /* thread-local allocation. */ + buffer[GC_TYPE_DESCR_LEN] = 0; + (GC_describe_type_fns[kind])(p, buffer); + GC_ASSERT(buffer[GC_TYPE_DESCR_LEN] == 0); + GC_err_puts(buffer); + } else { + switch(kind) { + case PTRFREE: + GC_err_puts("PTRFREE"); + break; + case NORMAL: + GC_err_puts("NORMAL"); + break; + case UNCOLLECTABLE: + GC_err_puts("UNCOLLECTABLE"); + break; +# ifdef ATOMIC_UNCOLLECTABLE + case AUNCOLLECTABLE: + GC_err_puts("ATOMIC UNCOLLECTABLE"); + break; +# endif + case STUBBORN: + GC_err_puts("STUBBORN"); + break; + default: + GC_err_printf2("kind %ld, descr 0x%lx", kind, hhdr -> hb_descr); + } + } +} + + + void GC_print_obj(p) ptr_t p; { @@ -334,11 +391,13 @@ ptr_t p; GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh))); GC_err_puts(ohdr -> oh_string); # ifdef SHORT_DBG_HDRS - GC_err_printf1(":%ld)\n", (unsigned long)(ohdr -> oh_int)); + GC_err_printf1(":%ld, ", (unsigned long)(ohdr -> oh_int)); # else - GC_err_printf2(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int), + GC_err_printf2(":%ld, sz=%ld, ", (unsigned long)(ohdr -> oh_int), (unsigned long)(ohdr -> oh_sz)); # endif + GC_print_type((ptr_t)(ohdr + 1)); + GC_err_puts(")\n"); PRINT_CALL_CHAIN(ohdr); } @@ -403,6 +462,8 @@ void GC_start_debugging() GC_register_displacement((word)sizeof(oh)); } +size_t GC_debug_header_size = sizeof(oh); + # if defined(__STDC__) || defined(__cplusplus) void GC_debug_register_displacement(GC_word offset) # else @@ -757,7 +818,15 @@ GC_PTR p; uncollectable = TRUE; } # endif - if (uncollectable) GC_free(base); + if (uncollectable) { + GC_free(base); + } else { + size_t i; + size_t obj_sz = hhdr -> hb_sz - BYTES_TO_WORDS(sizeof(oh)); + + for (i = 0; i < obj_sz; ++i) ((word *)p)[i] = 0xdeadbeef; + GC_ASSERT((word *)p + i == (word *)base + hhdr -> hb_sz); + } } /* !GC_find_leak */ } @@ -1013,7 +1082,8 @@ GC_PTR *ocd; GC_finalization_proc my_old_fn; GC_PTR my_old_cd; ptr_t base = GC_base(obj); - if (0 == base || (ptr_t)obj - base != sizeof(oh)) { + if (0 == base) return; + if ((ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_debug_register_finalizer called with non-base-pointer 0x%lx\n", obj); @@ -1045,7 +1115,8 @@ GC_PTR *ocd; GC_finalization_proc my_old_fn; GC_PTR my_old_cd; ptr_t base = GC_base(obj); - if (0 == base || (ptr_t)obj - base != sizeof(oh)) { + if (0 == base) return; + if ((ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_debug_register_finalizer_no_order called with non-base-pointer 0x%lx\n", obj); @@ -1078,7 +1149,8 @@ GC_PTR *ocd; GC_finalization_proc my_old_fn; GC_PTR my_old_cd; ptr_t base = GC_base(obj); - if (0 == base || (ptr_t)obj - base != sizeof(oh)) { + if (0 == base) return; + if ((ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_debug_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n", obj); diff --git a/boehm-gc/doc/README b/boehm-gc/doc/README index 29d954f023e..ff77113ee8c 100644 --- a/boehm-gc/doc/README +++ b/boehm-gc/doc/README @@ -1,7 +1,7 @@ Copyright (c) 1988, 1989 Hans-J. Boehm, Alan J. Demers Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. -Copyright (c) 1999-2003 by Hewlett-Packard Company. All rights reserved. +Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P. The file linux_threads.c is also Copyright (c) 1998 by Fergus Henderson. All rights reserved. @@ -28,7 +28,7 @@ are GPL'ed, but with an exception that should cover all uses in the collector. (If you are concerned about such things, I recommend you look at the notice in config.guess or ltmain.sh.) -This is version 6.3alpha1 of a conservative garbage collector for C and C++. +This is version 6.3 of a conservative garbage collector for C and C++. You might find a more recent version of this at diff --git a/boehm-gc/doc/README.changes b/boehm-gc/doc/README.changes index 619ea2e4a49..e27e7d635b6 100644 --- a/boehm-gc/doc/README.changes +++ b/boehm-gc/doc/README.changes @@ -1836,7 +1836,7 @@ Since 6.2alpha4: libgccpp. Since 6.2alpha5: - - There was extra underscore in the name of GC_save_registers_in_stack + - There was an extra underscore in the name of GC_save_registers_in_stack for NetBSD/SPARC. (Thanks to Jaap Boender for the patch.) - Integrated Brian Alliet's patch for Darwin. This restructured the linuxthreads/pthreads support to separate generic pthreads support @@ -1894,7 +1894,219 @@ Since 6.2: (Thanks to Roger Sayle for the patch.) - Applied more AIX threads patches from Scott Ananian. +Since 6.3alpha1: + - Reenabled I_HOLD_LOCK assertion in aix_irix_threads.h. + - Put back the WINABI qualifier for GC_CreateThread. (Thanks to + Danny Smith for the patch. 6.3alpha1 had the qualifier in one place + but not elsewhere, which was clearly wrong.) + - Sometimes explicitly define __private_extern__ before DARWIN dyld.h + include. (Thanks to Andreas Tobker for postting the patch.) + - Included signal.h from pthread_support.c. Removed GC_looping_handler, + which was dead code. + - GC_find_start was misdeclared by gc_pmark.h if PRINT_BLACK_LIST was + defined. (Thanks to Glauco Masotti for testing and reporting this.) + Changed GC_find_start to never just return 0. According to its + comment it doesn't, and it's unclear that's correct. + - GC_alloc_large had several largely compensating bugs in the + computation of GC_words_wasted. (It was confused about bytes vs. + words in two places.) + - Integrated Slava Sysoltev's patch to support more recent versions of + the Intel compiler on IA64/Linux. + - Changed win32 spinlock initialization to conditionally set a spin count. + (Emmanual Stumpf pointed out that enabling this makes a large performance + difference on win32 multiprocessors.) Also cleaned up the win32 spinlock + initialization code a bit. + - Fixed thread support for HP/UX/IA64. The register backing store base for + the main thread was sometimes not set correctly. (Thanks to Laurent + Morichetti.) + - Added -DEMPTY_GETENV_RESULTS flag to work around Wine problem. + - Declare GC_stack_alloc and GC_stack_free in solaris_threads.h to + avoid 64-bit size mismatches. (Thanks to Bernie Solomon.) + - Fixed GC_generic_push_regs to avoid a potential and very unfortunate + tail call optimization. This could lead to prematurely reclaimed + objects on configurations that used the generic routine and the new + build infrastructure (which potentially optimizes mach_dep.c). + This was a serious bug, but it's unclear whether it has resulted in + any real failures. + - Fixed CORD_str to deal with signed characters. (Thanks to Alexandr + Petrosian for noticing the problem and supplying the patch.) + - Merged a couple of NOSYS/ECOS tests into os_dep.c from gcj. (Thanks + to Anthony Green.) + - Partially merged a win32 patch from Ben Hutchings, and substantially + revised other parts of win32_threads.c. It had several problems. + Under MinGW with a statically linked library, the main thread was + not registered. Cygwin detached threads leaked thread descriptors. + There were several race conditions. For now, unfortunately the + static threads limit remains, though we increased it, and made table + traversal cost depend on the actual thread count. + There is also still some code duplication with pthread_support.c. + (Thread descriptors did become much smaller, since Ben Hutchings + removed the thread context from them.) + - Integrated a Solaris configure.in patch from Rainer Orth. + - Added GC_IGNORE_FB and associated warning to very partially address + the issue of the collector treating a mapped frame buffer as part + of the root set. (Thanks to David Peroutka for providing some + insight. More would be helpful. Is there anything that can be used + to at least partially identify such memory segments?) + +Since 6.3alpha2: + - Removed -DSMALL_CONFIG from BCC_MAKEFILE. + - Changed macros to test for an ARM processor (Patch from Richard Earnshaw.) + - Mostly applied a DJGPP patch from Doug Kaufman. Especially Makefile.dj + had suffered from serious bit rot. + - Rewrote GC_apply_to_maps, eliminating an off-by-one subscript error, + and a call to alloca (for lcc compatibility). + - Changed USE_MUNMAP behavior on posixy platforms to immediately remap + the memory with PROT_NONE instead of unmapping it. The latter risks + an intervening mmap grabbing the address space out from underneath us. + Updated this code to reflect a cleaner patch from Ulrich Drepper. + - Replaced _T with _Tp in new_gc_alloc.h to avoid a MACOS X conflict. + (Patch from Andrew Begel.) + - Dynamically choose whether or not lock should spin on win32. (Thanks + to Maurizio Vairani for the patch.) This may be a significant performance + improvement for win32. + - Fix Makefile.direct to actually include NT_STATIC_THREADS_MAKEFILE + in the distribution. (Again thanks to Maurizio Vairani.) + - Maybe_install_looping_handler() was accidentally exported, violating + our name space convention. + - Made os_dep.c use sigsetjmp and SA_NODEFER for NetBSD. (Thanks to + Christian Limpach.) (I generalized the patch to use sigsetjmp on all + UNIX_LIKE platforms, admittedly a slightly risky move. But it may avoid + similar problems on some other platforms. I also cleaned up the defn + of UNIX_LIKE a bit. - Hans) + - Integrated Andrew Begel's Darwin threads patch, adjusted according to + some of Fergus Hendersons's comments. (Patch didn't apply cleanly, + errors are possible.) + - Added another test or two for the Intel 8.0 compiler to avoid + confusing it with gcc. The single-threaded collector should now build + with icc, at least on ia64. + +Since 6.3alpha3: + - USE_MMAP was broken by confusion in the code dealing with USE_MMAP_ANON. + (This was pointed out, and fixes were suggested by several other people.) + - Darwin supprt was broken in alpha3 as a result of my misintegration of + Andrew Begel's patches. Fixed with another patch from Andrew Begel. + - A new sanity check in pthread_stop_world.c:GC_push_all_stacks() was + overly aggressive. We may collect from an unregistered thread during + thread creation. Fixed by explicitly checking for that case. (Added + GC_in_thread_creation.) + +Since 6.3alpha4: + - Fix & vs && typo in GC_generic_malloc and + GC_generic_malloc_ignore_off_page. (Propagated from the gcc tree.) + - Removed SA_NODEFER hack from NetBSD and Solaris write-protect handler. + (According to Christian Limpach, the NetBSD problem is fixed. + Presumably so is the Solaris 2.3 problem.) + - Removed placement delete from gc_cpp.h for the SGI compiler. + (Thanks to Simon Gornall for the patch.) + - Changed semantics of the GC_IGNORE_FB environment variable, based + on experimentation by Nicolas Cannasse pointing out that the old + interpretation was useless. We still need help in identifying win32 + graphics memory mappings. The current "solution" is a hack. + - Removed "MAKEOVERRIDES =" from Makefile.am and thus Makefile.in. + It probably made more sense in the gcc context. + - Explicitly ensure that NEED_FIND_LIMIT is defined for {Open,Net}BSD/ELF. + - Replaced USE_HPUX_TLS macro by USE_COMPILER_TLS, since gcc often + supports the same extension on various platforms. + - Added some basic (completely untested) defines for win64, in support + of future work. + - Declared GC_jmp_buf in os_dep.s as JMP_BUF instead of jmp_buf, fixing + a memory overwrite bug on Solaris and perhaps other platforms. + - Added 0 != __libc_stack_end test to GC_linux_stack_base. (Thanks to Jakub + Jelinek, both for the patch, and for explaining the problem to me.) + Otherwise "prelink"ing could cause the collector to fail. + - Changed default thread local storage implementation to USE_PTHREAD_SPECIFIC + for HP/UX with gcc. The compiler-based implementation appears to work + only with the vendor compiler. + - Export GC_debug_header_size and GC_USR_PTR_FROM_BASE from gc_mark.h, + making client mark code cleaner and less dependent on GC version. + - Export several new procedures and GC_generic_malloc from gc_mark.h + to support user-defined kinds. Use the new procedures to replace existing + code in gcj_mlc.c and typd_mlc.c. + - Added support for GC_BACKTRACES. + - Fixed a remaining problem in CORD_str with signed characters. (Thanks + to Alexandr Petrosian for the patch.) + - Removed supposedly redundant, but very buggy, definitions of finalizer + macros from javaxfc.h. Fortunately this file probably has no users. + The correct declarations were already in gc.h. + - Also need to set GC_in_thread_creation while waiting for GC during + thread termination, since it is also possible to collect from an + unregistered thread in that case. + - Define NO_GETENV for Windows CE, since getenv doesn't appear to exist. + + some other minor WinCE fixes. (Thanks to Alain Novak.) + - Added GC_register_describe_type_fn. + - Arrange for debugging finalizer registration to ignore non-heap + registrations, since the regular version of the routine also behaves + that way. + - GC_gcj_malloc and friends need to check for finalizers waiting to be run. + One of the more obscure allocation routines with missing a LOCK() call. + - Fixed cvtres invocations in NT_MAKEFILE and NT_STATIC_THREADS_MAKEFILE + to work with VS.NET. + - Cleaned up GC_INIT calls in test. Updated gc.man to encourage GC_INIT + use in portable code. + - Taught the GC to use libunwind if --enable-full-debug is specified on + IA64 and libunwind is present. + - The USE_MUNMAP code could get confused about the age of a block and + prematurely unmap it. GC_unmap_old had a bug related to wrapping of + GC_gc_no. GC_freehblk and GC_merge_unmapped didn't maintain + hb_last_reclaimed reasonably when blocks were merged. The code was + fixed to reflect original intent, but that may not always be an + improvement. See todo list item. + +Since 6.3alpha5: + - Define USE_GENERIC_PUSH_REGS for NetBSD/M68K. + - Fixed the X86_64 PREFETCH macros to correctly handle ia32e (which uses + different prefetch instructions from AMD64). (Thanks to H.J. Lu.) + - GC_config_macros.h did not correctly define GC_WIN32_THREADS from + GC_THREADS. + - Added simple_example.html. + - Merged Andrew Gray's patch to correctly restore signal handlers on + FreeBSD. + - Merged a patch from Andreas Jaeger to deal with prefetch-related warnings + on x86-64. Added some other casts so that the PREFETCH macros + always get a ptr_t argument. Removed some casts inthe PREFETCH + implementations. + - At Jesse Jones suggestion: Added a header guard for gc_allocator.h + and changed GC_debug_free to clobber contents of deallocated object. + - The signal masking code in pthread_stop_world.c contained some errors. + In particular SIGSEGV was masked in the handler, in spite of the fact that + it wrote to the heap. This could lead to an uncaught SIGSEGV, which + apparently became much more likely in Linux 2.6. Also fixed some + typos, and reduced code duplication in the same area. + - Remove ltconfig, clean up configure messages for DGUX (thanks to + Adrian Bunk for the patches). + - Integrated NetBSD/OpenBSD patches from Marc Recht and Matthias Drochner. + +Since gc6.3alpha6: + - Compile test_cpp.cc with CXXCOMPILE instead of COMPILE. + - Very large allocations could cause a collector hang. Correct + calculation of GC_collect_at_heapsize. + - GC_print_hblkfreelist printed some bogus results if USE_MUNMAP + was defined. + - The generic GC_THREADS macro didn't work correctly on Solaris, + since the implementation failed to include gc_config_macros.h + before deciding whether or not to compile the rest of the file. + - Threadlibs.c failed to expand the generic GC_THREADS macro. + - Correct MacOSX thread stop code. (Thanks to Dick Porter.) + - SMALL_OBJ definition was off by one. This could cause crashes + at startup. (Thanks to Zoltan Varga for narrowing this down to + a trivial test case.) + - Integrate Paolo Molara's patch to deal with a race in the Darwin + thread stopping code. + - Changed X86_64 implementation to use SA_SIGINFO in the MPROTECT_VDB + implementation. The old approach appears to have been broken by + recent kernels. + - Add GC_ATTR_UNUSED to eliminate a warning in gc_allocator.h. (Thanks + to Andrew Begel.) + - Fix GC_task_self declaration in os_dep.c. (Thanks to Andrew Pinski.) + - Increase INITIAL_BUF_SZ in os_dep.c for Solaris /proc reads. + To do: + - The USE_MUNMAP code should really use a separate data structure + indexed by physical page to keep track of time since last use of + a page. Using hblk headers means we lose track of ages when + blocks are merged, and we can't unmap pages that have been allocated and + dropped by the blacklisting code. I suspect both of these matter. - A dynamic libgc.so references dlopen unconditionally, but doesn't link against libdl. - GC_proc_fd for Solaris is not correctly updated in response to a diff --git a/boehm-gc/doc/README.environment b/boehm-gc/doc/README.environment index d1f3b5c053b..97a13dc3e45 100644 --- a/boehm-gc/doc/README.environment +++ b/boehm-gc/doc/README.environment @@ -1,6 +1,6 @@ The garbage collector looks at a number of environment variables which are then used to affect its operation. These are examined only on Un*x-like -platforms. +platforms and win32. GC_INITIAL_HEAP_SIZE= - Initial heap size in bytes. May speed up process start-up. @@ -26,6 +26,14 @@ GC_DUMP_REGULARLY - Generate a GC debugging dump GC_dump() on startup if you have a bug to report, but please include only the last complete dump. +GC_BACKTRACES= - Generate n random backtraces (for heap profiling) after + each GC. Collector must have been built with + KEEP_BACK_PTRS. This won't generate useful output unless + most objects in the heap were allocated through debug + allocators. This is intended to be only a statistical + sample; individual traces may be erroneous due to + concurrent heap mutation. + GC_PRINT_ADDRESS_MAP - Linux only. Dump /proc/self/maps, i.e. various address maps for the process, to stderr on every GC. Useful for mapping root addresses to source for deciphering leak @@ -86,6 +94,28 @@ GC_RETRY_SIGNALS, GC_NO_RETRY_SIGNALS - Try to compensate for lost was turned into a runtime flag to enable last-minute work-arounds. +GC_IGNORE_FB[=] - (Win32 only.) Try to avoid treating a mapped + frame buffer as part of the root set. Certain (higher end?) + graphics cards seems to result in the graphics memory mapped + into the user address space as writable memory. + Unfortunately, there seems to be no systematic way to + identify such memory. Setting the environment variable to n + causes the collector to ignore mappings longer than n MB. + The default value of n is currently 15. (This should cover + a 16 MB graphics card, since the mapping appears to be slightly + shorter than all of graphics memory. It will fail if a dll + writes pointers to collectable objects into a data segment + whose length is >= 15MB. Empirically that's rare, but + certainly possible.) WARNING: Security sensitive applications + should probably disable this feature by setting + GC_disallow_ignore_fb, or by building with -DNO_GETENV, + since small values could force collection of reachable + objects, which is conceivably a (difficult to exploit) + security hole. GC_IGNORE_FB values less than 3 MB + are never honored, eliminating this risk for most, + but not all, applications. This feature is likely to disappear + if/when we find a less disgusting "solution". + The following turn on runtime flags that are also program settable. Checked only during initialization. We expect that they will usually be set through other means, but this may help with debugging and testing: diff --git a/boehm-gc/doc/README.macros b/boehm-gc/doc/README.macros index b5fe6796cc2..df0ef2cda93 100644 --- a/boehm-gc/doc/README.macros +++ b/boehm-gc/doc/README.macros @@ -85,5 +85,10 @@ SRC_M3 Set if the collector is being built as a replacement of the It's there primarily incase someone wants to port to a similar system. +USE_COMPILER_TLS Assume the existence of __thread-style thread-local + storage. Set automatically for thread-local allocation with + the HP/UX vendor compiler. Usable with gcc on sufficiently + up-to-date ELF platforms. + diff --git a/boehm-gc/doc/README.win32 b/boehm-gc/doc/README.win32 index a40b375f550..6f57db11764 100644 --- a/boehm-gc/doc/README.win32 +++ b/boehm-gc/doc/README.win32 @@ -1,34 +1,11 @@ -The collector has at various times been compiled under Windows 95 & NT, -with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, with -the GNU win32 environment, with Borland 4.5, with Watcom C, and recently +The collector has at various times been compiled under Windows 95 & later, NT, +and XP, with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, with +the GNU win32 tools, with Borland 4.5, with Watcom C, and recently with the Digital Mars compiler. It is likely that some of these have been broken in the meantime. Patches are appreciated. -It runs under both win32s and win32, but with different semantics. -Under win32, all writable pages outside of the heaps and stack are -scanned for roots. Thus the collector sees pointers in DLL data -segments. Under win32s, only the main data segment is scanned. -(The main data segment should always be scanned. Under some -versions of win32s, other regions may also be scanned.) -Thus all accessible objects should be accessible from local variables -or variables in the main data segment. Alternatively, other data -segments (e.g. in DLLs) may be registered with the collector by -calling GC_init() and then GC_register_root_section(a), where -a is the address of some variable inside the data segment. (Duplicate -registrations are ignored, but not terribly quickly.) - -(There are two reasons for this. We didn't want to see many 16:16 -pointers. And the VirtualQuery call has different semantics under -the two systems, and under different versions of win32s.) - -Win32 applications compiled with some flavor of gcc currently behave -like win32s applications, in that dynamic library data segments are -not scanned. (Gcc does not directly support Microsoft's "structured -exception handling". It turns out that use of this feature is -unavoidable if you scan arbitrary memory segments obtained from -VirtualQuery.) - -The collector test program "gctest" is linked as a GUI application, +For historical reasons, +the collector test program "gctest" is linked as a GUI application, but does not open any windows. Its output appears in the file "gc.log". It may be started from the file manager. The hour glass cursor may appear as long as it's running. If it is started from the @@ -60,11 +37,23 @@ This is currently incompatible with -DUSE_MUNMAP. (Thanks to Jonathan Clark for tracking this down. There's some chance this may be fixed in 6.1alpha4, since we now separate heap sections with an unused page.) +Microsoft Tools +--------------- For Microsoft development tools, rename NT_MAKEFILE as MAKEFILE. (Make sure that the CPU environment variable is defined to be i386.) In order to use the gc_cpp.h C++ interface, all client code should include gc_cpp.h. +For historical reasons, +the collector test program "gctest" is linked as a GUI application, +but does not open any windows. Its output appears in the file +"gc.log". It may be started from the file manager. The hour glass +cursor may appear as long as it's running. If it is started from the +command line, it will usually run in the background. Wait a few +minutes (a few seconds on a modern machine) before you check the output. +You should see either a failure indication or a "Collector appears to +work" message. + If you would prefer a VC++.NET project file, ask boehm@acm.org. One has been contributed, but it seems to contain some absolute paths etc., so it can presumably only be a starting point, and is not in the standard @@ -75,13 +64,22 @@ Clients may need to define GC_NOT_DLL before including gc.h, if the collector was built as a static library (as it normally is in the absence of thread support). +GNU Tools +--------- For GNU-win32, use the regular makefile, possibly after uncommenting the line "include Makefile.DLLs". The latter should be necessary only -if you want to package the collector as a DLL. The GNU-win32 port is +if you want to package the collector as a DLL. +[Is the following sentence obsolete? -HB] The GNU-win32 port is believed to work only for b18, not b19, probably due to linker changes in b19. This is probably fixable with a different definition of DATASTART and DATAEND in gcconfig.h. +The collector should also be buildable under Cygwin with either the +old standard Makefile, or with the "configure;make" machinery. + +Borland Tools +------------- +[Rarely tested.] For Borland tools, use BCC_MAKEFILE. Note that Borland's compiler defaults to 1 byte alignment in structures (-a1), whereas Visual C++ appears to default to 8 byte alignment (/Zp8). @@ -97,6 +95,8 @@ version, change the line near the top. By default, it does not require the assembler. If you do have the assembler, I recommend removing the -DUSE_GENERIC. +Incremental Collection +---------------------- There is some support for incremental collection. This is currently pretty simple-minded. Pages are protected. Protection faults are caught by a handler installed at the bottom of the handler @@ -112,7 +112,11 @@ is called.) Note that incremental collection is disabled with -DSMALL_CONFIG. -James Clark has contributed the necessary code to support win32 threads. +Threads +------- + +James Clark has contributed the necessary code to support win32 threads +with the collector in a DLL. Use NT_THREADS_MAKEFILE (a.k.a gc.mak) instead of NT_MAKEFILE to build this version. Note that this requires some files whose names are more than 8 + 3 characters long. Thus you should unpack the tar file @@ -128,12 +132,31 @@ This version relies on the collector residing in a dll. This version currently supports incremental collection only if it is enabled before any additional threads are created. -Version 4.13 attempts to fix some of the earlier problems, but there -may be other issues. If you need solid support for win32 threads, you -might check with Geodesic Systems. Their collector must be licensed, -but they have invested far more time in win32-specific issues. -Hans +Since 6.3alpha2, threads are also better supported in static library builds +with Microsoft tools (use NT_STATIC_THREADS_MAKEFILE) and with the GNU +tools. In all cases,the collector must be built with GC_WIN32_THREADS +defined, even if the Cygwin pthreads interface is used. +(NT_STATIC_THREADS_MAKEFILE does this implicitly. Under Cygwin, +./configure --enable-threads=posix defines GC_WIN32_THREADS.) Threads must be +created with GC_CreateThread. This can be accomplished by +including gc.h and then calling CreateThread, which is redefined +by gc.h. + +For the statically linked versions, it is required that GC_init() +be called before other GC calls, since there seems to be no implicit way +to initialize the allocation lock. The easiest way to ensure this in +portable code is to call GC_INIT() from the main executable (not +a dynamic library) before calling any other GC_ routines. + +We strongly advise against using the TerminateThread() win32 API call, +especially with the garbage collector. Any use is likely to provoke a +crash in the GC, since it makes it impossible for the collector to +correctly track threads. + + +Watcom compiler +--------------- Ivan V. Demakov's README for the Watcom port: @@ -167,4 +190,26 @@ important, otherwise resulting programs will not run. Ivan Demakov (email: ivan@tgrad.nsk.su) +Win32S +------ + +[The following is probably obsolete. The win32s support is still in the +collector, but I doubt anyone cares, or has tested it recently.] + +The collector runs under both win32s and win32, but with different semantics. +Under win32, all writable pages outside of the heaps and stack are +scanned for roots. Thus the collector sees pointers in DLL data +segments. Under win32s, only the main data segment is scanned. +(The main data segment should always be scanned. Under some +versions of win32s, other regions may also be scanned.) +Thus all accessible objects should be accessible from local variables +or variables in the main data segment. Alternatively, other data +segments (e.g. in DLLs) may be registered with the collector by +calling GC_init() and then GC_register_root_section(a), where +a is the address of some variable inside the data segment. (Duplicate +registrations are ignored, but not terribly quickly.) + +(There are two reasons for this. We didn't want to see many 16:16 +pointers. And the VirtualQuery call has different semantics under +the two systems, and under different versions of win32s.) diff --git a/boehm-gc/doc/debugging.html b/boehm-gc/doc/debugging.html index 22273fed4bc..7c65f2bb40a 100644 --- a/boehm-gc/doc/debugging.html +++ b/boehm-gc/doc/debugging.html @@ -47,6 +47,10 @@ The garbage collector generates warning messages of the form
 Needed to allocate blacklisted block at 0x...
 
+or +
+Repeated allocation of very large block ...
+
when it needs to allocate a block at a location that it knows to be referenced by a false pointer. These false pointers can be either permanent (e.g. a static integer variable that never changes) or temporary. @@ -123,7 +127,8 @@ is commonly caused by data structures that are no longer being used, but were not cleared, or by caches growing without bounds.
  • Pointer misidentification. The garbage collector is interpreting integers or other data as pointers and retaining the "referenced" -objects. +objects. A common symptom is that GC_dump() shows much of the heap +as black-listed.
  • Heap fragmentation. This should never result in unbounded growth, but it may account for larger heaps. This is most commonly caused by allocation of large objects. On some platforms it can be reduced @@ -180,6 +185,12 @@ primitives is gc_typed.h, or separate out the pointerfree component.
  • Consider using GC_malloc_ignore_off_page() to allocate large objects. (See gc.h and above for details. Large means > 100K in most environments.) +
  • If your heap size is larger than 100MB or so, build the collector with +-DLARGE_CONFIG. This allows the collector to keep more precise black-list +information. +
  • If you are using heaps close to, or larger than, a gigabyte on a 32-bit +machine, you may want to consider moving to a platform with 64-bit pointers. +This is very likely to resolve any false pointer issues.

    Prematurely Reclaimed Objects

    The usual symptom of this is a segmentation fault, or an obviously overwritten diff --git a/boehm-gc/doc/gc.man b/boehm-gc/doc/gc.man index 5409e706550..2a550c71247 100644 --- a/boehm-gc/doc/gc.man +++ b/boehm-gc/doc/gc.man @@ -1,12 +1,14 @@ -.TH GC_MALLOC 1L "12 February 1996" +.TH GC_MALLOC 1L "2 October 2003" .SH NAME GC_malloc, GC_malloc_atomic, GC_free, GC_realloc, GC_enable_incremental, GC_register_finalizer, GC_malloc_ignore_off_page, GC_malloc_atomic_ignore_off_page, GC_set_warn_proc \- Garbage collecting malloc replacement .SH SYNOPSIS #include "gc.h" .br -# define malloc(n) GC_malloc(n) +void * GC_malloc(size_t size); .br -... malloc(...) ... +void GC_free(void *ptr); +.br +void * GC_realloc(void *ptr, size_t size); .br .sp cc ... gc.a @@ -23,6 +25,11 @@ will attempt to reclaim inaccessible space automatically by invoking a conservat GC_malloc or friends. .LP +In most cases it is preferable to call the macros GC_MALLOC, GC_FREE, etc. +instead of calling GC_malloc and friends directly. This allows debugging +versions of the routines to be substituted by defining GC_DEBUG before +including gc.h. +.LP See the documentation in the include file gc_cpp.h for an alternate, C++ specific interface to the garbage collector. .LP Unlike the standard implementations of malloc, @@ -56,9 +63,16 @@ It is also possible to use the collector to find storage leaks in programs desti .LP The collector may, on rare occasion produce warning messages. On UNIX machines these appear on stderr. Warning messages can be filtered, redirected, or ignored with .I -GC_set_warn_proc. +GC_set_warn_proc This is recommended for production code. See gc.h for details. .LP +Fully portable code should call +.I +GC_INIT +from the main program before making any other GC calls. +On most platforms this does nothing and the collector is initialized on first use. +On a few platforms explicit initialization is necessary. And it can never hurt. +.LP Debugging versions of many of the above routines are provided as macros. Their names are identical to the above, but consist of all capital letters. If GC_DEBUG is defined before gc.h is included, these routines do additional checking, and allow the leak detecting version of the collector to produce slightly more useful output. Without GC_DEBUG defined, they behave exactly like the lower-case versions. .LP On some machines, collection will be performed incrementally after a call to @@ -71,10 +85,13 @@ Other facilities not discussed here include limited facilities to support increm .SH "SEE ALSO" The README and gc.h files in the distribution. More detailed definitions of the functions exported by the collector are given there. (The above list is not complete.) .LP +The web site at http://www.hpl.hp.com/personal/Hans_Boehm/gc . +.LP Boehm, H., and M. Weiser, "Garbage Collection in an Uncooperative Environment", \fISoftware Practice & Experience\fP, September 1988, pp. 807-820. .LP The malloc(3) man page. .LP .SH AUTHOR -Hans-J. Boehm (boehm@parc.xerox.com). Some of the code was written by others, most notably Alan Demers. +Hans-J. Boehm (Hans.Boehm@hp.com). +Some of the code was written by others, most notably Alan Demers. diff --git a/boehm-gc/doc/gcdescr.html b/boehm-gc/doc/gcdescr.html index 8ecbac8db62..cab6bde4fba 100644 --- a/boehm-gc/doc/gcdescr.html +++ b/boehm-gc/doc/gcdescr.html @@ -4,7 +4,7 @@ Hans-J. Boehm, HP Labs (Much of this was written at SGI) -

    This is under construction

    +

    This is under construction, and may always be.

    Conservative GC Algorithmic Overview

    This is a description of the algorithms and data structures used in our @@ -27,20 +27,22 @@ We assume the default finalization model, but the code affected by that is very localized.

    Introduction

    The garbage collector uses a modified mark-sweep algorithm. Conceptually -it operates roughly in four phases: +it operates roughly in four phases, which are performed occasionally +as part of a memory allocation:
    1. -Preparation Clear all mark bits, indicating that all objects +Preparation Each object has an associated mark bit. +Clear all mark bits, indicating that all objects are potentially unreachable.
    2. Mark phase Marks all objects that can be reachable via chains of -pointers from variables. Normally the collector has no real information +pointers from variables. Often the collector has no real information about the location of pointer variables in the heap, so it views all static data areas, stacks and registers as potentially containing -containing pointers. Any bit patterns that represent addresses inside +pointers. Any bit patterns that represent addresses inside heap objects managed by the collector are viewed as pointers. Unless the client program has made heap object layout information available to the collector, any heap objects found to be reachable from @@ -87,8 +89,12 @@ others are not. Some may have per-object type descriptors that determine pointer locations. Or a specific kind may correspond to one specific object layout. Two built-in kinds are uncollectable. One (STUBBORN) is immutable without special precautions. -In spite of that, it is very likely that most applications currently +In spite of that, it is very likely that most C clients of the +collector currently use at most two kinds: NORMAL and PTRFREE objects. +The gcj runtime also makes +heavy use of a kind (allocated with GC_gcj_malloc) that stores +type information at a known offset in method tables.

      The collector uses a two level allocator. A large block is defined to be one larger than half of HBLKSIZE, which is a power of 2, @@ -175,6 +181,32 @@ for a single pool of physical memory.

      Mark phase

      +At each collection, the collector marks all objects that are +possibly reachable from pointer variables. Since it cannot generally +tell where pointer variables are located, it scans the following +root segments for pointers: +
        +
      • The registers. Depending on the architecture, this may be done using +assembly code, or by calling a setjmp-like function which saves +register contents on the stack. +
      • The stack(s). In the case of a single-threaded application, +on most platforms this +is done by scanning the memory between (an approximation of) the current +stack pointer and GC_stackbottom. (For Itanium, the register stack +scanned separately.) The GC_stackbottom variable is set in +a highly platform-specific way depending on the appropriate configuration +information in gcconfig.h. Note that the currently active +stack needs to be scanned carefully, since callee-save registers of +client code may appear inside collector stack frames, which may +change during the mark process. This is addressed by scanning +some sections of the stack "eagerly", effectively capturing a snapshot +at one point in time. +
      • Static data region(s). In the simplest case, this is the region +between DATASTART and DATAEND, as defined in +gcconfig.h. However, in most cases, this will also involve +static data regions associated with dynamic libraries. These are +identified by the mostly platform-specific code in dyn_load.c. +
      The marker maintains an explicit stack of memory regions that are known to be accessible, but that have not yet been searched for contained pointers. Each stack entry contains the starting address of the block to be scanned, @@ -182,8 +214,11 @@ as well as a descriptor of the block. If no layout information is available for the block, then the descriptor is simply a length. (For other possibilities, see gc_mark.h.)

      -At the beginning of the mark phase, all root segments are pushed on the -stack by GC_push_roots. If ALL_INTERIOR_PTRS is not +At the beginning of the mark phase, all root segments +(as described above) are pushed on the +stack by GC_push_roots. (Registers and eagerly processed +stack sections are processed by pushing the referenced objects instead +of the stack section itself.) If ALL_INTERIOR_PTRS is not defined, then stack roots require special treatment. In this case, the normal marking code ignores interior pointers, but GC_push_all_stack explicitly checks for interior pointers and pushes descriptors for target @@ -479,8 +514,9 @@ if there is low demand for small pointerfree objects. We support several different threading models. Unfortunately Pthreads, the only reasonably well standardized thread model, supports too narrow an interface for conservative garbage collection. There appears to be -no completely portable way to allow the collector to coexist with various Pthreads -implementations. Hence we currently support only a few of the more +no completely portable way to allow the collector +to coexist with various Pthreads +implementations. Hence we currently support only the more common Pthreads implementations.

      In particular, it is very difficult for the collector to stop all other @@ -510,6 +546,10 @@ accomplished with # define's in gc.h (really gc_pthread_redirects.h), or optionally by using ld's function call wrapping mechanism under Linux.

      +Recent versions of the collector support several facilites to enhance +the processor-scalability and thread performance of the collector. +These are discussed in more detail here. +

      Comments are appreciated. Please send mail to boehm@acm.org or Hans.Boehm@hp.com diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c index 1f4a63646b1..9bd9e060688 100644 --- a/boehm-gc/dyn_load.c +++ b/boehm-gc/dyn_load.c @@ -91,10 +91,18 @@ /* Newer versions of GNU/Linux define this macro. We * define it similarly for any ELF systems that don't. */ # ifndef ElfW -# if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32 -# define ElfW(type) Elf32_##type +# ifdef __NetBSD__ +# if ELFSIZE == 32 +# define ElfW(type) Elf32_##type +# else +# define ElfW(type) Elf64_##type +# endif # else -# define ElfW(type) Elf64_##type +# if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32 +# define ElfW(type) Elf32_##type +# else +# define ElfW(type) Elf64_##type +# endif # endif # endif @@ -552,6 +560,7 @@ extern void * GC_roots_present(); /* The type is a lie, since the real type doesn't make sense here, */ /* and we only test for NULL. */ + /* We use /proc to track down all parts of the address space that are */ /* mapped by the process, and throw out regions we know we shouldn't */ /* worry about. This may also work under other SVR4 variants. */ @@ -726,6 +735,90 @@ void GC_register_dynamic_libraries() # define HAVE_REGISTER_MAIN_STATIC_DATA + GC_bool GC_warn_fb = TRUE; /* Warn about traced likely */ + /* graphics memory. */ + GC_bool GC_disallow_ignore_fb = FALSE; + int GC_ignore_fb_mb; /* Ignore mappings bigger than the */ + /* specified number of MB. */ + GC_bool GC_ignore_fb = FALSE; /* Enable frame buffer */ + /* checking. */ + + /* Issue warning if tracing apparent framebuffer. */ + /* This limits us to one warning, and it's a back door to */ + /* disable that. */ + + /* Should [start, start+len) be treated as a frame buffer */ + /* and ignored? */ + /* Unfortunately, we currently have no real way to tell */ + /* automatically, and rely largely on user input. */ + /* FIXME: If we had more data on this phenomenon (e.g. */ + /* is start aligned to a MB multiple?) we should be able to */ + /* do better. */ + /* Based on a very limited sample, it appears that: */ + /* - Frame buffer mappings appear as mappings of length */ + /* 2**n MB - 192K. (We guess the 192K can vary a bit.) */ + /* - Have a stating address at best 64K aligned. */ + /* I'd love more information about the mapping, since I */ + /* can't reproduce the problem. */ + static GC_bool is_frame_buffer(ptr_t start, size_t len) + { + static GC_bool initialized = FALSE; +# define MB (1024*1024) +# define DEFAULT_FB_MB 15 +# define MIN_FB_MB 3 + + if (GC_disallow_ignore_fb) return FALSE; + if (!initialized) { + char * ignore_fb_string = GETENV("GC_IGNORE_FB"); + + if (0 != ignore_fb_string) { + while (*ignore_fb_string == ' ' || *ignore_fb_string == '\t') + ++ignore_fb_string; + if (*ignore_fb_string == '\0') { + GC_ignore_fb_mb = DEFAULT_FB_MB; + } else { + GC_ignore_fb_mb = atoi(ignore_fb_string); + if (GC_ignore_fb_mb < MIN_FB_MB) { + WARN("Bad GC_IGNORE_FB value. Using %ld\n", DEFAULT_FB_MB); + GC_ignore_fb_mb = DEFAULT_FB_MB; + } + } + GC_ignore_fb = TRUE; + } else { + GC_ignore_fb_mb = DEFAULT_FB_MB; /* For warning */ + } + initialized = TRUE; + } + if (len >= ((size_t)GC_ignore_fb_mb << 20)) { + if (GC_ignore_fb) { + return TRUE; + } else { + if (GC_warn_fb) { + WARN("Possible frame buffer mapping at 0x%lx: \n" + "\tConsider setting GC_IGNORE_FB to improve performance.\n", + start); + GC_warn_fb = FALSE; + } + return FALSE; + } + } else { + return FALSE; + } + } + +# ifdef DEBUG_VIRTUALQUERY + void GC_dump_meminfo(MEMORY_BASIC_INFORMATION *buf) + { + GC_printf4("BaseAddress = %lx, AllocationBase = %lx, RegionSize = %lx(%lu)\n", + buf -> BaseAddress, buf -> AllocationBase, buf -> RegionSize, + buf -> RegionSize); + GC_printf4("\tAllocationProtect = %lx, State = %lx, Protect = %lx, " + "Type = %lx\n", + buf -> AllocationProtect, buf -> State, buf -> Protect, + buf -> Type); + } +# endif /* DEBUG_VIRTUALQUERY */ + void GC_register_dynamic_libraries() { MEMORY_BASIC_INFORMATION buf; @@ -762,7 +855,11 @@ void GC_register_dynamic_libraries() if (buf.State == MEM_COMMIT && (protect == PAGE_EXECUTE_READWRITE || protect == PAGE_READWRITE) - && !GC_is_heap_base(buf.AllocationBase)) { + && !GC_is_heap_base(buf.AllocationBase) + && !is_frame_buffer(p, buf.RegionSize)) { +# ifdef DEBUG_VIRTUALQUERY + GC_dump_meminfo(&buf); +# endif if ((char *)p != limit) { GC_cond_add_roots(base, limit); base = p; @@ -980,12 +1077,13 @@ void GC_register_dynamic_libraries() #ifdef DARWIN +/* __private_extern__ hack required for pre-3.4 gcc versions. */ #ifndef __private_extern__ -#define __private_extern__ extern -#include -#undef __private_extern__ +# define __private_extern__ extern +# include +# undef __private_extern__ #else -#include +# include #endif #include diff --git a/boehm-gc/finalize.c b/boehm-gc/finalize.c index 3b9d9f5ea1e..e103228c2af 100644 --- a/boehm-gc/finalize.c +++ b/boehm-gc/finalize.c @@ -807,8 +807,37 @@ void (* GC_finalizer_notifier)() = (void (*) GC_PROTO((void)))0; static GC_word last_finalizer_notification = 0; +#ifdef KEEP_BACK_PTRS +void GC_generate_random_backtrace_no_gc(void); +#endif + void GC_notify_or_invoke_finalizers GC_PROTO((void)) { + /* This is a convenient place to generate backtraces if appropriate, */ + /* since that code is not callable with the allocation lock. */ +# ifdef KEEP_BACK_PTRS + if (GC_backtraces > 0) { + static word last_back_trace_gc_no = 3; /* Skip early ones. */ + long i; + + LOCK(); + if (GC_gc_no > last_back_trace_gc_no) { + /* Stops when GC_gc_no wraps; that's OK. */ + last_back_trace_gc_no = (word)(-1); /* disable others. */ + for (i = 0; i < GC_backtraces; ++i) { + /* FIXME: This tolerates concurrent heap mutation, */ + /* which may cause occasional mysterious results. */ + /* We need to release the GC lock, since GC_print_callers */ + /* acquires it. It probably shouldn't. */ + UNLOCK(); + GC_generate_random_backtrace_no_gc(); + LOCK(); + } + last_back_trace_gc_no = GC_gc_no; + } + UNLOCK(); + } +# endif if (GC_finalize_now == 0) return; if (!GC_finalize_on_demand) { (void) GC_invoke_finalizers(); diff --git a/boehm-gc/gcj_mlc.c b/boehm-gc/gcj_mlc.c index a10a66f926e..2aaef795d92 100644 --- a/boehm-gc/gcj_mlc.c +++ b/boehm-gc/gcj_mlc.c @@ -14,8 +14,6 @@ */ /* Boehm, July 31, 1995 5:02 pm PDT */ -#ifdef GC_GCJ_SUPPORT - /* * This is an allocator interface tuned for gcj (the GNU static * java compiler). @@ -40,6 +38,8 @@ #include "gc_gcj.h" #include "private/dbg_mlc.h" +#ifdef GC_GCJ_SUPPORT + GC_bool GC_gcj_malloc_initialized = FALSE; int GC_gcj_kind; /* Object kind for objects with descriptors */ @@ -72,46 +72,36 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) GC_printf0("Gcj-style type information is disabled!\n"); } # endif + GC_ASSERT(GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */ GC_mark_procs[mp_index] = (GC_mark_proc)mp; if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index"); /* Set up object kind gcj-style indirect descriptor. */ - GC_gcjobjfreelist = (ptr_t *) - GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); - if (GC_gcjobjfreelist == 0) ABORT("Couldn't allocate GC_gcjobjfreelist"); - BZERO(GC_gcjobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); - GC_gcj_kind = GC_n_kinds++; - GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist; - GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0; + GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner(); if (ignore_gcj_info) { /* Use a simple length-based descriptor, thus forcing a fully */ /* conservative scan. */ - GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH); - GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE; + GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist, + (0 | GC_DS_LENGTH), + TRUE, TRUE); } else { - GC_obj_kinds[GC_gcj_kind].ok_descriptor = - (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) - | GC_DS_PER_OBJECT); - GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE; + GC_gcj_kind = GC_new_kind_inner( + (void **)GC_gcjobjfreelist, + (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) + | GC_DS_PER_OBJECT), + FALSE, TRUE); } - GC_obj_kinds[GC_gcj_kind].ok_init = TRUE; /* Set up object kind for objects that require mark proc call. */ - GC_gcjdebugobjfreelist = (ptr_t *) - GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); - if (GC_gcjdebugobjfreelist == 0) - ABORT("Couldn't allocate GC_gcjdebugobjfreelist"); - BZERO(GC_gcjdebugobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); - GC_gcj_debug_kind = GC_n_kinds++; - GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist; - GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0; if (ignore_gcj_info) { - GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH); - GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE; + GC_gcj_debug_kind = GC_gcj_kind; + GC_gcjdebugobjfreelist = GC_gcjobjfreelist; } else { - GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor = - GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */); - GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE; + GC_gcjdebugobjfreelist = (ptr_t *)GC_new_free_list_inner(); + GC_gcj_debug_kind = GC_new_kind_inner( + (void **)GC_gcjdebugobjfreelist, + GC_MAKE_PROC(mp_index, + 1 /* allocated with debug info */), + FALSE, TRUE); } - GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE; UNLOCK(); ENABLE_SIGNALS(); } @@ -124,6 +114,25 @@ ptr_t GC_clear_stack(); #define GENERAL_MALLOC_IOP(lb,k) \ (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k)) +/* We need a mechanism to release the lock and invoke finalizers. */ +/* We don't really have an opportunity to do this on a rarely executed */ +/* path on which the lock is not held. Thus we check at a */ +/* rarely executed point at which it is safe to release the lock. */ +/* We do this even where we could just call GC_INVOKE_FINALIZERS, */ +/* since it's probably cheaper and certainly more uniform. */ +/* FIXME - Consider doing the same elsewhere? */ +static void maybe_finalize() +{ + static int last_finalized_no = 0; + + if (GC_gc_no == last_finalized_no) return; + if (!GC_is_initialized) return; + UNLOCK(); + GC_INVOKE_FINALIZERS(); + last_finalized_no = GC_gc_no; + LOCK(); +} + /* Allocate an object, clear it, and store the pointer to the */ /* type structure (vtable in gcj). */ /* This adds a byte at the end of the object if GC_malloc would.*/ @@ -143,7 +152,8 @@ DCL_LOCK_STATE; opp = &(GC_gcjobjfreelist[lw]); LOCK(); op = *opp; - if( EXPECT(op == 0, 0)) { + if(EXPECT(op == 0, 0)) { + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind); if (0 == op) { UNLOCK(); @@ -161,6 +171,7 @@ DCL_LOCK_STATE; UNLOCK(); } else { LOCK(); + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind); if (0 == op) { UNLOCK(); @@ -179,10 +190,10 @@ GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr, { GC_PTR result; - /* We clone the code from GC_debug_gcj_malloc, so that we */ - /* dont end up with extra frames on the stack, which could */ + /* We're careful to avoid extra calls, which could */ /* confuse the backtrace. */ LOCK(); + maybe_finalize(); result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind); if (result == 0) { UNLOCK(); @@ -215,6 +226,7 @@ DCL_LOCK_STATE; LOCK(); op = *opp; if( EXPECT(op == 0, 0) ) { + maybe_finalize(); op = (ptr_t)GC_clear_stack( GC_generic_malloc_words_small_inner(lw, GC_gcj_kind)); if (0 == op) { @@ -242,6 +254,7 @@ void * GC_debug_gcj_fast_malloc(size_t lw, /* dont end up with extra frames on the stack, which could */ /* confuse the backtrace. */ LOCK(); + maybe_finalize(); result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind); if (result == 0) { UNLOCK(); @@ -278,6 +291,7 @@ DCL_LOCK_STATE; opp = &(GC_gcjobjfreelist[lw]); LOCK(); if( (op = *opp) == 0 ) { + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind); # ifdef MERGE_SIZES lw = GC_size_map[lb]; /* May have been uninitialized. */ @@ -289,6 +303,8 @@ DCL_LOCK_STATE; *(void **)op = ptr_to_struct_containing_descr; UNLOCK(); } else { + LOCK(); + maybe_finalize(); op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind); if (0 != op) { *(void **)op = ptr_to_struct_containing_descr; diff --git a/boehm-gc/headers.c b/boehm-gc/headers.c index 0aa513973c9..b7be1d84930 100644 --- a/boehm-gc/headers.c +++ b/boehm-gc/headers.c @@ -206,7 +206,7 @@ register struct hblk * h; { hdr * result; - if (!get_index((word) h)) return(FALSE); + if (!get_index((word) h)) return(0); result = alloc_hdr(); SET_HDR(h, result); # ifdef USE_MUNMAP diff --git a/boehm-gc/if_not_there.c b/boehm-gc/if_not_there.c index 42dd8034ac7..8691e925920 100644 --- a/boehm-gc/if_not_there.c +++ b/boehm-gc/if_not_there.c @@ -4,6 +4,9 @@ # include # include # include +#ifdef __DJGPP__ +#include +#endif /* __DJGPP__ */ int main(argc, argv, envp) int argc; @@ -11,12 +14,21 @@ char ** argv; char ** envp; { FILE * f; +#ifdef __DJGPP__ + DIR * d; +#endif /* __DJGPP__ */ if (argc < 3) goto Usage; if ((f = fopen(argv[1], "rb")) != 0 || (f = fopen(argv[1], "r")) != 0) { fclose(f); return(0); } +#ifdef __DJGPP__ + if ((d = opendir(argv[1])) != 0) { + closedir(d); + return(0); + } +#endif printf("^^^^Starting command^^^^\n"); fflush(stdout); execvp(argv[2], argv+2); diff --git a/boehm-gc/include/Makefile.in b/boehm-gc/include/Makefile.in index cf6319732ec..825bac4ded0 100644 --- a/boehm-gc/include/Makefile.in +++ b/boehm-gc/include/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.8.5 from Makefile.am. +# Makefile.in generated by automake 1.9 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -135,6 +135,8 @@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -318,7 +320,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index 4444e991ff3..e1f2aa8f80f 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -30,6 +30,7 @@ # define _GC_H +# include # include "gc_config_macros.h" # if defined(__STDC__) || defined(__cplusplus) @@ -52,11 +53,18 @@ /* even semi-portably. The following is probably no better/worse */ /* than almost anything else. */ /* The ANSI standard suggests that size_t and ptr_diff_t might be */ -/* better choices. But those appear to have incorrect definitions */ -/* on may systems. Notably "typedef int size_t" seems to be both */ -/* frequent and WRONG. */ -typedef unsigned long GC_word; -typedef long GC_signed_word; +/* better choices. But those had incorrect definitions on some older */ +/* systems. Notably "typedef int size_t" is WRONG. */ +#ifndef _WIN64 + typedef unsigned long GC_word; + typedef long GC_signed_word; +#else + /* Win64 isn't really supported yet, but this is the first step. And */ + /* it might cause error messages to show up in more plausible places. */ + /* This needs basetsd.h, which is included by windows.h. */ + typedef ULONG_PTR GC_word; + typedef LONG_PTR GC_word; +#endif /* Public read-only variables */ @@ -247,6 +255,7 @@ GC_API unsigned long GC_time_limit; * allocation, since unlike the regular allocation routines, GC_local_malloc * is not self-initializing. If you use GC_local_malloc you should arrange * to call this somehow (e.g. from a constructor) before doing any allocation. + * For win32 threads, it needs to be called explicitly. */ GC_API void GC_init GC_PROTO((void)); @@ -470,14 +479,19 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb)); # include # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ && !defined(__ia64__) -# define GC_HAVE_BUILTIN_BACKTRACE -# define GC_CAN_SAVE_CALL_STACKS +# ifndef GC_HAVE_BUILTIN_BACKTRACE +# define GC_HAVE_BUILTIN_BACKTRACE +# endif # endif # if defined(__i386__) || defined(__x86_64__) # define GC_CAN_SAVE_CALL_STACKS # endif #endif +#if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS) +# define GC_CAN_SAVE_CALL_STACKS +#endif + #if defined(__sparc__) # define GC_CAN_SAVE_CALL_STACKS #endif @@ -604,7 +618,7 @@ GC_API GC_PTR GC_debug_realloc_replacement /* Finalization. Some of these primitives are grossly unsafe. */ /* The idea is to make them both cheap, and sufficient to build */ -/* a safer layer, closer to PCedar finalization. */ +/* a safer layer, closer to Modula-3, Java, or PCedar finalization. */ /* The interface represents my conclusions from a long discussion */ /* with Alan Demers, Dan Greene, Carl Hauser, Barry Hayes, */ /* Christian Jacobi, and Russ Atkinson. It's not perfect, and */ @@ -774,6 +788,7 @@ GC_API GC_PTR GC_call_with_alloc_lock /* The following routines are primarily intended for use with a */ /* preprocessor which inserts calls to check C pointer arithmetic. */ +/* They indicate failure by invoking the corresponding _print_proc. */ /* Check that p and q point to the same object. */ /* Fail conspicuously if they don't. */ @@ -851,7 +866,7 @@ GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR p)); # define GC_PTR_STORE(p, q) *((p) = (q)) #endif -/* Fynctions called to report pointer checking errors */ +/* Functions called to report pointer checking errors */ GC_API void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR p, GC_PTR q)); GC_API void (*GC_is_valid_displacement_print_proc) @@ -919,13 +934,19 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 */ #endif /* defined(GC_WIN32_THREADS) && !cygwin */ -/* - * If you are planning on putting - * the collector in a SunOS 5 dynamic library, you need to call GC_INIT() - * from the statically loaded program section. - * This circumvents a Solaris 2.X (X<=4) linker bug. - */ -#if defined(sparc) || defined(__sparc) + /* + * Fully portable code should call GC_INIT() from the main program + * before making any other GC_ calls. On most platforms this is a + * no-op and the collector self-initializes. But a number of platforms + * make that too hard. + */ +#if (defined(sparc) || defined(__sparc)) && defined(sun) + /* + * If you are planning on putting + * the collector in a SunOS 5 dynamic library, you need to call GC_INIT() + * from the statically loaded program section. + * This circumvents a Solaris 2.X (X<=4) linker bug. + */ # define GC_INIT() { extern end, etext; \ GC_noop(&end, &etext); } #else @@ -936,13 +957,13 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 */ */ # define GC_INIT() { GC_add_roots(DATASTART, DATAEND); } # else -# if defined(__APPLE__) && defined(__MACH__) +# if defined(__APPLE__) && defined(__MACH__) || defined(GC_WIN32_THREADS) # define GC_INIT() { GC_init(); } # else # define GC_INIT() -# endif -# endif -#endif +# endif /* !__MACH && !GC_WIN32_THREADS */ +# endif /* !AIX && !cygwin */ +#endif /* !sparc */ #if !defined(_WIN32_WCE) \ && ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ diff --git a/boehm-gc/include/gc_config.h.in b/boehm-gc/include/gc_config.h.in new file mode 100644 index 00000000000..fbd244610aa --- /dev/null +++ b/boehm-gc/include/gc_config.h.in @@ -0,0 +1,34 @@ +#undef ALL_INTERIOR_POINTERS +#undef ATOMIC_UNCOLLECTABLE +#undef DATASTART_IS_ETEXT +#undef DBG_HDRS_ALL +#undef DGUX_THREADS +#undef ECOS +#undef GC_AIX_THREADS +#undef GC_DARWIN_THREADS +#undef GC_DGUX386_THREADS +#undef GC_FREEBSD_THREADS +#undef GC_GCJ_SUPPORT +#undef GC_HPUX_THREADS +#undef GC_IRIX_THREADS +#undef GC_LINUX_THREADS +#undef GC_OSF1_THREADS +#undef GC_SOLARIS_PTHREADS +#undef GC_SOLARIS_THREADS +#undef GC_WIN32_THREADS +#undef JAVA_FINALIZATION +#undef KEEP_BACK_PTRS +#undef MAKE_BACK_GRAPH +#undef NO_DEBUGGING +#undef NO_EXECUTE_PERMISSION +#undef NO_SIGNALS +#undef NO_SIGSET +#undef PARALLEL_MARK +#undef SAVE_CALL_COUNT +#undef SILENT +#undef SOLARIS25_PROC_VDB_BUG_FIXED +#undef STACKBASE +#undef SUNOS53_SHARED_LIB +#undef THREAD_LOCAL_ALLOC +#undef _POSIX_C_SOURCE +#undef _REENTRANT diff --git a/boehm-gc/include/gc_config_macros.h b/boehm-gc/include/gc_config_macros.h index d8d31141262..90c574ed43c 100644 --- a/boehm-gc/include/gc_config_macros.h +++ b/boehm-gc/include/gc_config_macros.h @@ -1,43 +1,7 @@ /* * This should never be included directly. It is included only from gc.h. * We separate it only to make gc.h more suitable as documentation. - * - * Some tests for old macros. These violate our namespace rules and will - * disappear shortly. Use the GC_ names. */ -#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) -# define GC_SOLARIS_THREADS -#endif -#if defined(_SOLARIS_PTHREADS) -# define GC_SOLARIS_PTHREADS -#endif -#if defined(IRIX_THREADS) -# define GC_IRIX_THREADS -#endif -#if defined(DGUX_THREADS) -# if !defined(GC_DGUX386_THREADS) -# define GC_DGUX386_THREADS -# endif -#endif -#if defined(AIX_THREADS) -# define GC_AIX_THREADS -#endif -#if defined(HPUX_THREADS) -# define GC_HPUX_THREADS -#endif -#if defined(OSF1_THREADS) -# define GC_OSF1_THREADS -#endif -#if defined(LINUX_THREADS) -# define GC_LINUX_THREADS -#endif -#if defined(WIN32_THREADS) -# define GC_WIN32_THREADS -#endif -#if defined(USE_LD_WRAP) -# define GC_USE_LD_WRAP -#endif - #if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \ || defined(GC_SOLARIS_PTHREADS) \ || defined(GC_HPUX_THREADS) \ diff --git a/boehm-gc/include/gc_cpp.h b/boehm-gc/include/gc_cpp.h index d789a3731e3..c4d8b50e6b9 100644 --- a/boehm-gc/include/gc_cpp.h +++ b/boehm-gc/include/gc_cpp.h @@ -152,6 +152,11 @@ by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. # define GC_OPERATOR_NEW_ARRAY #endif +#if ! defined ( __BORLANDC__ ) /* Confuses the Borland compiler. */ \ + && ! defined ( __sgi ) +# define GC_PLACEMENT_DELETE +#endif + enum GCPlacement {UseGC, #ifndef GC_NAME_CONFLICT GC=UseGC, @@ -165,7 +170,7 @@ class gc {public: /* Must be redefined here, since the other overloadings */ /* hide the global definition. */ inline void operator delete( void* obj ); -# ifndef __BORLANDC__ /* Confuses the Borland compiler. */ +# ifdef GC_PLACEMENT_DELETE inline void operator delete( void*, void* ); # endif @@ -174,7 +179,7 @@ class gc {public: inline void* operator new[]( size_t size, GCPlacement gcp ); inline void* operator new[]( size_t size, void *p ); inline void operator delete[]( void* obj ); -# ifndef __BORLANDC__ +# ifdef GC_PLACEMENT_DELETE inline void gc::operator delete[]( void*, void* ); # endif #endif /* GC_OPERATOR_NEW_ARRAY */ @@ -282,7 +287,7 @@ inline void* gc::operator new( size_t size, void *p ) { inline void gc::operator delete( void* obj ) { GC_FREE( obj );} -#ifndef __BORLANDC__ +#ifdef GC_PLACEMENT_DELETE inline void gc::operator delete( void*, void* ) {} #endif @@ -300,7 +305,7 @@ inline void* gc::operator new[]( size_t size, void *p ) { inline void gc::operator delete[]( void* obj ) { gc::operator delete( obj );} -#ifndef __BORLANDC__ +#ifdef GC_PLACEMENT_DELETE inline void gc::operator delete[]( void*, void* ) {} #endif diff --git a/boehm-gc/include/gc_gcj.h b/boehm-gc/include/gc_gcj.h index 5e932afe8d0..5e79e27b821 100644 --- a/boehm-gc/include/gc_gcj.h +++ b/boehm-gc/include/gc_gcj.h @@ -53,7 +53,7 @@ /* respectively for the allocated objects. Mark_proc will be */ /* used to build the descriptor for objects allocated through the */ /* debugging interface. The mark_proc will be invoked on all such */ -/* objects with an "environment" value of 1. The client may chose */ +/* objects with an "environment" value of 1. The client may choose */ /* to use the same mark_proc for some of its generated mark descriptors.*/ /* In that case, it should use a different "environment" value to */ /* detect the presence or absence of the debug header. */ @@ -88,6 +88,17 @@ extern void * GC_debug_gcj_fast_malloc(size_t lw, extern void * GC_gcj_malloc_ignore_off_page(size_t lb, void * ptr_to_struct_containing_descr); +/* The kind numbers of normal and debug gcj objects. */ +/* Useful only for debug support, we hope. */ +extern int GC_gcj_kind; + +extern int GC_gcj_debug_kind; + +# if defined(GC_LOCAL_ALLOC_H) && defined(GC_REDIRECT_TO_LOCAL) + --> gc_local_alloc.h should be included after this. Otherwise + --> we undo the redirection. +# endif + # ifdef GC_DEBUG # define GC_GCJ_MALLOC(s,d) GC_debug_gcj_malloc(s,d,GC_EXTRAS) # define GC_GCJ_FAST_MALLOC(s,d) GC_debug_gcj_fast_malloc(s,d,GC_EXTRAS) diff --git a/boehm-gc/include/gc_local_alloc.h b/boehm-gc/include/gc_local_alloc.h index 88e29e9a11f..1874c7b6d20 100644 --- a/boehm-gc/include/gc_local_alloc.h +++ b/boehm-gc/include/gc_local_alloc.h @@ -61,6 +61,7 @@ GC_PTR GC_local_malloc_atomic(size_t bytes); #endif # ifdef GC_DEBUG + /* We don't really use local allocation in this case. */ # define GC_LOCAL_MALLOC(s) GC_debug_malloc(s,GC_EXTRAS) # define GC_LOCAL_MALLOC_ATOMIC(s) GC_debug_malloc_atomic(s,GC_EXTRAS) # ifdef GC_GCJ_SUPPORT diff --git a/boehm-gc/include/gc_mark.h b/boehm-gc/include/gc_mark.h index 9ddba2ca527..953bb74dc08 100644 --- a/boehm-gc/include/gc_mark.h +++ b/boehm-gc/include/gc_mark.h @@ -19,10 +19,8 @@ * This interface should not be used by normal C or C++ clients. * It will be useful to runtimes for other languages. * - * Note that this file is not "namespace-clean", i.e. it introduces names - * not prefixed with GC_, which may collide with the client's names. It - * should be included only in those few places that directly provide - * information to the collector. + * This is an experts-only interface! There are many ways to break the + * collector in subtle ways by using this functionality. */ #ifndef GC_MARK_H # define GC_MARK_H @@ -143,5 +141,63 @@ struct GC_ms_entry *GC_mark_and_push GC_mark_and_push(obj, msp, lim, src) : \ msp) +extern size_t GC_debug_header_size; + /* The size of the header added to objects allocated through */ + /* the GC_debug routines. */ + /* Defined as a variable so that client mark procedures don't */ + /* need to be recompiled for collector version changes. */ +#define GC_USR_PTR_FROM_BASE(p) ((GC_PTR)((char *)(p) + GC_debug_header_size)) + +/* And some routines to support creation of new "kinds", e.g. with */ +/* custom mark procedures, by language runtimes. */ +/* The _inner versions assume the caller holds the allocation lock. */ + +/* Return a new free list array. */ +void ** GC_new_free_list GC_PROTO((void)); +void ** GC_new_free_list_inner GC_PROTO((void)); + +/* Return a new kind, as specified. */ +int GC_new_kind GC_PROTO((void **free_list, GC_word mark_descriptor_template, + int add_size_to_descriptor, int clear_new_objects)); + /* The last two parameters must be zero or one. */ +int GC_new_kind_inner GC_PROTO((void **free_list, + GC_word mark_descriptor_template, + int add_size_to_descriptor, + int clear_new_objects)); + +/* Return a new mark procedure identifier, suitable for use as */ +/* the first argument in GC_MAKE_PROC. */ +int GC_new_proc GC_PROTO((GC_mark_proc)); +int GC_new_proc_inner GC_PROTO((GC_mark_proc)); + +/* Allocate an object of a given kind. Note that in multithreaded */ +/* contexts, this is usually unsafe for kinds that have the descriptor */ +/* in the object itself, since there is otherwise a window in which */ +/* the descriptor is not correct. Even in the single-threaded case, */ +/* we need to be sure that cleared objects on a free list don't */ +/* cause a GC crash if they are accidentally traced. */ +/* ptr_t */char * GC_generic_malloc GC_PROTO((GC_word lb, int k)); + +/* FIXME - Should return void *, but that requires other changes. */ + +typedef void (*GC_describe_type_fn) GC_PROTO((void *p, char *out_buf)); + /* A procedure which */ + /* produces a human-readable */ + /* description of the "type" of object */ + /* p into the buffer out_buf of length */ + /* GC_TYPE_DESCR_LEN. This is used by */ + /* the debug support when printing */ + /* objects. */ + /* These functions should be as robust */ + /* as possible, though we do avoid */ + /* invoking them on objects on the */ + /* global free list. */ +# define GC_TYPE_DESCR_LEN 40 + +void GC_register_describe_type_fn GC_PROTO((int kind, GC_describe_type_fn knd)); + /* Register a describe_type function */ + /* to be used when printing objects */ + /* of a particular kind. */ + #endif /* GC_MARK_H */ diff --git a/boehm-gc/include/javaxfc.h b/boehm-gc/include/javaxfc.h index 880020c5363..23e01005afe 100644 --- a/boehm-gc/include/javaxfc.h +++ b/boehm-gc/include/javaxfc.h @@ -18,24 +18,4 @@ */ void GC_finalize_all(); -/* - * A version of GC_register_finalizer that allows the object to be - * finalized before the objects it references. This is again error - * prone, in that it makes it easy to accidentally reference finalized - * objects. Again, recommended only for JVM implementors. - */ -void GC_register_finalizer_no_order(GC_PTR obj, - GC_finalization_proc fn, GC_PTR cd, - GC_finalization_proc *ofn, GC_PTR * ocd); - -void GC_debug_register_finalizer_no_order(GC_PTR obj, - GC_finalization_proc fn, GC_PTR cd, - GC_finalization_proc *ofn, GC_PTR * ocd); -#ifdef GC_DEBUG -# define GC_REGISTER_FINALIZER(p, f, d, of, od) \ - GC_debug_register_finalizer_no_order(p, f, d, of, od) -#else -# define GC_REGISTER_FINALIZER(p, f, d, of, od) \ - GC_register_finalizer_no_order(p, f, d, of, od) -#endif diff --git a/boehm-gc/include/new_gc_alloc.h b/boehm-gc/include/new_gc_alloc.h index 20a2fabf83c..f2219b7732d 100644 --- a/boehm-gc/include/new_gc_alloc.h +++ b/boehm-gc/include/new_gc_alloc.h @@ -393,12 +393,12 @@ __STL_END_NAMESPACE __STL_BEGIN_NAMESPACE -template -struct _Alloc_traits<_T, gc_alloc > +template +struct _Alloc_traits<_Tp, gc_alloc > { static const bool _S_instanceless = true; - typedef simple_alloc<_T, gc_alloc > _Alloc_type; - typedef __allocator<_T, gc_alloc > allocator_type; + typedef simple_alloc<_Tp, gc_alloc > _Alloc_type; + typedef __allocator<_Tp, gc_alloc > allocator_type; }; inline bool operator==(const gc_alloc&, @@ -413,12 +413,12 @@ inline bool operator!=(const gc_alloc&, return false; } -template -struct _Alloc_traits<_T, single_client_gc_alloc > +template +struct _Alloc_traits<_Tp, single_client_gc_alloc > { static const bool _S_instanceless = true; - typedef simple_alloc<_T, single_client_gc_alloc > _Alloc_type; - typedef __allocator<_T, single_client_gc_alloc > allocator_type; + typedef simple_alloc<_Tp, single_client_gc_alloc > _Alloc_type; + typedef __allocator<_Tp, single_client_gc_alloc > allocator_type; }; inline bool operator==(const single_client_gc_alloc&, @@ -433,12 +433,12 @@ inline bool operator!=(const single_client_gc_alloc&, return false; } -template -struct _Alloc_traits<_T, traceable_alloc > +template +struct _Alloc_traits<_Tp, traceable_alloc > { static const bool _S_instanceless = true; - typedef simple_alloc<_T, traceable_alloc > _Alloc_type; - typedef __allocator<_T, traceable_alloc > allocator_type; + typedef simple_alloc<_Tp, traceable_alloc > _Alloc_type; + typedef __allocator<_Tp, traceable_alloc > allocator_type; }; inline bool operator==(const traceable_alloc&, @@ -453,12 +453,12 @@ inline bool operator!=(const traceable_alloc&, return false; } -template -struct _Alloc_traits<_T, single_client_traceable_alloc > +template +struct _Alloc_traits<_Tp, single_client_traceable_alloc > { static const bool _S_instanceless = true; - typedef simple_alloc<_T, single_client_traceable_alloc > _Alloc_type; - typedef __allocator<_T, single_client_traceable_alloc > allocator_type; + typedef simple_alloc<_Tp, single_client_traceable_alloc > _Alloc_type; + typedef __allocator<_Tp, single_client_traceable_alloc > allocator_type; }; inline bool operator==(const single_client_traceable_alloc&, diff --git a/boehm-gc/include/private/dbg_mlc.h b/boehm-gc/include/private/dbg_mlc.h index e2003e6c44f..e0a994de5e2 100644 --- a/boehm-gc/include/private/dbg_mlc.h +++ b/boehm-gc/include/private/dbg_mlc.h @@ -123,7 +123,6 @@ typedef struct { # define UNCOLLECTABLE_DEBUG_BYTES (sizeof (oh) + sizeof (word)) # define DEBUG_BYTES (UNCOLLECTABLE_DEBUG_BYTES - EXTRA_BYTES) #endif -#define USR_PTR_FROM_BASE(p) ((ptr_t)(p) + sizeof(oh)) /* Round bytes to words without adding extra byte at end. */ #define SIMPLE_ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1) diff --git a/boehm-gc/include/private/gc_pmark.h b/boehm-gc/include/private/gc_pmark.h index c109738203a..51981914dc5 100644 --- a/boehm-gc/include/private/gc_pmark.h +++ b/boehm-gc/include/private/gc_pmark.h @@ -135,12 +135,7 @@ extern mse * GC_mark_stack; /* Return a pointer to within 1st page of object. */ /* Set *new_hdr_p to corr. hdr. */ #ifdef __STDC__ -# ifdef PRINT_BLACK_LIST - ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, - word source); -# else - ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p); -# endif + ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p); #else ptr_t GC_find_start(); #endif diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h index 5e7625fb150..08dd8ea247b 100644 --- a/boehm-gc/include/private/gc_priv.h +++ b/boehm-gc/include/private/gc_priv.h @@ -550,7 +550,7 @@ extern GC_warn_proc GC_current_warn_proc; #define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2) #define MAXOBJBYTES ((word)CPP_MAXOBJBYTES) -#define CPP_MAXOBJSZ BYTES_TO_WORDS(CPP_HBLKSIZE/2) +#define CPP_MAXOBJSZ BYTES_TO_WORDS(CPP_MAXOBJBYTES) #define MAXOBJSZ ((word)CPP_MAXOBJSZ) # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE) @@ -578,7 +578,7 @@ extern GC_warn_proc GC_current_warn_proc; # else # define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n) # endif -# define SMALL_OBJ(bytes) ((bytes) < (MAXOBJBYTES - EXTRA_BYTES)) +# define SMALL_OBJ(bytes) ((bytes) <= (MAXOBJBYTES - EXTRA_BYTES)) # define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES) # ifndef MIN_WORDS /* MIN_WORDS is the size of the smallest allocated object. */ @@ -615,6 +615,10 @@ extern GC_warn_proc GC_current_warn_proc; # define LOG_PHT_ENTRIES 16 /* Collisions are likely if heap grows */ /* to more than 64K hblks >= 256MB. */ /* Each hash table occupies 8K bytes. */ + /* Even for somewhat smaller heaps, */ + /* say half that, collisions may be an */ + /* issue because we blacklist */ + /* addresses outside the heap. */ # endif # endif # define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES) @@ -934,11 +938,11 @@ struct _GC_arrays { char _valid_offsets[VALID_OFFSET_SZ]; /* GC_valid_offsets[i] == TRUE ==> i */ /* is registered as a displacement. */ -# define OFFSET_VALID(displ) \ - (GC_all_interior_pointers || GC_valid_offsets[displ]) char _modws_valid_offsets[sizeof(word)]; /* GC_valid_offsets[i] ==> */ /* GC_modws_valid_offsets[i%sizeof(word)] */ +# define OFFSET_VALID(displ) \ + (GC_all_interior_pointers || GC_valid_offsets[displ]) # ifdef STUBBORN_ALLOC page_hash_table _changed_pages; /* Stubborn object pages that were changes since last call to */ @@ -966,7 +970,7 @@ struct _GC_arrays { # endif # else # ifdef SMALL_CONFIG -# define MAX_HEAP_SECTS 128 /* Roughly 1GB */ +# define MAX_HEAP_SECTS 128 /* Roughly 256MB (128*2048*1K) */ # else # define MAX_HEAP_SECTS 384 /* Roughly 3GB */ # endif @@ -1436,6 +1440,7 @@ GC_bool GC_is_tmp_root GC_PROTO((ptr_t p)); # endif void GC_register_dynamic_libraries GC_PROTO((void)); /* Add dynamic library data sections to the root set. */ + GC_bool GC_register_main_static_data GC_PROTO((void)); /* We need to register the main data segment. Returns */ /* TRUE unless this is done implicitly as part of */ @@ -1610,7 +1615,7 @@ void GC_collect_a_little_inner GC_PROTO((int n)); /* collection work, if appropriate. */ /* A unit is an amount appropriate for */ /* HBLKSIZE bytes of allocation. */ -ptr_t GC_generic_malloc GC_PROTO((word lb, int k)); +/* ptr_t GC_generic_malloc GC_PROTO((word lb, int k)); */ /* Allocate an object of the given */ /* kind. By default, there are only */ /* a few kinds: composite(pointerfree), */ @@ -1620,6 +1625,7 @@ ptr_t GC_generic_malloc GC_PROTO((word lb, int k)); /* internals to add more, e.g. to */ /* communicate object layout info */ /* to the collector. */ + /* The actual decl is in gc_mark.h. */ ptr_t GC_generic_malloc_ignore_off_page GC_PROTO((size_t b, int k)); /* As above, but pointers past the */ /* first page of the resulting object */ @@ -1717,6 +1723,10 @@ extern GC_bool GC_print_stats; /* Produce at least some logging output */ # define COND_DUMP #endif +#ifdef KEEP_BACK_PTRS + extern long GC_backtraces; +#endif + /* Macros used for collector internal allocation. */ /* These assume the collector lock is held. */ #ifdef DBG_HDRS_ALL diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h index 32b6e482cfe..38c2a96cc48 100644 --- a/boehm-gc/include/private/gcconfig.h +++ b/boehm-gc/include/private/gcconfig.h @@ -2,7 +2,7 @@ * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1996 by Silicon Graphics. All rights reserved. - * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 2000-2004 Hewlett-Packard Development Company, L.P. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -307,6 +307,10 @@ # define I386 # define mach_type_known # endif +# if defined(__NetBSD__) && defined(__x86_64__) +# define X86_64 +# define mach_type_known +# endif # if defined(bsdi) && (defined(i386) || defined(__i386__)) # define I386 # define BSDI @@ -347,6 +351,11 @@ # define MSWIN32 /* or Win32s */ # define mach_type_known # endif +# if defined(_MSC_VER) && defined(_M_IA64) +# define IA64 +# define MSWIN32 /* Really win64, but we don't treat 64-bit */ + /* variants as a differnt platform. */ +# endif # endif # if defined(__DJGPP__) # define I386 @@ -588,7 +597,8 @@ * USE_GENERIC_PUSH_REGS the preferred approach for marking from registers. */ # if defined(__GNUC__) && ((__GNUC__ >= 3) || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) + (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \ + && !defined(__INTEL_COMPILER) # define HAVE_BUILTIN_UNWIND_INIT # endif @@ -599,8 +609,14 @@ # ifdef OPENBSD # define OS_TYPE "OPENBSD" # define HEURISTIC2 - extern char etext[]; -# define DATASTART ((ptr_t)(etext)) +# ifdef __ELF__ +# define DATASTART GC_data_start +# define DYNAMIC_LOADING +# else + extern char etext[]; +# define DATASTART ((ptr_t)(etext)) +# endif +# define USE_GENERIC_PUSH_REGS # endif # ifdef NETBSD # define OS_TYPE "NETBSD" @@ -612,6 +628,7 @@ extern char etext[]; # define DATASTART ((ptr_t)(etext)) # endif +# define USE_GENERIC_PUSH_REGS # endif # ifdef LINUX # define OS_TYPE "LINUX" @@ -925,10 +942,17 @@ # ifdef I386 # define MACH_TYPE "I386" -# define ALIGNMENT 4 /* Appears to hold for all "32 bit" compilers */ +# if defined(__LP64__) || defined(_WIN64) +# define CPP_WORDSZ 64 +# define ALIGNMENT 8 +# else +# define CPP_WORDSZ 32 +# define ALIGNMENT 4 + /* Appears to hold for all "32 bit" compilers */ /* except Borland. The -a4 option fixes */ /* Borland. */ /* Ivan Demakov: For Watcom the option is -zp4. */ +# endif # ifndef SMALL_CONFIG # define ALIGN_DOUBLE /* Not strictly necessary, but may give speed */ /* improvement on Pentiums. */ @@ -1042,7 +1066,7 @@ /* possibly because Linux threads is itself a malloc client */ /* and can't deal with the signals. */ # endif -# define HEAP_START 0x1000 +# define HEAP_START (ptr_t)0x1000 /* This encourages mmap to give us low addresses, */ /* thus allowing the heap to grow to ~3GB */ # ifdef __ELF__ @@ -1073,6 +1097,8 @@ # define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) # endif # ifdef USE_I686_PREFETCH + /* FIXME: Thus should use __builtin_prefetch, but we'll leave that */ + /* for the next rtelease. */ # define PREFETCH(x) \ __asm__ __volatile__ (" prefetchnta %0": : "m"(*(char *)(x))) /* Empirically prefetcht0 is much more effective at reducing */ @@ -1562,6 +1588,7 @@ /* first putenv call. */ extern char ** environ; # define STACKBOTTOM ((ptr_t)environ) +# define HPUX_STACKBOTTOM # define DYNAMIC_LOADING # include # define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) @@ -1571,9 +1598,9 @@ /* 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)) + extern ptr_t GC_register_stackbottom; +# define BACKING_STORE_BASE GC_register_stackbottom + /* Known to be wrong for recent HP/UX versions!!! */ # endif # ifdef LINUX # define CPP_WORDSZ 64 @@ -1591,8 +1618,8 @@ /* 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) + extern ptr_t GC_register_stackbottom; +# define BACKING_STORE_BASE GC_register_stackbottom # define SEARCH_FOR_DATA_START # ifdef __GNUC__ # define DYNAMIC_LOADING @@ -1606,14 +1633,37 @@ 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))) +# ifndef __INTEL_COMPILER +# define PREFETCH(x) \ + __asm__ (" lfetch [%0]": : "r"(x)) +# define PREFETCH_FOR_WRITE(x) \ + __asm__ (" lfetch.excl [%0]": : "r"(x)) +# define CLEAR_DOUBLE(x) \ + __asm__ (" stf.spill [%0]=f0": : "r"((void *)(x))) +# else +# include +# define PREFETCH(x) \ + __lfetch(__lfhint_none, (x)) +# define PREFETCH_FOR_WRITE(x) \ + __lfetch(__lfhint_nta, (x)) +# define CLEAR_DOUBLE(x) \ + __stf_spill((void *)(x), 0) +# endif // __INTEL_COMPILER # endif # endif +# ifdef MSWIN32 + /* FIXME: This is a very partial guess. There is no port, yet. */ +# define OS_TYPE "MSWIN32" + /* STACKBOTTOM and DATASTART are handled specially in */ + /* os_dep.c. */ +# define DATAEND /* not needed */ +# if defined(_WIN64) +# define CPP_WORDSZ 64 +# else +# define CPP_WORDSZ 32 /* Is this possible? */ +# endif +# define ALIGNMENT 8 +# endif # endif # ifdef M88K @@ -1801,13 +1851,28 @@ extern int etext[]; # define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) # endif -# if defined(__GNUC__) && __GNUC__ >= 3 -# define PREFETCH(x) __builtin_prefetch ((x), 0, 0) -# define PREFETCH_FOR_WRITE(x) __builtin_prefetch ((x), 1) +# if defined(__GNUC__) && __GNUC >= 3 +# define PREFETCH(x) __builtin_prefetch((x), 0, 0) +# define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1) # endif # endif +# ifdef NETBSD +# define OS_TYPE "NETBSD" +# ifdef __ELF__ +# define DYNAMIC_LOADING +# endif +# define HEURISTIC2 + extern char etext[]; +# define SEARCH_FOR_DATA_START +# endif # endif +#if defined(LINUX) && defined(USE_MMAP) + /* The kernel may do a somewhat better job merging mappings etc. */ + /* with anonymous mappings. */ +# define USE_MMAP_ANON +#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 */ @@ -1862,9 +1927,13 @@ # define SUNOS5SIGS # endif -# if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \ +# if defined(FREEBSD) && (__FreeBSD__ >= 4) +# define SUNOS5SIGS +# endif + +# if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \ || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \ - || defined(DGUX) || defined(BSD) \ + || defined(DGUX) || defined(BSD) || defined(SUNOS4) \ || defined(_AIX) || defined(DARWIN) || defined(OSF1) # define UNIX_LIKE /* Basic Unix-like system calls work. */ # endif @@ -1980,6 +2049,10 @@ # define USE_GENERIC_PUSH_REGS # endif +# if defined(MSWINCE) +# define NO_GETENV +# endif + # if defined(SPARC) # define ASM_CLEAR_CODE /* Stack clearing is crucial, and we */ /* include assembly code to do it well. */ diff --git a/boehm-gc/include/private/solaris_threads.h b/boehm-gc/include/private/solaris_threads.h index 7d49c2987e0..b1f62620bd7 100644 --- a/boehm-gc/include/private/solaris_threads.h +++ b/boehm-gc/include/private/solaris_threads.h @@ -30,6 +30,8 @@ extern size_t GC_min_stack_sz; extern size_t GC_page_sz; extern void GC_thr_init(void); + extern ptr_t GC_stack_alloc(size_t * stack_size); + extern void GC_stack_free(ptr_t stack, size_t size); # endif /* GC_SOLARIS_THREADS */ diff --git a/boehm-gc/include/private/specific.h b/boehm-gc/include/private/specific.h index a0e6ae0ebc1..d04e19f5a4b 100644 --- a/boehm-gc/include/private/specific.h +++ b/boehm-gc/include/private/specific.h @@ -85,7 +85,7 @@ static __inline__ void * PREFIXED(getspecific) (tsd * key) { unsigned hash_val = CACHE_HASH(qtid); tse * volatile * entry_ptr = key -> cache + hash_val; tse * entry = *entry_ptr; /* Must be loaded only once. */ - if (EXPECT(entry -> qtid == qtid, 1)) { + if (EXPECT(entry -> qtid == qtid, 1)) { GC_ASSERT(entry -> thread == pthread_self()); return entry -> value; } diff --git a/boehm-gc/mach_dep.c b/boehm-gc/mach_dep.c index 2c321fa978d..327e11ca690 100644 --- a/boehm-gc/mach_dep.c +++ b/boehm-gc/mach_dep.c @@ -431,6 +431,9 @@ ptr_t cold_gc_frame; (void) setjmp(regs); # else (void) _setjmp(regs); + /* We don't want to mess with signals. According to */ + /* SUSV3, setjmp() may or may not save signal mask. */ + /* _setjmp won't, but is less portable. */ # endif # endif /* !HAVE_BUILTIN_UNWIND_INIT */ # if (defined(SPARC) && !defined(HAVE_BUILTIN_UNWIND_INIT)) \ diff --git a/boehm-gc/malloc.c b/boehm-gc/malloc.c index 353a9bc9599..cb3f3766386 100644 --- a/boehm-gc/malloc.c +++ b/boehm-gc/malloc.c @@ -36,6 +36,7 @@ register struct obj_kind * kind; /* Allocate a large block of size lw words. */ /* The block is not cleared. */ /* Flags is 0 or IGNORE_OFF_PAGE. */ +/* We hold the allocation lock. */ ptr_t GC_alloc_large(lw, k, flags) word lw; int k; @@ -62,20 +63,21 @@ unsigned flags; if (h == 0) { result = 0; } else { - int total_bytes = BYTES_TO_WORDS(n_blocks * HBLKSIZE); + int total_bytes = n_blocks * HBLKSIZE; if (n_blocks > 1) { - GC_large_allocd_bytes += n_blocks * HBLKSIZE; + GC_large_allocd_bytes += total_bytes; if (GC_large_allocd_bytes > GC_max_large_allocd_bytes) GC_max_large_allocd_bytes = GC_large_allocd_bytes; } result = (ptr_t) (h -> hb_body); - GC_words_wasted += total_bytes - lw; + GC_words_wasted += BYTES_TO_WORDS(total_bytes) - lw; } return result; } /* Allocate a large block of size lb bytes. Clear if appropriate. */ +/* We hold the allocation lock. */ ptr_t GC_alloc_large_and_clear(lw, k, flags) word lw; int k; @@ -311,6 +313,19 @@ DCL_LOCK_STATE; } # ifdef REDIRECT_MALLOC + +/* Avoid unnecessary nested procedure calls here, by #defining some */ +/* malloc replacements. Otherwise we end up saving a */ +/* meaningless return address in the object. It also speeds things up, */ +/* but it is admittedly quite ugly. */ +# ifdef GC_ADD_CALLER +# define RA GC_RETURN_ADDR, +# else +# define RA +# endif +# define GC_debug_malloc_replacement(lb) \ + GC_debug_malloc(lb, RA "unknown", 0) + # ifdef __STDC__ GC_PTR malloc(size_t lb) # else @@ -363,6 +378,8 @@ DCL_LOCK_STATE; /* and thus the right thing will happen even without overriding it. */ /* This seems to be true on most Linux systems. */ +#undef GC_debug_malloc_replacement + # endif /* REDIRECT_MALLOC */ /* Explicitly deallocate an object p. */ diff --git a/boehm-gc/mallocx.c b/boehm-gc/mallocx.c index 84993da2026..d45f21e8e51 100644 --- a/boehm-gc/mallocx.c +++ b/boehm-gc/mallocx.c @@ -147,6 +147,16 @@ int obj_kind; # endif # ifdef REDIRECT_REALLOC + +/* As with malloc, avoid two levels of extra calls here. */ +# ifdef GC_ADD_CALLER +# define RA GC_RETURN_ADDR, +# else +# define RA +# endif +# define GC_debug_realloc_replacement(p, lb) \ + GC_debug_realloc(p, lb, RA "unknown", 0) + # ifdef __STDC__ GC_PTR realloc(GC_PTR p, size_t lb) # else @@ -157,6 +167,8 @@ int obj_kind; { return(REDIRECT_REALLOC(p, lb)); } + +# undef GC_debug_realloc_replacement # endif /* REDIRECT_REALLOC */ diff --git a/boehm-gc/mark.c b/boehm-gc/mark.c index fffd62ac90c..c645bc0eeec 100644 --- a/boehm-gc/mark.c +++ b/boehm-gc/mark.c @@ -558,8 +558,8 @@ register hdr *hhdr, **new_hdr_p; current = current - HBLKSIZE*(word)hhdr; hhdr = HDR(current); } while(IS_FORWARDING_ADDR_OR_NIL(hhdr)); - /* current points to the start of the large object */ - if (hhdr -> hb_flags & IGNORE_OFF_PAGE) return(0); + /* current points to near the start of the large object */ + if (hhdr -> hb_flags & IGNORE_OFF_PAGE) return(orig); if ((word *)orig - (word *)current >= (ptrdiff_t)(hhdr->hb_sz)) { /* Pointer past the end of the block */ @@ -1739,7 +1739,7 @@ register hdr * hhdr; { register int sz = hhdr -> hb_sz; - if (sz < MAXOBJSZ) { + if (sz <= MAXOBJSZ) { return(GC_page_was_dirty(h)); } else { register ptr_t p = (ptr_t)h; diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c index 12d6d2e2ba6..5b10feeb961 100644 --- a/boehm-gc/misc.c +++ b/boehm-gc/misc.c @@ -116,6 +116,11 @@ GC_bool GC_print_back_height = 0; GC_bool GC_dump_regularly = 0; /* Generate regular debugging dumps. */ #endif +#ifdef KEEP_BACK_PTRS + long GC_backtraces = 0; /* Number of random backtraces to */ + /* generate for each GC. */ +#endif + #ifdef FIND_LEAK int GC_find_leak = 1; #else @@ -470,7 +475,17 @@ void GC_init() DISABLE_SIGNALS(); #if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) - if (!GC_is_initialized) InitializeCriticalSection(&GC_allocate_ml); + if (!GC_is_initialized) { + BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL; + HMODULE hK32 = GetModuleHandle("kernel32.dll"); + if (hK32) + (FARPROC) pfn = GetProcAddress(hK32, + "InitializeCriticalSectionAndSpinCount"); + if (pfn) + pfn(&GC_allocate_ml, 4000); + else + InitializeCriticalSection (&GC_allocate_ml); + } #endif /* MSWIN32 */ LOCK(); @@ -537,7 +552,7 @@ int sig; static GC_bool installed_looping_handler = FALSE; -void maybe_install_looping_handler() +static void maybe_install_looping_handler() { /* Install looping handler before the write fault handler, so we */ /* handle write faults correctly. */ @@ -574,6 +589,15 @@ void GC_init_inner() if (0 != GETENV("GC_DUMP_REGULARLY")) { GC_dump_regularly = 1; } +# endif +# ifdef KEEP_BACK_PTRS + { + char * backtraces_string = GETENV("GC_BACKTRACES"); + if (0 != backtraces_string) { + GC_backtraces = atol(backtraces_string); + if (backtraces_string[0] == '\0') GC_backtraces = 1; + } + } # endif if (0 != GETENV("GC_FIND_LEAK")) { GC_find_leak = 1; @@ -650,14 +674,14 @@ void GC_init_inner() || defined(GC_SOLARIS_THREADS) if (GC_stackbottom == 0) { GC_stackbottom = GC_get_stack_base(); -# if defined(LINUX) && defined(IA64) +# if (defined(LINUX) || defined(HPUX)) && defined(IA64) GC_register_stackbottom = GC_get_register_stack_base(); # endif } else { -# if defined(LINUX) && defined(IA64) +# if (defined(LINUX) || defined(HPUX)) && defined(IA64) if (GC_register_stackbottom == 0) { WARN("GC_register_stackbottom should be set with GC_stackbottom", 0); - /* The following is likely to fail, since we rely on */ + /* The following may fail, since we may rely on */ /* alignment properties that may not hold with a user set */ /* GC_stackbottom. */ GC_register_stackbottom = GC_get_register_stack_base(); @@ -754,7 +778,7 @@ void GC_init_inner() } # endif /* !SMALL_CONFIG */ COND_DUMP; - /* Get black list set up and/or incrmental GC started */ + /* Get black list set up and/or incremental GC started */ if (!GC_dont_precollect || GC_incremental) GC_gcollect_inner(); GC_is_initialized = TRUE; # ifdef STUBBORN_ALLOC @@ -1031,7 +1055,6 @@ GC_CONST char * msg; { # if defined(MSWIN32) (void) MessageBoxA(NULL, msg, "Fatal error in gc", MB_ICONERROR|MB_OK); - DebugBreak(); # else GC_err_printf1("%s\n", msg); # endif @@ -1042,7 +1065,7 @@ GC_CONST char * msg; /* about threads. */ for(;;) {} } -# ifdef MSWIN32 +# if defined(MSWIN32) || defined(MSWINCE) DebugBreak(); # else (void) abort(); @@ -1064,6 +1087,75 @@ void GC_disable() UNLOCK(); } +/* Helper procedures for new kind creation. */ +void ** GC_new_free_list_inner() +{ + void *result = GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); + if (result == 0) ABORT("Failed to allocate freelist for new kind"); + BZERO(result, (MAXOBJSZ+1)*sizeof(ptr_t)); + return result; +} + +void ** GC_new_free_list() +{ + void *result; + LOCK(); DISABLE_SIGNALS(); + result = GC_new_free_list_inner(); + UNLOCK(); ENABLE_SIGNALS(); + return result; +} + +int GC_new_kind_inner(fl, descr, adjust, clear) +void **fl; +GC_word descr; +int adjust; +int clear; +{ + int result = GC_n_kinds++; + + if (GC_n_kinds > MAXOBJKINDS) ABORT("Too many kinds"); + GC_obj_kinds[result].ok_freelist = (ptr_t *)fl; + GC_obj_kinds[result].ok_reclaim_list = 0; + GC_obj_kinds[result].ok_descriptor = descr; + GC_obj_kinds[result].ok_relocate_descr = adjust; + GC_obj_kinds[result].ok_init = clear; + return result; +} + +int GC_new_kind(fl, descr, adjust, clear) +void **fl; +GC_word descr; +int adjust; +int clear; +{ + int result; + LOCK(); DISABLE_SIGNALS(); + result = GC_new_kind_inner(fl, descr, adjust, clear); + UNLOCK(); ENABLE_SIGNALS(); + return result; +} + +int GC_new_proc_inner(proc) +GC_mark_proc proc; +{ + int result = GC_n_mark_procs++; + + if (GC_n_mark_procs > MAX_MARK_PROCS) ABORT("Too many mark procedures"); + GC_mark_procs[result] = proc; + return result; +} + +int GC_new_proc(proc) +GC_mark_proc proc; +{ + int result; + LOCK(); DISABLE_SIGNALS(); + result = GC_new_proc_inner(proc); + UNLOCK(); ENABLE_SIGNALS(); + return result; +} + + #if !defined(NO_DEBUGGING) void GC_dump() diff --git a/boehm-gc/new_hblk.c b/boehm-gc/new_hblk.c index 1aa2c7a1253..e5580e4ca21 100644 --- a/boehm-gc/new_hblk.c +++ b/boehm-gc/new_hblk.c @@ -104,7 +104,7 @@ ptr_t ofl; p[3] = 0; p += 4; for (; p < lim; p += 4) { - PREFETCH_FOR_WRITE(p+64); + PREFETCH_FOR_WRITE((ptr_t)(p+64)); p[0] = (word)(p-4); p[1] = 0; CLEAR_DOUBLE(p+2); @@ -142,7 +142,7 @@ ptr_t ofl; p[4] = (word)p; p += 8; for (; p < lim; p += 8) { - PREFETCH_FOR_WRITE(p+64); + PREFETCH_FOR_WRITE((ptr_t)(p+64)); p[0] = (word)(p-4); p[4] = (word)p; }; @@ -171,10 +171,10 @@ ptr_t list; /* If we were more serious about it, these should go inside */ /* the loops. But write prefetches usually don't seem to */ /* matter much. */ - PREFETCH_FOR_WRITE((char *)h); - PREFETCH_FOR_WRITE((char *)h + 128); - PREFETCH_FOR_WRITE((char *)h + 256); - PREFETCH_FOR_WRITE((char *)h + 378); + PREFETCH_FOR_WRITE((ptr_t)h); + PREFETCH_FOR_WRITE((ptr_t)h + 128); + PREFETCH_FOR_WRITE((ptr_t)h + 256); + PREFETCH_FOR_WRITE((ptr_t)h + 378); /* Handle small objects sizes more efficiently. For larger objects */ /* the difference is less significant. */ # ifndef SMALL_CONFIG diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c index 2defc7174a1..21d05635ab8 100644 --- a/boehm-gc/os_dep.c +++ b/boehm-gc/os_dep.c @@ -87,6 +87,12 @@ # endif #endif +#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) \ + && !defined(NEED_FIND_LIMIT) + /* Used by GC_init_netbsd_elf() below. */ +# define NEED_FIND_LIMIT +#endif + #ifdef NEED_FIND_LIMIT # include #endif @@ -111,25 +117,30 @@ # include # include /* for locking */ #endif -#ifdef USE_MMAP +#if defined(USE_MMAP) || defined(USE_MUNMAP) +# ifndef USE_MMAP + --> USE_MUNMAP requires USE_MMAP +# endif # include # include # include +# include #endif #ifdef UNIX_LIKE # include -#endif - -#if defined(SUNOS5SIGS) || defined (HURD) || defined(LINUX) -# ifdef SUNOS5SIGS +# if defined(SUNOS5SIGS) && !defined(FREEBSD) # include # endif -# undef setjmp -# undef longjmp -# define setjmp(env) sigsetjmp(env, 1) -# define longjmp(env, val) siglongjmp(env, val) -# define jmp_buf sigjmp_buf + /* Define SETJMP and friends to be the version that restores */ + /* the signal mask. */ +# define SETJMP(env) sigsetjmp(env, 1) +# define LONGJMP(env, val) siglongjmp(env, val) +# define JMP_BUF sigjmp_buf +#else +# define SETJMP(env) setjmp(env) +# define LONGJMP(env, val) longjmp(env, val) +# define JMP_BUF jmp_buf #endif #ifdef DARWIN @@ -183,45 +194,41 @@ ssize_t GC_repeat_read(int fd, char *buf, size_t count) /* * Apply fn to a buffer containing the contents of /proc/self/maps. * Return the result of fn or, if we failed, 0. + * We currently do nothing to /proc/self/maps other than simply read + * it. This code could be simplified if we could determine its size + * ahead of time. */ word GC_apply_to_maps(word (*fn)(char *)) { int f; int result; - int maps_size; - char maps_temp[32768]; - char *maps_buf; - - /* Read /proc/self/maps */ - /* Note that we may not allocate, and thus can't use stdio. */ - f = open("/proc/self/maps", O_RDONLY); - if (-1 == f) return 0; - /* stat() doesn't work for /proc/self/maps, so we have to - read it to find out how large it is... */ - maps_size = 0; + size_t maps_size = 4000; /* Initial guess. */ + static char init_buf[1]; + static char *maps_buf = init_buf; + static size_t maps_buf_sz = 1; + + /* Read /proc/self/maps, growing maps_buf as necessary. */ + /* Note that we may not allocate conventionally, and */ + /* thus can't use stdio. */ do { - result = GC_repeat_read(f, maps_temp, sizeof(maps_temp)); - if (result <= 0) return 0; - maps_size += result; - } while (result == sizeof(maps_temp)); - - if (maps_size > sizeof(maps_temp)) { - /* If larger than our buffer, close and re-read it. */ - close(f); + if (maps_size >= maps_buf_sz) { + /* Grow only by powers of 2, since we leak "too small" buffers. */ + while (maps_size >= maps_buf_sz) maps_buf_sz *= 2; + maps_buf = GC_scratch_alloc(maps_buf_sz); + if (maps_buf == 0) return 0; + } f = open("/proc/self/maps", O_RDONLY); if (-1 == f) return 0; - maps_buf = alloca(maps_size); - if (NULL == maps_buf) return 0; - result = GC_repeat_read(f, maps_buf, maps_size); - if (result <= 0) return 0; - } else { - /* Otherwise use the fixed size buffer */ - maps_buf = maps_temp; - } - - close(f); - maps_buf[result] = '\0'; + maps_size = 0; + do { + result = GC_repeat_read(f, maps_buf, maps_buf_sz-1); + if (result <= 0) return 0; + maps_size += result; + } while (result == maps_buf_sz-1); + close(f); + } while (maps_size >= maps_buf_sz); + maps_buf[maps_size] = '\0'; /* Apply fn to result. */ return fn(maps_buf); @@ -352,7 +359,8 @@ char *GC_parse_map_entry(char *buf_ptr, word *start, word *end, # endif /* ECOS_GC_MEMORY_SIZE */ // setjmp() function, as described in ANSI para 7.6.1.1 -#define setjmp( __env__ ) hal_setjmp( __env__ ) +#undef SETJMP +#define SETJMP( __env__ ) hal_setjmp( __env__ ) // FIXME: This is a simple way of allocating memory which is // compatible with ECOS early releases. Later releases use a more @@ -688,9 +696,11 @@ ptr_t GC_get_stack_base() typedef void (*handler)(); # endif -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) || defined(HURD) +# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \ + || defined(HURD) || defined(NETBSD) static struct sigaction old_segv_act; -# if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) || defined(HURD) +# if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) \ + || defined(HURD) || defined(NETBSD) static struct sigaction old_bus_act; # endif # else @@ -704,21 +714,17 @@ ptr_t GC_get_stack_base() handler h; # endif { -# if defined(SUNOS5SIGS) || defined(IRIX5) \ - || defined(OSF1) || defined(HURD) +# if defined(SUNOS5SIGS) || defined(IRIX5) \ + || defined(OSF1) || defined(HURD) || defined(NETBSD) struct sigaction act; act.sa_handler = h; -# ifdef SUNOS5SIGS +# if 0 /* Was necessary for Solaris 2.3 and very temporary */ + /* NetBSD bugs. */ act.sa_flags = SA_RESTART | SA_NODEFER; # else act.sa_flags = SA_RESTART; # endif - /* The presence of SA_NODEFER represents yet another gross */ - /* hack. Under Solaris 2.3, siglongjmp doesn't appear to */ - /* interact correctly with -lthread. We hide the confusion */ - /* by making sure that signal handling doesn't affect the */ - /* signal mask. */ (void) sigemptyset(&act.sa_mask); # ifdef GC_IRIX_THREADS @@ -729,7 +735,7 @@ ptr_t GC_get_stack_base() # else (void) sigaction(SIGSEGV, &act, &old_segv_act); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HPUX) || defined(HURD) + || defined(HPUX) || defined(HURD) || defined(NETBSD) /* Under Irix 5.x or HP/UX, we may get SIGBUS. */ /* Pthreads doesn't exist under Irix 5.x, so we */ /* don't have to worry in the threads case. */ @@ -748,13 +754,13 @@ ptr_t GC_get_stack_base() # ifdef NEED_FIND_LIMIT /* Some tools to implement HEURISTIC2 */ # define MIN_PAGE_SIZE 256 /* Smallest conceivable page size, bytes */ - /* static */ jmp_buf GC_jmp_buf; + /* static */ JMP_BUF GC_jmp_buf; /*ARGSUSED*/ void GC_fault_handler(sig) int sig; { - longjmp(GC_jmp_buf, 1); + LONGJMP(GC_jmp_buf, 1); } void GC_setup_temporary_fault_handler() @@ -764,19 +770,19 @@ ptr_t GC_get_stack_base() void GC_reset_fault_handler() { -# if defined(SUNOS5SIGS) || defined(IRIX5) \ - || defined(OSF1) || defined(HURD) - (void) sigaction(SIGSEGV, &old_segv_act, 0); -# if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HPUX) || defined(HURD) - (void) sigaction(SIGBUS, &old_bus_act, 0); -# endif -# else - (void) signal(SIGSEGV, old_segv_handler); -# ifdef SIGBUS - (void) signal(SIGBUS, old_bus_handler); -# endif -# endif +# if defined(SUNOS5SIGS) || defined(IRIX5) \ + || defined(OSF1) || defined(HURD) || defined(NETBSD) + (void) sigaction(SIGSEGV, &old_segv_act, 0); +# if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ + || defined(HPUX) || defined(HURD) || defined(NETBSD) + (void) sigaction(SIGBUS, &old_bus_act, 0); +# endif +# else + (void) signal(SIGSEGV, old_segv_handler); +# ifdef SIGBUS + (void) signal(SIGBUS, old_bus_handler); +# endif +# endif } /* Return the first nonaddressible location > p (up) or */ @@ -786,31 +792,31 @@ ptr_t GC_get_stack_base() ptr_t p; GC_bool up; { - static VOLATILE ptr_t result; - /* Needs to be static, since otherwise it may not be */ - /* preserved across the longjmp. Can safely be */ - /* static since it's only called once, with the */ - /* allocation lock held. */ - - - GC_setup_temporary_fault_handler(); - if (setjmp(GC_jmp_buf) == 0) { - result = (ptr_t)(((word)(p)) - & ~(MIN_PAGE_SIZE-1)); - for (;;) { - if (up) { - result += MIN_PAGE_SIZE; - } else { - result -= MIN_PAGE_SIZE; - } - GC_noop1((word)(*result)); + static VOLATILE ptr_t result; + /* Needs to be static, since otherwise it may not be */ + /* preserved across the longjmp. Can safely be */ + /* static since it's only called once, with the */ + /* allocation lock held. */ + + + GC_setup_temporary_fault_handler(); + if (SETJMP(GC_jmp_buf) == 0) { + result = (ptr_t)(((word)(p)) + & ~(MIN_PAGE_SIZE-1)); + for (;;) { + if (up) { + result += MIN_PAGE_SIZE; + } else { + result -= MIN_PAGE_SIZE; + } + GC_noop1((word)(*result)); + } } - } - GC_reset_fault_handler(); - if (!up) { - result += MIN_PAGE_SIZE; - } - return(result); + GC_reset_fault_handler(); + if (!up) { + result += MIN_PAGE_SIZE; + } + return(result); } # endif @@ -821,6 +827,29 @@ ptr_t GC_get_stack_base() } #endif +#ifdef HPUX_STACKBOTTOM + +#include +#include + + ptr_t GC_get_register_stack_base(void) + { + struct pst_vm_status vm_status; + + int i = 0; + while (pstat_getprocvm(&vm_status, sizeof(vm_status), 0, i++) == 1) { + if (vm_status.pst_type == PS_RSESTACK) { + return (ptr_t) vm_status.pst_vaddr; + } + } + + /* old way to get the register stackbottom */ + return (ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1) + & ~(BACKING_STORE_ALIGNMENT - 1)); + } + +#endif /* HPUX_STACK_BOTTOM */ + #ifdef LINUX_STACKBOTTOM #include @@ -903,7 +932,11 @@ ptr_t GC_get_stack_base() size_t i, buf_offset = 0; /* First try the easy way. This should work for glibc 2.2 */ - if (0 != &__libc_stack_end) { + /* This fails in a prelinked ("prelink" command) executable */ + /* since the correct value of __libc_stack_end never */ + /* becomes visible to us. The second test works around */ + /* this. */ + if (0 != &__libc_stack_end && 0 != __libc_stack_end ) { # ifdef IA64 /* Some versions of glibc set the address 16 bytes too */ /* low while the initialization code is running. */ @@ -1328,7 +1361,7 @@ int * etext_addr; /* max_page_size to &etext if &etext is at a page boundary */ GC_setup_temporary_fault_handler(); - if (setjmp(GC_jmp_buf) == 0) { + if (SETJMP(GC_jmp_buf) == 0) { /* Try writing to the address. */ *result = *result; GC_reset_fault_handler(); @@ -1362,7 +1395,7 @@ int * etext_addr; & ~((word)max_page_size - 1); VOLATILE ptr_t result = (ptr_t)text_end; GC_setup_temporary_fault_handler(); - if (setjmp(GC_jmp_buf) == 0) { + if (SETJMP(GC_jmp_buf) == 0) { /* Try reading at the address. */ /* This should happen before there is another thread. */ for (; next_page < (word)(DATAEND); next_page += (word)max_page_size) @@ -1497,8 +1530,7 @@ word bytes; #else /* Not RS6000 */ -#if defined(USE_MMAP) -/* Tested only under Linux, IRIX5 and Solaris 2 */ +#if defined(USE_MMAP) || defined(USE_MUNMAP) #ifdef USE_MMAP_FIXED # define GC_MMAP_FLAGS MAP_FIXED | MAP_PRIVATE @@ -1508,6 +1540,23 @@ word bytes; # define GC_MMAP_FLAGS MAP_PRIVATE #endif +#ifdef USE_MMAP_ANON +# define zero_fd -1 +# if defined(MAP_ANONYMOUS) +# define OPT_MAP_ANON MAP_ANONYMOUS +# else +# define OPT_MAP_ANON MAP_ANON +# endif +#else + static int zero_fd; +# define OPT_MAP_ANON 0 +#endif + +#endif /* defined(USE_MMAP) || defined(USE_MUNMAP) */ + +#if defined(USE_MMAP) +/* Tested only under Linux, IRIX5 and Solaris 2 */ + #ifndef HEAP_START # define HEAP_START 0 #endif @@ -1520,23 +1569,17 @@ word bytes; # ifndef USE_MMAP_ANON static GC_bool initialized = FALSE; - static int fd; if (!initialized) { - fd = open("/dev/zero", O_RDONLY); - fcntl(fd, F_SETFD, FD_CLOEXEC); + zero_fd = open("/dev/zero", O_RDONLY); + fcntl(zero_fd, F_SETFD, FD_CLOEXEC); initialized = TRUE; } # endif if (bytes & (GC_page_size -1)) ABORT("Bad GET_MEM arg"); -# ifdef USE_MMAP_ANON - result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC, - GC_MMAP_FLAGS | MAP_ANON, -1, 0/* offset */); -# else - result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC, - GC_MMAP_FLAGS, fd, 0/* offset */); -# endif + result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC, + GC_MMAP_FLAGS | OPT_MAP_ANON, zero_fd, 0/* offset */); if (result == MAP_FAILED) return(0); last_addr = (ptr_t)result + bytes + GC_page_size - 1; last_addr = (ptr_t)((word)last_addr & ~(GC_page_size - 1)); @@ -1794,7 +1837,15 @@ void GC_unmap(ptr_t start, word bytes) len -= free_len; } # else - if (munmap(start_addr, len) != 0) ABORT("munmap failed"); + /* We immediately remap it to prevent an intervening mmap from */ + /* accidentally grabbing the same address space. */ + { + void * result; + result = mmap(start_addr, len, PROT_NONE, + MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON, + zero_fd, 0/* offset */); + if (result != (void *)start_addr) ABORT("mmap(...PROT_NONE...) failed"); + } GC_unmapped_bytes += len; # endif } @@ -1802,13 +1853,13 @@ void GC_unmap(ptr_t start, word bytes) void GC_remap(ptr_t start, word bytes) { - static int zero_descr = -1; ptr_t start_addr = GC_unmap_start(start, bytes); ptr_t end_addr = GC_unmap_end(start, bytes); word len = end_addr - start_addr; - ptr_t result; # if defined(MSWIN32) || defined(MSWINCE) + ptr_t result; + if (0 == start_addr) return; while (len != 0) { MEMORY_BASIC_INFORMATION mem_info; @@ -1828,13 +1879,17 @@ void GC_remap(ptr_t start, word bytes) len -= alloc_len; } # else - if (-1 == zero_descr) zero_descr = open("/dev/zero", O_RDWR); - fcntl(zero_descr, F_SETFD, FD_CLOEXEC); + /* It was already remapped with PROT_NONE. */ + int result; + if (0 == start_addr) return; - result = mmap(start_addr, len, PROT_READ | PROT_WRITE | OPT_PROT_EXEC, - MAP_FIXED | MAP_PRIVATE, zero_descr, 0); - if (result != start_addr) { - ABORT("mmap remapping failed"); + result = mprotect(start_addr, len, + PROT_READ | PROT_WRITE | OPT_PROT_EXEC); + if (result != 0) { + GC_err_printf3( + "Mprotect failed at 0x%lx (length %ld) with errno %ld\n", + start_addr, len, errno); + ABORT("Mprotect remapping failed"); } GC_unmapped_bytes -= len; # endif @@ -2170,9 +2225,9 @@ GC_bool is_ptrfree; # endif /* !DARWIN */ # endif /* MSWIN32 || MSWINCE || DARWIN */ -#if defined(SUNOS4) || defined(FREEBSD) +#if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS)) typedef void (* SIG_PF)(); -#endif /* SUNOS4 || FREEBSD */ +#endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */ #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \ || defined(HURD) @@ -2199,13 +2254,13 @@ GC_bool is_ptrfree; #endif /* IRIX5 || OSF1 || HURD */ #if defined(SUNOS5SIGS) -# ifdef HPUX -# define SIGINFO __siginfo +# if defined(HPUX) || defined(FREEBSD) +# define SIGINFO_T siginfo_t # else -# define SIGINFO siginfo +# define SIGINFO_T struct siginfo # endif # ifdef __STDC__ - typedef void (* REAL_SIG_PF)(int, struct SIGINFO *, void *); + typedef void (* REAL_SIG_PF)(int, SIGINFO_T *, void *); # else typedef void (* REAL_SIG_PF)(); # endif @@ -2225,8 +2280,11 @@ GC_bool is_ptrfree; # if defined(ALPHA) || defined(M68K) typedef void (* REAL_SIG_PF)(int, int, s_c *); # else -# if defined(IA64) || defined(HP_PA) +# if defined(IA64) || defined(HP_PA) || defined(X86_64) typedef void (* REAL_SIG_PF)(int, siginfo_t *, s_c *); + /* FIXME: */ + /* According to SUSV3, the last argument should have type */ + /* void * or ucontext_t * */ # else typedef void (* REAL_SIG_PF)(int, s_c); # endif @@ -2301,7 +2359,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ /*ARGSUSED*/ #if !defined(DARWIN) -# if defined (SUNOS4) || defined(FREEBSD) +# if defined (SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS)) void GC_write_fault_handler(sig, code, scp, addr) int sig, code; struct sigcontext *scp; @@ -2316,7 +2374,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # define SIG_OK (sig == SIGBUS) # define CODE_OK (code == BUS_PAGE_FAULT) # endif -# endif /* SUNOS4 || FREEBSD */ +# endif /* SUNOS4 || (FREEBSD && !SUNOS5SIGS) */ # if defined(IRIX5) || defined(OSF1) || defined(HURD) # include @@ -2339,7 +2397,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # if defined(ALPHA) || defined(M68K) void GC_write_fault_handler(int sig, int code, s_c * sc) # else -# if defined(IA64) || defined(HP_PA) +# if defined(IA64) || defined(HP_PA) || defined(X86_64) void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp) # else # if defined(ARM32) @@ -2358,11 +2416,11 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # if defined(SUNOS5SIGS) # ifdef __STDC__ - void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context) + void GC_write_fault_handler(int sig, SIGINFO_T *scp, void * context) # else void GC_write_fault_handler(sig, scp, context) int sig; - struct SIGINFO *scp; + SIGINFO_T *scp; void * context; # endif # ifdef HPUX @@ -2373,9 +2431,14 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ || (scp -> si_code == SEGV_UNKNOWN) \ || (scp -> si_code == BUS_OBJERR) # else -# define SIG_OK (sig == SIGSEGV) -# define CODE_OK (scp -> si_code == SEGV_ACCERR) -# endif +# ifdef FREEBSD +# define SIG_OK (sig == SIGBUS) +# define CODE_OK (scp -> si_code == BUS_PAGE_FAULT) +# else +# define SIG_OK (sig == SIGSEGV) +# define CODE_OK (scp -> si_code == SEGV_ACCERR) +# endif +# endif # endif /* SUNOS5SIGS */ # if defined(MSWIN32) || defined(MSWINCE) @@ -2400,7 +2463,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ char * addr = (char *) (scp -> si_addr); # endif # ifdef LINUX -# if defined(I386) || defined (X86_64) +# if defined(I386) char * addr = (char *) (sc.cr2); # else # if defined(M68K) @@ -2435,7 +2498,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # ifdef ALPHA char * addr = get_fault_addr(sc); # else -# if defined(IA64) || defined(HP_PA) +# if defined(IA64) || defined(HP_PA) || defined(X86_64) char * addr = si -> si_addr; /* I believe this is claimed to work on all platforms for */ /* Linux 2.3.47 and later. Hopefully we don't have to */ @@ -2478,6 +2541,10 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ in_allocd_block = (HDR(addr) != 0); # endif if (!in_allocd_block) { + /* FIXME - We should make sure that we invoke the */ + /* old handler with the appropriate calling */ + /* sequence, which often depends on SA_SIGINFO. */ + /* Heap blocks now begin and end on page boundaries */ SIG_PF old_handler; @@ -2494,11 +2561,17 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ return(EXCEPTION_CONTINUE_SEARCH); # endif } else { -# if defined (SUNOS4) || defined(FREEBSD) +# if defined (SUNOS4) \ + || (defined(FREEBSD) && !defined(SUNOS5SIGS)) (*old_handler) (sig, code, scp, addr); return; # endif # if defined (SUNOS5SIGS) + /* + * FIXME: For FreeBSD, this code should check if the + * old signal handler used the traditional BSD style and + * if so call it using that style. + */ (*(REAL_SIG_PF)old_handler) (sig, scp, context); return; # endif @@ -2506,7 +2579,7 @@ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */ # if defined(ALPHA) || defined(M68K) (*(REAL_SIG_PF)old_handler) (sig, code, sc); # else -# if defined(IA64) || defined(HP_PA) +# if defined(IA64) || defined(HP_PA) || defined(X86_64) (*(REAL_SIG_PF)old_handler) (sig, si, scp); # else (*(REAL_SIG_PF)old_handler) (sig, sc); @@ -2600,7 +2673,8 @@ void GC_dirty_init() struct sigaction act, oldact; /* We should probably specify SA_SIGINFO for Linux, and handle */ /* the different architectures more uniformly. */ -# if defined(IRIX5) || defined(LINUX) || defined(OSF1) || defined(HURD) +# if defined(IRIX5) || defined(LINUX) && !defined(X86_64) \ + || defined(OSF1) || defined(HURD) act.sa_flags = SA_RESTART; act.sa_handler = (SIG_PF)GC_write_fault_handler; # else @@ -2623,7 +2697,7 @@ void GC_dirty_init() GC_err_printf0("Page size not multiple of HBLKSIZE\n"); ABORT("Page size not multiple of HBLKSIZE"); } -# if defined(SUNOS4) || defined(FREEBSD) +# if defined(SUNOS4) || (defined(FREEBSD) && !defined(SUNOS5SIGS)) GC_old_bus_handler = signal(SIGBUS, GC_write_fault_handler); if (GC_old_bus_handler == SIG_IGN) { GC_err_printf0("Previously ignored bus error!?"); @@ -2647,13 +2721,13 @@ void GC_dirty_init() # endif } # endif -# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \ - || defined(OSF1) || defined(HURD) +# if (defined(SUNOS5SIGS) && !defined(FREEBSD)) || defined(IRIX5) \ + || defined(LINUX) || defined(OSF1) || defined(HURD) /* SUNOS5SIGS includes HPUX */ # if defined(GC_IRIX_THREADS) sigaction(SIGSEGV, 0, &oldact); sigaction(SIGSEGV, &act, 0); -# else +# else { int res = sigaction(SIGSEGV, &act, &oldact); if (res != 0) ABORT("Sigaction failed"); @@ -2679,8 +2753,9 @@ void GC_dirty_init() GC_err_printf0("Replaced other SIGSEGV handler\n"); # endif } -# endif -# if defined(HPUX) || defined(LINUX) || defined(HURD) +# endif /* (SUNOS5SIGS && !FREEBSD) || IRIX5 || LINUX || OSF1 || HURD */ +# if defined(HPUX) || defined(LINUX) || defined(HURD) \ + || (defined(FREEBSD) && defined(SUNOS5SIGS)) sigaction(SIGBUS, &act, &oldact); GC_old_bus_handler = oldact.sa_handler; if (GC_old_bus_handler == SIG_IGN) { @@ -2692,7 +2767,7 @@ void GC_dirty_init() GC_err_printf0("Replaced other SIGBUS handler\n"); # endif } -# endif /* HPUX || LINUX || HURD */ +# endif /* HPUX || LINUX || HURD || (FREEBSD && SUNOS5SIGS) */ # if defined(MSWIN32) GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler); if (GC_old_segv_handler != NULL) { @@ -2977,7 +3052,7 @@ word n; #include #include -#define INITIAL_BUF_SZ 4096 +#define INITIAL_BUF_SZ 16384 word GC_proc_buf_size = INITIAL_BUF_SZ; char *GC_proc_buf; @@ -3091,7 +3166,7 @@ int dummy; GC_proc_buf = bufp = new_buf; GC_proc_buf_size = new_size; } - if (syscall(SYS_read, GC_proc_fd, bufp, GC_proc_buf_size) <= 0) { + if (READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) { WARN("Insufficient space for /proc read\n", 0); /* Punt: */ memset(GC_grungy_pages, 0xff, sizeof (page_hash_table)); @@ -3429,6 +3504,8 @@ static void *GC_mprotect_thread(void *arg) { } msg; mach_msg_id_t id; + + GC_darwin_register_mach_handler_thread(mach_thread_self()); for(;;) { r = mach_msg( @@ -3886,13 +3963,15 @@ kern_return_t catch_exception_raise_state_identity( #endif /* NEED_CALLINFO */ +#if defined(GC_HAVE_BUILTIN_BACKTRACE) +# include +#endif + #ifdef SAVE_CALL_CHAIN #if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \ && defined(GC_HAVE_BUILTIN_BACKTRACE) -#include - void GC_save_callers (info) struct callinfo info[NFRAMES]; { @@ -3968,6 +4047,8 @@ struct callinfo info[NFRAMES]; static int reentry_count = 0; GC_bool stop = FALSE; + /* FIXME: This should probably use a different lock, so that we */ + /* become callable with or without the allocation lock. */ LOCK(); ++reentry_count; UNLOCK(); @@ -4002,7 +4083,8 @@ struct callinfo info[NFRAMES]; # ifdef LINUX FILE *pipe; # endif -# if defined(GC_HAVE_BUILTIN_BACKTRACE) +# if defined(GC_HAVE_BUILTIN_BACKTRACE) \ + && !defined(GC_BACKTRACE_SYMBOLS_BROKEN) char **sym_name = backtrace_symbols((void **)(&(info[i].ci_pc)), 1); char *name = sym_name[0]; @@ -4021,6 +4103,9 @@ struct callinfo info[NFRAMES]; # define RESULT_SZ 200 static char result_buf[RESULT_SZ]; size_t result_len; + char *old_preload; +# define PRELOAD_SZ 200 + char preload_buf[PRELOAD_SZ]; static GC_bool found_exe_name = FALSE; static GC_bool will_fail = FALSE; int ret_code; @@ -4042,7 +4127,20 @@ struct callinfo info[NFRAMES]; /* isn't time critical. */ sprintf(cmd_buf, "/usr/bin/addr2line -f -e %s 0x%lx", exe_name, (unsigned long)info[i].ci_pc); + old_preload = getenv ("LD_PRELOAD"); + if (0 != old_preload) { + if (strlen (old_preload) >= PRELOAD_SZ) { + will_fail = TRUE; + goto out; + } + strcpy (preload_buf, old_preload); + unsetenv ("LD_PRELOAD"); + } pipe = popen(cmd_buf, "r"); + if (0 != old_preload + && 0 != setenv ("LD_PRELOAD", preload_buf, 0)) { + WARN("Failed to reset LD_PRELOAD\n", 0); + } if (pipe == NULL || (result_len = fread(result_buf, 1, RESULT_SZ - 1, pipe)) == 0) { @@ -4079,7 +4177,8 @@ struct callinfo info[NFRAMES]; } # endif /* LINUX */ GC_err_printf1("\t\t%s\n", name); -# if defined(GC_HAVE_BUILTIN_BACKTRACE) +# if defined(GC_HAVE_BUILTIN_BACKTRACE) \ + && !defined(GC_BACKTRACE_SYMBOLS_BROKEN) free(sym_name); /* May call GC_free; that's OK */ # endif } diff --git a/boehm-gc/pthread_support.c b/boehm-gc/pthread_support.c index 5bb157f8b3f..2a3b91917c7 100644 --- a/boehm-gc/pthread_support.c +++ b/boehm-gc/pthread_support.c @@ -47,6 +47,7 @@ /*#define DEBUG_THREADS 1*/ /*#define GC_ASSERTIONS*/ +# include "gc.h" # include "private/pthread_support.h" # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ diff --git a/boehm-gc/solaris_pthreads.c b/boehm-gc/solaris_pthreads.c index bae77193593..1e43d0904f9 100644 --- a/boehm-gc/solaris_pthreads.c +++ b/boehm-gc/solaris_pthreads.c @@ -16,8 +16,10 @@ * Modified by Peter C. for Solaris Posix Threads. */ -# if defined(GC_SOLARIS_PTHREADS) +# if defined(GC_SOLARIS_PTHREADS) || defined(GC_THREADS) # include "private/gc_priv.h" +# endif +# if defined(GC_SOLARIS_PTHREADS) # include # include # include diff --git a/boehm-gc/solaris_threads.c b/boehm-gc/solaris_threads.c index 5f05b19e008..0a07690a27a 100644 --- a/boehm-gc/solaris_threads.c +++ b/boehm-gc/solaris_threads.c @@ -16,9 +16,12 @@ */ /* Boehm, September 14, 1994 4:44 pm PDT */ -# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS) +# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS) \ + || defined(GC_THREADS) +# include "private/gc_priv.h" +# endif -# include "private/gc_priv.h" +# if defined(GC_SOLARIS_THREADS) || defined(GC_SOLARIS_PTHREADS) # include "private/solaris_threads.h" # include # include @@ -786,6 +789,7 @@ void GC_thr_init(void) { GC_thread t; thread_t tid; + int ret; if (GC_thr_initialized) return; @@ -803,9 +807,11 @@ void GC_thr_init(void) t = GC_new_thread(thr_self()); t -> stack_size = 0; t -> flags = DETACHED | CLIENT_OWNS_STACK; - if (thr_create(0 /* stack */, 0 /* stack_size */, GC_thr_daemon, - 0 /* arg */, THR_DETACHED | THR_DAEMON, - &tid /* thread_id */) != 0) { + ret = thr_create(0 /* stack */, 0 /* stack_size */, GC_thr_daemon, + 0 /* arg */, THR_DETACHED | THR_DAEMON, + &tid /* thread_id */); + if (ret != 0) { + GC_err_printf1("Thr_create returned %ld\n", ret); ABORT("Cant fork daemon"); } thr_setprio(tid, 126); diff --git a/boehm-gc/specific.c b/boehm-gc/specific.c index 2c40c2b44a2..f4e8aeed62c 100644 --- a/boehm-gc/specific.c +++ b/boehm-gc/specific.c @@ -11,11 +11,11 @@ * modified is included with the above copyright notice. */ -#if defined(GC_LINUX_THREADS) - #include "private/gc_priv.h" /* For GC_compare_and_exchange, GC_memory_barrier */ #include "private/specific.h" +#if defined(GC_LINUX_THREADS) + static tse invalid_tse = {INVALID_QTID, 0, 0, INVALID_THREADID}; /* A thread-specific data entry which will never */ /* appear valid to a reader. Used to fill in empty */ diff --git a/boehm-gc/tests/test.c b/boehm-gc/tests/test.c index cfe23c0efde..e1676aadead 100644 --- a/boehm-gc/tests/test.c +++ b/boehm-gc/tests/test.c @@ -208,7 +208,6 @@ sexpr y; #ifdef GC_GCJ_SUPPORT #include "gc_mark.h" -#include "private/dbg_mlc.h" /* For USR_PTR_FROM_BASE */ #include "gc_gcj.h" /* The following struct emulates the vtable in gcj. */ @@ -233,7 +232,7 @@ struct GC_ms_entry * fake_gcj_mark_proc(word * addr, sexpr x; if (1 == env) { /* Object allocated with debug allocator. */ - addr = (word *)USR_PTR_FROM_BASE(addr); + addr = (word *)GC_USR_PTR_FROM_BASE(addr); } x = (sexpr)(addr + 1); /* Skip the vtable pointer. */ mark_stack_ptr = GC_MARK_AND_PUSH( @@ -1256,9 +1255,11 @@ void run_one_test() FAIL; } if (!TEST_FAIL_COUNT(1)) { -# if!(defined(RS6000) || defined(POWERPC) || defined(IA64)) +# if!(defined(RS6000) || defined(POWERPC) || defined(IA64)) || defined(M68K) /* ON RS6000s function pointers point to a descriptor in the */ /* data segment, so there should have been no failures. */ + /* The same applies to IA64. Something similar seems to */ + /* be going on with NetBSD/M68K. */ (void)GC_printf0("GC_is_visible produced wrong failure indication\n"); FAIL; # endif @@ -1486,10 +1487,6 @@ void SetMinimumStack(long minSize) # endif n_tests = 0; -#if defined(__APPLE__) && defined(__MACH__) - GC_INIT(); -#endif - # if defined(DJGPP) /* No good way to determine stack base from library; do it */ /* manually on this platform. */ @@ -1501,7 +1498,7 @@ void SetMinimumStack(long minSize) /* Cheat and let stdio initialize toolbox for us. */ printf("Testing GC Macintosh port.\n"); # endif - GC_INIT(); /* Only needed if gc is dynamic library. */ + GC_INIT(); /* Only needed on a few platforms. */ (void) GC_set_warn_proc(warn_proc); # if (defined(MPROTECT_VDB) || defined(PROC_VDB)) \ && !defined(MAKE_BACK_GRAPH) @@ -1794,9 +1791,7 @@ main() (void)GC_printf0("pthread_default_stacksize_np failed.\n"); } # endif /* GC_HPUX_THREADS */ -# if defined(__APPLE__) && defined(__MACH__) - GC_INIT(); -# endif + GC_INIT(); pthread_attr_init(&attr); # if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS) \ diff --git a/boehm-gc/tests/test_cpp.cc b/boehm-gc/tests/test_cpp.cc index 7e50e8aa0fd..6661e411927 100644 --- a/boehm-gc/tests/test_cpp.cc +++ b/boehm-gc/tests/test_cpp.cc @@ -192,7 +192,7 @@ int APIENTRY WinMain( # endif #endif - GC_init(); + GC_INIT(); # if defined(MACOS) // MacOS char* argv_[] = {"test_cpp", "10"}; // doesn't diff --git a/boehm-gc/tests/trace_test.c b/boehm-gc/tests/trace_test.c index be9cb6ce6b6..870e38723a8 100644 --- a/boehm-gc/tests/trace_test.c +++ b/boehm-gc/tests/trace_test.c @@ -10,6 +10,7 @@ struct treenode { struct treenode * mktree(int i) { struct treenode * r = GC_MALLOC(sizeof(struct treenode)); if (0 == i) return 0; + if (1 == i) r = GC_MALLOC_ATOMIC(sizeof(struct treenode)); r -> x = mktree(i-1); r -> y = mktree(i-1); return r; diff --git a/boehm-gc/threadlibs.c b/boehm-gc/threadlibs.c index 247d3c652ec..264b7240cbe 100644 --- a/boehm-gc/threadlibs.c +++ b/boehm-gc/threadlibs.c @@ -1,3 +1,4 @@ +# include "gc_config_macros.h" # include "private/gcconfig.h" # include diff --git a/boehm-gc/typd_mlc.c b/boehm-gc/typd_mlc.c index a081c9797c3..373257cd260 100644 --- a/boehm-gc/typd_mlc.c +++ b/boehm-gc/typd_mlc.c @@ -348,8 +348,6 @@ mse * GC_array_mark_proc GC_PROTO((register word * addr, mse * mark_stack_limit, word env)); -GC_descr GC_generic_array_descr; - /* Caller does not hold allocation lock. */ void GC_init_explicit_typing() { @@ -370,47 +368,25 @@ void GC_init_explicit_typing() } GC_explicit_typing_initialized = TRUE; /* Set up object kind with simple indirect descriptor. */ - GC_eobjfreelist = (ptr_t *) - GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); - if (GC_eobjfreelist == 0) ABORT("Couldn't allocate GC_eobjfreelist"); - BZERO(GC_eobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); - GC_explicit_kind = GC_n_kinds++; - GC_obj_kinds[GC_explicit_kind].ok_freelist = GC_eobjfreelist; - GC_obj_kinds[GC_explicit_kind].ok_reclaim_list = 0; - GC_obj_kinds[GC_explicit_kind].ok_descriptor = - (((word)WORDS_TO_BYTES(-1)) | GC_DS_PER_OBJECT); - GC_obj_kinds[GC_explicit_kind].ok_relocate_descr = TRUE; - GC_obj_kinds[GC_explicit_kind].ok_init = TRUE; + GC_eobjfreelist = (ptr_t *)GC_new_free_list_inner(); + GC_explicit_kind = GC_new_kind_inner( + (void **)GC_eobjfreelist, + (((word)WORDS_TO_BYTES(-1)) | GC_DS_PER_OBJECT), + TRUE, TRUE); /* Descriptors are in the last word of the object. */ - GC_typed_mark_proc_index = GC_n_mark_procs; - GC_mark_procs[GC_typed_mark_proc_index] = GC_typed_mark_proc; - GC_n_mark_procs++; - /* Moving this up breaks DEC AXP compiler. */ + GC_typed_mark_proc_index = GC_new_proc_inner(GC_typed_mark_proc); /* Set up object kind with array descriptor. */ - GC_arobjfreelist = (ptr_t *) - GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); - if (GC_arobjfreelist == 0) ABORT("Couldn't allocate GC_arobjfreelist"); - BZERO(GC_arobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); - if (GC_n_mark_procs >= MAX_MARK_PROCS) - ABORT("No slot for array mark proc"); - GC_array_mark_proc_index = GC_n_mark_procs++; - if (GC_n_kinds >= MAXOBJKINDS) - ABORT("No kind available for array objects"); - GC_array_kind = GC_n_kinds++; - GC_obj_kinds[GC_array_kind].ok_freelist = GC_arobjfreelist; - GC_obj_kinds[GC_array_kind].ok_reclaim_list = 0; - GC_obj_kinds[GC_array_kind].ok_descriptor = - GC_MAKE_PROC(GC_array_mark_proc_index, 0);; - GC_obj_kinds[GC_array_kind].ok_relocate_descr = FALSE; - GC_obj_kinds[GC_array_kind].ok_init = TRUE; - /* Descriptors are in the last word of the object. */ - GC_mark_procs[GC_array_mark_proc_index] = GC_array_mark_proc; + GC_arobjfreelist = (ptr_t *)GC_new_free_list_inner(); + GC_array_mark_proc_index = GC_new_proc_inner(GC_array_mark_proc); + GC_array_kind = GC_new_kind_inner( + (void **)GC_arobjfreelist, + GC_MAKE_PROC(GC_array_mark_proc_index, 0), + FALSE, TRUE); for (i = 0; i < WORDSZ/2; i++) { GC_descr d = (((word)(-1)) >> (WORDSZ - i)) << (WORDSZ - i); d |= GC_DS_BITMAP; GC_bm_table[i] = d; } - GC_generic_array_descr = GC_MAKE_PROC(GC_array_mark_proc_index, 0); UNLOCK(); ENABLE_SIGNALS(); } diff --git a/boehm-gc/version.h b/boehm-gc/version.h index 9d858b2aaa6..93000c34e16 100644 --- a/boehm-gc/version.h +++ b/boehm-gc/version.h @@ -3,7 +3,7 @@ /* it to keep the old-style build process working. */ #define GC_TMP_VERSION_MAJOR 6 #define GC_TMP_VERSION_MINOR 3 -#define GC_TMP_ALPHA_VERSION 1 +#define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA #ifndef GC_NOT_ALPHA # define GC_NOT_ALPHA 0xff @@ -14,7 +14,7 @@ GC_TMP_VERSION_MINOR != GC_VERSION_MINOR || \ defined(GC_ALPHA_VERSION) != (GC_TMP_ALPHA_VERSION != GC_NOT_ALPHA) || \ defined(GC_ALPHA_VERSION) && GC_TMP_ALPHA_VERSION != GC_ALPHA_VERSION -# error Inconsistent version info. Check version.h and configure.in. +# error Inconsistent version info. Check README, version.h, and configure.in. # endif #else # define GC_VERSION_MAJOR GC_TMP_VERSION_MAJOR diff --git a/boehm-gc/win32_threads.c b/boehm-gc/win32_threads.c index 7a1dbe27cd2..d2e97dee7d0 100644 --- a/boehm-gc/win32_threads.c +++ b/boehm-gc/win32_threads.c @@ -130,7 +130,7 @@ static GC_thread GC_new_thread(void) { ABORT("DuplicateHandle failed"); } thread_table[i].stack_base = GC_get_stack_base(); - /* Up until this point, GC_psuh_all_stacks considers this thread */ + /* Up until this point, GC_push_all_stacks considers this thread */ /* invalid. */ if (thread_table[i].stack_base == NULL) ABORT("Failed to find stack base in GC_new_thread"); diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 71938837faa..6a73f1bf365 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,10 @@ +2004-08-13 Bryce McKinlay + + * configure.in (GCINCS): Don't use "boehm-cflags". Instead, -I + boehm-gc's include dirs. + * configure: Rebuilt. + * include/boehm-gc.h: Include gc_config.h. + 2004-08-13 Bryce McKinlay * java/net/InetAddress.java (loopbackAddress): Renamed from diff --git a/libjava/configure b/libjava/configure index 9aab57a2d9a..79926dd4737 100755 --- a/libjava/configure +++ b/libjava/configure @@ -7481,10 +7481,7 @@ echo "${ECHO_T}boehm" >&6 GCLIBS=../boehm-gc/libgcjgc_convenience.la JC1GCSPEC='-fuse-boehm-gc' GCTESTSPEC="-L`${PWDCMD-pwd}`/../boehm-gc/.libs -rpath `${PWDCMD-pwd}`/../boehm-gc/.libs" - - # We also want to pick up some cpp flags required when including - # boehm-config.h. Yuck. - GCINCS="`cat ../boehm-gc/boehm-cflags`" + GCINCS='-I$(top_srcdir)/../boehm-gc/include -I../boehm-gc/include' GCOBJS=boehm.lo GCHDR=boehm-gc.h # The POSIX thread support needs to know this. diff --git a/libjava/configure.in b/libjava/configure.in index 427e21e3d6e..fcc7094128c 100644 --- a/libjava/configure.in +++ b/libjava/configure.in @@ -579,11 +579,8 @@ case "$GC" in GCLIBS=../boehm-gc/libgcjgc_convenience.la JC1GCSPEC='-fuse-boehm-gc' GCTESTSPEC="-L`${PWDCMD-pwd}`/../boehm-gc/.libs -rpath `${PWDCMD-pwd}`/../boehm-gc/.libs" - - # We also want to pick up some cpp flags required when including - # boehm-config.h. Yuck. - GCINCS="`cat ../boehm-gc/boehm-cflags`" - GCOBJS=boehm.lo + GCINCS='-I$(top_srcdir)/../boehm-gc/include -I../boehm-gc/include' + GCOBJS=boehm.lo GCHDR=boehm-gc.h # The POSIX thread support needs to know this. AC_DEFINE(HAVE_BOEHM_GC, 1, [Define if Boehm GC in use.]) diff --git a/libjava/include/boehm-gc.h b/libjava/include/boehm-gc.h index 509900c737c..4e0065f5bb2 100644 --- a/libjava/include/boehm-gc.h +++ b/libjava/include/boehm-gc.h @@ -26,6 +26,8 @@ extern "C" #include #include +#include + extern "C" void * GC_gcj_malloc(size_t, void *); extern "C" void * GC_malloc_atomic(size_t); #ifdef THREAD_LOCAL_ALLOC -- 2.30.2