OSDN Git Service

Import GC 6.3alpha1.
authorjsturm <jsturm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Jul 2003 04:18:23 +0000 (04:18 +0000)
committerjsturm <jsturm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Jul 2003 04:18:23 +0000 (04:18 +0000)
* BCC_MAKEFILE: Merge with GC 6.3alpha1 release.
* ChangeLog: Likewise.
* Makefile.am: Likewise.
* Makefile.direct: Likewise.
* Makefile.dj: Likewise.
* allchblk.c: Likewise.
* alloc.c: Likewise.
* backgraph.c: Likewise.
* configure.host: Likewise.
* configure.in: Likewise.
* dbg_mlc.c: Likewise.
* dyn_load.c: Likewise.
* finalize.c: Likewise.
* gc_cpp.cc: Likewise.
* gc_dlopen.c: Likewise.
* gcj_mlc.c: Likewise.
* if_mach.c: Likewise.
* mach_dep.c: Likewise.
* malloc.c: Likewise.
* mallocx.c: Likewise.
* mark.c: Likewise.
* mark_rts.c: Likewise.
* misc.c: Likewise.
* os_dep.c: Likewise.
* ptr_chck.c: Likewise.
* reclaim.c: Likewise.
* solaris_pthreads.c: Likewise.
* solaris_threads.c: Likewise.
* sparc_mach_dep.S: Likewise.
* threadlibs.c: Likewise.
* typd_mlc.c: Likewise.
* version.h: Likewise.
* win32_threads.c: Likewise.
* Mac_files/MacOS_Test_config.h: Likewise.
* Mac_files/MacOS_config.h: Likewise.
* cord/cordbscs.c: Likewise.
* cord/cordprnt.c: Likewise.
* cord/de_win.c: Likewise.
* doc/README: Likewise.
* doc/README.MacOSX: Likewise.
* doc/README.changes: Likewise.
* doc/README.environment: Likewise.
* doc/README.ews4800: Likewise.
* doc/README.linux: Likewise.
* doc/README.macros: Likewise.
* doc/README.win32: Likewise.
* doc/debugging.html: Likewise.
* doc/gcdescr.html: Likewise.
* doc/tree.html: Likewise.
* include/Makefile.in: Likewise.
* include/gc.h: Likewise.
* include/gc_cpp.h: Likewise.
* include/gc_local_alloc.h: Likewise.
* include/gc_mark.h: Likewise.
* include/gc_pthread_redirects.h: Likewise.
* include/gc_typed.h: Likewise.
* include/new_gc_alloc.h: Likewise.
* include/private/dbg_mlc.h: Likewise.
* include/private/gc_hdrs.h: Likewise.
* include/private/gc_locks.h: Likewise.
* include/private/gc_pmark.h: Likewise.
* include/private/gc_priv.h: Likewise.
* include/private/gcconfig.h: Likewise.
* include/private/solaris_threads.h: Likewise.
* include/private/specific.h: Likewise.
* tests/test.c: Likewise.
* tests/test_cpp.cc: Likewise.

* configure: Rebuild.
* Makefile.in: Rebuild.

* mips_sgi_mach_dep.s: Add.

* alpha_mach_dep.s: Remove.
* irix_threads.c: Remove.
* linux_threads.c: Remove.
* mips_sgi_mach_dep.S: Remove.
* missing: Remove.
* powerpc_macosx_mach_dep.s: Remove.
* doc/Makefile.am: Remove.
* doc/Makefile.in: Remove.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69880 138bc75d-0d04-0410-961f-82ee72b054a4

72 files changed:
boehm-gc/BCC_MAKEFILE
boehm-gc/ChangeLog
boehm-gc/Mac_files/MacOS_Test_config.h
boehm-gc/Mac_files/MacOS_config.h
boehm-gc/Makefile.am
boehm-gc/Makefile.direct
boehm-gc/Makefile.dj
boehm-gc/Makefile.in
boehm-gc/allchblk.c
boehm-gc/alloc.c
boehm-gc/alpha_mach_dep.s [deleted file]
boehm-gc/configure
boehm-gc/configure.host
boehm-gc/configure.in
boehm-gc/cord/cordbscs.c
boehm-gc/cord/cordprnt.c
boehm-gc/cord/de_win.c
boehm-gc/dbg_mlc.c
boehm-gc/doc/Makefile.am [deleted file]
boehm-gc/doc/Makefile.in [deleted file]
boehm-gc/doc/README
boehm-gc/doc/README.MacOSX
boehm-gc/doc/README.changes
boehm-gc/doc/README.environment
boehm-gc/doc/README.linux
boehm-gc/doc/README.win32
boehm-gc/doc/debugging.html
boehm-gc/dyn_load.c
boehm-gc/finalize.c
boehm-gc/gc_cpp.cc
boehm-gc/gc_dlopen.c
boehm-gc/gcj_mlc.c
boehm-gc/if_mach.c
boehm-gc/include/Makefile.in
boehm-gc/include/gc.h
boehm-gc/include/gc_cpp.h
boehm-gc/include/gc_local_alloc.h
boehm-gc/include/gc_mark.h
boehm-gc/include/gc_pthread_redirects.h
boehm-gc/include/gc_typed.h
boehm-gc/include/new_gc_alloc.h
boehm-gc/include/private/dbg_mlc.h
boehm-gc/include/private/gc_hdrs.h
boehm-gc/include/private/gc_locks.h
boehm-gc/include/private/gc_pmark.h
boehm-gc/include/private/gc_priv.h
boehm-gc/include/private/gcconfig.h
boehm-gc/include/private/solaris_threads.h
boehm-gc/include/private/specific.h
boehm-gc/irix_threads.c [deleted file]
boehm-gc/linux_threads.c [deleted file]
boehm-gc/mach_dep.c
boehm-gc/malloc.c
boehm-gc/mallocx.c
boehm-gc/mark.c
boehm-gc/mark_rts.c
boehm-gc/mips_sgi_mach_dep.s [moved from boehm-gc/mips_sgi_mach_dep.S with 74% similarity]
boehm-gc/misc.c
boehm-gc/missing [deleted file]
boehm-gc/os_dep.c
boehm-gc/powerpc_macosx_mach_dep.s [deleted file]
boehm-gc/ptr_chck.c
boehm-gc/reclaim.c
boehm-gc/solaris_pthreads.c
boehm-gc/solaris_threads.c
boehm-gc/sparc_mach_dep.S
boehm-gc/tests/test.c
boehm-gc/tests/test_cpp.cc
boehm-gc/threadlibs.c
boehm-gc/typd_mlc.c
boehm-gc/version.h
boehm-gc/win32_threads.c

index a8e0682..3f86ed5 100644 (file)
@@ -1,29 +1,31 @@
-# Makefile for Borland C++ 4.5 on NT\r
-# For Borland 5.0, replace bc45 by bc5.\r
+# Makefile for Borland C++ 5.5 on NT\r
 # If you have the Borland assembler, remove "-DUSE_GENERIC"\r
 #\r
-bc=        c:\bc45\r
-bcbin=     $(bc)\bin\r
-bclib=     $(bc)\lib\r
+bc=       c:\Borland\BCC55\r
+bcbin=    $(bc)\bin\r
+bclib=    $(bc)\lib\r
 bcinclude= $(bc)\include\r
 \r
-cc=      $(bcbin)\bcc32\r
-rc=      $(bcbin)\brc32\r
-lib=     $(bcbin)\tlib\r
-link=    $(bcbin)\tlink32\r
-cflags=  -R -v -vi -H -H=gc.csm -I$(bcinclude);cord -L$(bclib) \\r
-         -w-pro -w-aus -w-par -w-ccc -w-rch -a4 -D__STDC__=0\r
+gcinclude1 = $(bc)\gc6.2\include\r
+gcinclude2 = $(bc)\gc6.2\cord\r
+\r
+cc=     $(bcbin)\bcc32\r
+rc=     $(bcbin)\brc32\r
+lib=    $(bcbin)\tlib\r
+link=   $(bcbin)\ilink32\r
+cflags=  -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude1);$(gcinclude2) -L$(bclib) \\r
+        -w-pro -w-aus -w-par -w-ccc -w-rch -a4 -D__STDC__=0\r
 #defines= -DSILENT\r
-defines= -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS -DUSE_GENERIC\r
+defines= -DSMALL_CONFIG -DSILENT -DALL_INTERIOR_POINTERS -DUSE_GENERIC -DNO_GETENV -DJAVA_FINALIZATION -DGC_OPERATOR_NEW_ARRAY\r
 \r
 .c.obj:\r
        $(cc) @&&|\r
-        $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c\r
+       $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c\r
 |\r
 \r
 .cpp.obj:\r
        $(cc) @&&|\r
-        $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp\r
+       $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp\r
 |\r
 \r
 .rc.res:\r
@@ -39,31 +41,31 @@ OBJS= $(XXXOBJS:XXX=)
 \r
 all: gctest.exe cord\de.exe test_cpp.exe\r
 \r
-$(OBJS) test.obj: gc_priv.h gc_hdrs.h gc.h gcconfig.h MAKEFILE\r
+$(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h MAKEFILE\r
 \r
 gc.lib: $(OBJS)\r
-    -del gc.lib\r
-       tlib $* @&&|\r
-        $(XXXOBJS:XXX=+)\r
+       del gc.lib\r
+       $(lib) $* @&&|\r
+       $(XXXOBJS:XXX=+)\r
 |\r
 \r
 gctest.exe: tests\test.obj gc.lib\r
     $(cc) @&&|\r
-        $(cflags) -W -e$* tests\test.obj gc.lib\r
+       $(cflags) -W -e$* tests\test.obj gc.lib\r
 |\r
 \r
-cord\de.obj cord\de_win.obj: cord\cord.h cord\private\cord_pos.h cord\de_win.h \\r
+cord\de.obj cord\de_win.obj: include\cord.h include\private\cord_pos.h cord\de_win.h \\r
     cord\de_cmds.h\r
 \r
 cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj \\r
-        cord\de_win.res gc.lib\r
+       cord\de_win.res gc.lib\r
        $(cc) @&&|\r
-        $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \\r
-        cord\de.obj cord\de_win.obj gc.lib\r
+       $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \\r
+       cord\de.obj cord\de_win.obj gc.lib\r
 |\r
     $(rc) cord\de_win.res cord\de.exe\r
 \r
-gc_cpp.obj: gc_cpp.h gc.h\r
+gc_cpp.obj: include\gc_cpp.h include\gc.h\r
 \r
 gc_cpp.cpp: gc_cpp.cc\r
        copy gc_cpp.cc gc_cpp.cpp\r
@@ -71,12 +73,16 @@ gc_cpp.cpp: gc_cpp.cc
 test_cpp.cpp: tests\test_cpp.cc\r
        copy tests\test_cpp.cc test_cpp.cpp\r
 \r
-test_cpp.exe: test_cpp.obj gc_cpp.h gc.h gc.lib\r
+test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib\r
     $(cc) @&&|\r
-        $(cflags) -W -e$* test_cpp.obj gc.lib\r
+       $(cflags) -W -e$* test_cpp.obj gc.lib\r
 |\r
 \r
 scratch:\r
     -del *.obj *.res *.exe *.csm cord\*.obj cord\*.res cord\*.exe cord\*.csm\r
 \r
+clean:\r
+      del gc.lib\r
+      del *.obj\r
+      del tests\test.obj\r
 \r
index 91acf27..afb1ce9 100644 (file)
@@ -1,3 +1,88 @@
+2003-07-28  Jeff Sturm  <jsturm@one-point.com>
+
+       Import GC 6.3alpha1.
+       * BCC_MAKEFILE: Merge with GC 6.3alpha1 release.
+       * ChangeLog: Likewise.
+       * Makefile.am: Likewise.
+       * Makefile.direct: Likewise.
+       * Makefile.dj: Likewise.
+       * allchblk.c: Likewise.
+       * alloc.c: Likewise.
+       * backgraph.c: Likewise.
+       * configure.host: Likewise.
+       * configure.in: Likewise.
+       * dbg_mlc.c: Likewise.
+       * dyn_load.c: Likewise.
+       * finalize.c: Likewise.
+       * gc_cpp.cc: Likewise.
+       * gc_dlopen.c: Likewise.
+       * gcj_mlc.c: Likewise.
+       * if_mach.c: Likewise.
+       * mach_dep.c: Likewise.
+       * malloc.c: Likewise.
+       * mallocx.c: Likewise.
+       * mark.c: Likewise.
+       * mark_rts.c: Likewise.
+       * misc.c: Likewise.
+       * os_dep.c: Likewise.
+       * ptr_chck.c: Likewise.
+       * reclaim.c: Likewise.
+       * solaris_pthreads.c: Likewise.
+       * solaris_threads.c: Likewise.
+       * sparc_mach_dep.S: Likewise.
+       * threadlibs.c: Likewise.
+       * typd_mlc.c: Likewise.
+       * version.h: Likewise.
+       * win32_threads.c: Likewise.
+       * Mac_files/MacOS_Test_config.h: Likewise.
+       * Mac_files/MacOS_config.h: Likewise.
+       * cord/cordbscs.c: Likewise.
+       * cord/cordprnt.c: Likewise.
+       * cord/de_win.c: Likewise.
+       * doc/README: Likewise.
+       * doc/README.MacOSX: Likewise.
+       * doc/README.changes: Likewise.
+       * doc/README.environment: Likewise.
+       * doc/README.ews4800: Likewise.
+       * doc/README.linux: Likewise.
+       * doc/README.macros: Likewise.
+       * doc/README.win32: Likewise.
+       * doc/debugging.html: Likewise.
+       * doc/gcdescr.html: Likewise.
+       * doc/tree.html: Likewise.
+       * include/Makefile.in: Likewise.
+       * include/gc.h: Likewise.
+       * include/gc_cpp.h: Likewise.
+       * include/gc_local_alloc.h: Likewise.
+       * include/gc_mark.h: Likewise.
+       * include/gc_pthread_redirects.h: Likewise.
+       * include/gc_typed.h: Likewise.
+       * include/new_gc_alloc.h: Likewise.
+       * include/private/dbg_mlc.h: Likewise.
+       * include/private/gc_hdrs.h: Likewise.
+       * include/private/gc_locks.h: Likewise.
+       * include/private/gc_pmark.h: Likewise.
+       * include/private/gc_priv.h: Likewise.
+       * include/private/gcconfig.h: Likewise.
+       * include/private/solaris_threads.h: Likewise.
+       * include/private/specific.h: Likewise.
+       * tests/test.c: Likewise.
+       * tests/test_cpp.cc: Likewise.
+       
+       * configure: Rebuild.
+       * Makefile.in: Rebuild.
+       
+       * mips_sgi_mach_dep.s: Add.
+       
+       * alpha_mach_dep.s: Remove.
+       * irix_threads.c: Remove.
+       * linux_threads.c: Remove.
+       * mips_sgi_mach_dep.S: Remove.
+       * missing: Remove.
+       * powerpc_macosx_mach_dep.s: Remove.
+       * doc/Makefile.am: Remove.
+       * doc/Makefile.in: Remove.
+
 2003-07-25  Roger Sayle  <roger@eyesopen.com>
 
        * configure.host: Only use +ESdbgasm when using the HPUX native
index c95f4bb..4e5d252 100644 (file)
@@ -74,7 +74,7 @@
 //   implementations, and it sometimes has a significant performance
 //   impact.  However, it is dangerous for many not-quite-ANSI C
 //   programs that call things like printf in asynchronous signal handlers.
-// -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the
+// -DGC_OPERATOR_NEW_ARRAY declares that the C++ compiler supports 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.
index 93c3c97..407bdf1 100644 (file)
@@ -72,7 +72,7 @@
 //   implementations, and it sometimes has a significant performance
 //   impact.  However, it is dangerous for many not-quite-ANSI C
 //   programs that call things like printf in asynchronous signal handlers.
-// -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the
+// -DGC_OPERATOR_NEW_ARRAY declares that the C++ compiler supports 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.
@@ -86,4 +86,4 @@
 //   since some ports use malloc or calloc to obtain system memory.
 //   (Probably works for UNIX, and win32.)
 // -DNO_DEBUG removes GC_dump and the debugging routines it calls.
-//   Reduces code size slightly at the expense of debuggability.
\ No newline at end of file
+//   Reduces code size slightly at the expense of debuggability.
index 4c22a0f..717af6e 100644 (file)
@@ -18,15 +18,23 @@ MULTICLEAN = true
 
 noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la
 
+if POWERPC_DARWIN
+asm_libgc_sources = powerpc_darwin_mach_dep.s
+else
+asm_libgc_sources = 
+endif
+
 GC_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
-dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
-linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.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
+backgraph.c win32_threads.c \
+pthread_support.c pthread_stop_world.c darwin_stop_world.c \
+$(asm_libgc_sources)
 
-EXTRA_GC_SOURCES = alpha_mach_dep.s \
-mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
+EXTRA_GC_SOURCES = alpha_mach_dep.S \
+mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_darwin_mach_dep.s \
 rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
 sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
 
@@ -63,7 +71,9 @@ TESTS = gctest
 ## FIXME: relies on internal code generated by automake.
 all_objs = @addobjs@ $(libgcjgc_la_OBJECTS)
 $(all_objs) : include/private/gcconfig.h include/private/gc_priv.h \
-include/private/gc_hdrs.h include/gc.h include/gc_gcj.h include/gc_mark.h
+include/private/gc_hdrs.h include/gc.h include/gc_gcj.h \
+include/gc_pthread_redirects.h include/gc_config_macros.h \
+include/gc_mark.h @addincludes@
 
 ## FIXME: we shouldn't have to do this, but automake forces us to.
 .s.lo:
index af6192e..a884ee5 100644 (file)
@@ -27,8 +27,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:
+# 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
+# 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
@@ -60,6 +63,16 @@ HOSTCFLAGS=$(CFLAGS)
 #   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
@@ -93,13 +106,15 @@ HOSTCFLAGS=$(CFLAGS)
 #   See gc_cpp.h for details.  No effect on the C part of the collector.
 #   This is defined implicitly in a few environments.  Must also be defined
 #   by clients that use gc_cpp.h.
-# -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be
-#   defined as aliases for X, GC_realloc, and GC_free, respectively.
+# -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,
@@ -111,6 +126,9 @@ HOSTCFLAGS=$(CFLAGS)
 #   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.
@@ -197,8 +215,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.
@@ -226,6 +247,24 @@ HOSTCFLAGS=$(CFLAGS)
 # -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) 
@@ -233,15 +272,15 @@ 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 backgraph.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 backgraph.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 \
+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 \
@@ -249,14 +288,17 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \
     threadlibs.c if_mach.c if_not_there.c gc_cpp.cc include/gc_cpp.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/debugging.html \
@@ -265,15 +307,19 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
        doc/README.win32 doc/barrett_diagram doc/README \
         doc/README.contributors doc/README.changes doc/gc.man \
        doc/README.environment doc/tree.html doc/gcdescr.html \
-       doc/README.autoconf doc/README.macros doc/README.ews4800
+       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
 
 TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
        tests/leak_test.c tests/thread_leak_test.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 ltconfig \
-                ltmain.sh mkinstalldirs
+                ltconfig 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 \
@@ -285,7 +331,7 @@ 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 \
+           add_gc_prefix.c gc_cpp.cpp \
           version.h AmigaOS.c \
           $(TESTS) $(GNU_BUILD_FILES) $(OTHER_MAKEFILES)
 
@@ -330,16 +376,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
 
@@ -434,17 +480,18 @@ 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 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
@@ -491,7 +538,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`
@@ -510,7 +557,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)
index 7aadaf3..6097293 100644 (file)
@@ -152,7 +152,7 @@ CFLAGS= -O -I$(srcdir)/include -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIO
 #   currently probably works only with Linux.
 
 
-CXXFLAGS= $(CFLAGS) -DOPERATOR_NEW_ARRAY
+CXXFLAGS= $(CFLAGS) -DGC_OPERATOR_NEW_ARRAY
 AR= ar
 RANLIB= ranlib
 
@@ -165,8 +165,8 @@ CORD_SRCS=  cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordt
 
 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_mark.h \
     include/gc_inl.h include/gc_inline.h gc.man \
@@ -177,7 +177,7 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_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 $(CORD_SRCS)
 
 OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
@@ -284,16 +284,16 @@ liblinuxgc.so: $(OBJS) dyn_load.o
        gcc -shared -o liblinuxgc.so $(OBJS) dyn_load.o -lo
        ln liblinuxgc.so libgc.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 $(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 $(AS) -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
-       ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s
+       ./if_mach POWERPC MACOSX $(AS) -o mach_dep.o $(srcdir)/powerpc_darwin_mach_dep.s
+       ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.S
+       ./if_mach SPARC SUNOS5 $(AS) -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_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
 
index edecc83..4e5bb36 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -66,9 +66,11 @@ target_triplet = @target@
 AR = @AR@
 AS = @AS@
 CC = @CC@
+CFLAGS = @CFLAGS@
 CPP = @CPP@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
 CXXINCLUDES = @CXXINCLUDES@
 DLLTOOL = @DLLTOOL@
 EXEEXT = @EXEEXT@
@@ -89,7 +91,10 @@ RANLIB = @RANLIB@
 STRIP = @STRIP@
 THREADLIBS = @THREADLIBS@
 VERSION = @VERSION@
+addincludes = @addincludes@
+addlibs = @addlibs@
 addobjs = @addobjs@
+addtests = @addtests@
 gc_basedir = @gc_basedir@
 mkinstalldirs = @mkinstalldirs@
 target_all = @target_all@
@@ -109,17 +114,21 @@ MULTIDO = true
 MULTICLEAN = true
 
 noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la
+@POWERPC_DARWIN_TRUE@asm_libgc_sources = @POWERPC_DARWIN_TRUE@powerpc_darwin_mach_dep.s
+@POWERPC_DARWIN_FALSE@asm_libgc_sources = 
 
 GC_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
-dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
-linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.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
+backgraph.c win32_threads.c \
+pthread_support.c pthread_stop_world.c darwin_stop_world.c \
+$(asm_libgc_sources)
 
 
-EXTRA_GC_SOURCES = alpha_mach_dep.s \
-mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
+EXTRA_GC_SOURCES = alpha_mach_dep.S \
+mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_darwin_mach_dep.s \
 rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
 sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
 
@@ -213,24 +222,53 @@ DEFS = @DEFS@ -I. -I$(srcdir)
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-libgcjgc_la_OBJECTS =  allchblk.lo alloc.lo blacklst.lo checksums.lo \
-dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \
-irix_threads.lo linux_threads.lo malloc.lo mallocx.lo mark.lo \
-mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo \
-ptr_chck.lo real_malloc.lo reclaim.lo solaris_pthreads.lo \
-solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo backgraph.lo \
-win32_threads.lo
+@POWERPC_DARWIN_FALSE@libgcjgc_la_OBJECTS =  allchblk.lo alloc.lo \
+@POWERPC_DARWIN_FALSE@blacklst.lo checksums.lo dbg_mlc.lo dyn_load.lo \
+@POWERPC_DARWIN_FALSE@finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \
+@POWERPC_DARWIN_FALSE@aix_irix_threads.lo malloc.lo mallocx.lo mark.lo \
+@POWERPC_DARWIN_FALSE@mark_rts.lo misc.lo new_hblk.lo obj_map.lo \
+@POWERPC_DARWIN_FALSE@os_dep.lo pcr_interface.lo ptr_chck.lo \
+@POWERPC_DARWIN_FALSE@real_malloc.lo reclaim.lo solaris_pthreads.lo \
+@POWERPC_DARWIN_FALSE@solaris_threads.lo specific.lo stubborn.lo \
+@POWERPC_DARWIN_FALSE@typd_mlc.lo backgraph.lo win32_threads.lo \
+@POWERPC_DARWIN_FALSE@pthread_support.lo pthread_stop_world.lo \
+@POWERPC_DARWIN_FALSE@darwin_stop_world.lo
+@POWERPC_DARWIN_TRUE@libgcjgc_la_OBJECTS =  allchblk.lo alloc.lo \
+@POWERPC_DARWIN_TRUE@blacklst.lo checksums.lo dbg_mlc.lo dyn_load.lo \
+@POWERPC_DARWIN_TRUE@finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \
+@POWERPC_DARWIN_TRUE@aix_irix_threads.lo malloc.lo mallocx.lo mark.lo \
+@POWERPC_DARWIN_TRUE@mark_rts.lo misc.lo new_hblk.lo obj_map.lo \
+@POWERPC_DARWIN_TRUE@os_dep.lo pcr_interface.lo ptr_chck.lo \
+@POWERPC_DARWIN_TRUE@real_malloc.lo reclaim.lo solaris_pthreads.lo \
+@POWERPC_DARWIN_TRUE@solaris_threads.lo specific.lo stubborn.lo \
+@POWERPC_DARWIN_TRUE@typd_mlc.lo backgraph.lo win32_threads.lo \
+@POWERPC_DARWIN_TRUE@pthread_support.lo pthread_stop_world.lo \
+@POWERPC_DARWIN_TRUE@darwin_stop_world.lo powerpc_darwin_mach_dep.lo
 libgcjgc_convenience_la_LDFLAGS = 
-libgcjgc_convenience_la_OBJECTS =  allchblk.lo alloc.lo blacklst.lo \
-checksums.lo dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
-headers.lo irix_threads.lo linux_threads.lo malloc.lo mallocx.lo \
-mark.lo mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo \
-pcr_interface.lo ptr_chck.lo real_malloc.lo reclaim.lo \
-solaris_pthreads.lo solaris_threads.lo specific.lo stubborn.lo \
-typd_mlc.lo backgraph.lo win32_threads.lo
+@POWERPC_DARWIN_FALSE@libgcjgc_convenience_la_OBJECTS =  allchblk.lo \
+@POWERPC_DARWIN_FALSE@alloc.lo blacklst.lo checksums.lo dbg_mlc.lo \
+@POWERPC_DARWIN_FALSE@dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
+@POWERPC_DARWIN_FALSE@headers.lo aix_irix_threads.lo malloc.lo \
+@POWERPC_DARWIN_FALSE@mallocx.lo mark.lo mark_rts.lo misc.lo \
+@POWERPC_DARWIN_FALSE@new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo \
+@POWERPC_DARWIN_FALSE@ptr_chck.lo real_malloc.lo reclaim.lo \
+@POWERPC_DARWIN_FALSE@solaris_pthreads.lo solaris_threads.lo \
+@POWERPC_DARWIN_FALSE@specific.lo stubborn.lo typd_mlc.lo backgraph.lo \
+@POWERPC_DARWIN_FALSE@win32_threads.lo pthread_support.lo \
+@POWERPC_DARWIN_FALSE@pthread_stop_world.lo darwin_stop_world.lo
+@POWERPC_DARWIN_TRUE@libgcjgc_convenience_la_OBJECTS =  allchblk.lo \
+@POWERPC_DARWIN_TRUE@alloc.lo blacklst.lo checksums.lo dbg_mlc.lo \
+@POWERPC_DARWIN_TRUE@dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
+@POWERPC_DARWIN_TRUE@headers.lo aix_irix_threads.lo malloc.lo \
+@POWERPC_DARWIN_TRUE@mallocx.lo mark.lo mark_rts.lo misc.lo new_hblk.lo \
+@POWERPC_DARWIN_TRUE@obj_map.lo os_dep.lo pcr_interface.lo ptr_chck.lo \
+@POWERPC_DARWIN_TRUE@real_malloc.lo reclaim.lo solaris_pthreads.lo \
+@POWERPC_DARWIN_TRUE@solaris_threads.lo specific.lo stubborn.lo \
+@POWERPC_DARWIN_TRUE@typd_mlc.lo backgraph.lo win32_threads.lo \
+@POWERPC_DARWIN_TRUE@pthread_support.lo pthread_stop_world.lo \
+@POWERPC_DARWIN_TRUE@darwin_stop_world.lo powerpc_darwin_mach_dep.lo
 check_PROGRAMS =  gctest$(EXEEXT)
 gctest_DEPENDENCIES =  ./libgcjgc.la
-CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 DIST_COMMON =  ChangeLog Makefile.am Makefile.in acinclude.m4 aclocal.m4 \
@@ -368,7 +406,7 @@ maintainer-clean-recursive:
        dot_seen=no; \
        rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
          rev="$$subdir $$rev"; \
-         test "$$subdir" = "." && dot_seen=yes; \
+         test "$$subdir" != "." || dot_seen=yes; \
        done; \
        test "$$dot_seen" = "no" && rev=". $$rev"; \
        target=`echo $@ | sed s/-recursive//`; \
@@ -598,7 +636,9 @@ mostlyclean distclean maintainer-clean
 test.o:        tests/test.c
        $(COMPILE) -c $(srcdir)/tests/test.c
 $(all_objs) : include/private/gcconfig.h include/private/gc_priv.h \
-include/private/gc_hdrs.h include/gc.h include/gc_gcj.h include/gc_mark.h
+include/private/gc_hdrs.h include/gc.h include/gc_gcj.h \
+include/gc_pthread_redirects.h include/gc_config_macros.h \
+include/gc_mark.h @addincludes@
 
 .s.lo:
        $(LTCOMPILE) -Wp,-P -x assembler-with-cpp -c $<
index 7d4cbd8..2b03939 100644 (file)
@@ -47,12 +47,16 @@ GC_bool GC_use_entire_heap = 0;
 struct hblk * GC_hblkfreelist[N_HBLK_FLS+1] = { 0 };
 
 #ifndef USE_MUNMAP
+
   word GC_free_bytes[N_HBLK_FLS+1] = { 0 };
        /* Number of free bytes on each list.   */
 
   /* Is bytes + the number of free bytes on lists n .. N_HBLK_FLS      */
   /* > GC_max_large_allocd_bytes?                                      */
-  GC_bool GC_enough_large_bytes_left(bytes,n)
+# ifdef __GNUC__
+  __inline__
+# endif
+  static GC_bool GC_enough_large_bytes_left(bytes,n)
   word bytes;
   int n;
   {
@@ -583,11 +587,11 @@ int n;
            if (!GC_use_entire_heap
                && size_avail != size_needed
                && USED_HEAP_SIZE >= GC_requested_heapsize
-               && !GC_incremental && GC_should_collect()) {
+               && !TRUE_INCREMENTAL && GC_should_collect()) {
 #              ifdef USE_MUNMAP
                    continue;
 #              else
-                   /* If we enough large blocks left to cover any      */
+                   /* If we have enough large blocks left to cover any */
                    /* previous request for large blocks, we go ahead   */
                    /* and split.  Assuming a steady state, that should */
                    /* be safe.  It means that we can use the full      */
@@ -595,6 +599,12 @@ int n;
                    if (!GC_enough_large_bytes_left(GC_large_allocd_bytes, n)) {
                      continue;
                    } 
+                   /* If we are deallocating lots of memory from       */
+                   /* finalizers, fail and collect sooner rather       */
+                   /* than later.                                      */
+                   if (GC_finalizer_mem_freed > (GC_heapsize >> 4))  {
+                     continue;
+                   }
 #              endif /* !USE_MUNMAP */
            }
            /* If the next heap block is obviously better, go on.       */
index f2e5af0..f53061f 100644 (file)
@@ -72,6 +72,13 @@ int GC_full_freq = 19;          /* Every 20th collection is a full   */
 GC_bool GC_need_full_gc = FALSE;
                           /* Need full GC do to heap growth.   */
 
+#ifdef THREADS
+  GC_bool GC_world_stopped = FALSE;
+# define IF_THREADS(x) x
+#else
+# define IF_THREADS(x)
+#endif
+
 word GC_used_heap_size_after_full = 0;
 
 char * GC_copyright[] =
@@ -160,7 +167,7 @@ static word min_words_allocd()
                               + (GC_large_free_bytes >> 2)
                                   /* use a bit more of large empty heap */
                               + total_root_size);
-    if (GC_incremental) {
+    if (TRUE_INCREMENTAL) {
         return scan_size / (2 * GC_free_space_divisor);
     } else {
         return scan_size / GC_free_space_divisor;
@@ -182,7 +189,8 @@ word GC_adj_words_allocd()
     /* managed object should not alter result, assuming the client     */
     /* is playing by the rules.                                                */
     result = (signed_word)GC_words_allocd
-            - (signed_word)GC_mem_freed - expl_managed;
+            - (signed_word)GC_mem_freed 
+            + (signed_word)GC_finalizer_mem_freed - expl_managed;
     if (result > (signed_word)GC_words_allocd) {
         result = GC_words_allocd;
        /* probably client bug or unfortunate scheduling */
@@ -250,7 +258,6 @@ void GC_maybe_gc()
 
     if (GC_should_collect()) {
         if (!GC_incremental) {
-           GC_notify_full_gc();
             GC_gcollect_inner();
             n_partial_gcs = 0;
             return;
@@ -302,10 +309,14 @@ void GC_maybe_gc()
 /*
  * Stop the world garbage collection.  Assumes lock held, signals disabled.
  * If stop_func is not GC_never_stop_func, then abort if stop_func returns TRUE.
+ * Return TRUE if we successfully completed the collection.
  */
 GC_bool GC_try_to_collect_inner(stop_func)
 GC_stop_func stop_func;
 {
+#   ifdef CONDPRINT
+        CLOCK_TYPE start_time, current_time;
+#   endif
     if (GC_dont_gc) return FALSE;
     if (GC_incremental && GC_collection_in_progress()) {
 #   ifdef CONDPRINT
@@ -320,8 +331,10 @@ GC_stop_func stop_func;
            GC_collect_a_little_inner(1);
        }
     }
+    if (stop_func == GC_never_stop_func) GC_notify_full_gc();
 #   ifdef CONDPRINT
       if (GC_print_stats) {
+        if (GC_print_stats) GET_TIME(start_time);
        GC_printf2(
           "Initiating full world-stop collection %lu after %ld allocd bytes\n",
           (unsigned long) GC_gc_no+1,
@@ -360,6 +373,13 @@ GC_stop_func stop_func;
       return(FALSE);
     }
     GC_finish_collection();
+#   if defined(CONDPRINT)
+      if (GC_print_stats) {
+        GET_TIME(current_time);
+        GC_printf1("Complete collection took %lu msecs\n",
+                   MS_TIME_DIFF(current_time,start_time));
+      }
+#   endif
     return(TRUE);
 }
 
@@ -430,6 +450,7 @@ int GC_collect_a_little GC_PROTO(())
     result = (int)GC_collection_in_progress();
     UNLOCK();
     ENABLE_SIGNALS();
+    if (!result && GC_debugging_started) GC_print_all_smashed();
     return(result);
 }
 
@@ -448,16 +469,17 @@ GC_stop_func stop_func;
        CLOCK_TYPE start_time, current_time;
 #   endif
        
-#   if defined(REGISTER_LIBRARIES_EARLY)
-        GC_cond_register_dynamic_libraries();
-#   endif
-    STOP_WORLD();
 #   ifdef PRINTTIMES
        GET_TIME(start_time);
 #   endif
 #   if defined(CONDPRINT) && !defined(PRINTTIMES)
        if (GC_print_stats) GET_TIME(start_time);
 #   endif
+#   if defined(REGISTER_LIBRARIES_EARLY)
+        GC_cond_register_dynamic_libraries();
+#   endif
+    STOP_WORLD();
+    IF_THREADS(GC_world_stopped = TRUE);
 #   ifdef CONDPRINT
       if (GC_print_stats) {
        GC_printf1("--> Marking for collection %lu ",
@@ -488,6 +510,7 @@ GC_stop_func stop_func;
                      }
 #                  endif
                    GC_deficit = i; /* Give the mutator a chance. */
+                    IF_THREADS(GC_world_stopped = FALSE);
                    START_WORLD();
                    return(FALSE);
            }
@@ -521,6 +544,8 @@ GC_stop_func stop_func;
             (*GC_check_heap)();
         }
     
+    IF_THREADS(GC_world_stopped = FALSE);
+    START_WORLD();
 #   ifdef PRINTTIMES
        GET_TIME(current_time);
        GC_printf1("World-stopped marking took %lu msecs\n",
@@ -534,7 +559,6 @@ GC_stop_func stop_func;
        }
 #     endif
 #   endif
-    START_WORLD();
     return(TRUE);
 }
 
@@ -611,6 +635,7 @@ void GC_finish_collection()
          GC_print_address_map();
        }
 #   endif
+    COND_DUMP;
     if (GC_find_leak) {
       /* Mark all objects on the free list.  All objects should be */
       /* marked when we're done.                                  */
@@ -707,6 +732,7 @@ void GC_finish_collection()
       GC_words_allocd = 0;
       GC_words_wasted = 0;
       GC_mem_freed = 0;
+      GC_finalizer_mem_freed = 0;
       
 #   ifdef USE_MUNMAP
       GC_unmap_old();
@@ -730,6 +756,7 @@ void GC_finish_collection()
     int result;
     DCL_LOCK_STATE;
     
+    if (GC_debugging_started) GC_print_all_smashed();
     GC_INVOKE_FINALIZERS();
     DISABLE_SIGNALS();
     LOCK();
@@ -741,14 +768,17 @@ void GC_finish_collection()
     EXIT_GC();
     UNLOCK();
     ENABLE_SIGNALS();
-    if(result) GC_INVOKE_FINALIZERS();
+    if(result) {
+        if (GC_debugging_started) GC_print_all_smashed();
+        GC_INVOKE_FINALIZERS();
+    }
     return(result);
 }
 
 void GC_gcollect GC_PROTO(())
 {
-    GC_notify_full_gc();
     (void)GC_try_to_collect(GC_never_stop_func);
+    if (GC_have_errors) GC_print_all_errors();
 }
 
 word GC_n_heap_sects = 0;      /* Number of sections currently in heap. */
@@ -950,7 +980,6 @@ GC_bool ignore_off_page;
 {
     if (!GC_incremental && !GC_dont_gc &&
        (GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) {
-      GC_notify_full_gc();
       GC_gcollect_inner();
     } else {
       word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)
@@ -975,7 +1004,6 @@ GC_bool ignore_off_page;
         && !GC_expand_hp_inner(needed_blocks)) {
        if (GC_fail_count++ < GC_max_retries) {
            WARN("Out of Memory!  Trying to continue ...\n", 0);
-           GC_notify_full_gc();
            GC_gcollect_inner();
        } else {
 #          if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC)
@@ -1005,29 +1033,38 @@ ptr_t GC_allocobj(sz, kind)
 word sz;
 int kind;
 {
-    register ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);
+    ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);
+    GC_bool tried_minor = FALSE;
     
     if (sz == 0) return(0);
 
     while (*flh == 0) {
       ENTER_GC();
       /* Do our share of marking work */
-        if(GC_incremental && !GC_dont_gc) GC_collect_a_little_inner(1);
+        if(TRUE_INCREMENTAL) GC_collect_a_little_inner(1);
       /* Sweep blocks for objects of this size */
-          GC_continue_reclaim(sz, kind);
+        GC_continue_reclaim(sz, kind);
       EXIT_GC();
       if (*flh == 0) {
         GC_new_hblk(sz, kind);
       }
       if (*flh == 0) {
         ENTER_GC();
-        if (!GC_collect_or_expand((word)1,FALSE)) {
+       if (GC_incremental && GC_time_limit == GC_TIME_UNLIMITED
+           && ! tried_minor ) {
+           GC_collect_a_little_inner(1);
+           tried_minor = TRUE;
+       } else {
+          if (!GC_collect_or_expand((word)1,FALSE)) {
            EXIT_GC();
            return(0);
+         }
        }
        EXIT_GC();
       }
     }
+    /* Successful allocation; reset failure count.     */
+    GC_fail_count = 0;
     
     return(*flh);
 }
diff --git a/boehm-gc/alpha_mach_dep.s b/boehm-gc/alpha_mach_dep.s
deleted file mode 100644 (file)
index a21f77a..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-       .arch ev6
-
-        .text
-        .align  4
-        .globl  GC_push_regs
-        .ent    GC_push_regs 2
-GC_push_regs:
-       ldgp    $gp, 0($27)
-       lda     $sp, -16($sp)
-       stq     $26, 0($sp)
-        .mask   0x04000000, 0
-        .frame  $sp, 16, $26, 0
-
- # $0          integer result
- # $1-$8       temp regs - not preserved cross calls
- # $9-$15      call saved regs
- # $16-$21     argument regs - not preserved cross calls
- # $22-$28     temp regs - not preserved cross calls
- # $29         global pointer - not preserved cross calls
- # $30         stack pointer
-
-# define call_push(x)                  \
-       mov   x, $16;                   \
-       jsr   $26, GC_push_one;         \
-       ldgp  $gp, 0($26)
-       
-        call_push($9)
-        call_push($10)
-        call_push($11)
-        call_push($12)
-        call_push($13)
-        call_push($14)
-        call_push($15)
-
- # $f0-$f1     floating point results
- # $f2-$f9     call saved regs
- # $f10-$f30   temp regs - not preserved cross calls
-
-       # Use the most efficient transfer method for this hardware.
-       # Bit 1 detects the FIX extension, which includes ftoit.
-       amask   2, $0
-       bne     $0, $use_stack
-
-#undef call_push
-#define call_push(x)                   \
-       ftoit   x, $16;                 \
-       jsr     $26, GC_push_one;       \
-       ldgp    $gp, 0($26)
-
-       call_push($f2)
-       call_push($f3)
-       call_push($f4)
-       call_push($f5)
-       call_push($f6)
-       call_push($f7)
-       call_push($f8)
-       call_push($f9)
-
-       ldq     $26, 0($sp)
-       lda     $sp, 16($sp)
-       ret     $31, ($26), 1
-
-       .align  4
-$use_stack:
-
-#undef call_push
-#define call_push(x)                   \
-       stt     x, 8($sp);              \
-       ldq     $16, 8($sp);            \
-       jsr     $26, GC_push_one;       \
-       ldgp    $gp, 0($26)
-
-       call_push($f2)
-       call_push($f3)
-       call_push($f4)
-       call_push($f5)
-       call_push($f6)
-       call_push($f7)
-       call_push($f8)
-       call_push($f9)
-
-       ldq     $26, 0($sp)
-       lda     $sp, 16($sp)
-       ret     $31, ($26), 1
-
-       .end    GC_push_regs
index ef1a1a7..e8ca37d 100755 (executable)
@@ -41,7 +41,12 @@ ac_help="$ac_help
 ac_help="$ac_help
   --with-ecos             enable runtime eCos target support"
 ac_help="$ac_help
-  --enable-shared[=PKGS]  build shared libraries [default=no]"
+  --enable-shared[=PKGS]  build shared libraries [default=yes]"
+ac_help="$ac_help
+  --with-target-subdir=SUBDIR
+                          configuring with a cross compiler"
+ac_help="$ac_help
+  --with-cross-host=HOST  configuring with a cross compiler"
 ac_help="$ac_help
   --enable-full-debug  include full support for pointer backtracing etc."
 
@@ -61,7 +66,6 @@ program_suffix=NONE
 program_transform_name=s,x,x,
 silent=
 site=
-sitefile=
 srcdir=
 target=NONE
 verbose=
@@ -176,7 +180,6 @@ Configuration:
   --help                  print this message
   --no-create             do not create output files
   --quiet, --silent       do not print \`checking...' messages
-  --site-file=FILE        use FILE as the site file
   --version               print the version of autoconf that created configure
 Directory and file names:
   --prefix=PREFIX         install architecture-independent files in PREFIX
@@ -347,11 +350,6 @@ EOF
   -site=* | --site=* | --sit=*)
     site="$ac_optarg" ;;
 
-  -site-file | --site-file | --site-fil | --site-fi | --site-f)
-    ac_prev=sitefile ;;
-  -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
-    sitefile="$ac_optarg" ;;
-
   -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
     ac_prev=srcdir ;;
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
@@ -517,16 +515,12 @@ fi
 srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
 # Prefer explicitly selected file to automatically selected ones.
-if test -z "$sitefile"; then
-  if test -z "$CONFIG_SITE"; then
-    if test "x$prefix" != xNONE; then
-      CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-    else
-      CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-    fi
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
   fi
-else
-  CONFIG_SITE="$sitefile"
 fi
 for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
@@ -604,7 +598,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:608: checking for a BSD compatible install" >&5
+echo "configure:602: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -657,7 +651,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:661: checking whether build environment is sane" >&5
+echo "configure:655: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -714,7 +708,7 @@ test "$program_suffix" != NONE &&
 test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:718: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:712: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -747,12 +741,12 @@ else
 fi
 
 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:751: checking for Cygwin environment" >&5
+echo "configure:745: checking for Cygwin environment" >&5
 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 756 "configure"
+#line 750 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -763,7 +757,7 @@ int main() {
 return __CYGWIN__;
 ; return 0; }
 EOF
-if { (eval echo configure:767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_cygwin=yes
 else
@@ -780,19 +774,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6
 CYGWIN=
 test "$ac_cv_cygwin" = yes && CYGWIN=yes
 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:784: checking for mingw32 environment" >&5
+echo "configure:778: checking for mingw32 environment" >&5
 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 789 "configure"
+#line 783 "configure"
 #include "confdefs.h"
 
 int main() {
 return __MINGW32__;
 ; return 0; }
 EOF
-if { (eval echo configure:796: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_mingw32=yes
 else
@@ -903,7 +897,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:907: checking host system type" >&5
+echo "configure:901: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -924,7 +918,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:928: checking target system type" >&5
+echo "configure:922: checking target system type" >&5
 
 target_alias=$target
 case "$target_alias" in
@@ -942,7 +936,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$target" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:946: checking build system type" >&5
+echo "configure:940: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -982,7 +976,7 @@ fi
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:986: checking for working aclocal" >&5
+echo "configure:980: checking for working aclocal" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -995,7 +989,7 @@ else
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:999: checking for working autoconf" >&5
+echo "configure:993: checking for working autoconf" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1008,7 +1002,7 @@ else
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:1012: checking for working automake" >&5
+echo "configure:1006: checking for working automake" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1021,7 +1015,7 @@ else
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:1025: checking for working autoheader" >&5
+echo "configure:1019: checking for working autoheader" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1034,7 +1028,7 @@ else
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:1038: checking for working makeinfo" >&5
+echo "configure:1032: checking for working makeinfo" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -1060,7 +1054,7 @@ fi
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1064: checking for $ac_word" >&5
+echo "configure:1058: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1090,7 +1084,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1094: checking for $ac_word" >&5
+echo "configure:1088: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1139,7 +1133,7 @@ fi
 fi
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1143: checking whether we are using GNU C" >&5
+echo "configure:1137: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1148,7 +1142,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1146: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1163,7 +1157,7 @@ if test $ac_cv_prog_gcc = yes; then
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1167: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1161: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1200,7 +1194,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1204: checking for $ac_word" >&5
+echo "configure:1198: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1233,7 +1227,7 @@ test -n "$CXX" || CXX="gcc"
 test -z "$CXX" && { echo "configure: error: no acceptable c++ found in \$PATH" 1>&2; exit 1; }
 
 echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:1237: checking whether we are using GNU C++" >&5
+echo "configure:1231: checking whether we are using GNU C++" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1242,7 +1236,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gxx=yes
 else
   ac_cv_prog_gxx=no
@@ -1257,7 +1251,7 @@ if test $ac_cv_prog_gxx = yes; then
   ac_save_CXXFLAGS="$CXXFLAGS"
   CXXFLAGS=
   echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:1261: checking whether ${CXX-g++} accepts -g" >&5
+echo "configure:1255: checking whether ${CXX-g++} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1290,7 +1284,7 @@ fi
 # NEWLIB_CONFIGURE, which doesn't work because that means that it will
 # be run before AC_CANONICAL_HOST.
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1294: checking build system type" >&5
+echo "configure:1288: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1311,7 +1305,7 @@ echo "$ac_t""$build" 1>&6
 # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
 set dummy ${ac_tool_prefix}as; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1315: checking for $ac_word" >&5
+echo "configure:1309: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1343,7 +1337,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1347: checking for $ac_word" >&5
+echo "configure:1341: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1375,7 +1369,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1379: checking for $ac_word" >&5
+echo "configure:1373: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1407,7 +1401,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1411: checking for $ac_word" >&5
+echo "configure:1405: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1452,7 +1446,7 @@ fi
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1456: checking for a BSD compatible install" >&5
+echo "configure:1450: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1506,7 +1500,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:1510: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:1504: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -1544,7 +1538,7 @@ if false; then
   
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1548: checking for executable suffix" >&5
+echo "configure:1542: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1554,10 +1548,10 @@ else
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:1558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:1552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -1676,7 +1670,7 @@ ac_prog=ld
 if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
-echo "configure:1680: checking for ld used by GCC" >&5
+echo "configure:1674: checking for ld used by GCC" >&5
   case $host in
   *-*-mingw*)
     # gcc leaves a trailing carriage return which upsets mingw
@@ -1706,10 +1700,10 @@ echo "configure:1680: checking for ld used by GCC" >&5
   esac
 elif test "$with_gnu_ld" = yes; then
   echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
-echo "configure:1710: checking for GNU ld" >&5
+echo "configure:1704: checking for GNU ld" >&5
 else
   echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
-echo "configure:1713: checking for non-GNU ld" >&5
+echo "configure:1707: checking for non-GNU ld" >&5
 fi
 if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1744,7 +1738,7 @@ else
 fi
 test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
 echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
-echo "configure:1748: checking if the linker ($LD) is GNU ld" >&5
+echo "configure:1742: checking if the linker ($LD) is GNU ld" >&5
 if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1761,7 +1755,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
 echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
-echo "configure:1765: checking for $LD option to reload object files" >&5
+echo "configure:1759: checking for $LD option to reload object files" >&5
 if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1773,7 +1767,7 @@ reload_flag=$lt_cv_ld_reload_flag
 test -n "$reload_flag" && reload_flag=" $reload_flag"
 
 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
-echo "configure:1777: checking for BSD-compatible nm" >&5
+echo "configure:1771: checking for BSD-compatible nm" >&5
 if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1811,7 +1805,7 @@ NM="$lt_cv_path_NM"
 echo "$ac_t""$NM" 1>&6
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1815: checking whether ln -s works" >&5
+echo "configure:1809: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1832,7 +1826,7 @@ else
 fi
 
 echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
-echo "configure:1836: checking how to recognise dependant libraries" >&5
+echo "configure:1830: checking how to recognise dependant libraries" >&5
 if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2005,13 +1999,13 @@ file_magic_cmd=$lt_cv_file_magic_cmd
 deplibs_check_method=$lt_cv_deplibs_check_method
 
 echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:2009: checking for object suffix" >&5
+echo "configure:2003: checking for object suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   rm -f conftest*
 echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:2015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2009: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   for ac_file in conftest.*; do
     case $ac_file in
     *.c) ;;
@@ -2035,7 +2029,7 @@ case $deplibs_check_method in
 file_magic*)
   if test "$file_magic_cmd" = '$MAGIC_CMD'; then
     echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
-echo "configure:2039: checking for ${ac_tool_prefix}file" >&5
+echo "configure:2033: checking for ${ac_tool_prefix}file" >&5
 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2097,7 +2091,7 @@ fi
 if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
     echo $ac_n "checking for file""... $ac_c" 1>&6
-echo "configure:2101: checking for file" >&5
+echo "configure:2095: checking for file" >&5
 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2168,7 +2162,7 @@ esac
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2172: checking for $ac_word" >&5
+echo "configure:2166: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2200,7 +2194,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2204: checking for $ac_word" >&5
+echo "configure:2198: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2235,7 +2229,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2239: checking for $ac_word" >&5
+echo "configure:2233: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2267,7 +2261,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2271: checking for $ac_word" >&5
+echo "configure:2265: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2334,8 +2328,8 @@ 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 2338 "configure"' > conftest.$ac_ext
-  if { (eval echo configure:2339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  echo '#line 2332 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:2333: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
    if test "$lt_cv_prog_gnu_ld" = yes; then
     case `/usr/bin/file conftest.$ac_objext` in
     *32-bit*)
@@ -2368,7 +2362,7 @@ case $host in
 ia64-*-hpux*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
-  if { (eval echo configure:2372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  if { (eval echo configure:2366: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
     case "`/usr/bin/file conftest.o`" in
     *ELF-32*)
       HPUX_IA64_MODE="32"
@@ -2384,7 +2378,7 @@ ia64-*-hpux*)
 x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
-  if { (eval echo configure:2388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  if { (eval echo configure:2382: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       case $host in
@@ -2428,7 +2422,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:2432: checking whether the C compiler needs -belf" >&5
+echo "configure:2426: checking whether the C compiler needs -belf" >&5
 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2441,14 +2435,14 @@ ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$a
 cross_compiling=$ac_cv_prog_cc_cross
 
      cat > conftest.$ac_ext <<EOF
-#line 2445 "configure"
+#line 2439 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   lt_cv_cc_needs_belf=yes
 else
@@ -2478,7 +2472,7 @@ echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
 esac
 
 echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
-echo "configure:2482: checking how to run the C++ preprocessor" >&5
+echo "configure:2476: checking how to run the C++ preprocessor" >&5
 if test -z "$CXXCPP"; then
 if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2491,12 +2485,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes
 cross_compiling=$ac_cv_prog_cxx_cross
   CXXCPP="${CXX-g++} -E"
   cat > conftest.$ac_ext <<EOF
-#line 2495 "configure"
+#line 2489 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2500: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2494: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -2643,7 +2637,7 @@ fi
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:2647: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:2641: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -2676,7 +2670,7 @@ if false; then
   
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:2680: checking for executable suffix" >&5
+echo "configure:2674: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2686,10 +2680,10 @@ else
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:2690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:2684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -2709,7 +2703,7 @@ ac_exeext=$EXEEXT
 fi
 
 echo $ac_n "checking for thread model used by GCC""... $ac_c" 1>&6
-echo "configure:2713: checking for thread model used by GCC" >&5
+echo "configure:2707: checking for thread model used by GCC" >&5
 THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
 if test -z "$THREADS"; then
    THREADS=no
@@ -2738,7 +2732,7 @@ case "$THREADS" in
     THREADS=posix
     THREADLIBS=-lpthread
     case "$host" in
-     x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
+     x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux*)
        cat >> confdefs.h <<\EOF
 #define GC_LINUX_THREADS 1
 EOF
@@ -2747,7 +2741,7 @@ EOF
 #define _REENTRANT 1
 EOF
 
-        if test "${enable_parallel_mark}"; then
+        if test "${enable_parallel_mark}" = yes; then
          cat >> confdefs.h <<\EOF
 #define PARALLEL_MARK 1
 EOF
@@ -2768,6 +2762,16 @@ EOF
 EOF
 
        ;;
+     *-*-aix*)
+       cat >> confdefs.h <<\EOF
+#define GC_AIX_THREADS 1
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+       ;;
      *-*-hpux*)
        echo "configure: warning: "Only HP/UX 11 threads are supported."" 1>&2
        cat >> confdefs.h <<\EOF
@@ -2816,7 +2820,46 @@ EOF
 
        ;;
      *-*-cygwin*)
-       THREADLIBS=
+       cat >> confdefs.h <<\EOF
+#define GC_WIN32_THREADS 1
+EOF
+
+       ;;
+     *-*-darwin*)
+       cat >> confdefs.h <<\EOF
+#define GC_DARWIN_THREADS 1
+EOF
+
+       cat >> confdefs.h <<\EOF
+#define THREAD_LOCAL_ALLOC 1
+EOF
+
+       if test "${enable_parallel_mark}" = yes; then
+         cat >> confdefs.h <<\EOF
+#define PARALLEL_MARK 1
+EOF
+
+       fi
+       ;;
+     *-*-osf*)
+       cat >> confdefs.h <<\EOF
+#define GC_OSF1_THREADS 1
+EOF
+
+        if test "${enable_parallel_mark}" = yes; then
+         cat >> confdefs.h <<\EOF
+#define PARALLEL_MARK 1
+EOF
+
+         cat >> confdefs.h <<\EOF
+#define THREAD_LOCAL_ALLOC 1
+EOF
+
+         # May want to enable it in other cases, too.
+         # Measurements havent yet been done.
+       fi
+       INCLUDES="$INCLUDES -pthread"
+       THREADLIBS="-lpthread -lrt"
        ;;
     esac
     ;;
@@ -2825,16 +2868,48 @@ EOF
 #define GC_WIN32_THREADS 1
 EOF
 
-    cat >> confdefs.h <<\EOF
+        cat >> confdefs.h <<\EOF
 #define NO_GETENV 1
 EOF
 
-    if test $enable_shared = yes; then
-      cat >> confdefs.h <<\EOF
-#define GC_DLL 1
+    ;;
+ dgux386)
+    THREADS=dgux386
+echo "$ac_t""$THREADLIBS" 1>&6
+    # Use pthread GCC  switch
+    THREADLIBS=-pthread
+    if test "${enable_parallel_mark}" = yes; then
+        cat >> confdefs.h <<\EOF
+#define PARALLEL_MARK 1
 EOF
 
     fi
+    cat >> confdefs.h <<\EOF
+#define THREAD_LOCAL_ALLOC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define GC_DGUX386_THREADS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define DGUX_THREADS 1
+EOF
+
+    # Enable _POSIX4A_DRAFT10_SOURCE with flag -pthread
+    INCLUDES="-pthread $INCLUDES"
+    ;;
+ aix)
+    THREADS=posix
+    THREADLIBS=-lpthread
+    cat >> confdefs.h <<\EOF
+#define GC_AIX_THREADS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
     ;;
  decosf1 | irix | mach | os2 | solaris | dce | vxworks)
     { echo "configure: error: thread package $THREADS not yet supported" 1>&2; exit 1; }
@@ -2845,8 +2920,28 @@ EOF
 esac
 
 
-echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:2850: checking for dlopen in -ldl" >&5
+case "$host" in 
+   powerpc-*-darwin*)
+      powerpc_darwin=true
+      ;;
+esac
+
+
+if test x$powerpc_darwin = xtrue; then
+  POWERPC_DARWIN_TRUE=
+  POWERPC_DARWIN_FALSE='#'
+else
+  POWERPC_DARWIN_TRUE='#'
+  POWERPC_DARWIN_FALSE=
+fi
+
+# We never want libdl on darwin. It is a fake libdl that just ends up making
+# dyld calls anyway
+case "$host" in
+  *-*-darwin*) ;;
+  *) 
+    echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:2945: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2854,7 +2949,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2858 "configure"
+#line 2953 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2865,7 +2960,7 @@ int main() {
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:2869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2885,6 +2980,9 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
+    ;;
+esac
+
 
 
 target_all=libgcjgc.la
@@ -2901,6 +2999,9 @@ fi
 
 
 addobjs=
+addlibs=
+addincludes=
+addtests=
 CXXINCLUDES=
 case "$TARGET_ECOS" in
    no)
@@ -2915,17 +3016,31 @@ EOF
       ;;
 esac
 
+if test "${enable_cplusplus}" = yes; then
+      addincludes="$addincludes include/gc_cpp.h include/gc_allocator.h"
+      addtests="$addtests test_cpp"
+fi
 
 
 
+if test "${enable_cplusplus}" = yes; then
+  CPLUSPLUS_TRUE=
+  CPLUSPLUS_FALSE='#'
+else
+  CPLUSPLUS_TRUE='#'
+  CPLUSPLUS_FALSE=
+fi
 
-machdep=
-case "$host" in
- alpha*-*-openbsd*)
-    machdep="alpha_mach_dep.lo"
-    if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
-       echo "configure: warning: OpenBSD/Alpha without dlopen(). Shared library support is disabled" 1>&2
-       # Check whether --enable-shared or --disable-shared was given.
+
+
+
+
+
+# Configuration of shared libraries
+#
+echo $ac_n "checking whether to build shared libraries""... $ac_c" 1>&6
+echo "configure:3043: checking whether to build shared libraries" >&5
+# Check whether --enable-shared or --disable-shared was given.
 if test "${enable_shared+set}" = set; then
   enableval="$enable_shared"
   p=${PACKAGE-default}
@@ -2945,12 +3060,33 @@ no) enable_shared=no ;;
   ;;
 esac
 else
-  enable_shared=no
+  enable_shared=yes
 fi
 
+
+case "$host" in
+ alpha-*-openbsd*)
+     enable_shared=no
+     echo "$ac_t""no" 1>&6
+     ;;
+ *)
+     echo "$ac_t""yes" 1>&6
+     ;;
+esac
+
+# Configuration of machine-dependent code
+#
+echo $ac_n "checking which machine-dependent code should be used""... $ac_c" 1>&6
+echo "configure:3081: checking which machine-dependent code should be used" >&5 
+machdep=
+case "$host" in
+ alpha*-*-openbsd*)
+    machdep="alpha_mach_dep.lo"
+    if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
+       echo "configure: warning: OpenBSD/Alpha without dlopen(). Shared library support is disabled" 1>&2
     fi
     ;;
- alpha*-*-*)
+ alpha*-*-linux*)
     machdep="alpha_mach_dep.lo"
     ;;
  i?86-*-solaris2.[89]*)
@@ -2973,8 +3109,10 @@ EOF
  mips-dec-ultrix*)
     machdep="mips_ultrix_mach-dep.lo"
     ;;
- mips*-*-linux*)
+ mips-nec-sysv*|mips-unknown-sysv*)
     ;;
+ mips*-*-linux*) 
+    ;; 
  mips-*-*)
     machdep="mips_sgi_mach_dep.lo"
     cat >> confdefs.h <<\EOF
@@ -2982,6 +3120,9 @@ EOF
 EOF
 
     ;;
+ sparc-*-netbsd*)
+    machdep="sparc_netbsd_mach_dep.lo"
+    ;;
  sparc-sun-solaris2.3*)
     machdep="sparc_mach_dep.lo"
     cat >> confdefs.h <<\EOF
@@ -2997,14 +3138,217 @@ EOF
     ;;
 esac
 if test x"$machdep" = x; then
+echo "$ac_t""$machdep" 1>&6
    machdep="mach_dep.lo"
 fi
 addobjs="$addobjs $machdep"
 
 
+
+
+
+  
+
+  
+        
+        
+
+#
+# Check for AViiON Machines running DGUX
+#
+echo $ac_n "checking if host is AViiON running DGUX""... $ac_c" 1>&6
+echo "configure:3161: checking if host is AViiON running DGUX" >&5
+ac_is_dgux=no
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:3164: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 3179 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3185: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 3196 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3202: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 3213 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3219: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_safe=`echo "sys/dg_sys_info.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/dg_sys_info.h""... $ac_c" 1>&6
+echo "configure:3245: checking for sys/dg_sys_info.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3250 "configure"
+#include "confdefs.h"
+#include <sys/dg_sys_info.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3255: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ac_is_dgux=yes;
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo "$ac_t""$ac_is_dgux" 1>&6 
+    ## :GOTCHA: we do not check anything but sys/dg_sys_info.h
+if test $ac_is_dgux = yes; then
+    if test "$enable_full_debug" = "yes"; then
+      CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+      CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+    else
+      CFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+      CXXFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+    fi
+    
+    
+fi
+
+# Check whether --with-target-subdir or --without-target-subdir was given.
+if test "${with_target_subdir+set}" = set; then
+  withval="$with_target_subdir"
+  :
+fi
+
+# Check whether --with-cross-host or --without-cross-host was given.
+if test "${with_cross_host+set}" = set; then
+  withval="$with_cross_host"
+  :
+fi
+
+
+# automake wants to see AC_EXEEXT.  But we don't need it.  And having
+# it is actually a problem, because the compiler we're passed can't
+# necessarily do a full link.  So we fool automake here.
+if false; then
+  # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
+  # to nothing, so nothing would remain between `then' and `fi' if it
+  # were not for the `:' below.
+  :
+  
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:3315: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:3325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+fi
+
+echo $ac_n "checking whether Solaris gcc optimization fix is necessary""... $ac_c" 1>&6
+echo "configure:3348: checking whether Solaris gcc optimization fix is necessary" >&5
 case "$host" in
- sparc-sun-solaris2*)
+ sparc-sun-solaris2*|*aix*)
     if test "$GCC" = yes; then
+       echo "$ac_t""yes" 1>&6
        new_CFLAGS=
        for i in $CFLAGS; do
          case "$i" in
@@ -3016,8 +3360,11 @@ case "$host" in
          esac
        done
        CFLAGS="$new_CFLAGS"
+    else
+       echo "$ac_t""no" 1>&6
     fi
     ;;
+ *) echo "$ac_t""no" 1>&6 ;;
 esac
 
 MY_CFLAGS="$CFLAGS"
@@ -3095,6 +3442,12 @@ EOF
 EOF
 
       ;;
+      i345686-*-dgux*)
+       cat >> confdefs.h <<\EOF
+#define MAKE_BACK_GRAPH 1
+EOF
+
+      ;;
     esac 
   fi
 fi
@@ -3311,11 +3664,19 @@ s%@STRIP@%$STRIP%g
 s%@LIBTOOL@%$LIBTOOL%g
 s%@CXXCPP@%$CXXCPP%g
 s%@THREADLIBS@%$THREADLIBS%g
+s%@POWERPC_DARWIN_TRUE@%$POWERPC_DARWIN_TRUE%g
+s%@POWERPC_DARWIN_FALSE@%$POWERPC_DARWIN_FALSE%g
 s%@EXTRA_TEST_LIBS@%$EXTRA_TEST_LIBS%g
 s%@target_all@%$target_all%g
+s%@CPLUSPLUS_TRUE@%$CPLUSPLUS_TRUE%g
+s%@CPLUSPLUS_FALSE@%$CPLUSPLUS_FALSE%g
 s%@INCLUDES@%$INCLUDES%g
 s%@CXXINCLUDES@%$CXXINCLUDES%g
 s%@addobjs@%$addobjs%g
+s%@addincludes@%$addincludes%g
+s%@addlibs@%$addlibs%g
+s%@addtests@%$addtests%g
+s%@CPP@%$CPP%g
 s%@MY_CFLAGS@%$MY_CFLAGS%g
 s%@toolexecdir@%$toolexecdir%g
 s%@toolexeclibdir@%$toolexeclibdir%g
@@ -3327,7 +3688,7 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
 ac_beg=1 # First line for current file.
 ac_end=$ac_max_sed_cmds # Line after last line for current file.
index 82294cf..a98a0a7 100644 (file)
 #   host               The configuration host
 #   host_cpu           The configuration host CPU
 #   target_optspace    --enable-target-optspace ("yes", "no", "")
+#   GCC                 should be "yes" if using gcc
 
 # It sets the following shell variables:
 #   gc_cflags  Special CFLAGS to use when building
 
+gc_cflags=""
+
 # We should set -fexceptions if we are using gcc and might be used
 # inside something like gcj.  This is the zeroth approximation:
-case "$host" in 
-    *-*-linux* )
-    gc_cflags=-fexceptions
-    ;;
-    hppa*-*-hpux* )
-    if test $GCC != "yes" ; then
-        gc_cflags=+ESdbgasm
-    fi
-    ;;
-esac
+if test :"$GCC": = :yes: ; then
+    gc_cflags="${gc_cflags} -fexceptions"
+else
+    case "$host" in 
+        hppa*-*-hpux* )
+       if test :$GCC: != :"yes": ; then
+            gc_cflags="${gc_flags} +ESdbgasm"
+       fi
+        # :TODO: actaully we should check using Autoconf if
+        #     the compiler supports this option.
+        ;;
+    esac
+fi
 
 case "${target_optspace}:${host}" in
   yes:*)
@@ -48,7 +54,7 @@ esac
 
 case "${host}" in
   mips-tx39-*|mipstx39-unknown-*)
-       boehm_gc_cflags="${boehm_gc_cflags} -G 0"
+       gc_cflags="${gc_cflags} -G 0"
        ;;
   *)
        ;;
index 95e9d7c..9968624 100644 (file)
@@ -73,10 +73,10 @@ case "$THREADS" in
     THREADS=posix
     THREADLIBS=-lpthread
     case "$host" in
-     x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
+     x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux*)
        AC_DEFINE(GC_LINUX_THREADS)
        AC_DEFINE(_REENTRANT)
-        if test "${enable_parallel_mark}"; then
+        if test "${enable_parallel_mark}" = yes; then
          AC_DEFINE(PARALLEL_MARK)
        fi
        AC_DEFINE(THREAD_LOCAL_ALLOC)
@@ -85,6 +85,10 @@ case "$THREADS" in
        AC_DEFINE(GC_LINUX_THREADS)
        AC_DEFINE(_REENTRANT)
        ;;
+     *-*-aix*)
+       AC_DEFINE(GC_AIX_THREADS)
+       AC_DEFINE(_REENTRANT)
+       ;;
      *-*-hpux*)
        AC_MSG_WARN("Only HP/UX 11 threads are supported.")
        AC_DEFINE(GC_HPUX_THREADS)
@@ -109,16 +113,52 @@ case "$THREADS" in
        AC_DEFINE(GC_IRIX_THREADS)
        ;;
      *-*-cygwin*)
-       THREADLIBS=
+       AC_DEFINE(GC_WIN32_THREADS)
+       ;;
+     *-*-darwin*)
+       AC_DEFINE(GC_DARWIN_THREADS)
+       AC_DEFINE(THREAD_LOCAL_ALLOC)
+       if test "${enable_parallel_mark}" = yes; then
+         AC_DEFINE(PARALLEL_MARK)
+       fi
+       ;;
+     *-*-osf*)
+       AC_DEFINE(GC_OSF1_THREADS)
+        if test "${enable_parallel_mark}" = yes; then
+         AC_DEFINE(PARALLEL_MARK)
+         AC_DEFINE(THREAD_LOCAL_ALLOC)
+         # May want to enable it in other cases, too.
+         # Measurements havent yet been done.
+       fi
+       INCLUDES="$INCLUDES -pthread"
+       THREADLIBS="-lpthread -lrt"
        ;;
     esac
     ;;
  win32)
     AC_DEFINE(GC_WIN32_THREADS)
+    dnl Wine getenv may not return NULL for missing entry
     AC_DEFINE(NO_GETENV)
-    if test $enable_shared = yes; then
-      AC_DEFINE(GC_DLL)
+    ;;
+ dgux386)
+    THREADS=dgux386
+AC_MSG_RESULT($THREADLIBS)
+    # Use pthread GCC  switch
+    THREADLIBS=-pthread
+    if test "${enable_parallel_mark}" = yes; then
+        AC_DEFINE(PARALLEL_MARK)
     fi
+    AC_DEFINE(THREAD_LOCAL_ALLOC)
+    AC_DEFINE(GC_DGUX386_THREADS)
+    AC_DEFINE(DGUX_THREADS)
+    # Enable _POSIX4A_DRAFT10_SOURCE with flag -pthread
+    INCLUDES="-pthread $INCLUDES"
+    ;;
+ aix)
+    THREADS=posix
+    THREADLIBS=-lpthread
+    AC_DEFINE(GC_AIX_THREADS)
+    AC_DEFINE(_REENTRANT)
     ;;
  decosf1 | irix | mach | os2 | solaris | dce | vxworks)
     AC_MSG_ERROR(thread package $THREADS not yet supported)
@@ -129,7 +169,22 @@ case "$THREADS" in
 esac
 AC_SUBST(THREADLIBS)
 
-AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
+case "$host" in 
+   powerpc-*-darwin*)
+      powerpc_darwin=true
+      ;;
+esac
+AM_CONDITIONAL(POWERPC_DARWIN,test x$powerpc_darwin = xtrue)
+
+# We never want libdl on darwin. It is a fake libdl that just ends up making
+# dyld calls anyway
+case "$host" in
+  *-*-darwin*) ;;
+  *) 
+    AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
+    ;;
+esac
+
 AC_SUBST(EXTRA_TEST_LIBS)
 
 target_all=libgcjgc.la
@@ -147,6 +202,9 @@ TARGET_ECOS="$with_ecos"
 )
 
 addobjs=
+addlibs=
+addincludes=
+addtests=
 CXXINCLUDES=
 case "$TARGET_ECOS" in
    no)
@@ -157,21 +215,46 @@ case "$TARGET_ECOS" in
       addobjs="$addobjs ecos.lo"
       ;;
 esac
+
+if test "${enable_cplusplus}" = yes; then
+      addincludes="$addincludes include/gc_cpp.h include/gc_allocator.h"
+      addtests="$addtests test_cpp"
+fi
+
+AM_CONDITIONAL(CPLUSPLUS, test "${enable_cplusplus}" = yes)
+
 AC_SUBST(CXX)
 
 AC_SUBST(INCLUDES)
 AC_SUBST(CXXINCLUDES)
 
+# Configuration of shared libraries
+#
+AC_MSG_CHECKING(whether to build shared libraries)
+AC_ENABLE_SHARED
+
+case "$host" in
+ alpha-*-openbsd*)
+     enable_shared=no
+     AC_MSG_RESULT(no)
+     ;;
+ *)
+     AC_MSG_RESULT(yes)
+     ;;
+esac
+
+# Configuration of machine-dependent code
+#
+AC_MSG_CHECKING(which machine-dependent code should be used) 
 machdep=
 case "$host" in
  alpha*-*-openbsd*)
     machdep="alpha_mach_dep.lo"
     if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
        AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled)
-       AM_DISABLE_SHARED
     fi
     ;;
- alpha*-*-*)
+ alpha*-*-linux*)
     machdep="alpha_mach_dep.lo"
     ;;
  i?86-*-solaris2.[[89]]*)
@@ -185,12 +268,17 @@ case "$host" in
  mips-dec-ultrix*)
     machdep="mips_ultrix_mach-dep.lo"
     ;;
- mips*-*-linux*)
+ mips-nec-sysv*|mips-unknown-sysv*)
     ;;
+ mips*-*-linux*) 
+    ;; 
  mips-*-*)
     machdep="mips_sgi_mach_dep.lo"
     AC_DEFINE(NO_EXECUTE_PERMISSION)
     ;;
+ sparc-*-netbsd*)
+    machdep="sparc_netbsd_mach_dep.lo"
+    ;;
  sparc-sun-solaris2.3*)
     machdep="sparc_mach_dep.lo"
     AC_DEFINE(SUNOS53_SHARED_LIB)
@@ -203,16 +291,65 @@ case "$host" in
     ;;
 esac
 if test x"$machdep" = x; then
+AC_MSG_RESULT($machdep)
    machdep="mach_dep.lo"
 fi
 addobjs="$addobjs $machdep"
 AC_SUBST(addobjs)
+AC_SUBST(addincludes)
+AC_SUBST(addlibs)
+AC_SUBST(addtests)
+
+AC_PROG_LIBTOOL
+
+#
+# Check for AViiON Machines running DGUX
+#
+AC_MSG_CHECKING(if host is AViiON running DGUX)
+ac_is_dgux=no
+AC_CHECK_HEADER(sys/dg_sys_info.h,
+[ac_is_dgux=yes;])
+
+AC_MSG_RESULT($ac_is_dgux) 
+    ## :GOTCHA: we do not check anything but sys/dg_sys_info.h
+if test $ac_is_dgux = yes; then
+    if test "$enable_full_debug" = "yes"; then
+      CFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+      CXXFLAGS="-g -mstandard -DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+    else
+      CFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+      CXXFLAGS="-DDGUX -D_DGUX_SOURCE -Di386 -mno-legend -O2"
+    fi
+    AC_SUBST(CFLAGS)
+    AC_SUBST(CXXFLAGS)
+fi
+
+dnl We use these options to decide which functions to include.
+AC_ARG_WITH(target-subdir,
+[  --with-target-subdir=SUBDIR
+                          configuring with a cross compiler])
+AC_ARG_WITH(cross-host,
+[  --with-cross-host=HOST  configuring with a cross compiler])
+
+# automake wants to see AC_EXEEXT.  But we don't need it.  And having
+# it is actually a problem, because the compiler we're passed can't
+# necessarily do a full link.  So we fool automake here.
+if false; then
+  # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
+  # to nothing, so nothing would remain between `then' and `fi' if it
+  # were not for the `:' below.
+  :
+  AC_EXEEXT
+fi
 
 dnl As of 4.13a2, the collector will not properly work on Solaris when
 dnl built with gcc and -O.  So we remove -O in the appropriate case.
+dnl
+AC_MSG_CHECKING(whether Solaris gcc optimization fix is necessary)
 case "$host" in
- sparc-sun-solaris2*)
+ sparc-sun-solaris2*|*aix*)
     if test "$GCC" = yes; then
+       AC_MSG_RESULT(yes)
        new_CFLAGS=
        for i in $CFLAGS; do
          case "$i" in
@@ -224,8 +361,11 @@ case "$host" in
          esac
        done
        CFLAGS="$new_CFLAGS"
+    else
+       AC_MSG_RESULT(no)
     fi
     ;;
+ *) AC_MSG_RESULT(no) ;;
 esac
 
 dnl We need to override the top-level CFLAGS.  This is how we do it.
@@ -267,6 +407,9 @@ AC_ARG_ENABLE(full-debug,
        AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
        AC_DEFINE(SAVE_CALL_COUNT, 8)
       ;;
+      i[3456]86-*-dgux*)
+       AC_DEFINE(MAKE_BACK_GRAPH)
+      ;;
     esac ]
   fi)
 
index 9fc894d..d83f406 100644 (file)
@@ -219,7 +219,7 @@ CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
        result->len = result_len;
        result->left = x;
        result->right = y;
-       if (depth > MAX_DEPTH) {
+       if (depth >= MAX_DEPTH) {
            return(CORD_balance((CORD)result));
        } else {
            return((CORD) result);
@@ -260,7 +260,11 @@ CORD CORD_cat(CORD x, CORD y)
        result->len = result_len;
        result->left = x;
        result->right = y;
-       return((CORD) result);
+       if (depth >= MAX_DEPTH) {
+           return(CORD_balance((CORD)result));
+       } else {
+           return((CORD) result);
+       }
     }
 }
 
index 8d57f04..6ecc00e 100644 (file)
@@ -233,7 +233,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args)
                        if (width == NONE && prec == NONE) {
                            register char c;
 
-                           c = va_arg(args, int);
+                           c = (char)va_arg(args, int);
                            CORD_ec_append(result, c);
                            goto done;
                        }
@@ -255,12 +255,18 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args)
                /* Use standard sprintf to perform conversion */
                {
                    register char * buf;
-                   va_list vsprintf_args = args;
-                       /* The above does not appear to be sanctioned   */
-                       /* by the ANSI C standard.                      */
+                   va_list vsprintf_args;
                    int max_size = 0;
                    int res;
-                       
+#                  ifdef __va_copy
+                      __va_copy(vsprintf_args, args);
+#                  else
+#                    if defined(__GNUC__) /* and probably in other cases */
+                        va_copy(vsprintf_args, args);
+#                    else
+                       vsprintf_args = args;
+#                    endif
+#                  endif
                    if (width == VARIABLE) width = va_arg(args, int);
                    if (prec == VARIABLE) prec = va_arg(args, int);
                    if (width != NONE) max_size = width;
index fedbfbe..0bbd676 100644 (file)
@@ -249,7 +249,7 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
 
                case IDM_HELPABOUT:
                   if( DialogBox( hInstance, "ABOUTBOX",
-                                 hwnd, lpfnAboutBox ) );
+                                 hwnd, lpfnAboutBox ) )
                      InvalidateRect( hwnd, NULL, TRUE );
                   return( 0 );
               case IDM_HELPCONTENTS:
index 57de3da..f640930 100644 (file)
@@ -60,7 +60,7 @@ ptr_t p;
 # include <stdlib.h>
 
 # if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \
-     || defined(HPUX) || defined(IRIX) || defined(OSF1)
+     || defined(HPUX) || defined(IRIX5) || defined(OSF1)
 #   define RANDOM() random()
 # else
 #   define RANDOM() (long)rand()
@@ -228,6 +228,8 @@ ptr_t p;
     
 #endif /* KEEP_BACK_PTRS */
 
+# define CROSSES_HBLK(p, sz) \
+       (((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)
 /* Store debugging info into p.  Return displaced pointer. */
 /* Assumes we don't hold allocation lock.                 */
 ptr_t GC_store_debug_info(p, sz, string, integer)
@@ -243,6 +245,8 @@ word integer;
     /* But that's expensive.  And this way things should only appear   */
     /* inconsistent while we're in the handler.                                */
     LOCK();
+    GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
+    GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
 #   ifdef KEEP_BACK_PTRS
       ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
 #   endif
@@ -275,6 +279,8 @@ word integer;
     /* There is some argument that we should disable signals here.     */
     /* But that's expensive.  And this way things should only appear   */
     /* inconsistent while we're in the handler.                                */
+    GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
+    GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
 #   ifdef KEEP_BACK_PTRS
       ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
 #   endif
@@ -324,10 +330,11 @@ ptr_t p;
 {
     register oh * ohdr = (oh *)GC_base(p);
     
+    GC_ASSERT(!I_HOLD_LOCK());
     GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));
     GC_err_puts(ohdr -> oh_string);
 #   ifdef SHORT_DBG_HDRS
-      GC_err_printf1(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int));
+      GC_err_printf1(":%ld)\n", (unsigned long)(ohdr -> oh_int));
 #   else
       GC_err_printf2(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int),
                                        (unsigned long)(ohdr -> oh_sz));
@@ -342,6 +349,7 @@ ptr_t p;
     ptr_t p;
 # endif
 {
+    GC_ASSERT(!I_HOLD_LOCK());
     if (GC_HAS_DEBUG_INFO(p)) {
        GC_print_obj(p);
     } else {
@@ -355,6 +363,7 @@ ptr_t p, clobbered_addr;
 {
     register oh * ohdr = (oh *)GC_base(p);
     
+    GC_ASSERT(!I_HOLD_LOCK());
     GC_err_printf2("0x%lx in object at 0x%lx(", (unsigned long)clobbered_addr,
                                                (unsigned long)p);
     if (clobbered_addr <= (ptr_t)(&(ohdr -> oh_sz))
@@ -376,14 +385,18 @@ ptr_t p, clobbered_addr;
 
 void GC_check_heap_proc GC_PROTO((void));
 
+void GC_print_all_smashed_proc GC_PROTO((void));
+
 void GC_do_nothing() {}
 
 void GC_start_debugging()
 {
 #   ifndef SHORT_DBG_HDRS
       GC_check_heap = GC_check_heap_proc;
+      GC_print_all_smashed = GC_print_all_smashed_proc;
 #   else
       GC_check_heap = GC_do_nothing;
+      GC_print_all_smashed = GC_do_nothing;
 #   endif
     GC_print_heap_obj = GC_debug_print_heap_obj_proc;
     GC_debugging_started = TRUE;
@@ -429,6 +442,62 @@ void GC_start_debugging()
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
+# ifdef __STDC__
+    GC_PTR GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
+# else
+    GC_PTR GC_debug_malloc_ignore_off_page(lb, s, i)
+    size_t lb;
+    char * s;
+    int i;
+#   ifdef GC_ADD_CALLER
+       --> GC_ADD_CALLER not implemented for K&R C
+#   endif
+# endif
+{
+    GC_PTR result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES);
+    
+    if (result == 0) {
+        GC_err_printf1("GC_debug_malloc_ignore_off_page(%ld) returning NIL (",
+                      (unsigned long) lb);
+        GC_err_puts(s);
+        GC_err_printf1(":%ld)\n", (unsigned long)i);
+        return(0);
+    }
+    if (!GC_debugging_started) {
+       GC_start_debugging();
+    }
+    ADD_CALL_CHAIN(result, ra);
+    return (GC_store_debug_info(result, (word)lb, s, (word)i));
+}
+
+# ifdef __STDC__
+    GC_PTR GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
+# else
+    GC_PTR GC_debug_malloc_atomic_ignore_off_page(lb, s, i)
+    size_t lb;
+    char * s;
+    int i;
+#   ifdef GC_ADD_CALLER
+       --> GC_ADD_CALLER not implemented for K&R C
+#   endif
+# endif
+{
+    GC_PTR result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES);
+    
+    if (result == 0) {
+        GC_err_printf1("GC_debug_malloc_atomic_ignore_off_page(%ld)"
+                      " returning NIL (", (unsigned long) lb);
+        GC_err_puts(s);
+        GC_err_printf1(":%ld)\n", (unsigned long)i);
+        return(0);
+    }
+    if (!GC_debugging_started) {
+       GC_start_debugging();
+    }
+    ADD_CALL_CHAIN(result, ra);
+    return (GC_store_debug_info(result, (word)lb, s, (word)i));
+}
+
 # ifdef DBG_HDRS_ALL
 /* 
  * An allocation function for internal use.
@@ -447,7 +516,7 @@ void GC_start_debugging()
                       (unsigned long) lb);
         return(0);
     }
-    ADD_CALL_CHAIN(result, ra);
+    ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
     return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
   }
 
@@ -461,7 +530,7 @@ void GC_start_debugging()
                       (unsigned long) lb);
         return(0);
     }
-    ADD_CALL_CHAIN(result, ra);
+    ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
     return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
   }
 # endif
@@ -592,7 +661,7 @@ GC_PTR p;
     int i;
 # endif
 {
-    GC_PTR result = GC_malloc_uncollectable(lb + DEBUG_BYTES);
+    GC_PTR result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
     
     if (result == 0) {
         GC_err_printf1("GC_debug_malloc_uncollectable(%ld) returning NIL (",
@@ -618,7 +687,8 @@ GC_PTR p;
     int i;
 # endif
 {
-    GC_PTR result = GC_malloc_atomic_uncollectable(lb + DEBUG_BYTES);
+    GC_PTR result =
+       GC_malloc_atomic_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
     
     if (result == 0) {
         GC_err_printf1(
@@ -774,6 +844,45 @@ void GC_debug_free_inner(GC_PTR p)
 }
 
 #ifndef SHORT_DBG_HDRS
+
+/* List of smashed objects.  We defer printing these, since we can't   */
+/* always print them nicely with the allocation lock held.             */
+/* We put them here instead of in GC_arrays, since it may be useful to */
+/* be able to look at them with the debugger.                          */
+#define MAX_SMASHED 20
+ptr_t GC_smashed[MAX_SMASHED];
+unsigned GC_n_smashed = 0;
+
+# if defined(__STDC__) || defined(__cplusplus)
+    void GC_add_smashed(ptr_t smashed)
+# else
+    void GC_add_smashed(smashed)
+    ptr_t smashed;
+#endif
+{
+    GC_ASSERT(GC_is_marked(GC_base(smashed)));
+    GC_smashed[GC_n_smashed] = smashed;
+    if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed;
+      /* In case of overflow, we keep the first MAX_SMASHED-1  */
+      /* entries plus the last one.                            */
+    GC_have_errors = TRUE;
+}
+
+/* Print all objects on the list.  Clear the list.     */
+void GC_print_all_smashed_proc ()
+{
+    unsigned i;
+
+    GC_ASSERT(!I_HOLD_LOCK());
+    if (GC_n_smashed == 0) return;
+    GC_err_printf0("GC_check_heap_block: found smashed heap objects:\n");
+    for (i = 0; i < GC_n_smashed; ++i) {
+        GC_print_smashed_obj(GC_base(GC_smashed[i]), GC_smashed[i]);
+       GC_smashed[i] = 0;
+    }
+    GC_n_smashed = 0;
+}
+
 /* Check all marked objects in the given block for validity */
 /*ARGSUSED*/
 # if defined(__STDC__) || defined(__cplusplus)
@@ -802,11 +911,7 @@ void GC_debug_free_inner(GC_PTR p)
                && GC_HAS_DEBUG_INFO((ptr_t)p)) {
                ptr_t clobbered = GC_check_annotated_obj((oh *)p);
                
-               if (clobbered != 0) {
-                   GC_err_printf0(
-                       "GC_check_heap_block: found smashed location at ");
-                   GC_print_smashed_obj((ptr_t)p, clobbered);
-               }
+               if (clobbered != 0) GC_add_smashed(clobbered);
            }
            word_no += sz;
            p += sz;
@@ -819,9 +924,11 @@ void GC_debug_free_inner(GC_PTR p)
 void GC_check_heap_proc()
 {
 #   ifndef SMALL_CONFIG
-       if (sizeof(oh) & (2 * sizeof(word) - 1) != 0) {
-           ABORT("Alignment problem: object header has inappropriate size\n");
-       }
+#     ifdef ALIGN_DOUBLE
+        GC_STATIC_ASSERT((sizeof(oh) & (2 * sizeof(word) - 1)) == 0);
+#     else
+        GC_STATIC_ASSERT((sizeof(oh) & (sizeof(word) - 1)) == 0);
+#     endif
 #   endif
     GC_apply_to_all_blocks(GC_check_heap_block, (word)0);
 }
@@ -842,12 +949,12 @@ struct closure {
 # endif
 {
     struct closure * result =
-#              ifdef DBG_HDRS_ALL
-                 (struct closure *) GC_debug_malloc(sizeof (struct closure),
-                                                    GC_EXTRAS);
-#              else
-                 (struct closure *) GC_malloc(sizeof (struct closure));
-#              endif
+#   ifdef DBG_HDRS_ALL
+      (struct closure *) GC_debug_malloc(sizeof (struct closure),
+                                        GC_EXTRAS);
+#   else
+      (struct closure *) GC_malloc(sizeof (struct closure));
+#   endif
     
     result -> cl_fn = fn;
     result -> cl_data = data;
@@ -908,7 +1015,7 @@ GC_PTR *ocd;
     ptr_t base = GC_base(obj);
     if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
         GC_err_printf1(
-           "GC_register_finalizer called with non-base-pointer 0x%lx\n",
+           "GC_debug_register_finalizer called with non-base-pointer 0x%lx\n",
            obj);
     }
     if (0 == fn) {
@@ -940,7 +1047,7 @@ GC_PTR *ocd;
     ptr_t base = GC_base(obj);
     if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
         GC_err_printf1(
-         "GC_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
+         "GC_debug_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
          obj);
     }
     if (0 == fn) {
@@ -973,7 +1080,7 @@ GC_PTR *ocd;
     ptr_t base = GC_base(obj);
     if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
         GC_err_printf1(
-           "GC_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
+           "GC_debug_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
            obj);
     }
     if (0 == fn) {
diff --git a/boehm-gc/doc/Makefile.am b/boehm-gc/doc/Makefile.am
deleted file mode 100644 (file)
index 9144630..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# 
-# 
-# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-# OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
-# 
-# Permission is hereby granted to use or copy this program
-# for any purpose,  provided the above notices are retained on all copies.
-# Permission to modify the code and to distribute modified code is granted,
-# provided the above notices are retained, and a notice that the code was
-# modified is included with the above copyright notice.
-#
-# Modified by: Grzegorz Jakacki <jakacki at acm dot org>
-
-## Process this file with automake to produce Makefile.in.
-
-# installed documentation
-#
-dist_pkgdata_DATA = barrett_diagram debugging.html gc.man \
-    gcdescr.html README README.amiga README.arm.cross \
-    README.autoconf README.changes README.contributors \
-    README.cords README.DGUX386 README.dj README.environment \
-    README.ews4800 README.hp README.linux README.Mac \
-    README.MacOSX README.macros README.OS2 README.rs6000 \
-    README.sgi README.solaris2 README.uts README.win32 \
-    tree.html leak.html gcinterface.html scale.html \
-    README.darwin
-
diff --git a/boehm-gc/doc/Makefile.in b/boehm-gc/doc/Makefile.in
deleted file mode 100644 (file)
index 9bf1ff5..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-# Makefile.in generated by automake 1.6.3 from Makefile.am.
-# @configure_input@
-
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-# 
-# 
-# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-# OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
-# 
-# Permission is hereby granted to use or copy this program
-# for any purpose,  provided the above notices are retained on all copies.
-# Permission to modify the code and to distribute modified code is granted,
-# provided the above notices are retained, and a notice that the code was
-# modified is included with the above copyright notice.
-#
-# Modified by: Grzegorz Jakacki <jakacki at acm dot org>
-SHELL = @SHELL@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = @program_transform_name@
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-host_alias = @host_alias@
-host_triplet = @host@
-
-EXEEXT = @EXEEXT@
-OBJEXT = @OBJEXT@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-AMTAR = @AMTAR@
-AR = @AR@
-AS = @AS@
-AWK = @AWK@
-CC = @CC@
-CCAS = @CCAS@
-CCASFLAGS = @CCASFLAGS@
-CFLAGS = @CFLAGS@
-CXX = @CXX@
-CXXFLAGS = @CXXFLAGS@
-CXXINCLUDES = @CXXINCLUDES@
-DEPDIR = @DEPDIR@
-DLLTOOL = @DLLTOOL@
-ECHO = @ECHO@
-EXTRA_TEST_LIBS = @EXTRA_TEST_LIBS@
-GC_CFLAGS = @GC_CFLAGS@
-GC_VERSION = @GC_VERSION@
-INCLUDES = @INCLUDES@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-MAINT = @MAINT@
-MY_CFLAGS = @MY_CFLAGS@
-OBJDUMP = @OBJDUMP@
-PACKAGE = @PACKAGE@
-RANLIB = @RANLIB@
-STRIP = @STRIP@
-THREADLIBS = @THREADLIBS@
-VERSION = @VERSION@
-addincludes = @addincludes@
-addlibs = @addlibs@
-addobjs = @addobjs@
-addtests = @addtests@
-am__include = @am__include@
-am__quote = @am__quote@
-install_sh = @install_sh@
-target_all = @target_all@
-
-# installed documentation
-#
-dist_pkgdata_DATA = barrett_diagram debugging.html gc.man \
-    gcdescr.html README README.amiga README.arm.cross \
-    README.autoconf README.changes README.contributors \
-    README.cords README.DGUX386 README.dj README.environment \
-    README.ews4800 README.hp README.linux README.Mac \
-    README.MacOSX README.macros README.OS2 README.rs6000 \
-    README.sgi README.solaris2 README.uts README.win32 \
-    tree.html leak.html gcinterface.html scale.html \
-    README.darwin
-
-subdir = doc
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_CLEAN_FILES =
-DIST_SOURCES =
-DATA = $(dist_pkgdata_DATA)
-
-DIST_COMMON = README $(dist_pkgdata_DATA) Makefile.am Makefile.in
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
-       cd $(top_srcdir) && \
-         $(AUTOMAKE) --gnu  doc/Makefile
-Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in  $(top_builddir)/config.status
-       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
-
-mostlyclean-libtool:
-       -rm -f *.lo
-
-clean-libtool:
-       -rm -rf .libs _libs
-
-distclean-libtool:
-       -rm -f libtool
-uninstall-info-am:
-dist_pkgdataDATA_INSTALL = $(INSTALL_DATA)
-install-dist_pkgdataDATA: $(dist_pkgdata_DATA)
-       @$(NORMAL_INSTALL)
-       $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
-       @list='$(dist_pkgdata_DATA)'; for p in $$list; do \
-         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-         f="`echo $$p | sed -e 's|^.*/||'`"; \
-         echo " $(dist_pkgdataDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgdatadir)/$$f"; \
-         $(dist_pkgdataDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgdatadir)/$$f; \
-       done
-
-uninstall-dist_pkgdataDATA:
-       @$(NORMAL_UNINSTALL)
-       @list='$(dist_pkgdata_DATA)'; for p in $$list; do \
-         f="`echo $$p | sed -e 's|^.*/||'`"; \
-         echo " rm -f $(DESTDIR)$(pkgdatadir)/$$f"; \
-         rm -f $(DESTDIR)$(pkgdatadir)/$$f; \
-       done
-tags: TAGS
-TAGS:
-
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-
-top_distdir = ..
-distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
-
-distdir: $(DISTFILES)
-       @list='$(DISTFILES)'; for file in $$list; do \
-         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-           dir="/$$dir"; \
-           $(mkinstalldirs) "$(distdir)$$dir"; \
-         else \
-           dir=''; \
-         fi; \
-         if test -d $$d/$$file; then \
-           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-           fi; \
-           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-         else \
-           test -f $(distdir)/$$file \
-           || cp -p $$d/$$file $(distdir)/$$file \
-           || exit 1; \
-         fi; \
-       done
-check-am: all-am
-check: check-am
-all-am: Makefile $(DATA)
-
-installdirs:
-       $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
-
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-       @echo "This command is intended for maintainers to use"
-       @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool mostlyclean-am
-
-distclean: distclean-am
-
-distclean-am: clean-am distclean-generic distclean-libtool
-
-dvi: dvi-am
-
-dvi-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-dist_pkgdataDATA
-
-install-exec-am:
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-
-uninstall-am: uninstall-dist_pkgdataDATA uninstall-info-am
-
-.PHONY: all all-am check check-am clean clean-generic clean-libtool \
-       distclean distclean-generic distclean-libtool distdir dvi \
-       dvi-am info info-am install install-am install-data \
-       install-data-am install-dist_pkgdataDATA install-exec \
-       install-exec-am install-info install-info-am install-man \
-       install-strip installcheck installcheck-am installdirs \
-       maintainer-clean maintainer-clean-generic mostlyclean \
-       mostlyclean-generic mostlyclean-libtool uninstall uninstall-am \
-       uninstall-dist_pkgdataDATA uninstall-info-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
index 6ac37c6..29d954f 100644 (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-2001 by Hewlett-Packard Company. All rights reserved.
+Copyright (c) 1999-2003 by Hewlett-Packard Company. All rights reserved.
 
 The file linux_threads.c is also
 Copyright (c) 1998 by Fergus Henderson.  All rights reserved.
@@ -9,8 +9,9 @@ Copyright (c) 1998 by Fergus Henderson.  All rights reserved.
 The files Makefile.am, and configure.in are
 Copyright (c) 2001 by Red Hat Inc. All rights reserved.
 
-The files config.guess and a few others are copyrighted by the Free
-Software Foundation.
+Several files supporting GNU-style builds are copyrighted by the Free
+Software Foundation, and carry a different license from that given
+below.
 
 THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -27,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.1alpha3 of a conservative garbage collector for C and C++.
+This is version 6.3alpha1 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
@@ -228,10 +229,12 @@ and several of those are compatible with the collector.
 or equivalent is supplied.  Many of these have separate README.system
 files.
 
-  Dynamic libraries are completely supported only under SunOS
+  Dynamic libraries are completely supported only under SunOS/Solaris,
 (and even that support is not functional on the last Sun 3 release),
-Linux, IRIX 5&6, HP-PA, Win32 (not Win32S) and OSF/1 on DEC AXP machines.
-On other machines we recommend that you do one of the following:
+Linux, FreeBSD, NetBSD, IRIX 5&6, HP/UX, Win32 (not Win32S) and OSF/1
+on DEC AXP machines plus perhaps a few others listed near the top
+of dyn_load.c.  On other machines we recommend that you do one of
+the following:
 
   1) Add dynamic library support (and send us the code).
   2) Use static versions of the libraries.
@@ -245,6 +248,8 @@ On other machines we recommend that you do one of the following:
   In all cases we assume that pointer alignment is consistent with that
 enforced by the standard C compilers.  If you use a nonstandard compiler
 you may have to adjust the alignment parameters defined in gc_priv.h.
+Note that this may also be an issue with packed records/structs, if those
+enforce less alignment for pointers.
 
   A port to a machine that is not byte addressed, or does not use 32 bit
 or 64 bit addresses will require a major effort.  A port to plain MSDOS
index 2abf0b4..f5333d5 100644 (file)
@@ -1,27 +1 @@
-While the GC should work on MacOS X Server, MacOS X and Darwin, I only tested
-it on MacOS X Server.
-I've added a PPC assembly version of GC_push_regs(), thus the setjmp() hack is
-no longer necessary. Incremental collection is supported via mprotect/signal.
-The current solution isn't really optimal because the signal handler must decode
-the faulting PPC machine instruction in order to find the correct heap address.
-Further, it must poke around in the register state which the kernel saved away
-in some obscure register state structure before it calls the signal handler -
-needless to say the layout of this structure is no where documented.
-Threads and dynamic libraries are not yet supported (adding dynamic library
-support via the low-level dyld API shouldn't be that hard).
-
-The original MacOS X port was brought to you by Andrew Stone.
-
-
-June, 1 2000
-
-Dietmar Planitzer
-dave.pl@ping.at
-
-Note from Andrew Begel:
-
-One more fix to enable gc.a to link successfully into a shared library for
-MacOS X. You have to add -fno-common to the CFLAGS in the Makefile. MacOSX
-disallows common symbols in anything that eventually finds its way into a
-shared library. (I don't completely understand why, but -fno-common seems to
-work and doesn't mess up the garbage collector's functionality).
+See README.darwin for the latest Darwin/MacOSX information.
index 232938b..619ea2e 100644 (file)
@@ -1469,8 +1469,439 @@ Since 6.1 alpha2:
  - Caused the Solaris and Irix thread creation primitives to call
    GC_init_inner().
  
+Since 6.1alpha3:
+ - Fixed typo in sparc_mach_dep.S, preventing the 64-bit version from
+   building.  Increased 64-bit heap size limit in test.c slightly, since
+   a functional SPARC collector seems to slightly exceed the old limits.
+   (Thanks again to Jeff Sturm.)
+ - Use NPRGREG in solaris_threads.c, thus printing all registers if things
+   go wrong.
+ - Added GC_MARKERS environment variable to allow use of a single marker
+   thread on an MP without confusing the lock implementation.
+ - Collect much less aggressively in incremental mode with GC_TIME_UNLIMITED.
+   This is really a purely generational mode, and we can afford to 
+   postpone the collection until the heap is (nearly) full.
+ - Remove read() wrapper for MPROTECT_VDB.  It was causing more harm than
+   good.  It is often no longer needed if system calls avoid writing to
+   pointerfull heap objects.
+ - Fix MACOSX test in gcconfig.h. (Thanks to John Clements.)
+ - Change GC_test_and_set so that it consistently has one argument.
+   Add spaces to ::: in powerpc assembly code in gc_locks.h.
+   (Thanks to Ryan Murray.)
+ - Fixed a formatting error in dbg_mlc.c.  Added prototype to GC_abort()
+   declaration.   (Thanks to Michael Smith.)
+ - Removed "source" argument to GC_find_start().  Eliminate GC_FIND_START().
+ - Added win32 recognition code in configure.in.  Changed some of the
+   dllimport/export defines in gc.h.  (Thanks to Adam Megacz.)
+ - GC_malloc_many didn't set hb_last_reclaimed when it called 
+   GC_reclaim_generic.  (I'm not sure this matters much, but ...)
+ - Allocating uncollectable objects with debug information sometimes
+   allocated objects that were one byte too small, since uncollectable
+   objects don't have the extra byte added at the end.  (Thanks to
+   Wink Saville for pointing this out.)
+ - Added a bit more assertion checking to make sure that gcj objects
+   on free lists never have a nonzero second word.
+ - Replaced BCC_MAKEFILE with an up-to-date one.  (Thanks to 
+   Andre Leiradella.)
+ - Upgraded libtool, cinfigure.in and some related files to hopefully
+   support NetBSD/SPARC.  (Thanks to Adrian Bunk.)  Unfortunately,
+   libtool 1.4.2 seemed to be buggy due to missing quotes in several
+   "test" invocations.  Fixed those in the ltmain.sh script.
+ - Some win32-specific patches, including the introduction of
+   GC_CreateThread.  (Thanks to Adam Megacz.)
+ - Merged in gcj changes from Anthony Green to support embedded systems.
+ - Tried to consistently rename preprocessed assembly files with a capital
+   .S extension.
+ - Use alpha_mach_dep.S on ALPHA again.  It doesn't really matter, but this
+   makes our distribution consistent with the gcc one, avoiding future merge
+   problems.
+ - Move GET_MEM definition into gcconfig.h.  Include gcconfig.h slightly
+   later in gc_priv.h to avoid forward references to ptr_t.
+ - Add some testing of local allocation to test.c.
+ - Change definition of INVALID_QTID in specific.h.  The -1 value was used
+   inconsistently, and too likely to collide with a valid stack address.
+   Some general clean-up of specific.[ch].  Added assertions.  (Thanks
+   to Michael Smith for tracking down an intermittent bug to this
+   general area.  I'm not sure it has been squashed yet, however.)
+ - On Pthread systems it was not safe to call GC_malloc() between fork()
+   and exec().  According to the applicable standards, it doesn't appear
+   to be safe to call malloc() or many other libc functions either, thus
+   it's not clear this is fixable.  Added experimental support for
+   -DHANDLE_FORK in linux_threads.c which tries to support it.  It may
+   succeed if libc does the right thing.  I'm not sure whether it does.
+   (Thanks to Kenneth Schalk for pointing out this issue.)
+ - Documented thread local allocation primitives to require an
+   explicit GC_init call.  GC_init_parallel is no longer declared to
+   be a constructor function, since that isn't portable and often
+   seems to lead to initialization order problems.
+ - Changed gc_cpp.cc and gc_cpp.h in one more attempt to make them
+   compatible with Visual C++ 6.  (Thanks to Wink Saville for the
+   patch.)
+ - Some more patches for Linux on HP PA-RISC.
+ - Added include/gc_allocator.h.  It implements (hopefully) standard
+   conforming (as opposed to SGI-style) allocators that allocate
+   collectable (gc_allocator) or GC-traceable, but not collectable
+   (traceable_allocator) objects.  This borrows heavily from libstc++,
+   which borrows heavily from the SGI implementation, this part of
+   which was written by Matt Austern.  Changed test_cpp.cc to very
+   minimally test this.
+ - On Linux/X86, retry mmap with a different start argument.  That should
+   allow the collector to use more (closer to 3GB) of the address space.
+   (Thanks to Jeffrey Mark Siskind for tracking this down.)
+ - Force 64 bit alignment with GCJ support.  (Reflects Bryce McKinley's
+   patch to the gcc tree.)
+ - Refined the choice of sa_handler vs. sa_sigaction in GC_dirty_init
+   to accomodate some glibc5 systems.  (Thanks to Dan Fandrich for the
+   patch.)
+ - Compensated for the fact that current versions of glibc set
+   __libc_stack_end incorrectly on Linux/IA64 while initialization code
+   is running.  This could cause the collector to miss 16 bytes of
+   the memory stack if GC_malloc or friends where called before main().
+ - Mostly integrated Takis Psarogiannakopoulos' port to DG/UX Inix 86.
+   This will probably take another iteration to work, since his
+   patch conflicted with the libtool upgrade. 
+ - Added README.arm.cross containing some information about cross-
+   compiling to an ARM processor from Margaret Fleck.
+
+Since 6.1alpha4:
+ - Added GC_finalizer_mem_freed, and changed some of the code that
+   decided on heap expansion to look at it.  Memory explicitly
+   deallocated by finalizers essentially needs to be counted as reclaimed
+   by the GC.  Otherwise there are cases in which the heap can grow
+   unboundedly.  (Thanks to Mark Reichert for the test case.)
+ - Integrated Adam Megacz patches to not scan dynamic libraries if
+   we are compiling with gcc on win32.  Otherwise we need structured
+   exception handling to deal with asynchronously unmapped root
+   segments, and gcc doesn't directly support that.
+ - Integrated Anthony Green's patch to support Wine.
+ - GC_OPERATOR_NEW_ARRAY was misspelled OPERATOR_NEW_ARRAY in several
+   places, including gc_cpp.cc.  (Thanks to Wink Saville for pointing
+   this out.)
+ - Integrated Loren James Rittle's Alpha FreeBSD patches.  In
+   response to Richard Henderson's suggestion, these also
+   changed the declarations of symbols like _end on many platforms to
+   that they wouldn't mistakenly be declared as short data symbols.
+ - Integrated changes from the Debian distribution.  (Thanks to Ryan Murray
+   for pointing these out.)  Fix C++ comments in POWERPC port.  Add ARM32
+   incremental GC support.  Get rid of USE_GENERIC_PUSH_REGS for alpha/Linux,
+   this time for real.  Use va_copy to get rid of cord printf problems
+   (finally).
+ - Close file descriptor used to count cpus.  Thanks to Jeff Sturm for
+   pointing out the omission.
+ - Don't just drop gcj free lists in GC_start_reclaim, since that can
+   eventually cause the marker to see a bogus mark descriptor in the 
+   dropped objects.  The usual symptom was a very intermittent segmentation
+   fault in the marker.  This mattered only if one of the GC_gcj_malloc
+   variants was used.  (Thanks to Michael Smith, Jeff Sturm, Bryce
+   McKinley and Tom Tromey for helping to track this down.)
+ - Fixed Linux and Solaris/64 SPARC configuration.  (Thanks to David Miller,
+   Jeff Sturm, Tom Tromey, and Christian Joensson.)
+ - Fixed a typo in strdup definition.  (Thanks to Gerard A Allan.)
+ - Changed Makefile.direct to invoke $(CC) to assemble alpha_mach_dep.S.
+   This is needed on Linux.  I'm not sure whether it's better or worse
+   on Tru64.
+ - Changed gc_cpp.h once more to declare operator new and friends only in
+   a Microsoft environment.  This may need further fine tuning.  (Thanks to
+   Johannes Schmidt for pointing out that the older code breaks on gcc3.0.4.)
+ - Don't ever override strdup if it's already macro defined.  (Thanks to
+   Adnan Ali for pointing out the problem.)
+ - Changed gc_cpp.h yet again to also overload placement new.  Due to the
+   C++ overloading rules, the other overloaded new operations otherwise hide
+   placement new, which causes many STL uses to break.  (Thanks to Reza
+   Shahidi for reporting this, and to Matt Austern for proposing a fix.)
+ - Integrated cygwin pthreads support from Dan Bonachea.
+ - Turn on DYNAMIC_LOADING for NetBSD.  (Thanks to Krister Walfridsson.)
+ - Changed printing code to print more complete GC times.
+ - Applied Mark Mitchell's Irix patch to correct some bitrot.
+ - Clarified which object-printing routines in dbg_mlc.c should hold
+   the allocation lock.  Restructured the code to allow reasonable object
+   printing with -DREDIRECT_MALLOC.
+ - Fix the Linux mmap code to always start with 0x1000 as the initial hint.
+   Minor patches for 64-bit AIX, particularly to STACKBOTTOM.
+   (Thanks again to Jeffrey Mark Siskind.)
+ - Renamed "SUSPENDED" flag for Solaris threads support to avoid a conflict
+   with a system header. (Thanks to Philp Brown.)
+ - Cause win32_threads.c to handle an out of range stack pointer correctly,
+   though currently with a warning.  (Thanks to Jonathan Clark for
+   observing that win32 applications may temporarily use the stack
+   pointer for other purposes, and suggesting a fix.  Unfortunately, it's
+   not clear that there is a complete solution to this problem.)
+
+Since 6.1alpha5:
+ - Added GC_MAXIMUM_HEAP_SIZE environment variable.
+ - Fix configure.in for MIPS/LINUX. (Thanks to H.J. Lu.)
+ - Double page hash table size for -DLARGE_CONFIG.
+ - Integrated Bo Thorsen's X86-64 support.
+ - STACKBOTTOM definition for LINUX/MIPS was partially changed back.
+   (Thanks to H.J. Lu and Hiroshi Kawashima for resolving this.)
+ - Replaced all occurrences of LINUX_DATA_START in gcconfig.h with
+   SEARCH_FOR_DATA_START.  It doesn't hurt to falll back to a search.
+   And __data_start doesn't seem to get defined correctly of the GC
+   library is loaded with LD_PRELOAD, e.g. for leak detection.
+ - If the GC_find_leak environment variable is set, do a
+   atexit(GC_gcollect) to give us at least one chance to detect leaks.
+   This may report some very benign leaks, but ...
+ - Addeded REDIRECT_FREE.  It's necessary if we want leak detection with
+   LD_PRELOAD.
+ - Defer printing of leaked objects, as for smashed objects.
+ - Fixed process and descriptor leak in GC_print_callers.  Try for
+   line number even if we got function name.)
+ - Ported parallel GC support and thread local allocation to Alpha.
+   Not yet well-tested.
+ - Added GC_DUMP_REGULARLY and added finalization statistics to GC_dump().
+ - Fixed Makefile.am to mention alpha_mach_dep.S instead of the defunct
+   alpha_mach_dep.s.  (Thanks to Fergus Henderson.)
+ - Incorporated a change to new_gc_alloc.h, suggested by Johannes Schmidt,
+   which should make it work with gcc3.1.  (I would still like to encourage
+   use of gc_allocator.h instead.) 
+ - Use alpha_mach_dep.S only on Linux.  (It's not clear that this is
+   optimal, but it otherwise didn't build on Tru64.  Thanks to Fergus
+   Henderson.)
+ - Added ifdef to guard free() in os_dep.c.  Otherwise we get a
+   compilation error on Irix.  (Thanks to Dai Sato.)
+ - Added an experimental version of GC_memalign to mallocx.c.  This can't
+   always work, since we don't handle alignment requests in the hblk-level
+   allocator, and we can't handle arbitrary pointer displacements unless
+   GC_all_interior_pointers is enabled.  But it should work for alignment
+   requests up to HBLKSIZE.  This is not yet documented in the standard
+   places.
+ - Finally debugged the OSF1/Tru64 thread support.  This needs more testing,
+   since I needed to add a somewhat unconvincing workaround for signal
+   delivery issues that I don't yet completely understand.  But it does
+   pass my tests, even in parallel GC mode.  Incremental GC support is
+   disabled if thread support is enabled, due to the signal issues.
+ - Eliminated name-space-incorrect definition of _cdecl from gc_cpp.h.
+ - Added GC_debug_malloc_replacement and GC_debug_realloc_replacement
+   declarations to gc.h.  On IA64, this is required for REDIRECT_MALLOC
+   to work correctly with these.
+ - Fixed Linux USE_PROC_FOR_LIBRARIES to work with a 64-bit /proc format.
+
+Since 6.1:
+ - Guard the test for GC_DUMP_REGULARLY in misc.c with
+   "#ifndef NO_DEBUGGING".  Otherwise it fails to build with NO_DEBUGGING
+   defined.  (Thanks to Manuel Serrano.)
+ - Message about retrying suspend signals was incorrectly generated even when
+   flag was not set.
+ - Cleaned up MACOSX/NEXT root registration code.  There was apparently a
+   separate ifdef case in GC_register_data_segments() for no reason.
+ - Removed MPROTECT_VDB for MACOSX port, based on one negative report.
+ - Arrange for gc.h and friends to be correctly installed with GNU-style
+   "make install".
+ - Enable the GNU-style build facility include C++ support in the library
+   with --enable-cplusplus. (Thanks to Thomas Maier for some of the patch.)
+ - Mark from GC_thread_key in linux_threads.c, in case that's allocated
+   from the garbage collected heap, as it is with our own thread-specific
+   storage implementation.  (Thanks to Jeff Sturm.)
+ - Mark all free list header blocks if they are heap allocated.  This avoids
+   some unnecessary tracing.  And it remains correct if we clear the
+   root set. (Thanks to Jeff Sturm for identifying the bug.)
+ - Improved S390/Linux support.  Add S390/Linux 64-bit support.  (Thanks
+   to Ulrich Weigand.)
+ - Corrected the spelling of GC_{M,C}ALLOC_EXPLICTLY_TYPED to
+   GC_{M,C}ALLOC_EXPLICITLY_TYPED in gc_typed.h.  This is technically
+   an interface change.  Based on the fact that nobody reported this,
+   I suspect/hope there were no clients.
+ - Cleaned up gc_typed.h so that (1) it adds an extern "C" declaration
+   when appropriate, (2) doesn't generate references to undefined internal
+   macros, and (3) allows easier manual construction of descriptors.
+ - Close the file descriptor used by GC_print_address_map().
+ - Set the "close-on-exec" bit for various file descriptors maintained
+   for the collector's internal use.
+ - Added a hack to find memory segments owned by the system allocator
+   under win32.  Based on my tests, this tends to eventually find all
+   segments, though it may take a while.  There appear to be cleaner,
+   but slower solutions under NT/XP.  But they rely on an API that's
+   unsupported under 9X.
+ - Changed Linux PowerPC stack finding to LINUX_STACKBOTTOM.  (Thanks
+   to Akira Tagoh for pointing out that HEURISTIC1 doesn't work on
+   64-bit kernels.)
+ - Added GC_set_free_space_divisor to avoid some Windows dll issues.
+ - Added FIXUP_POINTER, POINTER_SHIFT, POINTER_MASK to allow preprocessing
+   of candidate pointers for tagging, etc.
+ - Always lock around GC_notify_full_gc().  Simplified code for
+   invoking GC_notify_full_gc().
+ - Changed the way DATASTART is defined on FreeBSD to be robust against
+   an unmapped page after etext.  (Thanks to Hironori Sakamoto for
+   tracking down the intermittent failure.)
+ - Made GC_enable() and GC_disable() official.  Deprecated direct update
+   of GC_dont_gc.  Changed GC_gcollect to be a noop when garbage collection
+   is disabled.
+ - Call GC_register_dynamic_libraries before stopping the world on Linux,
+   in order to avoid a potential deadlock due to the dl_iterate_phdr lock.
+ - Introduced a more general mechanism for platform-dependent code to
+   decide whether the main data segment should be handled separately
+   from dynamic libraries, or registered by GC_register_dynamic_libraries.
+   The latter is more reliable and easier on Linux with dl_iterate_phdr. 
+
+Since 6.2alpha1:
+ - Fixed the completely broken FreeBSD code in 6.2alpha1.  (Thanks to
+   Hironori Sakamoto for the patch.)
+ - Changed IRIX reference in dbg_mlc.c to IRIX5. (Thanks to Marcus Herbert.)
+ - Attempted to work around the problems with .S filenames and the SGI
+   compiler.  (Reported by several people. Untested.)
+ - Worked around an HP/UX make issue with the GNU-style build process.
+ - Fixed the --enable-cplusplus build machinery to allow builds without
+   a C++ compiler.  (That was always the intent ...)
+ - Changed the debugging allocation macros to explicitly pass the return
+   address for Linux and XXXBSD on hardware for which we can't get stack
+   traces.  Use __builtin_return_address(0) to generate it when possible.
+   Some of the configuration work was cleaned up (good) and moved to gc.h
+   (bad, but necessary).  This should make leak detection more useful
+   on a number of platforms.  (Thanks to Fabian Thylman for the suggestion.)
+ - Fixed compilation problems in dbg_mlc.c with GC_ADD_CALLER.
+ - Bumped revision number for dynamic library.
+
+Since 6.2alpha2:
+ - Don't include execinfo.h in os_dep.c when it's not needed, and may not exist.
+
+Since 6.2alpha3:
+ - Use LINUX_STACKBOTTOM for >= glibc2.2 on Linux/MIPS.  (See Debian bug
+   # 177204)
+ - Integrated Jeff Sturm and Jesse Rosenstock's MACOSX threads patches.
+ - Integrated Grzegorz Jakacki's substantial GNU build patch.  "Make dist"
+   should now work for the GNU build process.  Documentation files
+   are installed under share/gc.
+ - Tweaked gc_cpp.h to again support the Borland compiler.  (Thanks to
+   Rene Girard for pointing out the problems.)
+ - Updated BCC_MAKEFILE (thanks to Rene Girard).
+ - Added GC_ASSERT check for minimum thread stack size.
+ - Added --enable-gc-assertions.
+ - Added some web documentation to the distribution.  Updated it in the
+   process.
+ - Separate gc_conf_macros.h from gc.h.
+ - Added generic GC_THREADS client-defined macro to set the appropriate
+   GC_XXX_THREADS internal macro.  (gc_config_macros.h.)
+ - Add debugging versions of _ignore_off_page allocation primitves.
+ - Moved declarations of GC_make_closure and GC_debug_invoke_finalizer
+   from gc.h to gc_priv.h.
+ - Reset GC_fail_count even if only a small allocation succeeds.
+ - Integrated Brian Alliet's patch for dynamic library support on Darwin.
+ - gc_cpp.h's gc_cleanup destructor called GC_REGISTER_FINALIZER_IGNORE_SELF
+   when it should have called the lower case version, since it was
+   explicitly computing a base pointer.
+
+Since 6.2alpha4:
+ - GC_invoke_finalizers could, under rare conditions, set
+   GC_finalizer_mem_freed to an essentially random value.  This could
+   possibly cause unbounded heap growth for long-running applications
+   under some conditions.  (The bug was introduced in 6.1alpha5, and
+   is not in gcc3.3.  Thanks to Ben Hutchings for finding it.)
+ - Attempted to sanitize the various DLL macros.  GC_USE_DLL disappeared.
+   GC_DLL is used instead.  All internal tests are now on GC_DLL.
+   README.macros is now more precise about the intended meaning.
+ - Include DllMain in the multithreaded win32 version only if the
+   collector is actually built as a dll.  (Thanks to Mohan Embar for
+   a version of the patch.)
+ - Hide the cygwin threadAttach/Detach functions.  They were violating our
+   namespace rules.  
+ - Fixed an assertion in GC_check_heap_proc.  Added GC_STATIC_ASSERT.
+   (Thanks again to Ben Hutchings.)
+ - Removed some obsolete definitions for Linux/PowerPC in gcconfig.h.
+ - CORD_cat was not rebalancing unbalanced trees in some cases, violating
+   a CORD invariant.  Also tweaked the rebalancing rule for
+   CORD_cat_char_star.  (Thanks to Alexandr Petrosian for the bug report
+   and patch.)
+ - Added hand-coded structured exception handling support to mark.c.
+   This should enable support of dynamic libraries under win32 with
+   gcc-compiled code.  (Thanks to Ranjit Mathew for the patch.)
+   Turned on dynamic library scanning for win32/gcc.
+ - Removed some remnants of read wrapping.  (Thanks to Kenneth Schalk.)
+   GC_USE_LD_WRAP ws probably broken in recent versions.
+ - The build could fail on some platforms since gcconfig.h could include
+   declarations mentioning ptr_t, which was not defined, e.g. when if_mach
+   was built.  (Thanks to Yann Dirson for pointing this out.)  Also
+   cleaned up tests for GC_PRIVATE_H in gcconfig.h a bit. 
+ - The GC_LOOP_ON_ABORT environment variable interfered with incremental
+   collection, since the write fault handler was erroneously overridden.
+   Handlers are now set up in the correct order.
+ - It used to be possible to call GC_mark_thread_local_free_lists() while
+   the world was not stopped during an incremental GC.  This was not safe.
+   Fortunately, it was also unnecessary.  Added GC_world_stopped flag
+   to avoid it.  (This caused occasional crashes in GC_set_fl_marks
+   with thread local allocation and incremental GC.  This probably happened
+   primarily on old, slow multiprocessors.)
+ - Allowed overriding of MAX_THREADS in win32_threads.c from the build
+   command line.  (Patch from Yannis Bres.)
+ - Taught the IA64/linux code to determine the register backing store base from
+   /proc/self/maps after checking the __libc symbol, but before guessing.
+   (__libc symbols are on the endangered list, and the guess is likely to not
+   always be right for 2.6 kernels.)  Restructured the code to read and parse
+   /proc/self/maps so it only exists in one place (all platforms).
+ - The -DUSE_PROC_FOR_LIBRARIES code was broken on Linux.  It claimed that it
+   also registered the main data segment, but didn't actually do so.  (I don't
+   think anyone actually uses this configuration, but ...)
+ - Made another attempt to get --enablecplusplus to do the right thing.
+   Since there are unavoidable problems with C programs linking against a
+   dynamic library that includes C++ code, I separated out the c++ code into
+   libgccpp.
+
+Since 6.2alpha5:
+ - There was 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
+   from more the system-dependent thread-stopping code.  I believe this
+   should make it easier to eliminate the code duplication between
+   pthreads platforms in the future.  The patch included some other
+   code cleanups.
+ - Integrated Dan Bonachea's patch to support AIX threads.  This required
+   substantial manual integration, mostly due to conflicts with other
+   recent threads changes.  It may take another iteration to
+   get it to work.
+ - Removed HPUX/PA-RISC support from aix_irix_threads.c.  It wasn't used
+   anyway and it cluttered up the code.  And anything we can do to migrate
+   towards generic pthreads support is a good thing.
+ - Added a more explicit test for tracing of function arguments to test.c.
+   (Thanks to Dan Grayson.)
+ - Added Akira Tagoh's PowerPC64 patch.
+ - Fixed some bit rot in the Cygwin port.  (Thanks to Dan Bonachea for
+   pointing it out.)  Gc.h now includes just windows.h, not winbase.h.
+ - Declared GC_save_regs_in_stack() in gc_priv.h.  Remove other declarations.
+ - Changed --enable-cplusplus to use automake consitionals.  The old way
+   confused libtool.  "Make install" didn't work correctly for the old version.
+   Previously --enable-cplusplus was broken on cygwin.
+ - Changed the C version of GC_push_regs to fail at compile time if it is
+   generated with an empty body.  This seems to have been the cause of one
+   or two subtle failures on unusual platforms.  Those failures should
+   now occur at build time and be easily fixable.
+
+Since 6.2alpha6:
+ - Integrated a second round of Irix/AIX patches from Dan Bonachea.
+   Renamed mips_sgi_mach_dep.S back to mips_sgi_mach_dep.s, since it requires
+   the Irix assembler to do the C preprocessing; gcc -E doesn't work.
+ - Fixed Makefile.direct for DARWIN.  (Thanks to Manuel Serrano.)
+ - There was a race between GC_pthread_detach and thread exit that could
+   result in a thread structure being deallocated by GC_pthread_detach
+   eventhough it was still needed by the thread exit code.  (Thanks to
+   Dick Porter for the small test case that allowed this to be debugged.)
+ - Fixed version parsing for non-alpha versions in acinclude.m4 and
+   version checking in version.h.
+
+Since 6.2:
+ - Integrated some NetBSD patches forwarded to me by Marc Recht.  These
+   were already in the NetBSD package.    
+ - GC_pthread_create waited for the semaphore even if pthread_create failed.
+   Thanks to Dick Porter for the pthread_support.c patch.  Applied the
+   analogous fix for aix_irix_threads.c.
+ - Added Rainer Orth's Tru64 fixes.
+ - The check for exceeding the thread table size in win32 threadDetach
+   was incorrect.  (Thanks to Alexandr Petrosian for the patch.)
+ - Applied Andrew Begel's patch to correct some reentrancy issues
+   with dynamic loading on Darwin.
+ - GC_CreateThread() was neglecting to duplicate the thread handle in
+   the table.  (Thanks to Tum Nguyen for the patch.)
+ - Pass +ESdbgasm only on PA-RISC machines with vendor compiler.
+   (Thanks to Roger Sayle for the patch.)
+ - Applied more AIX threads patches from Scott Ananian.
 
 To do:
+ - 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
+   fork() call.  Thus incremental collection in the child won't work
+   correctly.  (Thanks to Ben Cottrell for pointing this out.)
+ - --enable-redirect-malloc is mostly untested and known not to work
+   on some platforms. 
  - There seem to be outstanding issues on Solaris/X86, possibly with
    finding the data segment starting address.  Information/patches would
    be appreciated.
@@ -1488,7 +1919,4 @@ To do:
  - Incremental collector should handle large objects better.  Currently,
    it looks like the whole object is treated as dirty if any part of it
    is.
- - Cord/cordprnt.c doesn't build on a few platforms (notably PowerPC), since
-   we make some unwarranted assumptions about how varargs are handled.  This
-   currently makes the cord-aware versions of printf unusable on some platforms.
-   Fixing this is unfortunately not trivial.
index c7daddb..d1f3b5c 100644 (file)
@@ -5,6 +5,8 @@ platforms.
 GC_INITIAL_HEAP_SIZE=<bytes> - Initial heap size in bytes.  May speed up
                                process start-up.
 
+GC_MAXIMUM_HEAP_SIZE=<bytes> - Maximum collected heap size.
+
 GC_LOOP_ON_ABORT - Causes the collector abort routine to enter a tight loop.
                   This may make it easier to debug, such a process, especially
                   for multithreaded platforms that don't produce usable core
@@ -19,6 +21,11 @@ GC_PRINT_STATS - Turn on as much logging as is easily feasible without
                 by setting GC_quiet.  On by default if the collector
                 was built without -DSILENT.
 
+GC_DUMP_REGULARLY - Generate a GC debugging dump GC_dump() on startup
+                   and during every collection.  Very verbose.  Useful
+                   if you have a bug to report, but please include only the
+                   last complete dump.
+
 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
@@ -27,7 +34,14 @@ GC_PRINT_ADDRESS_MAP - Linux only.  Dump /proc/self/maps, i.e. various address
 GC_NPROCS=<n> - Linux w/threads only.  Explicitly sets the number of processors
                that the GC should expect to use.  Note that setting this to 1
                when multiple processors are available will preserve
-               correctness, but may lead to really horrible performance.
+               correctness, but may lead to really horrible performance,
+               since the lock implementation will immediately yield without
+               first spinning.
+
+GC_MARKERS=<n> - Linux w/threads and parallel marker only.  Set the number
+               of marker threads.  This is normaly set to the number of
+               processors.  It is safer to adjust GC_MARKERS than GC_NPROCS,
+               since GC_MARKERS has no impact on the lock implementation.
 
 GC_NO_BLACKLIST_WARNING - Prevents the collector from issuing
                warnings about allocations of very large blocks.
@@ -62,6 +76,20 @@ GC_PRINT_BACK_HEIGHT - Print max length of chain through unreachable objects
                     of Conservative Garbage Collectors", POPL 2001, or
                     http://lib.hpl.hp.com/techpubs/2001/HPL-2001-251.html .
 
+GC_RETRY_SIGNALS, GC_NO_RETRY_SIGNALS - Try to compensate for lost
+                    thread suspend signals in linux_threads.c.  On by
+                    default for GC_OSF1_THREADS, off otherwise.  Note 
+                    that this does not work around a possible loss of
+                    thread restart signals.  This seems to be necessary for
+                    some versions of Tru64.  Since we've previously seen
+                    similar issues on some other operating systems, it
+                    was turned into a runtime flag to enable last-minute
+                    work-arounds.
+
+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:
+
 GC_ENABLE_INCREMENTAL - Turn on incremental collection at startup.  Note that,
                     depending on platform and collector configuration, this
                     may involve write protecting pieces of the heap to
@@ -71,22 +99,20 @@ GC_ENABLE_INCREMENTAL - Turn on incremental collection at startup.  Note that,
                     Use with caution.
 
 GC_PAUSE_TIME_TARGET - Set the desired garbage collector pause time in msecs.
-                    This only has an effect if incremental collection is enabled.
-                    If a collection requires appreciably more time than this,
-                    the client will be restarted, and the collector will need
-                    to do additional work to compensate.  The special value
-                    "999999" indicates that pause time is unlimited, and the
-                    incremental collector will behave completely like a
-                    simple generational collector.  If the collector is
-                    configured for parallel marking, and run on a multiprocessor,
-                    incremental collection should only be used with unlimited
-                    pause time.
-
-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:
+                    This only has an effect if incremental collection is
+                    enabled.  If a collection requires appreciably more time
+                    than this, the client will be restarted, and the collector
+                    will need to do additional work to compensate.  The
+                    special value "999999" indicates that pause time is
+                    unlimited, and the incremental collector will behave
+                    completely like a simple generational collector.  If
+                    the collector is configured for parallel marking, and
+                    run on a multiprocessor, incremental collection should
+                    only be used with unlimited pause time.
 
-GC_FIND_LEAK - Turns on GC_find_leak and thus leak detection.
+GC_FIND_LEAK - Turns on GC_find_leak and thus leak detection.  Forces a
+              collection at program termination to detect leaks that would
+              otherwise occur after the last GC.
 
 GC_ALL_INTERIOR_POINTERS - Turns on GC_all_interior_pointers and thus interior
                           pointer recognition.
index efd0a26..1d0fd4c 100644 (file)
@@ -1,21 +1,18 @@
 See README.alpha for Linux on DEC AXP info.
 
-This file applies mostly to Linux/Intel IA32.  Ports to Linux on an M68K
-and PowerPC are also integrated.  They should behave similarly, except that
-the PowerPC port lacks incremental GC support, and it is unknown to what
-extent the Linux threads code is functional.  See below for M68K specific
-notes.
+This file applies mostly to Linux/Intel IA32.  Ports to Linux on an M68K, IA64,
+SPARC, MIPS, Alpha and PowerPC are also integrated.  They should behave
+similarly, except that the PowerPC port lacks incremental GC support, and
+it is unknown to what extent the Linux threads code is functional.
+See below for M68K specific notes.
 
-Incremental GC is supported on Intel IA32 and M68K.
+Incremental GC is generally supported.
 
 Dynamic libraries are supported on an ELF system.  A static executable
 should be linked with the gcc option "-Wl,-defsym,_DYNAMIC=0".
 
-The collector appears to work with Linux threads.  We have seen
-intermittent hangs in sem_wait.  So far we have been unable to reproduce
-these unless the process was being debugged or traced.  Thus it's
-possible that the only real issue is that the debugger loses
-signals on rare occasions.
+The collector appears to work reliably with Linux threads, but beware 
+of older versions of glibc and gdb.
 
 The garbage collector uses SIGPWR and SIGXCPU if it is used with
 Linux threads.  These should not be touched by the client program.
index b1a6ec5..a40b375 100644 (file)
@@ -21,6 +21,13 @@ registrations are ignored, but not terribly quickly.)
 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,
 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
@@ -50,13 +57,20 @@ This appears to cause problems under Windows NT and Windows 2000 (but
 not Windows 95/98) if the memory is later passed to CreateDIBitmap.
 To work around this problem, build the collector with -DUSE_GLOBAL_ALLOC.
 This is currently incompatible with -DUSE_MUNMAP.  (Thanks to Jonathan
-Clark for tracking this down.)
+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.)
 
 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.
 
+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
+distribution.  It is unclear (to me, Hans Boehm) whether it is feasible to
+change that.
+
 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).
@@ -64,7 +78,7 @@ absence of thread support).
 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
-believed to work only for b18, not b19, probably dues to linker changes
+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.
 
@@ -147,7 +161,7 @@ To compile the collector and testing programs use the command:
 All programs using gc should be compiled with 4-byte alignment.
 For further explanations on this see comments about Borland.
 
-If gc compiled as dll, the macro ``GC_DLL'' should be defined before
+If the gc is compiled as dll, the macro ``GC_DLL'' should be defined before
 including "gc.h" (for example, with -DGC_DLL compiler option). It's
 important, otherwise resulting programs will not run.
 
index 04773fa..22273fe 100644 (file)
@@ -248,8 +248,12 @@ The <TT>hb_last_reclaimed</tt> field will identify the collection number
 during which its block was last swept.
 <LI> Verify that the offending object still has its correct contents at
 this point.
-The call <TT>GC_is_marked(p)</tt> from the debugger to verify that the
-object has not been marked, and is about to be reclaimed.
+Then call <TT>GC_is_marked(p)</tt> from the debugger to verify that the
+object has not been marked, and is about to be reclaimed.  Note that
+<TT>GC_is_marked(p)</tt> expects the real address of an object (the
+address of the debug header if there is one), and thus it may
+be more appropriate to call <TT>GC_is_marked(GC_base(p))</tt>
+instead.
 <LI> Determine a path from a root, i.e. static variable, stack, or
 register variable,
 to the reclaimed object.  Call <TT>GC_is_marked(q)</tt> for each object
index 71ad5fb..5ae0e0d 100644 (file)
     !defined(MSWIN32) && !defined(MSWINCE) && \
     !(defined(ALPHA) && defined(OSF1)) && \
     !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
-    !defined(RS6000) && !defined(SCO_ELF) && \
+    !defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \
     !(defined(FREEBSD) && defined(__ELF__)) && \
-    !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD)
+    !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
+    !defined(DARWIN)
  --> We only know how to find data segments of dynamic libraries for the
  --> above.  Additional SVR4 variants might not be too
  --> hard to add.
@@ -80,7 +81,7 @@
 #endif
 
 #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
-    (defined(FREEBSD) && defined(__ELF__)) || \
+    (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
     (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
 #   include <stddef.h>
 #   include <elf.h>
@@ -264,7 +265,7 @@ void GC_register_dynamic_libraries()
 # endif /* SUNOS */
 
 #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
-    (defined(FREEBSD) && defined(__ELF__)) || \
+    (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
     (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
 
 
@@ -282,56 +283,23 @@ extern ssize_t GC_repeat_read(int fd, char *buf, size_t count);
        /* Repeatedly read until buffer is filled, or EOF is encountered */
        /* Defined in os_dep.c.                                          */
 
-static char *parse_map_entry(char *buf_ptr, word *start, word *end,
-                             char *prot_buf, unsigned int *maj_dev);
+char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,
+                         char *prot_buf, unsigned int *maj_dev);
+word GC_apply_to_maps(word (*fn)(char *));
+       /* From os_dep.c        */
 
-void GC_register_dynamic_libraries()
+word GC_register_map_entries(char *maps)
 {
-    int f;
-    int result;
     char prot_buf[5];
-    int maps_size;
-    char maps_temp[32768];
-    char *maps_buf;
-    char *buf_ptr;
+    char *buf_ptr = maps;
     int count;
     word start, end;
-    unsigned int maj_dev, min_dev;
+    unsigned int maj_dev;
     word least_ha, greatest_ha;
     unsigned i;
     word datastart = (word)(DATASTART);
 
-    /* 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) ABORT("Couldn't open /proc/self/maps");
-       /* stat() doesn't work for /proc/self/maps, so we have to
-          read it to find out how large it is... */
-       maps_size = 0;
-       do {
-           result = GC_repeat_read(f, maps_temp, sizeof(maps_temp));
-           if (result <= 0) ABORT("Couldn't read /proc/self/maps");
-           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);
-           f = open("/proc/self/maps", O_RDONLY);
-           if (-1 == f) ABORT("Couldn't open /proc/self/maps");
-           maps_buf = alloca(maps_size);
-           if (NULL == maps_buf) ABORT("/proc/self/maps alloca failed");
-           result = GC_repeat_read(f, maps_buf, maps_size);
-           if (result <= 0) ABORT("Couldn't read /proc/self/maps");
-       } else {
-           /* Otherwise use the fixed size buffer */
-           maps_buf = maps_temp;
-       }
-
-       close(f);
-        maps_buf[result] = '\0';
-        buf_ptr = maps_buf;
-    /* Compute heap bounds. Should be done by add_to_heap?     */
+    /* Compute heap bounds. FIXME: Should be done by add_to_heap?      */
        least_ha = (word)(-1);
        greatest_ha = 0;
        for (i = 0; i < GC_n_heap_sects; ++i) {
@@ -342,11 +310,10 @@ void GC_register_dynamic_libraries()
         }
        if (greatest_ha < (word)GC_scratch_last_end_ptr)
            greatest_ha = (word)GC_scratch_last_end_ptr; 
-    for (;;) {
-
-        buf_ptr = parse_map_entry(buf_ptr, &start, &end, prot_buf, &maj_dev);
-       if (buf_ptr == NULL) return;
 
+    for (;;) {
+        buf_ptr = GC_parse_map_entry(buf_ptr, &start, &end, prot_buf, &maj_dev);
+       if (buf_ptr == NULL) return 1;
        if (prot_buf[1] == 'w') {
            /* This is a writable mapping.  Add it to           */
            /* the root set unless it is already otherwise      */
@@ -358,16 +325,7 @@ void GC_register_dynamic_libraries()
 #          ifdef THREADS
              if (GC_segment_is_thread_stack(start, end)) continue;
 #          endif
-           /* The rest of this assumes that there is no mapping        */
-           /* spanning the beginning of the data segment, or extending */
-           /* beyond the entire heap at both ends.                     */
-           /* Empirically these assumptions hold.                      */
-           
-           if (start < (word)DATAEND && end > (word)DATAEND) {
-               /* Rld may use space at the end of the main data        */
-               /* segment.  Thus we add that in.                       */
-               start = (word)DATAEND;
-           }
+           /* We no longer exclude the main data segment.              */
            if (start < least_ha && end > least_ha) {
                end = least_ha;
            }
@@ -377,7 +335,14 @@ void GC_register_dynamic_libraries()
            if (start >= least_ha && end <= greatest_ha) continue;
            GC_add_roots_inner((char *)start, (char *)end, TRUE);
        }
-     }
+    }
+    return 1;
+}
+
+void GC_register_dynamic_libraries()
+{
+   if (!GC_apply_to_maps(GC_register_map_entries))
+       ABORT("Failed to read /proc for library registration.");
 }
 
 /* We now take care of the main data segment ourselves: */
@@ -387,60 +352,6 @@ GC_bool GC_register_main_static_data()
 }
   
 # define HAVE_REGISTER_MAIN_STATIC_DATA
-//
-//  parse_map_entry parses an entry from /proc/self/maps so we can
-//  locate all writable data segments that belong to shared libraries.
-//  The format of one of these entries and the fields we care about
-//  is as follows:
-//  XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537     name of mapping...\n
-//  ^^^^^^^^ ^^^^^^^^ ^^^^          ^^
-//  start    end      prot          maj_dev
-//  0        9        18            32
-//
-//  The parser is called with a pointer to the entry and the return value
-//  is either NULL or is advanced to the next entry(the byte after the
-//  trailing '\n'.)
-//
-#define OFFSET_MAP_START   0
-#define OFFSET_MAP_END     9
-#define OFFSET_MAP_PROT   18
-#define OFFSET_MAP_MAJDEV 32
-
-static char *parse_map_entry(char *buf_ptr, word *start, word *end,
-                             char *prot_buf, unsigned int *maj_dev)
-{
-    int i;
-    unsigned int val;
-    char *tok;
-
-    if (buf_ptr == NULL || *buf_ptr == '\0') {
-        return NULL;
-    }
-
-    memcpy(prot_buf, buf_ptr+OFFSET_MAP_PROT, 4); // do the protections first
-    prot_buf[4] = '\0';
-
-    if (prot_buf[1] == 'w') { // we can skip all of this if it's not writable
-
-        tok = buf_ptr;
-        buf_ptr[OFFSET_MAP_START+8] = '\0';
-        *start = strtoul(tok, NULL, 16);
-
-        tok = buf_ptr+OFFSET_MAP_END;
-        buf_ptr[OFFSET_MAP_END+8] = '\0';
-        *end = strtoul(tok, NULL, 16);
-
-        buf_ptr += OFFSET_MAP_MAJDEV;
-        tok = buf_ptr;
-        while (*buf_ptr != ':') buf_ptr++;
-        *buf_ptr++ = '\0';
-        *maj_dev = strtoul(tok, NULL, 16);
-    }
-
-    while (*buf_ptr && *buf_ptr++ != '\n');
-
-    return buf_ptr;
-}
 
 #endif /* USE_PROC_FOR_LIBRARIES */
 
@@ -508,6 +419,7 @@ GC_bool GC_register_dynamic_libraries_dl_iterate_phdr()
           GC_add_roots_inner(DATASTART2, (char *)(DATAEND2), TRUE);
 #       endif
     }
+
     return TRUE;
   } else {
     return FALSE;
@@ -534,6 +446,16 @@ GC_bool GC_register_main_static_data()
 
 #if defined(NETBSD)
 #  include <sys/exec_elf.h>
+/* for compatibility with 1.4.x */
+#  ifndef DT_DEBUG
+#  define DT_DEBUG     21
+#  endif
+#  ifndef PT_LOAD
+#  define PT_LOAD      1
+#  endif
+#  ifndef PF_W
+#  define PF_W         2
+#  endif
 #else
 #  include <elf.h>
 #endif
@@ -1048,7 +970,7 @@ void GC_register_dynamic_libraries()
                len = ldi->ldinfo_next;
                GC_add_roots_inner(
                                ldi->ldinfo_dataorg,
-                               (unsigned long)ldi->ldinfo_dataorg
+                               (ptr_t)(unsigned long)ldi->ldinfo_dataorg
                                + ldi->ldinfo_datasize,
                                TRUE);
                ldi = len ? (struct ld_info *)((char *)ldi + len) : 0;
@@ -1056,7 +978,133 @@ void GC_register_dynamic_libraries()
 }
 #endif /* RS6000 */
 
+#ifdef DARWIN
+
+#include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
+
+/*#define DARWIN_DEBUG*/
+
+const static struct { 
+        const char *seg;
+        const char *sect;
+} GC_dyld_sections[] = {
+        { SEG_DATA, SECT_DATA },
+        { SEG_DATA, SECT_BSS },
+        { SEG_DATA, SECT_COMMON }
+};
+    
+#ifdef DARWIN_DEBUG
+static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) {
+    unsigned long i,c;
+    c = _dyld_image_count();
+    for(i=0;i<c;i++) if(_dyld_get_image_header(i) == hdr)
+        return _dyld_get_image_name(i);
+    return NULL;
+}
+#endif
+        
+/* This should never be called by a thread holding the lock */
+static void GC_dyld_image_add(struct mach_header* hdr, unsigned long slide) {
+    unsigned long start,end,i;
+    const struct section *sec;
+    for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
+        sec = getsectbynamefromheader(
+            hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
+            if(sec == NULL || sec->size == 0) continue;
+            start = slide + sec->addr;
+            end = start + sec->size;
+#              ifdef DARWIN_DEBUG
+                GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n",
+                start,end,sec->size,GC_dyld_name_for_hdr(hdr));
+#                      endif
+        GC_add_roots((char*)start,(char*)end);
+        }
+#      ifdef DARWIN_DEBUG
+    GC_print_static_roots();
+#      endif
+}
+
+/* This should never be called by a thread holding the lock */
+static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) {
+    unsigned long start,end,i;
+    const struct section *sec;
+    for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
+        sec = getsectbynamefromheader(
+            hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
+        if(sec == NULL || sec->size == 0) continue;
+        start = slide + sec->addr;
+        end = start + sec->size;
+#              ifdef DARWIN_DEBUG
+            GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n",
+                start,end,sec->size,GC_dyld_name_for_hdr(hdr));
+#              endif
+        GC_remove_roots((char*)start,(char*)end);
+    }
+#      ifdef DARWIN_DEBUG
+    GC_print_static_roots();
+#      endif
+}
+
+void GC_register_dynamic_libraries() {
+    /* Currently does nothing. The callbacks are setup by GC_init_dyld() 
+    The dyld library takes it from there. */
+}
+
+/* The _dyld_* functions have an internal lock so no _dyld functions
+   can be called while the world is stopped without the risk of a deadlock.
+   Because of this we MUST setup callbacks BEFORE we ever stop the world.
+   This should be called BEFORE any thread in created and WITHOUT the
+   allocation lock held. */
+   
+void GC_init_dyld() {
+  static GC_bool initialized = FALSE;
+  char *bind_fully_env = NULL;
+  
+  if(initialized) return;
+  
+#   ifdef DARWIN_DEBUG
+  GC_printf0("Registering dyld callbacks...\n");
+#   endif
+  
+  /* Apple's Documentation:
+     When you call _dyld_register_func_for_add_image, the dynamic linker runtime
+     calls the specified callback (func) once for each of the images that is
+     currently loaded into the program. When a new image is added to the program,
+     your callback is called again with the mach_header for the new image, and the     
+     virtual memory slide amount of the new image. 
+     
+     This WILL properly register already linked libraries and libraries 
+     linked in the future
+  */
+  
+    _dyld_register_func_for_add_image(GC_dyld_image_add);
+    _dyld_register_func_for_remove_image(GC_dyld_image_remove);
+
+    /* Set this early to avoid reentrancy issues. */
+    initialized = TRUE;
+
+    bind_fully_env = getenv("DYLD_BIND_AT_LAUNCH");
+    
+    if (bind_fully_env == NULL) {
+#   ifdef DARWIN_DEBUG
+      GC_printf0("Forcing full bind of GC code...\n");
+#   endif
+      
+      if(!_dyld_bind_fully_image_containing_address((unsigned long*)GC_malloc))
+        GC_abort("_dyld_bind_fully_image_containing_address failed");
+    }
+
+}
+
+#define HAVE_REGISTER_MAIN_STATIC_DATA
+GC_bool GC_register_main_static_data()
+{
+  /* Already done through dyld callbacks */
+  return FALSE;
+}
 
+#endif /* DARWIN */
 
 #else /* !DYNAMIC_LOADING */
 
index a316010..3b9d9f5 100644 (file)
@@ -207,7 +207,8 @@ signed_word * log_size_ptr;
        UNLOCK();
        ENABLE_SIGNALS();
 #     endif
-      new_dl = GC_oom_fn(sizeof(struct disappearing_link));
+      new_dl = (struct disappearing_link *)
+             GC_oom_fn(sizeof(struct disappearing_link));
       if (0 == new_dl) {
        GC_finalization_failures++;
        return(0);
@@ -433,7 +434,8 @@ finalization_mark_proc * mp;
        UNLOCK();
        ENABLE_SIGNALS();
 #     endif
-      new_fo = GC_oom_fn(sizeof(struct finalizable_object));
+      new_fo = (struct finalizable_object *)
+             GC_oom_fn(sizeof(struct finalizable_object));
       if (0 == new_fo) {
        GC_finalization_failures++;
        return;
@@ -759,8 +761,9 @@ int GC_should_invoke_finalizers GC_PROTO((void))
 /* Should be called without allocation lock.                           */
 int GC_invoke_finalizers()
 {
-    register struct finalizable_object * curr_fo;
-    register int count = 0;
+    struct finalizable_object * curr_fo;
+    int count = 0;
+    word mem_freed_before;
     DCL_LOCK_STATE;
     
     while (GC_finalize_now != 0) {
@@ -768,6 +771,9 @@ int GC_invoke_finalizers()
            DISABLE_SIGNALS();
            LOCK();
 #      endif
+       if (count == 0) {
+           mem_freed_before = GC_mem_freed;
+       }
        curr_fo = GC_finalize_now;
 #      ifdef THREADS
            if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo);
@@ -789,6 +795,11 @@ int GC_invoke_finalizers()
            GC_free((GC_PTR)curr_fo);
 #      endif
     }
+    if (count != 0 && mem_freed_before != GC_mem_freed) {
+        LOCK();
+       GC_finalizer_mem_freed += (GC_mem_freed - mem_freed_before);
+       UNLOCK();
+    }
     return count;
 }
 
@@ -801,7 +812,9 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void))
     if (GC_finalize_now == 0) return;
     if (!GC_finalize_on_demand) {
        (void) GC_invoke_finalizers();
-       GC_ASSERT(GC_finalize_now == 0);
+#      ifndef THREADS
+         GC_ASSERT(GC_finalize_now == 0);
+#      endif   /* Otherwise GC can run concurrently and add more */
        return;
     }
     if (GC_finalizer_notifier != (void (*) GC_PROTO((void)))0
@@ -839,3 +852,17 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void))
     return(result);
 }
 
+#if !defined(NO_DEBUGGING)
+
+void GC_print_finalization_stats()
+{
+    struct finalizable_object *fo = GC_finalize_now;
+    size_t ready = 0;
+
+    GC_printf2("%lu finalization table entries; %lu disappearing links\n",
+              GC_fo_entries, GC_dl_entries);
+    for (; 0 != fo; fo = fo_next(fo)) ++ready;
+    GC_printf1("%lu objects are eligible for immediate finalization\n", ready);
+}
+
+#endif /* NO_DEBUGGING */
index a97091c..f8b803a 100644 (file)
@@ -26,15 +26,13 @@ Authors: John R. Ellis and Jesse Hull
 
 #include "gc_cpp.h"
 
-#ifndef _MSC_VER
-/* In the Visual C++ case, we moved this into the header. */
 void* operator new( size_t size ) {
     return GC_MALLOC_UNCOLLECTABLE( size );}
   
 void operator delete( void* obj ) {
     GC_FREE( obj );}
   
-#ifdef OPERATOR_NEW_ARRAY
+#ifdef GC_OPERATOR_NEW_ARRAY
 
 void* operator new[]( size_t size ) {
     return GC_MALLOC_UNCOLLECTABLE( size );}
@@ -42,8 +40,22 @@ void* operator new[]( size_t size ) {
 void operator delete[]( void* obj ) {
     GC_FREE( obj );}
 
-#endif /* OPERATOR_NEW_ARRAY */
+#endif /* GC_OPERATOR_NEW_ARRAY */
 
-#endif /* _MSC_VER */
+#ifdef _MSC_VER
+
+// This new operator is used by VC++ in case of Debug builds !
+void* operator new( size_t size,
+                         int ,//nBlockUse,
+                         const char * szFileName,
+                         int nLine )
+{
+#ifndef GC_DEBUG
+       return GC_malloc_uncollectable( size );
+#else
+       return GC_debug_malloc_uncollectable(size, szFileName, nLine);
+#endif
+}
 
+#endif /* _MSC_VER */
 
index eafaa2b..4c690ed 100644 (file)
 /*
  * This used to be in dyn_load.c.  It was extracted into a separate file
  * to avoid having to link against libdl.{a,so} if the client doesn't call
- * dlopen.  -HB
+ * dlopen.  Of course this fails if the collector is in a dynamic
+ * library. -HB
  */
 
 #include "private/gc_priv.h"
 
-# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)
+# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
+      || defined(GC_SOLARIS_THREADS)
 
 # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
     /* To support various threads pkgs, gc.h interposes on dlopen by     */
   /* calls in either a multithreaded environment, or if the library    */
   /* initialization code allocates substantial amounts of GC'ed memory.        */
   /* But I don't know of a better solution.                            */
-  /* This can still deadlock if the client explicitly starts a GC      */
-  /* during the dlopen.  He shouldn't do that.                         */
-  static GC_bool disable_gc_for_dlopen()
+  static void disable_gc_for_dlopen()
   {
-    GC_bool result;
     LOCK();
-    result = GC_dont_gc;
     while (GC_incremental && GC_collection_in_progress()) {
        GC_collect_a_little_inner(1000);
     }
-    GC_dont_gc = TRUE;
+    ++GC_dont_gc;
     UNLOCK();
-    return(result);
   }
 
   /* Redefine dlopen to guarantee mutual exclusion with        */
 #endif
 {
     void * result;
-    GC_bool dont_gc_save;
     
 #   ifndef USE_PROC_FOR_LIBRARIES
-      dont_gc_save = disable_gc_for_dlopen();
+      disable_gc_for_dlopen();
 #   endif
 #   ifdef GC_USE_LD_WRAP
       result = (void *)__real_dlopen(path, mode);
@@ -85,7 +81,7 @@
       result = dlopen(path, mode);
 #   endif
 #   ifndef USE_PROC_FOR_LIBRARIES
-      GC_dont_gc = dont_gc_save;
+      GC_enable(); /* undoes disable_gc_for_dlopen */
 #   endif
     return(result);
 }
index 89f0d72..a10a66f 100644 (file)
@@ -157,6 +157,7 @@ DCL_LOCK_STATE;
             GC_words_allocd += lw;
         }
        *(void **)op = ptr_to_struct_containing_descr;
+       GC_ASSERT(((void **)op)[1] == 0);
        UNLOCK();
     } else {
        LOCK();
index fd6009e..3dcccf2 100644 (file)
@@ -14,7 +14,7 @@ char ** envp;
     if (strcmp(MACH_TYPE, argv[1]) != 0) return(0);
     if (strcmp(OS_TYPE, "") != 0 && strcmp(argv[2], "") != 0
         && strcmp(OS_TYPE, argv[2]) != 0) return(0);
-    printf("^^^^Starting command^^^^\n");
+    fprintf(stderr, "^^^^Starting command^^^^\n");
     fflush(stdout);
     execvp(argv[3], argv+3);
     perror("Couldn't execute");
index 65bd34e..94ece1a 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -66,9 +66,11 @@ target_triplet = @target@
 AR = @AR@
 AS = @AS@
 CC = @CC@
+CFLAGS = @CFLAGS@
 CPP = @CPP@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
 CXXINCLUDES = @CXXINCLUDES@
 DLLTOOL = @DLLTOOL@
 EXEEXT = @EXEEXT@
@@ -89,10 +91,15 @@ RANLIB = @RANLIB@
 STRIP = @STRIP@
 THREADLIBS = @THREADLIBS@
 VERSION = @VERSION@
+addincludes = @addincludes@
+addlibs = @addlibs@
 addobjs = @addobjs@
+addtests = @addtests@
 gc_basedir = @gc_basedir@
 mkinstalldirs = @mkinstalldirs@
 target_all = @target_all@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
 
 AUTOMAKE_OPTIONS = foreign
 
index 69075b0..d49cd9d 100644 (file)
 
 # define _GC_H
 
-/*
- * 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(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) \
-                            || defined(GC_LINUX_THREADS))
-# define _REENTRANT
-       /* Better late than never.  This fails if system headers that   */
-       /* depend on this were previously included.                     */
-#endif
-
-#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
-#   define GC_SOLARIS_THREADS
-#endif
-
-# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
-       defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
-       defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
-#   define GC_PTHREADS
-# endif
-
-# define __GC
-# include <stddef.h>
-# ifdef _WIN32_WCE
-/* Yet more kluges for WinCE */
-#   include <stdlib.h>         /* size_t is defined here */
-    typedef long ptrdiff_t;    /* ptrdiff_t is not defined */
-# endif
-
-#if defined(__MINGW32__) &&defined(_DLL) && !defined(GC_NOT_DLL)
-# ifdef GC_BUILD
-#   define GC_API __declspec(dllexport)
-# else
-#   define GC_API __declspec(dllimport)
-# endif
-#endif
-
-#if (defined(__DMC__) || defined(_MSC_VER)) \
-               && (defined(_DLL) && !defined(GC_NOT_DLL) \
-                   || defined(GC_DLL))
-# ifdef GC_BUILD
-#   define GC_API extern __declspec(dllexport)
-# else
-#   define GC_API __declspec(dllimport)
-# endif
-#endif
-
-#if defined(__WATCOMC__) && defined(GC_DLL)
-# ifdef GC_BUILD
-#   define GC_API extern __declspec(dllexport)
-# else
-#   define GC_API extern __declspec(dllimport)
-# endif
-#endif
-
-#ifndef GC_API
-#define GC_API extern
-#endif
+# include "gc_config_macros.h"
 
 # if defined(__STDC__) || defined(__cplusplus)
 #   define GC_PROTO(args) args
@@ -154,7 +70,7 @@ GC_API int GC_parallel;      /* GC is parallelized for performance on        */
                        /*  Env variable GC_NPROC is set to > 1, or     */
                        /*  GC_NPROC is not set and this is an MP.      */
                        /* If GC_parallel is set, incremental           */
-                       /* collection is aonly partially functional,    */
+                       /* collection is only partially functional,     */
                        /* and may not be desirable.                    */
                        
 
@@ -215,8 +131,14 @@ GC_API void (* GC_finalizer_notifier)();
                        /* thread, which will call GC_invoke_finalizers */
                        /* in response.                                 */
 
-GC_API int GC_dont_gc; /* Dont collect unless explicitly requested, e.g. */
-                       /* because it's not safe.                         */
+GC_API int GC_dont_gc; /* != 0 ==> Dont collect.  In versions 6.2a1+,  */
+                       /* this overrides explicit GC_gcollect() calls. */
+                       /* Used as a counter, so that nested enabling   */
+                       /* and disabling work correctly.  Should        */
+                       /* normally be updated with GC_enable() and     */
+                       /* GC_disable() calls.                          */
+                       /* Direct assignment to GC_dont_gc is           */
+                       /* deprecated.                                  */
 
 GC_API int GC_dont_expand;
                        /* Dont expand heap unless explicitly requested */
@@ -316,9 +238,18 @@ GC_API unsigned long GC_time_limit;
                                /* enabled.                              */
 #      define GC_TIME_UNLIMITED 999999
                                /* Setting GC_time_limit to this value   */
-                               /* will disable the "pause time exceeded */
+                               /* will disable the "pause time exceeded"*/
                                /* tests.                                */
 
+/* Public procedures */
+
+/* Initialize the collector.  This is only required when using thread-local
+ * 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.
+ */
+GC_API void GC_init GC_PROTO((void));
+
 /*
  * general purpose allocation routines, with roughly malloc calling conv.
  * The atomic versions promise that no relevant pointers are contained
@@ -419,17 +350,21 @@ GC_API void GC_clear_roots GC_PROTO((void));
 GC_API void GC_add_roots GC_PROTO((char * low_address,
                                   char * high_address_plus_1));
 
+/* Remove a root segment.  Wizards only. */
+GC_API void GC_remove_roots GC_PROTO((char * low_address, 
+    char * high_address_plus_1));
+
 /* Add a displacement to the set of those considered valid by the      */
 /* collector.  GC_register_displacement(n) means that if p was returned */
 /* by GC_malloc, then (char *)p + n will be considered to be a valid   */
-/* pointer to n.  N must be small and less than the size of p.         */
+/* pointer to p.  N must be small and less than the size of p.         */
 /* (All pointers to the interior of objects from the stack are         */
 /* considered valid in any case.  This applies to heap objects and     */
 /* static data.)                                                       */
 /* Preferably, this should be called before any other GC procedures.   */
 /* Calling it later adds to the probability of excess memory           */
 /* retention.                                                          */
-/* This is a no-op if the collector was compiled with recognition of   */
+/* This is a no-op if the collector has recognition of                 */
 /* arbitrary interior pointers enabled, which is now the default.      */
 GC_API void GC_register_displacement GC_PROTO((GC_word n));
 
@@ -464,9 +399,18 @@ GC_API size_t GC_get_free_bytes GC_PROTO((void));
 GC_API size_t GC_get_bytes_since_gc GC_PROTO((void));
 
 /* Return the total number of bytes allocated in this process.         */
-/* Never decreases.                                                    */
+/* Never decreases, except due to wrapping.                            */
 GC_API size_t GC_get_total_bytes GC_PROTO((void));
 
+/* Disable garbage collection.  Even GC_gcollect calls will be                 */
+/* ineffective.                                                                */
+GC_API void GC_disable GC_PROTO((void));
+
+/* Reenable garbage collection.  GC_disable() and GC_enable() calls    */
+/* nest.  Garbage collection is enabled if the number of calls to both */
+/* both functions is equal.                                            */
+GC_API void GC_enable GC_PROTO((void));
+
 /* Enable incremental/generational collection. */
 /* Not advisable unless dirty bits are                 */
 /* available or most heap objects are          */
@@ -474,7 +418,11 @@ GC_API size_t GC_get_total_bytes GC_PROTO((void));
 /* Don't use in leak finding mode.             */
 /* Ignored if GC_dont_gc is true.              */
 /* Only the generational piece of this is      */
-/* functional if GC_parallel is TRUE.          */
+/* functional if GC_parallel is TRUE           */
+/* or if GC_time_limit is GC_TIME_UNLIMITED.   */
+/* Causes GC_local_gcj_malloc() to revert to   */
+/* locked allocation.  Must be called          */
+/* before any GC_local_gcj_malloc() calls.     */
 GC_API void GC_enable_incremental GC_PROTO((void));
 
 /* Does incremental mode write-protect pages?  Returns zero or */
@@ -518,6 +466,42 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
 #   define GC_RETURN_ADDR (GC_word)__return_address
 #endif
 
+#ifdef __linux__
+# include <features.h>
+# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
+     && !defined(__ia64__)
+#   define GC_HAVE_BUILTIN_BACKTRACE
+#   define GC_CAN_SAVE_CALL_STACKS
+# endif
+# if defined(__i386__) || defined(__x86_64__)
+#   define GC_CAN_SAVE_CALL_STACKS
+# endif
+#endif
+
+#if defined(__sparc__)
+#   define GC_CAN_SAVE_CALL_STACKS
+#endif
+
+/* If we're on an a platform on which we can't save call stacks, but   */
+/* gcc is normally used, we go ahead and define GC_ADD_CALLER.         */
+/* We make this decision independent of whether gcc is actually being  */
+/* used, in order to keep the interface consistent, and allow mixing   */
+/* of compilers.                                                       */
+/* This may also be desirable if it is possible but expensive to       */
+/* retrieve the call chain.                                            */
+#if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \
+     || defined(__FreeBSD__)) & !defined(GC_CAN_SAVE_CALL_STACKS)
+# define GC_ADD_CALLER
+# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) 
+    /* gcc knows how to retrieve return address, but we don't know */
+    /* how to generate call stacks.                               */
+#   define GC_RETURN_ADDR (GC_word)__builtin_return_address(0)
+# else
+    /* Just pass 0 for gcc compatibility. */
+#   define GC_RETURN_ADDR 0
+# endif
+#endif
+
 #ifdef GC_ADD_CALLER
 #  define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
 #  define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * s, int i
@@ -536,18 +520,42 @@ GC_API GC_PTR GC_debug_malloc_uncollectable
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_stubborn
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
+GC_API GC_PTR GC_debug_malloc_ignore_off_page
+       GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
+GC_API GC_PTR GC_debug_malloc_atomic_ignore_off_page
+       GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
 GC_API void GC_debug_free GC_PROTO((GC_PTR object_addr));
 GC_API GC_PTR GC_debug_realloc
        GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes,
                  GC_EXTRA_PARAMS));
-                                
 GC_API void GC_debug_change_stubborn GC_PROTO((GC_PTR));
 GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_PTR));
+
+/* Routines that allocate objects with debug information (like the     */
+/* above), but just fill in dummy file and line number information.    */
+/* Thus they can serve as drop-in malloc/realloc replacements.  This   */
+/* can be useful for two reasons:                                      */
+/* 1) It allows the collector to be built with DBG_HDRS_ALL defined    */
+/*    even if some allocation calls come from 3rd party libraries      */
+/*    that can't be recompiled.                                                */
+/* 2) On some platforms, the file and line information is redundant,   */
+/*    since it can be reconstructed from a stack trace.  On such       */
+/*    platforms it may be more convenient not to recompile, e.g. for   */
+/*    leak detection.  This can be accomplished by instructing the     */
+/*    linker to replace malloc/realloc with these.                     */
+GC_API GC_PTR GC_debug_malloc_replacement GC_PROTO((size_t size_in_bytes));
+GC_API GC_PTR GC_debug_realloc_replacement
+             GC_PROTO((GC_PTR object_addr, size_t size_in_bytes));
+                                
 # ifdef GC_DEBUG
 #   define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS)
 #   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
-#   define GC_MALLOC_UNCOLLECTABLE(sz) GC_debug_malloc_uncollectable(sz, \
-                                                       GC_EXTRAS)
+#   define GC_MALLOC_UNCOLLECTABLE(sz) \
+                       GC_debug_malloc_uncollectable(sz, GC_EXTRAS)
+#   define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
+                       GC_debug_malloc_ignore_off_page(sz, GC_EXTRAS)
+#   define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \
+                       GC_debug_malloc_atomic_ignore_off_page(sz, GC_EXTRAS)
 #   define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS)
 #   define GC_FREE(p) GC_debug_free(p)
 #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
@@ -566,6 +574,10 @@ GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_PTR));
 #   define GC_MALLOC(sz) GC_malloc(sz)
 #   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
 #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
+#   define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
+                       GC_malloc_ignore_off_page(sz)
+#   define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \
+                       GC_malloc_atomic_ignore_off_page(sz)
 #   define GC_REALLOC(old, sz) GC_realloc(old, sz)
 #   define GC_FREE(p) GC_free(p)
 #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
@@ -644,7 +656,8 @@ GC_API void GC_debug_register_finalizer
 /* itself.  There is a stylistic argument that this is wrong,  */
 /* but it's unavoidable for C++, since the compiler may                */
 /* silently introduce these.  It's also benign in that specific        */
-/* case.                                                       */
+/* case.  And it helps if finalizable objects are split to     */
+/* avoid cycles.                                               */
 /* Note that cd will still be viewed as accessible, even if it */
 /* refers to the object itself.                                        */
 GC_API void GC_register_finalizer_ignore_self
@@ -717,11 +730,6 @@ GC_API int GC_unregister_disappearing_link GC_PROTO((GC_PTR * /* link */));
        /* Undoes a registration by either of the above two     */
        /* routines.                                            */
 
-/* Auxiliary fns to make finalization work correctly with displaced    */
-/* pointers introduced by the debugging allocators.                    */
-GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
-GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
-
 /* Returns !=0  if GC_invoke_finalizers has something to do.           */
 GC_API int GC_should_invoke_finalizers GC_PROTO((void));
 
@@ -738,6 +746,10 @@ GC_API int GC_invoke_finalizers GC_PROTO((void));
 typedef void (*GC_warn_proc) GC_PROTO((char *msg, GC_word arg));
 GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p));
     /* Returns old warning procedure.  */
+
+GC_API GC_word GC_set_free_space_divisor GC_PROTO((GC_word value));
+    /* Set free_space_divisor.  See above for definition.      */
+    /* Returns old value.                                      */
        
 /* The following is intended to be used by a higher level      */
 /* (e.g. Java-like) finalization facility.  It is expected     */
@@ -873,14 +885,17 @@ extern void GC_thr_init();        /* Needed for Solaris/X86       */
 
 #endif /* THREADS && !SRC_M3 */
 
-#if defined(GC_WIN32_THREADS)
+#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
 # include <windows.h>
 
   /*
    * All threads must be created using GC_CreateThread, so that they will be
-   * recorded in the thread table.
+   * recorded in the thread table.  For backwards compatibility, this is not
+   * technically true if the GC is built as a dynamic library, since it can
+   * and does then use DllMain to keep track of thread creations.  But new code
+   * should be built to call GC_CreateThread.
    */
-  HANDLE WINAPI GC_CreateThread(
+  GC_API HANDLE GC_CreateThread(
       LPSECURITY_ATTRIBUTES lpThreadAttributes,
       DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
       LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );
@@ -902,7 +917,7 @@ extern void GC_thr_init();  /* Needed for Solaris/X86       */
 #  endif
 # endif /* defined(_WIN32_WCE) */
 
-#endif /* defined(GC_WIN32_THREADS) */
+#endif /* defined(GC_WIN32_THREADS)  && !cygwin */
 
 /*
  * If you are planning on putting
@@ -914,13 +929,18 @@ extern void GC_thr_init();        /* Needed for Solaris/X86       */
 #   define GC_INIT() { extern end, etext; \
                       GC_noop(&end, &etext); }
 #else
-# if (defined(__CYGWIN32__) && defined(GC_USE_DLL)) || defined (_AIX)
+# if defined(__CYGWIN32__) && defined(GC_DLL) || defined (_AIX)
     /*
-     * Similarly gnu-win32 DLLs need explicit initialization
+     * Similarly gnu-win32 DLLs need explicit initialization from
+     * the main program, as does AIX.
      */
 #   define GC_INIT() { GC_add_roots(DATASTART, DATAEND); }
 # else
+#  if defined(__APPLE__) && defined(__MACH__)
+#   define GC_INIT() { GC_init(); }
+#  else
 #   define GC_INIT()
+#  endif
 # endif
 #endif
 
index ceb73f5..d789a37 100644 (file)
@@ -134,7 +134,9 @@ by UseGC.  GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined.
 #include "gc.h"
 
 #ifndef THINK_CPLUS
-#define _cdecl
+#  define GC_cdecl
+#else
+#  define GC_cdecl _cdecl
 #endif
 
 #if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \
@@ -159,12 +161,22 @@ enum GCPlacement {UseGC,
 class gc {public:
     inline void* operator new( size_t size );
     inline void* operator new( size_t size, GCPlacement gcp );
+    inline void* operator new( size_t size, void *p );
+       /* Must be redefined here, since the other overloadings */
+       /* hide the global definition.                          */
     inline void operator delete( void* obj );
+#   ifndef __BORLANDC__  /* Confuses the Borland compiler. */
+      inline void operator delete( void*, void* );
+#   endif
 
 #ifdef GC_OPERATOR_NEW_ARRAY
     inline void* operator new[]( size_t size );
     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__
+      inline void gc::operator delete[]( void*, void* );
+#   endif
 #endif /* GC_OPERATOR_NEW_ARRAY */
     };    
     /*
@@ -176,7 +188,7 @@ class gc_cleanup: virtual public gc {public:
     inline gc_cleanup();
     inline virtual ~gc_cleanup();
 private:
-    inline static void _cdecl cleanup( void* obj, void* clientData );};
+    inline static void GC_cdecl cleanup( void* obj, void* clientData );};
     /*
     Instances of classes derived from "gc_cleanup" will be allocated
     in the collected heap by default.  When the collector discovers an
@@ -211,7 +223,6 @@ inline void* operator new(
     classes derived from "gc_cleanup" or containing members derived
     from "gc_cleanup". */
 
-#ifdef GC_OPERATOR_NEW_ARRAY
 
 #ifdef _MSC_VER
  /** This ensures that the system default operator new[] doesn't get
@@ -220,42 +231,24 @@ inline void* operator new(
   *  There seems to be really redirect new in this environment without
   *  including this everywhere. 
   */
- inline void *operator new[]( size_t size )
- {
-    return GC_MALLOC_UNCOLLECTABLE( size );
- }
-
- inline void operator delete[](void* obj)
- {
-    GC_FREE(obj);
- };
-
- inline void* operator new( size_t size)
- {
-    return GC_MALLOC_UNCOLLECTABLE( size);
- };   
+ void *operator new[]( size_t size );
+ void operator delete[](void* obj);
 
- inline void operator delete(void* obj)
- {
-    GC_FREE(obj);
- };
+ void* operator new( size_t size);
 
+ void operator delete(void* obj);
 
-// This new operator is used by VC++ in case of Debug builds !
 inline void* operator new( size_t size,
+ // This new operator is used by VC++ in case of Debug builds !
void* operator new(  size_t size,
                      int ,//nBlockUse,
                      const char * szFileName,
-                     int nLine
-                     ) {
-# ifndef GC_DEBUG
-     return GC_malloc_uncollectable( size );
-# else
-     return GC_debug_malloc_uncollectable(size, szFileName, nLine);
-# endif
-  }
-
+                     int nLine );
 #endif /* _MSC_VER */
 
+
+#ifdef GC_OPERATOR_NEW_ARRAY
+
 inline void* operator new[](
     size_t size, 
     GCPlacement gcp,
@@ -283,9 +276,15 @@ inline void* gc::operator new( size_t size, GCPlacement gcp ) {
     else
         return GC_MALLOC_UNCOLLECTABLE( size );}
 
+inline void* gc::operator new( size_t size, void *p ) {
+    return p;}
+
 inline void gc::operator delete( void* obj ) {
     GC_FREE( obj );}
     
+#ifndef __BORLANDC__
+  inline void gc::operator delete( void*, void* ) {}
+#endif
 
 #ifdef GC_OPERATOR_NEW_ARRAY
 
@@ -295,14 +294,21 @@ inline void* gc::operator new[]( size_t size ) {
 inline void* gc::operator new[]( size_t size, GCPlacement gcp ) {
     return gc::operator new( size, gcp );}
 
+inline void* gc::operator new[]( size_t size, void *p ) {
+    return p;}
+
 inline void gc::operator delete[]( void* obj ) {
     gc::operator delete( obj );}
+
+#ifndef __BORLANDC__
+  inline void gc::operator delete[]( void*, void* ) {}
+#endif
     
 #endif /* GC_OPERATOR_NEW_ARRAY */
 
 
 inline gc_cleanup::~gc_cleanup() {
-    GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );}
+    GC_register_finalizer_ignore_self( GC_base(this), 0, 0, 0, 0 );}
 
 inline void gc_cleanup::cleanup( void* obj, void* displ ) {
     ((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
index 1e58730..88e29e9 100644 (file)
@@ -33,6 +33,9 @@
  * -DTHREAD_LOCAL_ALLOC, which is currently supported only on Linux.
  *
  * The debugging allocators use standard, not thread-local allocation.
+ *
+ * These routines normally require an explicit call to GC_init(), though
+ * that may be done from a constructor function.
  */
 
 #ifndef GC_LOCAL_ALLOC_H
index 0856d16..9ddba2c 100644 (file)
@@ -129,7 +129,9 @@ extern GC_PTR GC_greatest_plausible_heap_addr;
 /* be reserved for exceptional cases.  That will ensure that           */
 /* performance of this call is not extremely performance critical.     */
 /* (Otherwise we would need to inline GC_mark_and_push completely,     */
-/* which would tie the client code to a fixed colllector version.)     */
+/* which would tie the client code to a fixed collector version.)      */
+/* Note that mark procedures should explicitly call FIXUP_POINTER()    */
+/* if required.                                                                */
 struct GC_ms_entry *GC_mark_and_push
                GC_PROTO((GC_PTR obj,
                          struct GC_ms_entry * mark_stack_ptr,
index 47284fb..842518c 100644 (file)
   int GC_pthread_create(pthread_t *new_thread,
                         const pthread_attr_t *attr,
                        void *(*start_routine)(void *), void *arg);
+#ifndef GC_DARWIN_THREADS
   int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
+#endif
   int GC_pthread_join(pthread_t thread, void **retval);
   int GC_pthread_detach(pthread_t thread);
 
+#if defined(GC_OSF1_THREADS) \
+    && defined(_PTHREAD_USE_MANGLED_NAMES_) && !defined(_PTHREAD_USE_PTDNAM_)
+/* Unless the compiler supports #pragma extern_prefix, the Tru64 UNIX
+   <pthread.h> redefines some POSIX thread functions to use mangled names.
+   If so, undef them before redefining. */
+# undef pthread_create
+# undef pthread_join
+# undef pthread_detach
+#endif
+
 # define pthread_create GC_pthread_create
-# define pthread_sigmask GC_pthread_sigmask
 # define pthread_join GC_pthread_join
 # define pthread_detach GC_pthread_detach
+
+#ifndef GC_DARWIN_THREADS
+# define pthread_sigmask GC_pthread_sigmask
 # define dlopen GC_dlopen
+#endif
 
 #endif /* GC_xxxxx_THREADS */
 
index 2e0598f..905734b 100644 (file)
 #   include "gc.h"
 # endif
 
+#ifdef __cplusplus
+  extern "C" {
+#endif
 typedef GC_word * GC_bitmap;
        /* The least significant bit of the first word is one if        */
        /* the first word in the object may be a pointer.               */
        
+# define GC_WORDSZ (8*sizeof(GC_word))
 # define GC_get_bit(bm, index) \
-               (((bm)[divWORDSZ(index)] >> modWORDSZ(index)) & 1)
+               (((bm)[index/GC_WORDSZ] >> (index%GC_WORDSZ)) & 1)
 # define GC_set_bit(bm, index) \
-               (bm)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index)
+               (bm)[index/GC_WORDSZ] |= ((GC_word)1 << (index%GC_WORDSZ))
+# define GC_WORD_OFFSET(t, f) (offsetof(t,f)/sizeof(GC_word))
+# define GC_WORD_LEN(t) (sizeof(t)/ sizeof(GC_word))
+# define GC_BITMAP_SIZE(t) ((GC_WORD_LEN(t) + GC_WORDSZ-1)/GC_WORDSZ)
 
 typedef GC_word GC_descr;
 
@@ -57,6 +64,16 @@ GC_API GC_descr GC_make_descriptor GC_PROTO((GC_bitmap bm, size_t len));
                /* is intended to be called once per type, not once     */
                /* per allocation.                                      */
 
+/* It is possible to generate a descriptor for a C type T with */
+/* word aligned pointer fields f1, f2, ... as follows:                 */
+/*                                                                     */
+/* GC_descr T_descr;                                                    */
+/* GC_word T_bitmap[GC_BITMAP_SIZE(T)] = {0};                          */
+/* GC_set_bit(T_bitmap, GC_WORD_OFFSET(T,f1));                         */
+/* GC_set_bit(T_bitmap, GC_WORD_OFFSET(T,f2));                         */
+/* ...                                                                 */
+/* T_descr = GC_make_descriptor(T_bitmap, GC_WORD_LEN(T));             */
+
 GC_API GC_PTR GC_malloc_explicitly_typed
                        GC_PROTO((size_t size_in_bytes, GC_descr d));
                /* Allocate an object whose layout is described by d.   */
@@ -79,15 +96,18 @@ GC_API GC_PTR GC_calloc_explicitly_typed
        /* Returned object is cleared.                          */
 
 #ifdef GC_DEBUG
-#   define GC_MALLOC_EXPLICTLY_TYPED(bytes, d) GC_MALLOC(bytes)
-#   define GC_CALLOC_EXPLICTLY_TYPED(n, bytes, d) GC_MALLOC(n*bytes)
+#   define GC_MALLOC_EXPLICITLY_TYPED(bytes, d) GC_MALLOC(bytes)
+#   define GC_CALLOC_EXPLICITLY_TYPED(n, bytes, d) GC_MALLOC(n*bytes)
 #else
-#  define GC_MALLOC_EXPLICTLY_TYPED(bytes, d) \
+#  define GC_MALLOC_EXPLICITLY_TYPED(bytes, d) \
        GC_malloc_explicitly_typed(bytes, d)
-#  define GC_CALLOC_EXPLICTLY_TYPED(n, bytes, d) \
+#  define GC_CALLOC_EXPLICITLY_TYPED(n, bytes, d) \
        GC_calloc_explicitly_typed(n, bytes, d)
 #endif /* !GC_DEBUG */
 
+#ifdef __cplusplus
+  } /* matches extern "C" */
+#endif
 
 #endif /* _GC_TYPED_H */
 
index aad9446..20a2fab 100644 (file)
 #endif
 #endif
 
+/* A hack to deal with gcc 3.1.  If you are using gcc3.1 and later,    */
+/* you should probably really use gc_allocator.h instead.              */
+#if defined (__GNUC__) && \
+    (__GNUC > 3 || (__GNUC__ == 3 && (__GNUC_MINOR__ >= 1)))
+# define simple_alloc __simple_alloc
+#endif
+
+
 
 #define GC_ALLOC_H
 
index 5378835..e2003e6 100644 (file)
@@ -115,16 +115,24 @@ typedef struct {
 
 #ifdef SHORT_DBG_HDRS
 #   define DEBUG_BYTES (sizeof (oh))
+#   define UNCOLLECTABLE_DEBUG_BYTES DEBUG_BYTES
 #else
     /* Add space for END_FLAG, but use any extra space that was already        */
     /* added to catch off-the-end pointers.                            */
-#   define DEBUG_BYTES (sizeof (oh) + sizeof (word) - EXTRA_BYTES)
+    /* For uncollectable objects, the extra byte is not added.         */
+#   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)
 
+/* ADD_CALL_CHAIN stores a (partial) call chain into an object */
+/* header.  It may be called with or without the allocation    */
+/* lock.                                                       */
+/* PRINT_CALL_CHAIN prints the call chain stored in an object  */
+/* to stderr.  It requires that we do not hold the lock.       */
 #ifdef SAVE_CALL_CHAIN
 #   define ADD_CALL_CHAIN(base, ra) GC_save_callers(((oh *)(base)) -> oh_ci)
 #   define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci)
index dd61545..96749ab 100644 (file)
@@ -70,7 +70,7 @@ extern hdr * GC_invalid_header; /* header for an imaginary block      */
 #define ADVANCE(p, hhdr, source) \
            { \
              hdr * new_hdr = GC_invalid_header; \
-              p = GC_FIND_START(p, hhdr, &new_hdr, (word)source); \
+              p = GC_find_start(p, hhdr, &new_hdr); \
              hhdr = new_hdr; \
            }
 
index 9b91ada..775176b 100644 (file)
 #    if defined(POWERPC)
         inline static int GC_test_and_set(volatile unsigned int *addr) {
           int oldval;
-          int temp = 1; // locked value
+          int temp = 1; /* locked value */
 
           __asm__ __volatile__(
-               "1:\tlwarx %0,0,%3\n"   // load and reserve
-               "\tcmpwi %0, 0\n"       // if load is
-               "\tbne 2f\n"            //   non-zero, return already set
-               "\tstwcx. %2,0,%1\n"    // else store conditional
-               "\tbne- 1b\n"           // retry if lost reservation
-               "2:\t\n"                // oldval is zero if we set
+               "1:\tlwarx %0,0,%3\n"   /* load and reserve               */
+               "\tcmpwi %0, 0\n"       /* if load is                     */
+               "\tbne 2f\n"            /*   non-zero, return already set */
+               "\tstwcx. %2,0,%1\n"    /* else store conditional         */
+               "\tbne- 1b\n"           /* retry if lost reservation      */
+               "\tsync\n"              /* import barrier                 */
+               "2:\t\n"                /* oldval is zero if we set       */
               : "=&r"(oldval), "=p"(addr)
               : "r"(temp), "1"(addr)
-              : "memory");
-          return (int)oldval;
+              : "cr0","memory");
+          return oldval;
         }
 #       define GC_TEST_AND_SET_DEFINED
         inline static void GC_clear(volatile unsigned int *addr) {
-         __asm__ __volatile__("eieio" ::: "memory");
+         __asm__ __volatile__("eieio" : : : "memory");
           *(addr) = 0;
         }
 #       define GC_CLEAR_DEFINED
                              "       bne %2,2f\n"
                              "       xor %0,%3,%0\n"
                              "       stl_c %0,%1\n"
+#      ifdef __ELF__
                              "       beq %0,3f\n"
+#      else
+                             "       beq %0,1b\n"
+#      endif
                              "       mb\n"
                              "2:\n"
+#      ifdef __ELF__
                              ".section .text2,\"ax\"\n"
                              "3:     br 1b\n"
                              ".previous"
+#      endif
                              :"=&r" (temp), "=m" (*addr), "=&r" (oldvalue)
                              :"Ir" (1), "m" (*addr)
                             :"memory");
           return oldvalue;
         }
 #       define GC_TEST_AND_SET_DEFINED
-        /* Should probably also define GC_clear, since it needs        */
-        /* a memory barrier ??                                 */
+        inline static void GC_clear(volatile unsigned int *addr) {
+          __asm__ __volatile__("mb" : : : "memory");
+          *(addr) = 0;
+        }
+#       define GC_CLEAR_DEFINED
 #    endif /* ALPHA */
 #    ifdef ARM32
         inline static int GC_test_and_set(volatile unsigned int *addr) {
 #       define GC_TEST_AND_SET_DEFINED
 #    endif /* ARM32 */
 #    ifdef S390
-       inline static int GC_test_and_set(volatile unsigned int *addr) {
-        int ret;
-        __asm__ __volatile__ (
-               "       l       %0,0(%2)\n"
-               "0:     cs      %0,%1,0(%2)\n"
-               "       jl      0b"
-               : "=&d" (ret)
-               : "d" (1), "a" (addr)
-               : "cc", "memory");
-         return ret;
-       }
+       inline static int GC_test_and_set(volatile unsigned int *addr) {
+         int ret;
+         __asm__ __volatile__ (
+          "     l     %0,0(%2)\n"
+          "0:   cs    %0,%1,0(%2)\n"
+          "     jl    0b"
+          : "=&d" (ret)
+          : "d" (1), "a" (addr)
+          : "cc", "memory");
+         return ret;
+       }
 #    endif
 #  endif /* __GNUC__ */
 #  if (defined(ALPHA) && !defined(__GNUC__))
-#    define GC_test_and_set(addr) __cxx_test_and_set_atomic(addr, 1)
+#    ifndef OSF1
+       --> We currently assume that if gcc is not used, we are
+       --> running under Tru64.
+#    endif
+#    include <machine/builtins.h>
+#    include <c_asm.h>
+#    define GC_test_and_set(addr) __ATOMIC_EXCH_LONG(addr, 1)
 #    define GC_TEST_AND_SET_DEFINED
+#    define GC_clear(addr) { asm("mb"); *(volatile unsigned *)addr = 0; }
+#    define GC_CLEAR_DEFINED
 #  endif
 #  if defined(MSWIN32)
 #    define GC_test_and_set(addr) InterlockedExchange((LPLONG)addr,1)
 #      define GC_TEST_AND_SET_DEFINED
 #    elif __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
        || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
-#        define GC_test_and_set(addr) test_and_set(addr, 1)
+#       ifdef __GNUC__
+#          define GC_test_and_set(addr) _test_and_set((void *)addr,1)
+#       else
+#          define GC_test_and_set(addr) test_and_set((void *)addr,1)
+#       endif
 #    else
-#       define GC_test_and_set(addr) __test_and_set(addr,1)
+#       define GC_test_and_set(addr) __test_and_set32((void *)addr,1)
 #       define GC_clear(addr) __lock_release(addr);
 #       define GC_CLEAR_DEFINED
 #    endif
 #    define GC_TEST_AND_SET_DEFINED
 #  endif /* MIPS */
+#  if defined(_AIX)
+#    include <sys/atomic_op.h>
+#    if (defined(_POWER) || defined(_POWERPC)) 
+#      if defined(__GNUC__)  
+         inline static void GC_memsync() {
+           __asm__ __volatile__ ("sync" : : : "memory");
+         }
+#      else
+#        ifndef inline
+#          define inline __inline
+#        endif
+#        pragma mc_func GC_memsync { \
+           "7c0004ac" /* sync (same opcode used for dcs)*/ \
+         }
+#      endif
+#    else 
+#    error dont know how to memsync
+#    endif
+     inline static int GC_test_and_set(volatile unsigned int * addr) {
+          int oldvalue = 0;
+          if (compare_and_swap((void *)addr, &oldvalue, 1)) {
+            GC_memsync();
+            return 0;
+          } else return 1;
+     }
+#    define GC_TEST_AND_SET_DEFINED
+     inline static void GC_clear(volatile unsigned int *addr) {
+          GC_memsync();
+          *(addr) = 0;
+     }
+#    define GC_CLEAR_DEFINED
+
+#  endif
 #  if 0 /* defined(HP_PA) */
      /* The official recommendation seems to be to not use ldcw from   */
      /* user mode.  Since multithreaded incremental collection doesn't */
 #  endif
 
 #  if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
-      && !defined(GC_IRIX_THREADS)
+      && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
 #    define NO_THREAD (pthread_t)(-1)
 #    include <pthread.h>
 #    if defined(PARALLEL_MARK) 
          {
           char result;
           __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
-               : "=m"(*(addr)), "=r"(result)
-               : "r" (new_val), "0"(*(addr)), "a"(old) : "memory");
+               : "+m"(*(addr)), "=r"(result)
+               : "r" (new_val), "a"(old) : "memory");
           return (GC_bool) result;
          }
 #      endif /* !GENERIC_COMPARE_AND_SWAP */
-       inline static void GC_memory_write_barrier()
+       inline static void GC_memory_barrier()
        {
         /* We believe the processor ensures at least processor */
         /* consistent ordering.  Thus a compiler barrier       */
          __asm__ __volatile__("" : : : "memory");
        }
 #     endif /* I386 */
+
+#     if defined(POWERPC)
+#      if !defined(GENERIC_COMPARE_AND_SWAP)
+        /* Returns TRUE if the comparison succeeded. */
+        inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
+            GC_word old, GC_word new_val) 
+        {
+            int result, dummy;
+            __asm__ __volatile__(
+                "1:\tlwarx %0,0,%5\n"
+                  "\tcmpw %0,%4\n"
+                  "\tbne  2f\n"
+                  "\tstwcx. %3,0,%2\n"
+                  "\tbne- 1b\n"
+                  "\tsync\n"
+                  "\tli %1, 1\n"
+                  "\tb 3f\n"
+                "2:\tli %1, 0\n"
+                "3:\t\n"
+                :  "=&r" (dummy), "=r" (result), "=p" (addr)
+                :  "r" (new_val), "r" (old), "2"(addr)
+                : "cr0","memory");
+            return (GC_bool) result;
+        }
+#      endif /* !GENERIC_COMPARE_AND_SWAP */
+        inline static void GC_memory_barrier()
+        {
+            __asm__ __volatile__("sync" : : : "memory");
+        }
+#     endif /* POWERPC */
+
 #     if defined(IA64)
 #      if !defined(GENERIC_COMPARE_AND_SWAP)
          inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
 #      endif /* !GENERIC_COMPARE_AND_SWAP */
 #      if 0
        /* Shouldn't be needed; we use volatile stores instead. */
-        inline static void GC_memory_write_barrier()
+        inline static void GC_memory_barrier()
         {
           __sync_synchronize ();
         }
 #      endif /* 0 */
 #     endif /* IA64 */
+#     if defined(ALPHA)
+#      if !defined(GENERIC_COMPARE_AND_SWAP)
+#        if defined(__GNUC__)
+           inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
+                                                        GC_word old, GC_word new_val) 
+          {
+            unsigned long was_equal;
+             unsigned long temp;
+
+             __asm__ __volatile__(
+                             "1:     ldq_l %0,%1\n"
+                             "       cmpeq %0,%4,%2\n"
+                            "       mov %3,%0\n"
+                             "       beq %2,2f\n"
+                             "       stq_c %0,%1\n"
+                             "       beq %0,1b\n"
+                             "2:\n"
+                             "       mb\n"
+                             :"=&r" (temp), "=m" (*addr), "=&r" (was_equal)
+                             : "r" (new_val), "Ir" (old)
+                            :"memory");
+             return was_equal;
+           }
+#        else /* !__GNUC__ */
+           inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
+                                                        GC_word old, GC_word new_val) 
+         {
+           return __CMP_STORE_QUAD(addr, old, new_val, addr);
+          }
+#        endif /* !__GNUC__ */
+#      endif /* !GENERIC_COMPARE_AND_SWAP */
+#      ifdef __GNUC__
+         inline static void GC_memory_barrier()
+         {
+           __asm__ __volatile__("mb" : : : "memory");
+         }
+#      else
+#       define GC_memory_barrier() asm("mb")
+#      endif /* !__GNUC__ */
+#     endif /* ALPHA */
 #     if defined(S390)
 #      if !defined(GENERIC_COMPARE_AND_SWAP)
-        inline static GC_bool GC_compare_and_exchange(volatile C_word *addr,
-                                                      GC_word old, GC_word new_val) 
-        {
-          int retval;
-          __asm__ __volatile__ (
-#          ifndef __s390x__
-               "       cs  %1,%2,0(%3)\n"
-#          else
-               "       csg %1,%2,0(%3)\n"
-#         endif
-               "       ipm %0\n"
-               "       srl %0,28\n"
-               : "=&d" (retval), "+d" (old)
-               : "d" (new_val), "a" (addr)
-               : "cc", "memory");
-          return retval == 0;
-       }
+         inline static GC_bool GC_compare_and_exchange(volatile C_word *addr,
+                                         GC_word old, GC_word new_val)
+         {
+           int retval;
+           __asm__ __volatile__ (
+#            ifndef __s390x__
+               "     cs  %1,%2,0(%3)\n"
+#            else
+               "     csg %1,%2,0(%3)\n"
+#            endif
+             "     ipm %0\n"
+             "     srl %0,28\n"
+             : "=&d" (retval), "+d" (old)
+             : "d" (new_val), "a" (addr)
+             : "cc", "memory");
+           return retval == 0;
+         }
 #      endif
 #     endif
 #     if !defined(GENERIC_COMPARE_AND_SWAP)
                { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
                  pthread_mutex_unlock(&GC_allocate_ml); }
 #      else /* !GC_ASSERTIONS */
+#        if defined(NO_PTHREAD_TRYLOCK)
+#          define LOCK() GC_lock();
+#        else /* !defined(NO_PTHREAD_TRYLOCK) */
 #        define LOCK() \
           { if (0 != pthread_mutex_trylock(&GC_allocate_ml)) GC_lock(); }
+#        endif
 #        define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
 #      endif /* !GC_ASSERTIONS */
 #   endif /* USE_PTHREAD_LOCKS */
      /* on Irix anymore.                                               */
 #    include <mutex.h>
 
-     extern unsigned long GC_allocate_lock;
+     extern volatile unsigned int GC_allocate_lock;
        /* This is not a mutex because mutexes that obey the (optional)         */
        /* POSIX scheduling rules are subject to convoys in high contention     */
        /* applications.  This is basically a spin lock.                        */
                }
 #    define EXIT_GC() GC_collecting = 0;
 #  endif /* GC_IRIX_THREADS */
-#  ifdef GC_WIN32_THREADS
-#    include <windows.h>
-     GC_API CRITICAL_SECTION GC_allocate_ml;
-#    define LOCK() EnterCriticalSection(&GC_allocate_ml);
-#    define UNLOCK() LeaveCriticalSection(&GC_allocate_ml);
+#  if defined(GC_WIN32_THREADS)
+#    if defined(GC_PTHREADS)
+#      include <pthread.h>
+       extern pthread_mutex_t GC_allocate_ml;
+#      define LOCK()   pthread_mutex_lock(&GC_allocate_ml)
+#      define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
+#    else
+#      include <windows.h>
+       GC_API CRITICAL_SECTION GC_allocate_ml;
+#      define LOCK() EnterCriticalSection(&GC_allocate_ml);
+#      define UNLOCK() LeaveCriticalSection(&GC_allocate_ml);
+#    endif
 #  endif
 #  ifndef SET_LOCK_HOLDER
 #      define SET_LOCK_HOLDER()
index 8720657..c109738 100644 (file)
@@ -137,7 +137,7 @@ extern mse * GC_mark_stack;
 #ifdef __STDC__
 # ifdef PRINT_BLACK_LIST
     ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p,
-                       ptr_t source);
+                       word source);
 # else
     ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p);
 # endif
@@ -145,7 +145,7 @@ extern mse * GC_mark_stack;
   ptr_t GC_find_start();
 #endif
 
-mse *GC_signal_mark_stack_overflow(mse *msp);
+mse * GC_signal_mark_stack_overflow GC_PROTO((mse *msp));
 
 # ifdef GATHERSTATS
 #   define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz)
@@ -174,14 +174,6 @@ mse *GC_signal_mark_stack_overflow(mse *msp);
     } \
 }
 
-#ifdef PRINT_BLACK_LIST
-#   define GC_FIND_START(current, hhdr, new_hdr_p, source) \
-       GC_find_start(current, hhdr, new_hdr_p, source)
-#else
-#   define GC_FIND_START(current, hhdr, new_hdr_p, source) \
-       GC_find_start(current, hhdr, new_hdr_p)
-#endif
-
 /* Push the contents of current onto the mark stack if it is a valid   */
 /* ptr to a currently unmarked object.  Mark it.                       */
 /* If we assumed a standard-conforming compiler, we could probably     */
@@ -195,8 +187,7 @@ mse *GC_signal_mark_stack_overflow(mse *msp);
     GET_HDR(my_current, my_hhdr); \
     if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \
         hdr * new_hdr = GC_invalid_header; \
-         my_current = GC_FIND_START(my_current, my_hhdr, \
-                                   &new_hdr, (word)source); \
+         my_current = GC_find_start(my_current, my_hhdr, &new_hdr); \
          my_hhdr = new_hdr; \
     } \
     PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \
@@ -290,21 +281,39 @@ exit_label: ; \
 
 /*
  * Push a single value onto mark stack. Mark from the object pointed to by p.
+ * Invoke FIXUP_POINTER(p) before any further processing.
  * P is considered valid even if it is an interior pointer.
  * Previously marked objects are not pushed.  Hence we make progress even
  * if the mark stack overflows.
  */
-# define GC_PUSH_ONE_STACK(p, source) \
-    if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr      \
+
+# if NEED_FIXUP_POINTER
+    /* Try both the raw version and the fixed up one.  */
+#   define GC_PUSH_ONE_STACK(p, source) \
+      if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr    \
         && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) {      \
         PUSH_ONE_CHECKED_STACK(p, source);     \
-    }
+      } \
+      FIXUP_POINTER(p); \
+      if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr    \
+        && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) {      \
+        PUSH_ONE_CHECKED_STACK(p, source);     \
+      }
+# else /* !NEED_FIXUP_POINTER */
+#   define GC_PUSH_ONE_STACK(p, source) \
+      if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr    \
+        && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) {      \
+        PUSH_ONE_CHECKED_STACK(p, source);     \
+      }
+# endif
+
 
 /*
  * As above, but interior pointer recognition as for
  * normal for heap pointers.
  */
 # define GC_PUSH_ONE_HEAP(p,source) \
+    FIXUP_POINTER(p); \
     if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr      \
         && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) {      \
            GC_mark_stack_top = GC_mark_and_push( \
index b09c484..ffa398b 100644 (file)
 #   define BSD_TIME
 #endif
 
+#ifdef DGUX
+#   include <sys/types.h>
+#   include <sys/time.h>
+#   include <sys/resource.h>
+#endif /* DGUX */
+
 #ifdef BSD_TIME
 #   include <sys/types.h>
 #   include <sys/time.h>
 #   include <sys/resource.h>
 #endif /* BSD_TIME */
 
-# ifndef GC_H
-#   include "gc.h"
+# ifndef _GC_H
+#   include "../gc.h"
 # endif
 
 # ifndef GC_MARK_H
@@ -206,11 +212,10 @@ typedef char * ptr_t;     /* A generic pointer to which we can add        */
 #endif
 
 #if defined(GC_GCJ_SUPPORT) && ALIGNMENT < 8 && !defined(ALIGN_DOUBLE)
-   /* GCJ's Hashtable synchronization code requires 64-bit alignment.  */
+   /* GCJ's Hashtable synchronization code requires 64-bit alignment.  */
 #  define ALIGN_DOUBLE
 #endif
 
-
 /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
 # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
 #   define MERGE_SIZES
@@ -347,7 +352,8 @@ void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
 #   include <string.h>
 #   define BCOPY_EXISTS
 # endif
-# if defined(MACOSX)
+# if defined(DARWIN)
+#   include <string.h>
 #   define BCOPY_EXISTS
 # endif
 
@@ -360,68 +366,6 @@ void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
 #   define BZERO(x,n) bzero((char *)(x),(int)(n))
 # endif
 
-/* HBLKSIZE aligned allocation.  0 is taken to mean failure    */
-/* space is assumed to be cleared.                             */
-/* In the case os USE_MMAP, the argument must also be a        */
-/* physical page size.                                         */
-/* GET_MEM is currently not assumed to retrieve 0 filled space, */
-/* though we should perhaps take advantage of the case in which */
-/* does.                                                       */
-struct hblk;   /* See below.   */
-# ifdef PCR
-    char * real_malloc();
-#   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
-                                 + GC_page_size-1)
-# else
-#   ifdef OS2
-      void * os2_alloc(size_t bytes);
-#     define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
-                                   + GC_page_size) \
-                                    + GC_page_size-1)
-#   else
-#     if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
-        (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
-        (defined(SUNOS5) && !defined(USE_MMAP))
-#       define GET_MEM(bytes) HBLKPTR((size_t) \
-                                     calloc(1, (size_t)bytes + GC_page_size) \
-                                      + GC_page_size-1)
-#     else
-#      ifdef MSWIN32
-          extern ptr_t GC_win32_get_mem();
-#         define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
-#      else
-#        ifdef MACOS
-#          if defined(USE_TEMPORARY_MEMORY)
-               extern Ptr GC_MacTemporaryNewPtr(size_t size,
-                                                Boolean clearMemory);
-#               define GET_MEM(bytes) HBLKPTR( \
-                   GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
-                   + GC_page_size-1)
-#          else
-#                  define GET_MEM(bytes) HBLKPTR( \
-                       NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
-#          endif
-#        else
-#          ifdef MSWINCE
-             extern ptr_t GC_wince_get_mem();
-#            define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
-#          else
-#            if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
-               extern void *GC_amiga_get_mem(size_t size);
-               define GET_MEM(bytes) HBLKPTR((size_t) \
-                  GC_amiga_get_mem((size_t)bytes + GC_page_size) \
-                 + GC_page_size-1)
-#            else
-                extern ptr_t GC_unix_get_mem();
-#               define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
-#            endif
-#          endif
-#        endif
-#      endif
-#     endif
-#   endif
-# endif
-
 /* Delay any interrupts or signals that may abort this thread.  Data   */
 /* structures are in a consistent state outside this pair of calls.    */
 /* ANSI C allows both to be empty (though the standard isn't very      */
@@ -486,7 +430,7 @@ struct hblk;        /* See below.   */
 #   ifdef SMALL_CONFIG
 #      define ABORT(msg) abort();
 #   else
-       GC_API void GC_abort();
+       GC_API void GC_abort GC_PROTO((GC_CONST char * msg));
 #       define ABORT(msg) GC_abort(msg);
 #   endif
 # endif
@@ -646,9 +590,10 @@ extern GC_warn_proc GC_current_warn_proc;
  */
  
 # ifdef LARGE_CONFIG
-#   define LOG_PHT_ENTRIES  19  /* Collisions likely at 512K blocks,   */
-                               /* which is >= 2GB.  Each table takes   */
-                               /* 64KB.                                */
+#   define LOG_PHT_ENTRIES  20  /* Collisions likely at 1M blocks,     */
+                               /* which is >= 4GB.  Each table takes   */
+                               /* 128KB, some of which may never be    */
+                               /* touched.                             */
 # else
 #   ifdef SMALL_CONFIG
 #     define LOG_PHT_ENTRIES  14 /* Collisions are likely if heap grows        */
@@ -656,7 +601,7 @@ extern GC_warn_proc GC_current_warn_proc;
                                 /* Each hash table occupies 2K bytes.   */
 #   else /* default "medium" configuration */
 #     define LOG_PHT_ENTRIES  16 /* Collisions are likely if heap grows        */
-                                /* to more than 16K hblks >= 256MB.    */
+                                /* to more than 64K hblks >= 256MB.    */
                                 /* Each hash table occupies 8K bytes.  */
 #   endif
 # endif
@@ -897,6 +842,10 @@ struct _GC_arrays {
   word _mem_freed;
        /* Number of explicitly deallocated words of memory     */
        /* since last collection.                               */
+  word _finalizer_mem_freed;
+       /* Words of memory explicitly deallocated while         */
+       /* finalizers were running.  Used to approximate mem.   */
+       /* explicitly deallocated by finalizers.                */
   ptr_t _scratch_end_ptr;
   ptr_t _scratch_last_end_ptr;
        /* Used by headers.c, and can easily appear to point to */
@@ -957,7 +906,7 @@ struct _GC_arrays {
                       /* OFFSET_TOO_BIG if the value j would be too    */
                       /* large to fit in the entry.  (Note that the    */
                       /* size of these entries matters, both for       */
-                      /* space consumption and for cache utilization.  */
+                      /* space consumption and for cache utilization.) */
 #   define OFFSET_TOO_BIG 0xfe
 #   define OBJ_INVALID 0xff
 #   define MAP_ENTRY(map, bytes) (map)[bytes]
@@ -1067,6 +1016,7 @@ GC_API GC_FAR struct _GC_arrays GC_arrays;
 # define GC_words_finalized GC_arrays._words_finalized
 # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
 # define GC_mem_freed GC_arrays._mem_freed
+# define GC_finalizer_mem_freed GC_arrays._finalizer_mem_freed
 # define GC_scratch_end_ptr GC_arrays._scratch_end_ptr
 # define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr
 # define GC_mark_procs GC_arrays._mark_procs
@@ -1201,17 +1151,19 @@ extern struct hblk * GC_hblkfreelist[];
                                /* header structure associated with     */
                                /* block.                               */
 
-extern GC_bool GC_is_initialized;      /* GC_init() has been run.      */
-
 extern GC_bool GC_objects_are_marked;  /* There are marked objects in  */
                                        /* the heap.                    */
 
 #ifndef SMALL_CONFIG
   extern GC_bool GC_incremental;
                        /* Using incremental/generational collection. */
+# define TRUE_INCREMENTAL \
+       (GC_incremental && GC_time_limit != GC_TIME_UNLIMITED)
+       /* True incremental, not just generational, mode */
 #else
 # define GC_incremental FALSE
                        /* Hopefully allow optimizer to remove some code. */
+# define TRUE_INCREMENTAL FALSE
 #endif
 
 extern GC_bool GC_dirty_maintained;
@@ -1229,6 +1181,10 @@ extern long GC_large_alloc_warn_interval;
 extern long GC_large_alloc_warn_suppressed;
        /* Number of warnings suppressed so far.        */
 
+#ifdef THREADS
+  extern GC_bool GC_world_stopped;
+#endif
+
 /* Operations */
 # ifndef abs
 #   define abs(x)  ((x) < 0? (-(x)) : (x))
@@ -1403,6 +1359,11 @@ extern void (*GC_start_call_back) GC_PROTO((void));
 # else
   void GC_push_regs GC_PROTO((void));
 # endif
+# if defined(SPARC) || defined(IA64)
+  /* Cause all stacked registers to be saved in memory.  Return a      */
+  /* pointer to the top of the corresponding memory stack.             */
+  word GC_save_regs_in_stack GC_PROTO((void));
+# endif
                        /* Push register contents onto mark stack.      */
                        /* If NURSERY is defined, the default push      */
                        /* action can be overridden with GC_push_proc   */
@@ -1452,6 +1413,7 @@ void GC_set_fl_marks GC_PROTO((ptr_t p));
                                    /* Set all mark bits associated with */
                                    /* a free list.                      */
 void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp));
+void GC_remove_roots_inner GC_PROTO((char * b, char * e));
 GC_bool GC_is_static_root GC_PROTO((ptr_t p));
                /* Is the address p in one of the registered static     */
                /* root sections?                                       */
@@ -1462,11 +1424,10 @@ 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       */
-               /* dynamic library registration.                        */
+               /* We need to register the main data segment.  Returns  */
+               /* TRUE unless this is done implicitly as part of       */
+               /* dynamic library registration.                        */
   
 /* Machine dependent startup routines */
 ptr_t GC_get_stack_base GC_PROTO((void));      /* Cold end of stack */
@@ -1624,6 +1585,8 @@ GC_bool GC_collect_or_expand GC_PROTO(( \
                                /* until the blocks are available or    */
                                /* until it fails by returning FALSE.   */
 
+extern GC_bool GC_is_initialized;      /* GC_init() has been run.      */
+
 #if defined(MSWIN32) || defined(MSWINCE)
   void GC_deinit GC_PROTO((void));
                                 /* Free any resources allocated by      */
@@ -1665,6 +1628,8 @@ ptr_t GC_allocobj GC_PROTO((word sz, int kind));
                                /* Make the indicated                   */
                                /* free list nonempty, and return its   */
                                /* head.                                */
+
+void GC_free_inner(GC_PTR p);
   
 void GC_init_headers GC_PROTO((void));
 struct hblkhdr * GC_install_header GC_PROTO((struct hblk *h));
@@ -1694,6 +1659,12 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void));
                        /* Call *GC_finalizer_notifier if there are     */
                        /* finalizers to be run, and we haven't called  */
                        /* this procedure yet this GC cycle.            */
+
+GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
+GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
+                       /* Auxiliary fns to make finalization work      */
+                       /* correctly with displaced pointers introduced */
+                       /* by the debugging allocators.                 */
                        
 void GC_add_to_heap GC_PROTO((struct hblk *p, word bytes));
                        /* Add a HBLKSIZE aligned chunk to the heap.    */
@@ -1704,16 +1675,36 @@ void GC_print_obj GC_PROTO((ptr_t p));
                        /* description of the object to stderr.         */
 extern void (*GC_check_heap) GC_PROTO((void));
                        /* Check that all objects in the heap with      */
-                       /* debugging info are intact.  Print            */
-                       /* descriptions of any that are not.            */
+                       /* debugging info are intact.                   */
+                       /* Add any that are not to GC_smashed list.     */
+extern void (*GC_print_all_smashed) GC_PROTO((void));
+                       /* Print GC_smashed if it's not empty.          */
+                       /* Clear GC_smashed list.                       */
+extern void GC_print_all_errors GC_PROTO((void));
+                       /* Print smashed and leaked objects, if any.    */
+                       /* Clear the lists of such objects.             */
 extern void (*GC_print_heap_obj) GC_PROTO((ptr_t p));
                        /* If possible print s followed by a more       */
                        /* detailed description of the object           */
                        /* referred to by p.                            */
+#if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
+  void GC_print_address_map GC_PROTO((void));
+                       /* Print an address map of the process.         */
+#endif
 
+extern GC_bool GC_have_errors;  /* We saw a smashed or leaked object.  */
+                               /* Call error printing routine          */
+                               /* occasionally.                        */
 extern GC_bool GC_print_stats; /* Produce at least some logging output */
                                /* Set from environment variable.       */
 
+#ifndef NO_DEBUGGING
+  extern GC_bool GC_dump_regularly;  /* Generate regular debugging dumps. */
+# define COND_DUMP if (GC_dump_regularly) GC_dump();
+#else
+# define COND_DUMP
+#endif
+
 /* Macros used for collector internal allocation.      */
 /* These assume the collector lock is held.            */
 #ifdef DBG_HDRS_ALL
@@ -1785,6 +1776,7 @@ void GC_print_block_list GC_PROTO((void));
 void GC_print_hblkfreelist GC_PROTO((void));
 void GC_print_heap_sects GC_PROTO((void));
 void GC_print_static_roots GC_PROTO((void));
+void GC_print_finalization_stats GC_PROTO((void));
 void GC_dump GC_PROTO((void));
 
 #ifdef KEEP_BACK_PTRS
@@ -1866,6 +1858,16 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
 #      define GC_ASSERT(expr)
 # endif
 
+/* Check a compile time assertion at compile time.  The error  */
+/* message for failure is a bit baroque, but ...               */
+#if defined(mips) && !defined(__GNUC__)
+/* DOB: MIPSPro C gets an internal error taking the sizeof an array type. 
+   This code works correctly (ugliness is to avoid "unused var" warnings) */
+# define GC_STATIC_ASSERT(expr) do { if (0) { char j[(expr)? 1 : -1]; j[0]='\0'; j[0]=j[0]; } } while(0)
+#else
+# define GC_STATIC_ASSERT(expr) sizeof(char[(expr)? 1 : -1])
+#endif
+
 # if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
     /* We need additional synchronization facilities from the thread   */
     /* support.  We believe these are less performance critical                */
@@ -1911,7 +1913,7 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
   /* in Linux glibc, but it's not exported.)  Thus we continue to use  */
   /* the same hard-coded signals we've always used.                    */
 #  if !defined(SIG_SUSPEND)
-#   if defined(GC_LINUX_THREADS)
+#   if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)
 #    if defined(SPARC) && !defined(SIGPWR)
        /* SPARC/Linux doesn't properly define SIGPWR in <signal.h>.
         * It is aliased to SIGLOST in asm/signal.h, though.            */
index 809887f..29dab21 100644 (file)
  * provided the above notices are retained, and a notice that the code was
  * modified is included with the above copyright notice.
  */
+
+/*
+ * This header is private to the gc.  It is almost always included from
+ * gc_priv.h.  However it is possible to include it by itself if just the
+ * configuration macros are needed.  In that
+ * case, a few declarations relying on types declared in gc_priv.h will be
+ * omitted.
+ */
  
 #ifndef GCCONFIG_H
 
 # define GCCONFIG_H
 
+# ifndef GC_PRIVATE_H
+    /* Fake ptr_t declaration, just to avoid compilation errors.       */
+    /* This avoids many instances if "ifndef GC_PRIVATE_H" below.      */
+    typedef struct GC_undefined_struct * ptr_t;
+# endif
+
 /* Machine dependent parameters.  Some tuning parameters can be found  */
 /* near the top of gc_private.h.                                       */
 
@@ -25,7 +39,9 @@
 
 /* First a unified test for Linux: */
 # if defined(linux) || defined(__linux__)
+#  ifndef LINUX
 #    define LINUX
+#  endif
 # endif
 
 /* And one for NetBSD: */
@@ -44,9 +60,9 @@
 # endif
 
 /* Determine the machine type: */
-# if defined(__arm__) || defined(__thumb__)
+# if defined(__XSCALE__)
 #    define ARM32
-#    if !defined(LINUX) && !defined(NETBSD)
+#    if !defined(LINUX)
 #      define NOSYS
 #      define mach_type_known
 #    endif
@@ -69,7 +85,7 @@
 #    define SPARC
 #    define mach_type_known
 # endif
-# if defined(NETBSD) && defined(m68k)
+# if defined(NETBSD) && (defined(m68k) || defined(__m68k__))
 #    define M68K
 #    define mach_type_known
 # endif
@@ -77,7 +93,7 @@
 #    define POWERPC
 #    define mach_type_known
 # endif
-# if defined(NETBSD) && defined(__arm__)
+# if defined(NETBSD) && (defined(__arm32__) || defined(__arm__))
 #    define ARM32
 #    define mach_type_known
 # endif
 #    endif
 #    define mach_type_known
 # endif
+# if defined(__NetBSD__) && defined(__vax__)
+#    define VAX
+#    define mach_type_known
+# endif
 # if defined(mips) || defined(__mips) || defined(_mips)
 #    define MIPS
 #    if defined(nec_ews) || defined(_nec_ews)
 #    endif /* !LINUX */
 #    define mach_type_known
 # endif
+# if defined(DGUX) && (defined(i386) || defined(__i386__))
+#    define I386
+#    ifndef _USING_DGUX
+#    define _USING_DGUX
+#    endif
+#    define mach_type_known
+# endif
 # if defined(sequent) && (defined(i386) || defined(__i386__))
 #    define I386
 #    define SEQUENT
 #    define IA64
 #    define mach_type_known
 # endif
-# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__))
+# if defined(LINUX) && defined(__arm__)
+#    define ARM32
+#    define mach_type_known
+# endif
+# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) || defined(powerpc64) || defined(__powerpc64__))
 #    define POWERPC
 #    define mach_type_known
 # endif
 #   define MACOS
 #   define mach_type_known
 # endif
-# if defined(__MWERKS__) && defined(__powerc)
+# if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__)
 #   define POWERPC
 #   define MACOS
 #   define mach_type_known
 # endif
 # if defined(macosx) || \
      defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
-#    define MACOSX
+#    define DARWIN
 #    define POWERPC
 #    define mach_type_known
 # endif
 # if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
-#    define MACOSX
+#    define DARWIN
 #    define I386
      --> Not really supported, but at least we recognize it.
 # endif
 #   define CX_UX
 #   define mach_type_known
 # endif
-# if defined(DGUX)
+# if defined(DGUX) && defined(m88k)
 #   define M88K
     /* DGUX defined */
 #   define mach_type_known
                    /*                  (CX_UX and DGUX)                */
                    /*             S370       ==> 370-like machine      */
                    /*                  running Amdahl UTS4             */
-                   /*             S390       ==> 390-like machine      */
-                   /*                  running LINUX                   */
+                    /*             S390       ==> 390-like machine      */
+                   /*                  running LINUX                   */
                    /*             ARM32      ==> Intel StrongARM       */
                    /*             IA64       ==> Intel IPF             */
                    /*                            (e.g. Itanium)        */
                    /*                  (LINUX and HPUX)                */
-                   /*             IA64_32    ==> IA64 w/32 bit ABI     */
-                   /*                  (HPUX)                          */
                    /*             SH         ==> Hitachi SuperH        */
                    /*                  (LINUX & MSWINCE)               */
                    /*             X86_64     ==> AMD x86-64            */
+                   /*             POWERPC    ==> IBM/Apple PowerPC     */
+                   /*                  (MACOS(<=9),DARWIN(incl.MACOSX),*/
+                   /*                   LINUX, NETBSD, NOSYS variants) */
 
 
 /*
  * defining it to be 1 will always work, but perform poorly.
  *
  * DATASTART is the beginning of the data segment.
- * On UNIX systems, the collector will scan the area between DATASTART
+ * On some platforms SEARCH_FOR_DATA_START is defined.
+ * SEARCH_FOR_DATASTART will cause GC_data_start to
+ * be set to an address determined by accessing data backwards from _end
+ * until an unmapped page is found.  DATASTART will be defined to be
+ * GC_data_start.
+ * On UNIX-like systems, the collector will scan the area between DATASTART
  * and DATAEND for root pointers.
  *
  * DATAEND, if not `end' where `end' is defined as ``extern int end[];''.
  * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
  * 2) define exactly one of
  *     STACKBOTTOM (should be defined to be an expression)
+ *     LINUX_STACKBOTTOM
  *     HEURISTIC1
  *     HEURISTIC2
+ * If STACKBOTTOM is defined, then it's value will be used directly as the
+ * stack base.  If LINUX_STACKBOTTOM is defined, then it will be determined
+ * with a method appropriate for most Linux systems.  Currently we look
+ * first for __libc_stack_end, and if that fails read it from /proc.
  * If either of the last two macros are defined, then STACKBOTTOM is computed
  * during collector startup using one of the following two heuristics:
  * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to
  * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
  * clear the two words at GC_malloc-aligned address x.  By default,
  * word stores of 0 are used instead.
+ *
+ * HEAP_START may be defined as the initial address hint for mmap-based
+ * allocation.
  */
 
 /* If we are using a recent version of gcc, we can use __builtin_unwind_init()
 #   ifdef NETBSD
 #      define OS_TYPE "NETBSD"
 #      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
 #   endif
 #   ifdef LINUX
 #       define OS_TYPE "LINUX"
 #       define STACKBOTTOM ((ptr_t)0xf0000000)
+#       define USE_GENERIC_PUSH_REGS
+               /* We never got around to the assembly version. */
 /* #       define MPROTECT_VDB - Reported to not work  9/17/01 */
 #       ifdef __ELF__
 #            define DYNAMIC_LOADING
 #           include <features.h>
 #           if defined(__GLIBC__)&& __GLIBC__>=2
-#              define LINUX_DATA_START
+#              define SEARCH_FOR_DATA_START
 #           else /* !GLIBC2 */
                extern char **__environ;
 #              define DATASTART ((ptr_t)(&__environ))
 #     define DATAEND  /* not needed */
 #   endif
 #   ifdef LINUX
-#     define ALIGNMENT 4       /* Guess.  Can someone verify?  */
+#     if (defined (powerpc64) || defined(__powerpc64__))
+#       define ALIGNMENT 8
+#       define CPP_WORDSZ 64
+#     else
+#       define ALIGNMENT 4     /* Guess.  Can someone verify?  */
                                /* This was 2, but that didn't sound right. */
+#     endif
 #     define OS_TYPE "LINUX"
-#     define DYNAMIC_LOADING
+      /* HEURISTIC1 has been reliably reported to fail for a 32-bit    */
+      /* executable on a 64 bit kernel.                                        */
 #     define LINUX_STACKBOTTOM
-       /* Stack usually starts at 0x80000000 */
-#     define LINUX_DATA_START
+#     define DYNAMIC_LOADING
+#     define SEARCH_FOR_DATA_START
       extern int _end[];
 #     define DATAEND (_end)
 #   endif
-#   ifdef MACOSX
-      /* There are reasons to suspect this may not be reliable.        */
+#   ifdef DARWIN
 #     define ALIGNMENT 4
-#     define OS_TYPE "MACOSX"
+#     define OS_TYPE "DARWIN"
+#     define DYNAMIC_LOADING
+      /* XXX: see get_end(3), get_etext() and get_end() should not be used.
+         These aren't used when dyld support is enabled (it is by default) */
 #     define DATASTART ((ptr_t) get_etext())
+#     define DATAEND   ((ptr_t) get_end())
 #     define STACKBOTTOM ((ptr_t) 0xc0000000)
-#     define DATAEND   /* not needed */
-#     undef MPROTECT_VDB
+#     define USE_MMAP
+#     define USE_MMAP_ANON
+#     define USE_ASM_PUSH_REGS
+      /* This is potentially buggy. It needs more testing. See the comments in
+         os_dep.c */
+#     define MPROTECT_VDB
 #     include <unistd.h>
 #     define GETPAGESIZE() getpagesize()
+#     if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
+       /* The performance impact of prefetches is untested */
+#      define PREFETCH(x) \
+         __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
+#      define PREFETCH_FOR_WRITE(x) \
+         __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
+#     endif
+      /* There seems to be some issues with trylock hanging on darwin. This
+         should be looked into some more */
+#     define NO_PTHREAD_TRYLOCK
 #   endif
 #   ifdef NETBSD
 #     define ALIGNMENT 4
 #      define OS_TYPE "SUNOS5"
        extern int _etext[];
        extern int _end[];
-       extern char * GC_SysVGetDataStart();
-#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
+       extern ptr_t GC_SysVGetDataStart();
+#       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
 #      define DATAEND (_end)
 #      if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
 #          define USE_MMAP
 #   endif
 #   ifdef DRSNX
 #      define OS_TYPE "DRSNX"
-       extern char * GC_SysVGetDataStart();
+       extern ptr_t GC_SysVGetDataStart();
        extern int etext[];
-#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext)
+#       define DATASTART GC_SysVGetDataStart(0x10000, etext)
 #      define MPROTECT_VDB
 #       define STACKBOTTOM ((ptr_t) 0xdfff0000)
 #      define DYNAMIC_LOADING
       extern int _etext[];
 #     define DATAEND (_end)
 #     define SVR4
+      extern ptr_t GC_SysVGetDataStart();
 #     ifdef __arch64__
+#      define DATASTART GC_SysVGetDataStart(0x100000, _etext)
        /* libc_stack_end is not set reliably for sparc64 */
-#       define STACKBOTTOM ((ptr_t) 0x80000000000)
-#      define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, _etext)
+#       define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
 #     else
-#       define LINUX_STACKBOTTOM
-#      define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
+#       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
+#      define LINUX_STACKBOTTOM
 #     endif
 #   endif
 #   ifdef OPENBSD
 #   ifdef SUNOS5
 #      define OS_TYPE "SUNOS5"
         extern int _etext[], _end[];
-       extern char * GC_SysVGetDataStart();
+       extern ptr_t GC_SysVGetDataStart();
 #       define DATASTART GC_SysVGetDataStart(0x1000, _etext)
 #      define DATAEND (_end)
 /*     # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,      */
 #       define DYNAMIC_LOADING
 #      define ELF_CLASS ELFCLASS32
 #   endif
+#   ifdef DGUX
+#      define OS_TYPE "DGUX"
+       extern int _etext, _end;
+       extern ptr_t GC_SysVGetDataStart();
+#      define DATASTART GC_SysVGetDataStart(0x1000, &_etext)
+#      define DATAEND (&_end)
+#      define STACK_GROWS_DOWN
+#      define HEURISTIC2
+#      include <unistd.h>
+#      define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
+#      define DYNAMIC_LOADING
+#      ifndef USE_MMAP
+#        define USE_MMAP
+#      endif /* USE_MMAP */
+#      define MAP_FAILED (void *) -1
+#      ifdef USE_MMAP
+#        define HEAP_START (ptr_t)0x40000000
+#      else /* USE_MMAP */
+#        define HEAP_START DATAEND
+#      endif /* USE_MMAP */
+#   endif /* DGUX */
+
 #   ifdef LINUX
 #      ifndef __GNUC__
          /* The Intel compiler doesn't like inline assembly */
            /* possibly because Linux threads is itself a malloc client */
            /* and can't deal with the signals.                         */
 #      endif
+#      define HEAP_START 0x1000
+               /* This encourages mmap to give us low addresses,       */
+               /* thus allowing the heap to grow to ~3GB               */
 #       ifdef __ELF__
 #            define DYNAMIC_LOADING
 #           ifdef UNDEFINED    /* includes ro data */
 #           endif
 #           include <features.h>
 #           if defined(__GLIBC__) && __GLIBC__ >= 2
-#               define LINUX_DATA_START
+#               define SEARCH_FOR_DATA_START
 #           else
                 extern char **__environ;
 #                define DATASTART ((ptr_t)(&__environ))
        /*      DATAEND     = _data_end__               */
        /* To get it right for both, we take the        */
        /* minumum/maximum of the two.                  */
+#     ifndef MAX
 #      define MAX(x,y) ((x) > (y) ? (x) : (y))
+#     endif
+#     ifndef MIN
 #      define MIN(x,y) ((x) < (y) ? (x) : (y))
+#     endif
 #       define DATASTART ((ptr_t) MIN(_data_start__, _bss_start__))
 #       define DATAEND  ((ptr_t) MAX(_data_end__, _bss_end__))
 #      undef STACK_GRAN
 #      ifdef __ELF__
 #          define DYNAMIC_LOADING
 #      endif
-/* Handle unmapped hole i386*-*-freebsd[45]* may put between etext and edata. */
        extern char etext[];
-       extern char edata[];
-       extern char end[];
-#      define NEED_FIND_LIMIT
-#      define DATASTART ((ptr_t)(etext))
-#      define MIN(x,y) ((x) < (y) ? (x) : (y))
-#      define DATAEND (MIN (GC_find_limit (DATASTART, TRUE), DATASTART2))
-#      define DATASTART2 ((ptr_t)(edata))
-#      define DATAEND2 ((ptr_t)(end))
+       extern char * GC_FreeBSDGetDataStart();
+#      define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
 #   endif
 #   ifdef NETBSD
 #      define OS_TYPE "NETBSD"
 #     define DATASTART ((ptr_t)(__data_start))
 #     define ALIGNMENT 4
 #     define USE_GENERIC_PUSH_REGS
-#     define LINUX_STACKBOTTOM
+#     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
+#        define LINUX_STACKBOTTOM
+#     else
+#        define STACKBOTTOM 0x80000000
+#     endif
 #   endif /* Linux */
 #   ifdef EWS4800
 #      define HEURISTIC2
                              /* heap sections so they're not           */
                              /* considered as roots.                   */
 #      define OS_TYPE "IRIX5"
-#       define MPROTECT_VDB
+/*#       define MPROTECT_VDB DOB: this should work, but there is evidence */
+/*             of recent breakage.                                        */
 #       ifdef _MIPS_SZPTR
 #        define CPP_WORDSZ _MIPS_SZPTR
 #        define ALIGNMENT (_MIPS_SZPTR/8)
 #     define ALIGNMENT 4
 #     define HEURISTIC2
 #     define USE_GENERIC_PUSH_REGS
-      extern int _fdata[];
-#     define DATASTART ((ptr_t)(_fdata))
-      extern int _end[];
-#     define DATAEND ((ptr_t)(_end))
-#     define DYNAMIC_LOADING
+#     ifdef __ELF__
+        extern int etext[];
+#       define DATASTART GC_data_start
+#       define NEED_FIND_LIMIT
+#       define DYNAMIC_LOADING
+#     else
+#       define DATASTART ((ptr_t) 0x10000000)
+#       define STACKBOTTOM ((ptr_t) 0x7ffff000)
+#     endif /* _ELF_ */
 #  endif
 # endif
 
 # ifdef RS6000
 #   define MACH_TYPE "RS6000"
+#   ifdef ALIGNMENT
+#     undef ALIGNMENT
+#   endif
+#   ifdef IA64
+#     undef IA64 /* DOB: some AIX installs stupidly define IA64 in /usr/include/sys/systemcfg.h */
+#   endif
 #   ifdef __64BIT__
 #     define ALIGNMENT 8
 #     define CPP_WORDSZ 64
+#     define STACKBOTTOM ((ptr_t)0x1000000000000000)
 #   else
 #     define ALIGNMENT 4
 #     define CPP_WORDSZ 32
-#   endif
+#     define STACKBOTTOM ((ptr_t)((ulong)&errno))
+#   endif
+ /* From AIX linker man page:
+ _text Specifies the first location of the program.
+ _etext Specifies the first location after the program.
+ _data Specifies the first location of the data.
+ _edata Specifies the first location after the initialized data
+ _end or end Specifies the first location after all data.
+ */
     extern int _data[], _end[];
 #   define DATASTART ((ptr_t)((ulong)_data))
 #   define DATAEND ((ptr_t)((ulong)_end))
     extern int errno;
-#   define STACKBOTTOM ((ptr_t)((ulong)&errno))
 #   define USE_GENERIC_PUSH_REGS
 #   define DYNAMIC_LOADING
        /* For really old versions of AIX, this may have to be removed. */
 #     define OS_TYPE "LINUX"
 #     define LINUX_STACKBOTTOM
 #     define DYNAMIC_LOADING
-#     define LINUX_DATA_START
+#     define SEARCH_FOR_DATA_START
       extern int _end[];
-#     define DATAEND (_end)
+#     define DATAEND (&_end)
 #   endif /* LINUX */
 # endif /* HP_PA */
 
 # ifdef ALPHA
 #   define MACH_TYPE "ALPHA"
 #   define ALIGNMENT 8
+#   define CPP_WORDSZ 64
+#   ifndef LINUX
+#     define USE_GENERIC_PUSH_REGS
+      /* Gcc and probably the DEC/Compaq compiler spill pointers to preserved */
+      /* fp registers in some cases when the target is a 21264.  The assembly */
+      /* code doesn't handle that yet, and version dependencies make that a   */
+      /* bit tricky.  Do the easy thing for now.                                   */
+#   endif
 #   ifdef NETBSD
 #      define OS_TYPE "NETBSD"
 #      define HEURISTIC2
 #      define ELFCLASS32 32
 #      define ELFCLASS64 64
 #      define ELF_CLASS ELFCLASS64
-#      define CPP_WORDSZ 64
 #       define DYNAMIC_LOADING
 #   endif
 #   ifdef OPENBSD
 #      define OS_TYPE "OPENBSD"
 #      define HEURISTIC2
-#      define CPP_WORDSZ 64
 #      ifdef __ELF__   /* since OpenBSD/Alpha 2.9 */
 #         define DATASTART GC_data_start
 #         define ELFCLASS32 32
        extern char edata[];
        extern char end[];
 #      define NEED_FIND_LIMIT
-#      define DATASTART ((ptr_t)(etext))
+#      define DATASTART ((ptr_t)(&etext))
 #      define DATAEND (GC_find_limit (DATASTART, TRUE))
-#      define DATASTART2 ((ptr_t)(edata))
-#      define DATAEND2 ((ptr_t)(end))
-#      define CPP_WORDSZ 64
+#      define DATASTART2 ((ptr_t)(&edata))
+#      define DATAEND2 ((ptr_t)(&end))
 #   endif
 #   ifdef OSF1
 #      define OS_TYPE "OSF1"
 #      define DATASTART ((ptr_t) 0x140000000)
        extern int _end[];
-#      define DATAEND ((ptr_t) _end)
+#      define DATAEND ((ptr_t) &_end)
        extern char ** environ;
        /* round up from the value of environ to the nearest page boundary */
        /* Probably breaks if putenv is called before collector            */
        /* the text segment immediately follows the stack.              */
        /* Hence we give an upper pound.                                */
        /* This is currently unused, since we disabled HEURISTIC2       */
-       extern int __start[];
+       extern int __start[];
 #      define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
-#      define CPP_WORDSZ 64
-#      define MPROTECT_VDB
+#      ifndef GC_OSF1_THREADS
+         /* Unresolved signal issues with threads.     */
+#        define MPROTECT_VDB
+#       endif
 #      define DYNAMIC_LOADING
 #   endif
 #   ifdef LINUX
 #       define OS_TYPE "LINUX"
-#       define CPP_WORDSZ 64
 #       define STACKBOTTOM ((ptr_t) 0x120000000)
 #       ifdef __ELF__
 #        define SEARCH_FOR_DATA_START
-#        define DATASTART GC_data_start
 #         define DYNAMIC_LOADING
 #       else
 #           define DATASTART ((ptr_t) 0x140000000)
        extern char * GC_register_stackbottom;
 #      define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom)
 #      define SEARCH_FOR_DATA_START
-#      define DATASTART GC_data_start
 #      ifdef __GNUC__
 #         define DYNAMIC_LOADING
 #      else
 #   endif
 #   ifdef  DGUX
 #      define OS_TYPE "DGUX"
-       extern char * GC_SysVGetDataStart();
-#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext)
+       extern ptr_t GC_SysVGetDataStart();
+#       define DATASTART GC_SysVGetDataStart(0x10000, etext)
 #   endif
 #   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
 # endif
 
 # ifdef S370
+    /* If this still works, and if anyone cares, this should probably  */
+    /* be moved to the S390 category.                                  */
 #   define MACH_TYPE "S370"
 #   define ALIGNMENT 4 /* Required by hardware */
 #   define USE_GENERIC_PUSH_REGS
 #   ifdef UTS4
 #       define OS_TYPE "UTS4"
-        extern int etext[];
+       extern int etext[];
        extern int _etext[];
        extern int _end[];
-       extern char * GC_SysVGetDataStart();
-#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
+       extern ptr_t GC_SysVGetDataStart();
+#       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
 #      define DATAEND (_end)
 #      define HEURISTIC2
 #   endif
 #   define MACH_TYPE "S390"
 #   define USE_GENERIC_PUSH_REGS
 #   ifndef __s390x__
-#      define ALIGNMENT 4
-#      define CPP_WORDSZ 32
+#   define ALIGNMENT 4
+#   define CPP_WORDSZ 32
 #   else
-#      define ALIGNMENT 8
-#      define CPP_WORDSZ 64
-#      define HBLKSIZE 4096
+#   define ALIGNMENT 8
+#   define CPP_WORDSZ 64
+#   define HBLKSIZE 4096
 #   endif
 #   ifdef LINUX
 #       define OS_TYPE "LINUX"
 #       define LINUX_STACKBOTTOM
 #       define DYNAMIC_LOADING
-        extern int __data_start[];
+       extern int __data_start[];
 #       define DATASTART ((ptr_t)(__data_start))
-       extern int _end[];
-#      define DATAEND (_end)
-#      define CACHE_LINE_SIZE 256
-#      define GETPAGESIZE() 4096
+    extern int _end[];
+#   define DATAEND (_end)
+#   define CACHE_LINE_SIZE 256
+#   define GETPAGESIZE() 4096
 #   endif
 # endif
 
 #   ifdef NETBSD
 #       define OS_TYPE "NETBSD"
 #       define HEURISTIC2
-#      ifdef __ELF__
-#          define DATASTART GC_data_start
-#          define DYNAMIC_LOADING
-#      else
-            extern char etext[];
-#           define DATASTART ((ptr_t)(etext))
-#      endif
+       extern char etext[];
+#       define DATASTART ((ptr_t)(etext))
 #       define USE_GENERIC_PUSH_REGS
 #   endif
 #   ifdef LINUX
 #            define DYNAMIC_LOADING
 #           include <features.h>
 #           if defined(__GLIBC__) && __GLIBC__ >= 2
-#               define LINUX_DATA_START
+#               define SEARCH_FOR_DATA_START
 #           else
                 extern char **__environ;
 #                define DATASTART ((ptr_t)(&__environ))
 #     define STACKBOTTOM ((ptr_t) 0x7c000000)
 #     define USE_GENERIC_PUSH_REGS
 #     define DYNAMIC_LOADING
-#     define LINUX_DATA_START
+#     define SEARCH_FOR_DATA_START
       extern int _end[];
 #     define DATAEND (_end)
 #   endif
 #   define MACH_TYPE "X86_64"
 #   define ALIGNMENT 8
 #   define CPP_WORDSZ 64
-#   define HBLKSIZE 4096
+#   ifndef HBLKSIZE
+#     define HBLKSIZE 4096
+#   endif
 #   define CACHE_LINE_SIZE 64
 #   define USE_GENERIC_PUSH_REGS
 #   ifdef LINUX
 #              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
 #           endif
 #           include <features.h>
-#           define LINUX_DATA_START
+#           define SEARCH_FOR_DATA_START
             extern int _end[];
 #           define DATAEND (_end)
 #      else
 #   endif
 # endif
 
-#ifdef LINUX_DATA_START
-    /* Some Linux distributions arrange to define __data_start.  Some  */
-    /* define data_start as a weak symbol.  The latter is technically  */
-    /* broken, since the user program may define data_start, in which  */
-    /* case we lose.  Nonetheless, we try both, prefering __data_start.        */
-    /* We assume gcc.  */
-#   pragma weak __data_start
-    extern int __data_start[];
-#   pragma weak data_start
-    extern int data_start[];
-#   define DATASTART ((ptr_t)(__data_start != 0? __data_start : data_start))
-#endif
-
 #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   */
 # endif
 
 # if defined(SUNOS5) || defined(DRSNX) || defined(UTS4)
-    /* OS has SVR4 generic features.  Probably others also qualify.    */
+           /* OS has SVR4 generic features.  Probably others also qualify.     */
 #   define SVR4
 # endif
 
 # if defined(SUNOS5) || defined(DRSNX)
-    /* OS has SUNOS5 style semi-undocumented interface to dynamic      */
-    /* loader.                                                         */
+           /* OS has SUNOS5 style semi-undocumented interface to dynamic       */
+           /* loader.                                                          */
 #   define SUNOS5DL
-    /* OS has SUNOS5 style signal handlers.                            */
+           /* OS has SUNOS5 style signal handlers.                             */
 #   define SUNOS5SIGS
 # endif
 
 # endif
 
 # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \
-    || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
-    || defined(BSD) || defined(_AIX) || defined(MACOSX) || defined(OSF1)
+           || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
+