configure.in (GCINCS): Don't use "boehm-cflags".

libjava:
2004-08-13  Bryce McKinlay  <mckinlay@redhat.com>

	* 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  <mckinlay@redhat.com>

	* 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 <gc_config.h>.

2004-08-13  Bryce McKinlay  <mckinlay@redhat.com>

	Import Boehm GC version 6.3.

From-SVN: r85972
This commit is contained in:
Bryce McKinlay 2004-08-13 23:05:36 +00:00 committed by Bryce McKinlay
parent f13bb1997a
commit 4109fe8594
69 changed files with 2217 additions and 776 deletions

View File

@ -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) @&&|

View File

@ -1,3 +1,19 @@
2004-08-13 Bryce McKinlay <mckinlay@redhat.com>
* 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 <gc_config.h>.
2004-08-13 Bryce McKinlay <mckinlay@redhat.com>
Import Boehm GC version 6.3.
2004-08-12 Kelley Cook <kcook@gcc.gnu.org>
* include/Makefile.in: Regenerate

View File

@ -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 \

View File

@ -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=<n> 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)

View File

@ -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

View File

@ -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:

View File

@ -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 <ntwin32.mak>
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

178
boehm-gc/aclocal.m4 vendored
View File

@ -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 <conftest.tar])
grep GrepMe conftest.dir/file >/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])

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

424
boehm-gc/configure vendored
View File

@ -309,7 +309,7 @@ ac_includes_default="\
# include <unistd.h>
#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 <<CEOF' >>$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 <<CEOF' >>$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

View File

@ -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

View File

@ -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;

View File

@ -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 <string.h>
# include <stdio.h>
@ -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();

View File

@ -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);
}
}

View File

@ -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];

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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=<bytes> - 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=<n> - 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[=<n>] - (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:

View File

@ -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.

View File

@ -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.)

View File

@ -47,6 +47,10 @@ The garbage collector generates warning messages of the form
<PRE>
Needed to allocate blacklisted block at 0x...
</pre>
or
<PRE>
Repeated allocation of very large block ...
</pre>
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
(<I>e.g.</i> 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.
<LI> 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.
<LI> 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 <TT>gc_typed.h</tt>, or separate out the pointerfree component.
<LI> Consider using <TT>GC_malloc_ignore_off_page()</tt>
to allocate large objects. (See <TT>gc.h</tt> and above for details.
Large means &gt; 100K in most environments.)
<LI> 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.
<LI> 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.
</ol>
<H2>Prematurely Reclaimed Objects</h2>
The usual symptom of this is a segmentation fault, or an obviously overwritten

View File

@ -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.

View File

@ -4,7 +4,7 @@
<AUTHOR> Hans-J. Boehm, HP Labs (Much of this was written at SGI)</author>
</HEAD>
<BODY>
<H1> <I>This is under construction</i> </h1>
<H1> <I>This is under construction, and may always be.</i> </h1>
<H1> Conservative GC Algorithmic Overview </h1>
<P>
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.
<H2> Introduction </h2>
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:
<OL>
<LI>
<I>Preparation</i> Clear all mark bits, indicating that all objects
<I>Preparation</i> Each object has an associated mark bit.
Clear all mark bits, indicating that all objects
are potentially unreachable.
<LI>
<I>Mark phase</i> 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 (<TT>STUBBORN</tt>) 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: <TT>NORMAL</tt> and <TT>PTRFREE</tt> objects.
The <A HREF="http://gcc.gnu.org/java">gcj</a> runtime also makes
heavy use of a kind (allocated with GC_gcj_malloc) that stores
type information at a known offset in method tables.
<P>
The collector uses a two level allocator. A large block is defined to
be one larger than half of <TT>HBLKSIZE</tt>, which is a power of 2,
@ -175,6 +181,32 @@ for a single pool of physical memory.
<H2>Mark phase</h2>
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
<I>root segments</i> for pointers:
<UL>
<LI>The registers. Depending on the architecture, this may be done using
assembly code, or by calling a <TT>setjmp</tt>-like function which saves
register contents on the stack.
<LI>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 <TT>GC_stackbottom</tt>. (For Itanium, the register stack
scanned separately.) The <TT>GC_stackbottom</tt> variable is set in
a highly platform-specific way depending on the appropriate configuration
information in <TT>gcconfig.h</tt>. 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.
<LI>Static data region(s). In the simplest case, this is the region
between <TT>DATASTART</tt> and <TT>DATAEND</tt>, as defined in
<TT>gcconfig.h</tt>. 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 <TT>dyn_load.c</tt>.
</ul>
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 <TT>gc_mark.h</tt>.)
<P>
At the beginning of the mark phase, all root segments are pushed on the
stack by <TT>GC_push_roots</tt>. If <TT>ALL_INTERIOR_PTRS</tt> is not
At the beginning of the mark phase, all root segments
(as described above) are pushed on the
stack by <TT>GC_push_roots</tt>. (Registers and eagerly processed
stack sections are processed by pushing the referenced objects instead
of the stack section itself.) If <TT>ALL_INTERIOR_PTRS</tt> is not
defined, then stack roots require special treatment. In this case, the
normal marking code ignores interior pointers, but <TT>GC_push_all_stack</tt>
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.
<P>
In particular, it is very difficult for the collector to stop all other
@ -510,6 +546,10 @@ accomplished with <TT># define</tt>'s in <TT>gc.h</tt>
(really <TT>gc_pthread_redirects.h</tt>), or optionally
by using ld's function call wrapping mechanism under Linux.
<P>
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 <A HREF="scale.html">here</a>.
<P>
Comments are appreciated. Please send mail to
<A HREF="mailto:boehm@acm.org"><TT>boehm@acm.org</tt></a> or
<A HREF="mailto:Hans.Boehm@hp.com"><TT>Hans.Boehm@hp.com</tt></a>

View File

@ -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 <mach-o/dyld.h>
#undef __private_extern__
# define __private_extern__ extern
# include <mach-o/dyld.h>
# undef __private_extern__
#else
#include <mach-o/dyld.h>
# include <mach-o/dyld.h>
#endif
#include <mach-o/getsect.h>

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -4,6 +4,9 @@
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
#ifdef __DJGPP__
#include <dirent.h>
#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);

View File

@ -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"

View File

@ -30,6 +30,7 @@
# define _GC_H
# include <gc_config.h>
# 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 <features.h>
# 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) \

View File

@ -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

View File

@ -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) \

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -393,12 +393,12 @@ __STL_END_NAMESPACE
__STL_BEGIN_NAMESPACE
template <class _T>
struct _Alloc_traits<_T, gc_alloc >
template <class _Tp>
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 <class _T>
struct _Alloc_traits<_T, single_client_gc_alloc >
template <class _Tp>
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 <class _T>
struct _Alloc_traits<_T, traceable_alloc >
template <class _Tp>
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 <class _T>
struct _Alloc_traits<_T, single_client_traceable_alloc >
template <class _Tp>
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&,

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 <unistd.h>
# 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 <ia64intrin.h>
# 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. */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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)) \

View File

@ -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. */

View File

@ -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 */

View File

@ -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;

View File

@ -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()

View File

@ -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

View File

@ -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 <setjmp.h>
#endif
@ -111,25 +117,30 @@
# include <sys/uio.h>
# include <malloc.h> /* for locking */
#endif
#ifdef USE_MMAP
#if defined(USE_MMAP) || defined(USE_MUNMAP)
# ifndef USE_MMAP
--> USE_MUNMAP requires USE_MMAP
# endif
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/stat.h>
# include <errno.h>
#endif
#ifdef UNIX_LIKE
# include <fcntl.h>
#endif
#if defined(SUNOS5SIGS) || defined (HURD) || defined(LINUX)
# ifdef SUNOS5SIGS
# if defined(SUNOS5SIGS) && !defined(FREEBSD)
# include <sys/siginfo.h>
# 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;
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 */
/* 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;
/* 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. */
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_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 <sys/param.h>
#include <sys/pstat.h>
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 <sys/types.h>
@ -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 <errno.h>
@ -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 <sys/procfs.h>
#include <sys/stat.h>
#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 <execinfo.h>
#endif
#ifdef SAVE_CALL_CHAIN
#if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \
&& defined(GC_HAVE_BUILTIN_BACKTRACE)
#include <execinfo.h>
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
}

View File

@ -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) \

View File

@ -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 <pthread.h>
# include <thread.h>
# include <signal.h>

View File

@ -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 <thread.h>
# include <synch.h>
@ -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);

View File

@ -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 */

View File

@ -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) \

View File

@ -192,7 +192,7 @@ int APIENTRY WinMain(
# endif
#endif
GC_init();
GC_INIT();
# if defined(MACOS) // MacOS
char* argv_[] = {"test_cpp", "10"}; // doesn't

View File

@ -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;

View File

@ -1,3 +1,4 @@
# include "gc_config_macros.h"
# include "private/gcconfig.h"
# include <stdio.h>

View File

@ -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();
}

View File

@ -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

View File

@ -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");

View File

@ -1,3 +1,10 @@
2004-08-13 Bryce McKinlay <mckinlay@redhat.com>
* 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 <mckinlay@redhat.com>
* java/net/InetAddress.java (loopbackAddress): Renamed from

5
libjava/configure vendored
View File

@ -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.

View File

@ -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.])

View File

@ -26,6 +26,8 @@ extern "C"
#include <java/lang/Class.h>
#include <string.h>
#include <gc_config.h>
extern "C" void * GC_gcj_malloc(size_t, void *);
extern "C" void * GC_malloc_atomic(size_t);
#ifdef THREAD_LOCAL_ALLOC